All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/33] DC Patches October 24, 2020
@ 2021-10-24 13:31 Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 01/33] drm/amd/display: Align bw context with hw config when system resume Rodrigo Siqueira
                   ` (33 more replies)
  0 siblings, 34 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez

This new DC version brings improvements in the following areas:
- Improvements for USB4;
- Isolate FPU code for DCN20, DCN301, and DSC;
- Fixes on Linking training;
- Refactoring some parts of the code, such as PSR;

Thanks

Ahmad Othman (2):
  drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1
  drm/amd/display: fix a crash on USB4 over C20 PHY

Anson Jacob (2):
  drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
  drm/amd/display: Remove unused macros

Anthony Koo (2):
  drm/amd/display: [FW Promotion] Release 0.0.89
  drm/amd/display: [FW Promotion] Release 0.0.90

Aric Cyr (4):
  drm/amd/display: Handle I2C-over-AUX write channel status update
  drm/amd/display: 3.2.158
  drm/amd/display: Fix 3DLUT skipped programming
  drm/amd/display: 3.2.159

Dmytro Laktyushkin (3):
  drm/amd/display: clean up dcn31 revision check
  drm/amd/display: restyle dcn31 resource header inline with other asics
  drm/amd/display: allow windowed mpo + odm

George Shen (2):
  drm/amd/display: Implement fixed DP drive settings
  drm/amd/display: Add comment for preferred_training_settings

Guo, Bing (2):
  drm/amd/display: Get ceiling for v_total calc
  drm/amd/display: set Layout properly for 8ch audio at timing
    validation

Hansen (1):
  drm/amd/display: Set phy_mux_sel bit in dmub scratch register

Jimmy Kizito (1):
  drm/amd/display: Add workaround flag for EDID read on certain docks

Lewis Huang (1):
  drm/amd/display: Align bw context with hw config when system resume

Martin Leung (1):
  drm/amd/display: Manually adjust strobe for DCN303

Meenakshikumar Somasundaram (2):
  drm/amd/display: FEC configuration for dpia links
  drm/amd/display: FEC configuration for dpia links in MST mode

Michael Strauss (2):
  drm/amd/display: Set i2c memory to light sleep during hw init
  drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate

Qingqing Zhuo (2):
  drm/amd/display: move FPU associated DSC code to DML folder
  drm/amd/display: move FPU associated DCN301 code to DML folder

Robin Chen (1):
  drm/amd/display: dc_link_set_psr_allow_active refactoring

Wenjing Liu (5):
  drm/amd/display: adopt DP2.0 LT SCR revision 8
  drm/amd/display: implement decide lane settings
  drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings
  drm/amd/display: add two lane settings training options
  drm/amd/display: fix link training regression for 1 or 2 lane

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   2 +
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c |  10 +-
 .../drm/amd/display/dc/bios/bios_parser2.c    |   2 +
 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |  16 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  17 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 118 ++++-
 .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |  15 +-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 498 +++++++-----------
 .../drm/amd/display/dc/core/dc_link_dpia.c    |  57 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  14 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |  23 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |   5 -
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  13 +-
 .../gpu/drm/amd/display/dc/dce/dce_audio.c    |   6 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |  34 +-
 .../gpu/drm/amd/display/dc/dce/dce_hwseq.h    |   3 +-
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c |  20 +
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h |   1 +
 .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c |  12 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   6 +
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |  19 +-
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c  |  14 +
 .../drm/amd/display/dc/dcn30/dcn30_dpp_cm.c   |   8 +-
 .../drm/amd/display/dc/dcn30/dcn30_resource.c |  35 +-
 .../gpu/drm/amd/display/dc/dcn301/Makefile    |  26 -
 .../amd/display/dc/dcn301/dcn301_resource.c   | 349 +-----------
 .../amd/display/dc/dcn301/dcn301_resource.h   |   3 +
 .../amd/display/dc/dcn303/dcn303_resource.c   |  14 +
 .../display/dc/dcn31/dcn31_dio_link_encoder.c |   4 +-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   5 +
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |  11 +-
 .../drm/amd/display/dc/dcn31/dcn31_resource.h |  10 +
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h    |   2 +
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |   6 +
 .../amd/display/dc/dml/dcn301/dcn301_fpu.c    | 390 ++++++++++++++
 .../amd/display/dc/dml/dcn301/dcn301_fpu.h    |  42 ++
 .../amd/display/dc/{ => dml}/dsc/qp_tables.h  |   0
 .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.c  | 291 ++++++++++
 .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.h  |  94 ++++
 drivers/gpu/drm/amd/display/dc/dsc/Makefile   |  29 -
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c  | 259 ---------
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h  |  50 +-
 .../gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c  |   1 -
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |  16 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |   2 +
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |   1 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |  55 +-
 .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c |   2 +
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c   |   1 +
 .../display/include/grph_object_ctrl_defs.h   |   1 +
 .../amd/display/include/i2caux_interface.h    |   3 +
 .../amd/display/include/link_service_types.h  |  29 +-
 .../amd/display/modules/freesync/freesync.c   |  15 +-
 .../drm/amd/display/modules/inc/mod_hdcp.h    |   2 +
 55 files changed, 1529 insertions(+), 1134 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
 rename drivers/gpu/drm/amd/display/dc/{ => dml}/dsc/qp_tables.h (100%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/33] drm/amd/display: Align bw context with hw config when system resume
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 02/33] drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled Rodrigo Siqueira
                   ` (32 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Lewis Huang, Anthony Koo

From: Lewis Huang <Lewis.Huang@amd.com>

[Why]
When the vbios config and driver config are different, if we update
clock to lower before call program_timing and program_pixel_clk, garbage
appear.

[How]
Align bw context with hw config when system resume

Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Lewis Huang <Lewis.Huang@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 44d27579d898..a25732d07222 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -1378,6 +1378,12 @@ void dcn10_init_hw(struct dc *dc)
 	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
 		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
 
+	/* Align bw context with hw config when system resume. */
+	if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
+		dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz;
+		dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz;
+	}
+
 	// Initialize the dccg
 	if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init)
 		dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 02/33] drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 01/33] drm/amd/display: Align bw context with hw config when system resume Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 03/33] drm/amd/display: Get ceiling for v_total calc Rodrigo Siqueira
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Christian König, Hersen Wu,
	Harry Wentland

From: Anson Jacob <Anson.Jacob@amd.com>

Limit when FPU is enabled to only functions that does FPU operations for
dcn20_resource_construct, which gets called during driver
initialization.

Enabling FPU operation disables preemption.  Sleeping functions(mutex
(un)lock, memory allocation using GFP_KERNEL, etc.) should not be called
when preemption is disabled.

Fixes the following case caught by enabling
CONFIG_DEBUG_ATOMIC_SLEEP in kernel config
[    1.338434] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:281
[    1.347395] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 197, name: systemd-udevd
[    1.356356] CPU: 7 PID: 197 Comm: systemd-udevd Not tainted 5.13.0+ #3
[    1.356358] Hardware name: System manufacturer System Product Name/PRIME X570-PRO, BIOS 3405 02/01/2021
[    1.356360] Call Trace:
[    1.356361]  dump_stack+0x6b/0x86
[    1.356366]  ___might_sleep.cold+0x87/0x98
[    1.356370]  __might_sleep+0x4b/0x80
[    1.356372]  mutex_lock+0x21/0x50
[    1.356376]  smu_get_uclk_dpm_states+0x3f/0x80 [amdgpu]
[    1.356538]  pp_nv_get_uclk_dpm_states+0x35/0x50 [amdgpu]
[    1.356711]  init_soc_bounding_box+0xf9/0x210 [amdgpu]
[    1.356892]  ? create_object+0x20d/0x340
[    1.356897]  ? dcn20_resource_construct+0x46f/0xd30 [amdgpu]
[    1.357077]  dcn20_resource_construct+0x4b1/0xd30 [amdgpu]
...

Tested on: 5700XT (NAVI10 0x1002:0x731F 0x1DA2:0xE410 0xC1)

Cc: Christian König <christian.koenig@amd.com>
Cc: Hersen Wu <hersenxs.wu@amd.com>
Cc: Anson Jacob <Anson.Jacob@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>

Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Anson Jacob <Anson.Jacob@amd.com>
---
 .../drm/amd/display/dc/dcn20/dcn20_resource.c    | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 756f5d411d9a..001737487800 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -3698,16 +3698,22 @@ static bool init_soc_bounding_box(struct dc *dc,
 			clock_limits_available = (status == PP_SMU_RESULT_OK);
 		}
 
-		if (clock_limits_available && uclk_states_available && num_states)
+		if (clock_limits_available && uclk_states_available && num_states) {
+			DC_FP_START();
 			dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states);
-		else if (clock_limits_available)
+			DC_FP_END();
+		} else if (clock_limits_available) {
+			DC_FP_START();
 			dcn20_cap_soc_clocks(loaded_bb, max_clocks);
+			DC_FP_END();
+		}
 	}
 
 	loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
 	loaded_ip->max_num_dpp = pool->base.pipe_count;
+	DC_FP_START();
 	dcn20_patch_bounding_box(dc, loaded_bb);
-
+	DC_FP_END();
 	return true;
 }
 
@@ -3727,8 +3733,6 @@ static bool dcn20_resource_construct(
 	enum dml_project dml_project_version =
 			get_dml_project_version(ctx->asic_id.hw_internal_rev);
 
-	DC_FP_START();
-
 	ctx->dc_bios->regs = &bios_regs;
 	pool->base.funcs = &dcn20_res_pool_funcs;
 
@@ -4077,12 +4081,10 @@ static bool dcn20_resource_construct(
 		pool->base.oem_device = NULL;
 	}
 
-	DC_FP_END();
 	return true;
 
 create_fail:
 
-	DC_FP_END();
 	dcn20_resource_destruct(pool);
 
 	return false;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 03/33] drm/amd/display: Get ceiling for v_total calc
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 01/33] drm/amd/display: Align bw context with hw config when system resume Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 02/33] drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 04/33] drm/amd/display: dc_link_set_psr_allow_active refactoring Rodrigo Siqueira
                   ` (30 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Guo, Bing, Chris Park

From: "Guo, Bing" <Bing.Guo@amd.com>

Updating certain variable blanking calculations to use ceiling function.

Reviewed-by: Chris Park <chris.park@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Bing Guo <Bing.Guo@amd.com>
---
 .../drm/amd/display/modules/freesync/freesync.c   | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index b99aa232bd8b..bd1d1dc93629 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -155,9 +155,18 @@ 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;
 
-	v_total = div64_u64(div64_u64(((unsigned long long)(
-				duration_in_us) * (stream->timing.pix_clk_100hz / 10)),
-				stream->timing.h_total), 1000);
+	if (dc_is_hdmi_signal(stream->signal)) {
+		uint32_t h_total_up_scaled;
+
+		h_total_up_scaled = stream->timing.h_total * 10000;
+		v_total = div_u64((unsigned long long)duration_in_us
+					* stream->timing.pix_clk_100hz + (h_total_up_scaled - 1),
+					h_total_up_scaled);
+	} else {
+		v_total = div64_u64(div64_u64(((unsigned long long)(
+					duration_in_us) * (stream->timing.pix_clk_100hz / 10)),
+					stream->timing.h_total), 1000);
+	}
 
 	/* v_total cannot be less than nominal */
 	if (v_total < stream->timing.v_total) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 04/33] drm/amd/display: dc_link_set_psr_allow_active refactoring
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (2 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 03/33] drm/amd/display: Get ceiling for v_total calc Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 05/33] drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1 Rodrigo Siqueira
                   ` (29 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Robin Chen, Anthony Koo

From: Robin Chen <po-tchen@amd.com>

[Why]
To expose new power optimization flags to PSR interface. It allows the
PSR related power features can be enabled separately base on different
use scenarios.

Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Robin Chen <po-tchen@amd.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 10 +++-
 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |  6 ++-
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  7 ++-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 39 ++++++++++------
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  8 +++-
 drivers/gpu/drm/amd/display/dc/dc.h           |  6 +++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  5 +-
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 20 ++++++++
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h |  1 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 46 +++++++++++++++++++
 10 files changed, 125 insertions(+), 23 deletions(-)

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 70a554f1e725..c022e56f9459 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
@@ -107,6 +107,8 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
 	 */
 	// Init fail safe of 2 frames static
 	unsigned int num_frames_static = 2;
+	unsigned int power_opt = 0;
+	bool psr_enable = true;
 
 	DRM_DEBUG_DRIVER("Enabling psr...\n");
 
@@ -133,7 +135,9 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
 					   &stream, 1,
 					   &params);
 
-	return dc_link_set_psr_allow_active(link, true, false, false);
+	power_opt |= psr_power_opt_z10_static_screen;
+
+	return dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt);
 }
 
 /*
@@ -144,10 +148,12 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
  */
 bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
 {
+	unsigned int power_opt = 0;
+	bool psr_enable = false;
 
 	DRM_DEBUG_DRIVER("Disabling psr...\n");
 
-	return dc_link_set_psr_allow_active(stream->link, false, true, false);
+	return dc_link_set_psr_allow_active(stream->link, &psr_enable, true, false, &power_opt);
 }
 
 /*
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 1548b2a3fe03..acbda3962650 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
@@ -100,11 +100,13 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
 
 	if (edp_num) {
 		for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
+			bool allow_active = false;
+
 			edp_link = edp_links[panel_inst];
 			if (!edp_link->psr_settings.psr_feature_enabled)
 				continue;
 			clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
-			dc_link_set_psr_allow_active(edp_link, false, false, false);
+			dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
 		}
 	}
 
@@ -124,7 +126,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
 			if (!edp_link->psr_settings.psr_feature_enabled)
 				continue;
 			dc_link_set_psr_allow_active(edp_link,
-					clk_mgr->psr_allow_active_cache, false, false);
+					&clk_mgr->psr_allow_active_cache, false, false, NULL);
 		}
 	}
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 8be04be19124..a575d372ef5f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3479,6 +3479,7 @@ void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_
 bool dc_set_psr_allow_active(struct dc *dc, bool enable)
 {
 	int i;
+	bool allow_active;
 
 	for (i = 0; i < dc->current_state->stream_count ; i++) {
 		struct dc_link *link;
@@ -3490,10 +3491,12 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable)
 
 		if (link->psr_settings.psr_feature_enabled) {
 			if (enable && !link->psr_settings.psr_allow_active) {
-				if (!dc_link_set_psr_allow_active(link, true, false, false))
+				allow_active = true;
+				if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL))
 					return false;
 			} else if (!enable && link->psr_settings.psr_allow_active) {
-				if (!dc_link_set_psr_allow_active(link, false, true, false))
+				allow_active = false;
+				if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL))
 					return false;
 			}
 		}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index e5d6cbd7ea78..dfec35caf426 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2916,8 +2916,8 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
 	return true;
 }
 
-bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
-		bool wait, bool force_static)
+bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
+		bool wait, bool force_static, const unsigned int *power_opts)
 {
 	struct dc  *dc = link->ctx->dc;
 	struct dmcu *dmcu = dc->res_pool->dmcu;
@@ -2930,20 +2930,33 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
 	if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
 		return false;
 
-	link->psr_settings.psr_allow_active = allow_active;
+	/* Set power optimization flag */
+	if (power_opts && link->psr_settings.psr_power_opt != *power_opts) {
+		link->psr_settings.psr_power_opt = *power_opts;
+
+		if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt)
+			psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt);
+	}
+
+	/* Enable or Disable PSR */
+	if (allow_active && link->psr_settings.psr_allow_active != *allow_active) {
+		link->psr_settings.psr_allow_active = *allow_active;
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-	if (!allow_active)
-		dc_z10_restore(dc);
+		if (!link->psr_settings.psr_allow_active)
+			dc_z10_restore(dc);
 #endif
 
-	if (psr != NULL && link->psr_settings.psr_feature_enabled) {
-		if (force_static && psr->funcs->psr_force_static)
-			psr->funcs->psr_force_static(psr, panel_inst);
-		psr->funcs->psr_enable(psr, allow_active, wait, panel_inst);
-	} else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
-		dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
-	else
-		return false;
+		if (psr != NULL && link->psr_settings.psr_feature_enabled) {
+			if (force_static && psr->funcs->psr_force_static)
+				psr->funcs->psr_force_static(psr, panel_inst);
+			psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst);
+		} else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) &&
+			link->psr_settings.psr_feature_enabled)
+			dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait);
+		else
+			return false;
+	}
 
 	return true;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 296b0defcd1c..3819eb58a9e5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -3523,6 +3523,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
 		if (psr_error_status.bits.LINK_CRC_ERROR ||
 				psr_error_status.bits.RFB_STORAGE_ERROR ||
 				psr_error_status.bits.VSC_SDP_ERROR) {
+			bool allow_active;
+
 			/* Acknowledge and clear error bits */
 			dm_helpers_dp_write_dpcd(
 				link->ctx,
@@ -3532,8 +3534,10 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
 				sizeof(psr_error_status.raw));
 
 			/* PSR error, disable and re-enable PSR */
-			dc_link_set_psr_allow_active(link, false, true, false);
-			dc_link_set_psr_allow_active(link, true, true, false);
+			allow_active = false;
+			dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
+			allow_active = true;
+			dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
 
 			return true;
 		} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index fc3f0fd1f068..f0141f27880f 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -342,6 +342,12 @@ enum visual_confirm {
 	VISUAL_CONFIRM_SWIZZLE = 9,
 };
 
+enum dc_psr_power_opts {
+	psr_power_opt_invalid = 0x0,
+	psr_power_opt_smu_opt_static_screen = 0x1,
+	psr_power_opt_z10_static_screen = 0x10,
+};
+
 enum dcc_option {
 	DCC_ENABLE = 0,
 	DCC_DISABLE = 1,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index a73d64b1fd33..eaff496690af 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -85,6 +85,7 @@ struct psr_settings {
 	 */
 	bool psr_frame_capture_indication_req;
 	unsigned int psr_sdp_transmit_line_num_deadline;
+	unsigned int psr_power_opt;
 };
 
 /*
@@ -267,8 +268,8 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);
 
 int dc_link_get_target_backlight_pwm(const struct dc_link *link);
 
-bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable,
-		bool wait, bool force_static);
+bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable,
+		bool wait, bool force_static, const unsigned int *power_opts);
 
 bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index 05d96ca80512..90eb8eedacf2 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -227,6 +227,25 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_
 	dc_dmub_srv_wait_idle(dc->dmub_srv);
 }
 
+/**
+ * Set PSR power optimization flags.
+ */
+static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt)
+{
+	union dmub_rb_cmd cmd;
+	struct dc_context *dc = dmub->ctx;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.psr_set_power_opt.header.type = DMUB_CMD__PSR;
+	cmd.psr_set_power_opt.header.sub_type = DMUB_CMD__SET_PSR_POWER_OPT;
+	cmd.psr_set_power_opt.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_power_opt_data);
+	cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt;
+
+	dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
+	dc_dmub_srv_cmd_execute(dc->dmub_srv);
+	dc_dmub_srv_wait_idle(dc->dmub_srv);
+}
+
 /*
  * Setup PSR by programming phy registers and sending psr hw context values to firmware.
  */
@@ -358,6 +377,7 @@ static const struct dmub_psr_funcs psr_funcs = {
 	.psr_set_level			= dmub_psr_set_level,
 	.psr_force_static		= dmub_psr_force_static,
 	.psr_get_residency		= dmub_psr_get_residency,
+	.psr_set_power_opt		= dmub_psr_set_power_opt,
 };
 
 /*
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
index 9675c269e649..5dbd479660f1 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
@@ -46,6 +46,7 @@ struct dmub_psr_funcs {
 	void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst);
 	void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency,
 	uint8_t panel_inst);
+	void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt);
 };
 
 struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
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 bfe052afc518..f4bd9ece2af2 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -1379,6 +1379,10 @@ enum dmub_cmd_psr_type {
 	 * Forces PSR enabled until an explicit PSR disable call.
 	 */
 	DMUB_CMD__PSR_FORCE_STATIC		= 5,
+	/**
+	 * Set PSR power option
+	 */
+	DMUB_CMD__SET_PSR_POWER_OPT = 7,
 };
 
 /**
@@ -1676,6 +1680,44 @@ struct dmub_rb_cmd_psr_force_static {
 	struct dmub_cmd_psr_force_static_data psr_force_static_data;
 };
 
+/**
+ * Data passed from driver to FW in a DMUB_CMD__SET_PSR_POWER_OPT command.
+ */
+struct dmub_cmd_psr_set_power_opt_data {
+	/**
+	 * PSR control version.
+	 */
+	uint8_t cmd_version;
+	/**
+	 * Panel Instance.
+	 * Panel isntance to identify which psr_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[2];
+	/**
+	 * PSR power option
+	 */
+	uint32_t power_opt;
+};
+
+/**
+ * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command.
+ */
+struct dmub_rb_cmd_psr_set_power_opt {
+	/**
+	 * Command header.
+	 */
+	struct dmub_cmd_header header;
+	/**
+	 * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command.
+	 */
+	struct dmub_cmd_psr_set_power_opt_data psr_set_power_opt_data;
+};
+
 /**
  * Set of HW components that can be locked.
  *
@@ -2459,6 +2501,10 @@ union dmub_rb_cmd {
 	 * Definition of a DMUB_CMD__PSR_FORCE_STATIC command.
 	 */
 	struct dmub_rb_cmd_psr_force_static psr_force_static;
+	/**
+	 * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command.
+	 */
+	struct dmub_rb_cmd_psr_set_power_opt psr_set_power_opt;
 	/**
 	 * Definition of a DMUB_CMD__PLAT_54186_WA command.
 	 */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 05/33] drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (3 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 04/33] drm/amd/display: dc_link_set_psr_allow_active refactoring Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 06/33] drm/amd/display: move FPU associated DSC code to DML folder Rodrigo Siqueira
                   ` (28 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Ahmad Othman, Wenjing Liu, Ahmad Othman

From: Ahmad Othman <ahmad.Othman@amd.com>

[Why]
Created new fields that matches new B0 structs On DCN31 the mapping of
DIO output to PHY differs from A0 to B0 boards with new PHY C20 & this
new mapping needed to be handled.

[How]
Mapped new structure based on new structs Added logic for mapping over
A0 and B0 boards Hooked all new structs together.

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Ahmad Othman <Ahmad.Othman@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 53 ++++++++++++++++++-
 drivers/gpu/drm/amd/display/dc/dc.h           | 13 +++--
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h    |  2 +
 .../drm/amd/display/modules/inc/mod_hdcp.h    |  2 +
 4 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index dfec35caf426..42f96de496cb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3582,6 +3582,9 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 	struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	struct link_encoder *link_enc = NULL;
+	struct dc_state *state = pipe_ctx->stream->ctx->dc->current_state;
+	struct link_enc_assignment link_enc_assign;
+	int i;
 #endif
 
 	if (cp_psp && cp_psp->funcs.update_stream_config) {
@@ -3595,9 +3598,57 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 		config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 		config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA;
-		if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY) {
+		
+		if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY ||
+				pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
 			link_enc = pipe_ctx->stream->link->link_enc;
+			config.dio_output_type = pipe_ctx->stream->link->ep_type;
+			config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
+			// Initialize PHY ID with ABCDE - 01234 mapping except when it is B0
 			config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
+
+			//look up the link_enc_assignment for the current pipe_ctx
+			for (i = 0; i < state->stream_count; i++) {
+				if (pipe_ctx->stream == state->streams[i]) {
+					link_enc_assign = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
+				}
+			}
+
+			if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0)
+				config.dig_be = link_enc_assign.eng_id;
+
+			// Add RegKey to guard B0 implementation
+			if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 && link_enc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+				if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
+					link_enc = pipe_ctx->stream->link->link_enc;
+
+					// enum ID 1-4 maps to DPIA PHY ID 0-3
+					config.phy_idx = link_enc_assign.ep_id.link_id.enum_id - ENUM_ID_1;
+				} else {  // for non DPIA mode over B0, ABCDE maps to 01564
+
+					switch (link_enc->transmitter) {
+					case TRANSMITTER_UNIPHY_A:
+						config.phy_idx = 0;
+						break;
+					case TRANSMITTER_UNIPHY_B:
+						config.phy_idx = 1;
+						break;
+					case TRANSMITTER_UNIPHY_C:
+						config.phy_idx = 5;
+						break;
+					case TRANSMITTER_UNIPHY_D:
+						config.phy_idx = 6;
+						break;
+					case TRANSMITTER_UNIPHY_E:
+						config.phy_idx = 4;
+						break;
+					default:
+						config.phy_idx = 0;
+						break;
+					}
+
+				}
+			}
 		} else if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) {
 			link_enc = link_enc_cfg_get_link_enc_used_by_stream(
 					pipe_ctx->stream->ctx->dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index f0141f27880f..23977de4811b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -211,12 +211,12 @@ struct dc_dcc_setting {
 	unsigned int max_uncompressed_blk_size;
 	bool independent_64b_blks;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-	//These bitfields to be used starting with DCN 3.0
+	//These bitfields to be used starting with DCN
 	struct {
-		uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN 3.0 (the worst compression case)
-		uint32_t dcc_128_128_uncontrained : 1;  //available in ASICs before DCN 3.0
-		uint32_t dcc_256_128_128 : 1;		//available starting with DCN 3.0
-		uint32_t dcc_256_256_unconstrained : 1;  //available in ASICs before DCN 3.0 (the best compression case)
+		uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN (the worst compression case)
+		uint32_t dcc_128_128_uncontrained : 1;  //available in ASICs before DCN
+		uint32_t dcc_256_128_128 : 1;		//available starting with DCN
+		uint32_t dcc_256_256_unconstrained : 1;  //available in ASICs before DCN (the best compression case)
 	} dcc_controls;
 #endif
 };
@@ -731,6 +731,9 @@ struct dc {
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	bool idle_optimizations_allowed;
 #endif
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+	bool enable_c20_dtm_b0;
+#endif
 
 	/* Require to maintain clocks and bandwidth for UEFI enabled HW */
 
diff --git a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
index 43f33e186088..511f9e1159c7 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h
@@ -35,6 +35,8 @@ struct cp_psp_stream_config {
 	uint8_t link_enc_idx;
 	uint8_t stream_enc_idx;
 	uint8_t phy_idx;
+	uint8_t dio_output_idx;
+	uint8_t dio_output_type;
 	uint8_t assr_enabled;
 	uint8_t mst_enabled;
 	uint8_t dp2_enabled;
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 f37101f5a777..6d648c889866 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
@@ -249,6 +249,8 @@ struct mod_hdcp_link {
 	uint8_t ddc_line;
 	uint8_t link_enc_idx;
 	uint8_t phy_idx;
+	uint8_t dio_output_type;
+	uint8_t dio_output_id;
 	uint8_t hdcp_supported_informational;
 	union {
 		struct mod_hdcp_displayport dp;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 06/33] drm/amd/display: move FPU associated DSC code to DML folder
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (4 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 05/33] drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 07/33] drm/amd/display: fix a crash on USB4 over C20 PHY Rodrigo Siqueira
                   ` (27 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Christian König, Hersen Wu,
	Harry Wentland

From: Qingqing Zhuo <qingqing.zhuo@amd.com>

[Why & How]
As part of the FPU isolation work documented in
https://patchwork.freedesktop.org/series/93042/, isolate code that uses
FPU in DSC to DML, where all FPU code should locate.

This change does not refactor any functions but move code around.

Cc: Christian König <christian.koenig@amd.com>
Cc: Hersen Wu <hersenxs.wu@amd.com>
Cc: Anson Jacob <Anson.Jacob@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Tested-by: Anson Jacob <Anson.Jacob@amd.com>
Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |   3 +
 .../amd/display/dc/{ => dml}/dsc/qp_tables.h  |   0
 .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.c  | 291 ++++++++++++++++++
 .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.h  |  94 ++++++
 drivers/gpu/drm/amd/display/dc/dsc/Makefile   |  29 --
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c  | 259 ----------------
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h  |  50 +--
 .../gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c  |   1 -
 8 files changed, 389 insertions(+), 338 deletions(-)
 rename drivers/gpu/drm/amd/display/dc/{ => dml}/dsc/qp_tables.h (100%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h

diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index 169a4e68f86e..e7bb69ec99b6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -70,6 +70,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(fram
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_rcflags)
@@ -84,6 +85,7 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_rcfla
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o  := $(dml_rcflags)
 endif
 CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags)
@@ -99,6 +101,7 @@ DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
 DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o
 DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o
 DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o
+DML += dsc/rc_calc_fpu.o
 endif
 
 AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h b/drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h
rename to drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
new file mode 100644
index 000000000000..3ee858f311d1
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "rc_calc_fpu.h"
+
+#include "qp_tables.h"
+#include "amdgpu_dm/dc_fpu.h"
+
+#define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min)
+
+#define MODE_SELECT(val444, val422, val420) \
+	(cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420))
+
+
+#define TABLE_CASE(mode, bpc, max)   case (table_hash(mode, BPC_##bpc, max)): \
+	table = qp_table_##mode##_##bpc##bpc_##max; \
+	table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \
+	break
+
+static int median3(int a, int b, int c)
+{
+	if (a > b)
+		swap(a, b);
+	if (b > c)
+		swap(b, c);
+	if (a > b)
+		swap(b, c);
+
+	return b;
+}
+
+static double dsc_roundf(double num)
+{
+	if (num < 0.0)
+		num = num - 0.5;
+	else
+		num = num + 0.5;
+
+	return (int)(num);
+}
+
+static double dsc_ceil(double num)
+{
+	double retval = (int)num;
+
+	if (retval != num && num > 0)
+		retval = num + 1;
+
+	return (int)retval;
+}
+
+static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
+		       enum max_min max_min, float bpp)
+{
+	int mode = MODE_SELECT(444, 422, 420);
+	int sel = table_hash(mode, bpc, max_min);
+	int table_size = 0;
+	int index;
+	const struct qp_entry *table = 0L;
+
+	// alias enum
+	enum { min = DAL_MM_MIN, max = DAL_MM_MAX };
+	switch (sel) {
+		TABLE_CASE(444,  8, max);
+		TABLE_CASE(444,  8, min);
+		TABLE_CASE(444, 10, max);
+		TABLE_CASE(444, 10, min);
+		TABLE_CASE(444, 12, max);
+		TABLE_CASE(444, 12, min);
+		TABLE_CASE(422,  8, max);
+		TABLE_CASE(422,  8, min);
+		TABLE_CASE(422, 10, max);
+		TABLE_CASE(422, 10, min);
+		TABLE_CASE(422, 12, max);
+		TABLE_CASE(422, 12, min);
+		TABLE_CASE(420,  8, max);
+		TABLE_CASE(420,  8, min);
+		TABLE_CASE(420, 10, max);
+		TABLE_CASE(420, 10, min);
+		TABLE_CASE(420, 12, max);
+		TABLE_CASE(420, 12, min);
+	}
+
+	if (table == 0)
+		return;
+
+	index = (bpp - table[0].bpp) * 2;
+
+	/* requested size is bigger than the table */
+	if (index >= table_size) {
+		dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n");
+		return;
+	}
+
+	memcpy(qps, table[index].qps, sizeof(qp_set));
+}
+
+static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp)
+{
+	int   *p = ofs;
+
+	if (mode == CM_444 || mode == CM_RGB) {
+		*p++ = (bpp <=  6) ? (0) : ((((bpp >=  8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0))))));
+		*p++ = (bpp <=  6) ? (-2) : ((((bpp >=  8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0))))));
+		*p++ = (bpp <=  6) ? (-2) : ((((bpp >=  8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0))))));
+		*p++ = (bpp <=  6) ? (-4) : ((((bpp >=  8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0))))));
+		*p++ = (bpp <=  6) ? (-6) : ((((bpp >=  8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0))))));
+		*p++ = (bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0))));
+		*p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0))));
+		*p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0))));
+		*p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0))));
+		*p++ = (bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0))));
+		*p++ = -10;
+		*p++ = (bpp <=  6) ? (-12) : ((bpp >=  8) ? (-10) : (-12 + dsc_roundf((bpp -  6) * (2 / 2.0))));
+		*p++ = -12;
+		*p++ = -12;
+		*p++ = -12;
+	} else if (mode == CM_422) {
+		*p++ = (bpp <=  8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp -  8) * (8 / 2.0))));
+		*p++ = (bpp <=  8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp -  8) * (8 / 2.0))));
+		*p++ = (bpp <=  8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp -  8) * (6 / 2.0))));
+		*p++ = (bpp <=  8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp -  8) * (6 / 2.0))));
+		*p++ = (bpp <=  8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp -  8) * (6 / 2.0))));
+		*p++ = (bpp <=  8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp -  8) * (6 / 2.0))));
+		*p++ = (bpp <=  8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp -  8) * (6 / 2.0))));
+		*p++ = (bpp <=  8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp -  8) * (4 / 2.0))));
+		*p++ = (bpp <=  8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp -  8) * (2 / 2.0))));
+		*p++ = (bpp <=  8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp -  8) * (2 / 2.0))));
+		*p++ = -10;
+		*p++ = (bpp <=  6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp -  6) * (2.0 / 1))));
+		*p++ = -12;
+		*p++ = -12;
+		*p++ = -12;
+	} else {
+		*p++ = (bpp <=  6) ? (2) : ((bpp >=  8) ? (10) : (2 + dsc_roundf((bpp -  6) * (8 / 2.0))));
+		*p++ = (bpp <=  6) ? (0) : ((bpp >=  8) ? (8) : (0 + dsc_roundf((bpp -  6) * (8 / 2.0))));
+		*p++ = (bpp <=  6) ? (0) : ((bpp >=  8) ? (6) : (0 + dsc_roundf((bpp -  6) * (6 / 2.0))));
+		*p++ = (bpp <=  6) ? (-2) : ((bpp >=  8) ? (4) : (-2 + dsc_roundf((bpp -  6) * (6 / 2.0))));
+		*p++ = (bpp <=  6) ? (-4) : ((bpp >=  8) ? (2) : (-4 + dsc_roundf((bpp -  6) * (6 / 2.0))));
+		*p++ = (bpp <=  6) ? (-6) : ((bpp >=  8) ? (0) : (-6 + dsc_roundf((bpp -  6) * (6 / 2.0))));
+		*p++ = (bpp <=  6) ? (-8) : ((bpp >=  8) ? (-2) : (-8 + dsc_roundf((bpp -  6) * (6 / 2.0))));
+		*p++ = (bpp <=  6) ? (-8) : ((bpp >=  8) ? (-4) : (-8 + dsc_roundf((bpp -  6) * (4 / 2.0))));
+		*p++ = (bpp <=  6) ? (-8) : ((bpp >=  8) ? (-6) : (-8 + dsc_roundf((bpp -  6) * (2 / 2.0))));
+		*p++ = (bpp <=  6) ? (-10) : ((bpp >=  8) ? (-8) : (-10 + dsc_roundf((bpp -  6) * (2 / 2.0))));
+		*p++ = -10;
+		*p++ = (bpp <=  4) ? (-12) : ((bpp >=  5) ? (-10) : (-12 + dsc_roundf((bpp -  4) * (2 / 1.0))));
+		*p++ = -12;
+		*p++ = -12;
+		*p++ = -12;
+	}
+}
+
+void _do_calc_rc_params(struct rc_params *rc,
+		enum colour_mode cm,
+		enum bits_per_comp bpc,
+		u16 drm_bpp,
+		bool is_navite_422_or_420,
+		int slice_width,
+		int slice_height,
+		int minor_version)
+{
+	float bpp;
+	float bpp_group;
+	float initial_xmit_delay_factor;
+	int padding_pixels;
+	int i;
+
+	dc_assert_fp_enabled();
+
+	bpp = ((float)drm_bpp / 16.0);
+	/* in native_422 or native_420 modes, the bits_per_pixel is double the
+	 * target bpp (the latter is what calc_rc_params expects)
+	 */
+	if (is_navite_422_or_420)
+		bpp /= 2.0;
+
+	rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
+	rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
+
+	bpp_group = MODE_SELECT(bpp, bpp * 2.0, bpp * 2.0);
+
+	switch (cm) {
+	case CM_420:
+		rc->initial_fullness_offset = (bpp >=  6) ? (2048) : ((bpp <=  4) ? (6144) : ((((bpp >  4) && (bpp <=  5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp -  5) * (3584)))));
+		rc->first_line_bpg_offset   = median3(0, (12 + (int) (0.09 *  min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group)));
+		rc->second_line_bpg_offset  = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group)));
+		break;
+	case CM_422:
+		rc->initial_fullness_offset = (bpp >=  8) ? (2048) : ((bpp <=  7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584))));
+		rc->first_line_bpg_offset   = median3(0, (12 + (int) (0.09 *  min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group)));
+		rc->second_line_bpg_offset  = 0;
+		break;
+	case CM_444:
+	case CM_RGB:
+		rc->initial_fullness_offset = (bpp >= 12) ? (2048) : ((bpp <=  8) ? (6144) : ((((bpp >  8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2)))));
+		rc->first_line_bpg_offset   = median3(0, (12 + (int) (0.09 *  min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group)));
+		rc->second_line_bpg_offset  = 0;
+		break;
+	}
+
+	initial_xmit_delay_factor = (cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0;
+	rc->initial_xmit_delay = dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor);
+
+	if (cm == CM_422 || cm == CM_420)
+		slice_width /= 2;
+
+	padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0;
+	if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) {
+		if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1)
+			rc->initial_xmit_delay++;
+	}
+
+	rc->flatness_min_qp     = ((bpc == BPC_8) ?  (3) : ((bpc == BPC_10) ? (7)  : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
+	rc->flatness_max_qp     = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
+	rc->flatness_det_thresh = 2 << (bpc - 8);
+
+	get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp);
+	get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp);
+	if (cm == CM_444 && minor_version == 1) {
+		for (i = 0; i < QP_SET_SIZE; ++i) {
+			rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0;
+			rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0;
+		}
+	}
+	get_ofs_set(rc->ofs, cm, bpp);
+
+	/* fixed parameters */
+	rc->rc_model_size    = 8192;
+	rc->rc_edge_factor   = 6;
+	rc->rc_tgt_offset_hi = 3;
+	rc->rc_tgt_offset_lo = 3;
+
+	rc->rc_buf_thresh[0] = 896;
+	rc->rc_buf_thresh[1] = 1792;
+	rc->rc_buf_thresh[2] = 2688;
+	rc->rc_buf_thresh[3] = 3584;
+	rc->rc_buf_thresh[4] = 4480;
+	rc->rc_buf_thresh[5] = 5376;
+	rc->rc_buf_thresh[6] = 6272;
+	rc->rc_buf_thresh[7] = 6720;
+	rc->rc_buf_thresh[8] = 7168;
+	rc->rc_buf_thresh[9] = 7616;
+	rc->rc_buf_thresh[10] = 7744;
+	rc->rc_buf_thresh[11] = 7872;
+	rc->rc_buf_thresh[12] = 8000;
+	rc->rc_buf_thresh[13] = 8064;
+}
+
+u32 _do_bytes_per_pixel_calc(int slice_width,
+		u16 drm_bpp,
+		bool is_navite_422_or_420)
+{
+	float bpp;
+	u32 bytes_per_pixel;
+	double d_bytes_per_pixel;
+
+	dc_assert_fp_enabled();
+
+	bpp = ((float)drm_bpp / 16.0);
+	d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width;
+	// TODO: Make sure the formula for calculating this is precise (ceiling
+	// vs. floor, and at what point they should be applied)
+	if (is_navite_422_or_420)
+		d_bytes_per_pixel /= 2;
+
+	bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000);
+
+	return bytes_per_pixel;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h
new file mode 100644
index 000000000000..b93b95409fbe
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __RC_CALC_FPU_H__
+#define __RC_CALC_FPU_H__
+
+#include "os_types.h"
+#include <drm/drm_dsc.h>
+
+#define QP_SET_SIZE 15
+
+typedef int qp_set[QP_SET_SIZE];
+
+struct rc_params {
+	int      rc_quant_incr_limit0;
+	int      rc_quant_incr_limit1;
+	int      initial_fullness_offset;
+	int      initial_xmit_delay;
+	int      first_line_bpg_offset;
+	int      second_line_bpg_offset;
+	int      flatness_min_qp;
+	int      flatness_max_qp;
+	int      flatness_det_thresh;
+	qp_set   qp_min;
+	qp_set   qp_max;
+	qp_set   ofs;
+	int      rc_model_size;
+	int      rc_edge_factor;
+	int      rc_tgt_offset_hi;
+	int      rc_tgt_offset_lo;
+	int      rc_buf_thresh[QP_SET_SIZE - 1];
+};
+
+enum colour_mode {
+	CM_RGB,   /* 444 RGB */
+	CM_444,   /* 444 YUV or simple 422 */
+	CM_422,   /* native 422 */
+	CM_420    /* native 420 */
+};
+
+enum bits_per_comp {
+	BPC_8  =  8,
+	BPC_10 = 10,
+	BPC_12 = 12
+};
+
+enum max_min {
+	DAL_MM_MIN = 0,
+	DAL_MM_MAX = 1
+};
+
+struct qp_entry {
+	float         bpp;
+	const qp_set  qps;
+};
+
+typedef struct qp_entry qp_table[];
+
+u32 _do_bytes_per_pixel_calc(int slice_width,
+		u16 drm_bpp,
+		bool is_navite_422_or_420);
+
+void _do_calc_rc_params(struct rc_params *rc,
+		enum colour_mode cm,
+		enum bits_per_comp bpc,
+		u16 drm_bpp,
+		bool is_navite_422_or_420,
+		int slice_width,
+		int slice_height,
+		int minor_version);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile
index 8d31eb75c6a6..a2537229ee88 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile
@@ -1,35 +1,6 @@
 # SPDX-License-Identifier: MIT
 #
 # Makefile for the 'dsc' sub-component of DAL.
-
-ifdef CONFIG_X86
-dsc_ccflags := -mhard-float -msse
-endif
-
-ifdef CONFIG_PPC64
-dsc_ccflags := -mhard-float -maltivec
-endif
-
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-endif
-
-ifdef CONFIG_X86
-ifdef IS_OLD_GCC
-# Stack alignment mismatch, proceed with caution.
-# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
-# (8B stack alignment).
-dsc_ccflags += -mpreferred-stack-boundary=4
-else
-dsc_ccflags += -msse2
-endif
-endif
-
-CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags)
-CFLAGS_REMOVE_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_rcflags)
-
 DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o
 
 AMD_DAL_DSC = $(addprefix $(AMDDALPATH)/dc/dsc/,$(DSC))
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
index 7b294f637881..b19d3aeb5962 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
@@ -23,266 +23,7 @@
  * Authors: AMD
  *
  */
-#include <drm/drm_dsc.h>
-
-#include "os_types.h"
 #include "rc_calc.h"
-#include "qp_tables.h"
-
-#define table_hash(mode, bpc, max_min) ((mode << 16) | (bpc << 8) | max_min)
-
-#define MODE_SELECT(val444, val422, val420) \
-	(cm == CM_444 || cm == CM_RGB) ? (val444) : (cm == CM_422 ? (val422) : (val420))
-
-
-#define TABLE_CASE(mode, bpc, max)   case (table_hash(mode, BPC_##bpc, max)): \
-	table = qp_table_##mode##_##bpc##bpc_##max; \
-	table_size = sizeof(qp_table_##mode##_##bpc##bpc_##max)/sizeof(*qp_table_##mode##_##bpc##bpc_##max); \
-	break
-
-
-static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
-		       enum max_min max_min, float bpp)
-{
-	int mode = MODE_SELECT(444, 422, 420);
-	int sel = table_hash(mode, bpc, max_min);
-	int table_size = 0;
-	int index;
-	const struct qp_entry *table = 0L;
-
-	// alias enum
-	enum { min = DAL_MM_MIN, max = DAL_MM_MAX };
-	switch (sel) {
-		TABLE_CASE(444,  8, max);
-		TABLE_CASE(444,  8, min);
-		TABLE_CASE(444, 10, max);
-		TABLE_CASE(444, 10, min);
-		TABLE_CASE(444, 12, max);
-		TABLE_CASE(444, 12, min);
-		TABLE_CASE(422,  8, max);
-		TABLE_CASE(422,  8, min);
-		TABLE_CASE(422, 10, max);
-		TABLE_CASE(422, 10, min);
-		TABLE_CASE(422, 12, max);
-		TABLE_CASE(422, 12, min);
-		TABLE_CASE(420,  8, max);
-		TABLE_CASE(420,  8, min);
-		TABLE_CASE(420, 10, max);
-		TABLE_CASE(420, 10, min);
-		TABLE_CASE(420, 12, max);
-		TABLE_CASE(420, 12, min);
-	}
-
-	if (table == 0)
-		return;
-
-	index = (bpp - table[0].bpp) * 2;
-
-	/* requested size is bigger than the table */
-	if (index >= table_size) {
-		dm_error("ERROR: Requested rc_calc to find a bpp entry that exceeds the table size\n");
-		return;
-	}
-
-	memcpy(qps, table[index].qps, sizeof(qp_set));
-}
-
-static double dsc_roundf(double num)
-{
-	if (num < 0.0)
-		num = num - 0.5;
-	else
-		num = num + 0.5;
-
-	return (int)(num);
-}
-
-static double dsc_ceil(double num)
-{
-	double retval = (int)num;
-
-	if (retval != num && num > 0)
-		retval = num + 1;
-
-	return (int)retval;
-}
-
-static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp)
-{
-	int   *p = ofs;
-
-	if (mode == CM_444 || mode == CM_RGB) {
-		*p++ = (bpp <=  6) ? (0) : ((((bpp >=  8) && (bpp <= 12))) ? (2) : ((bpp >= 15) ? (10) : ((((bpp > 6) && (bpp < 8))) ? (0 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (2 + dsc_roundf((bpp - 12) * (8 / 3.0))))));
-		*p++ = (bpp <=  6) ? (-2) : ((((bpp >=  8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (8) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (8 / 3.0))))));
-		*p++ = (bpp <=  6) ? (-2) : ((((bpp >=  8) && (bpp <= 12))) ? (0) : ((bpp >= 15) ? (6) : ((((bpp > 6) && (bpp < 8))) ? (-2 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (0 + dsc_roundf((bpp - 12) * (6 / 3.0))))));
-		*p++ = (bpp <=  6) ? (-4) : ((((bpp >=  8) && (bpp <= 12))) ? (-2) : ((bpp >= 15) ? (4) : ((((bpp > 6) && (bpp < 8))) ? (-4 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (-2 + dsc_roundf((bpp - 12) * (6 / 3.0))))));
-		*p++ = (bpp <=  6) ? (-6) : ((((bpp >=  8) && (bpp <= 12))) ? (-4) : ((bpp >= 15) ? (2) : ((((bpp > 6) && (bpp < 8))) ? (-6 + dsc_roundf((bpp -  6) * (2 / 2.0))) : (-4 + dsc_roundf((bpp - 12) * (6 / 3.0))))));
-		*p++ = (bpp <= 12) ? (-6) : ((bpp >= 15) ? (0) : (-6 + dsc_roundf((bpp - 12) * (6 / 3.0))));
-		*p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-2) : (-8 + dsc_roundf((bpp - 12) * (6 / 3.0))));
-		*p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-4) : (-8 + dsc_roundf((bpp - 12) * (4 / 3.0))));
-		*p++ = (bpp <= 12) ? (-8) : ((bpp >= 15) ? (-6) : (-8 + dsc_roundf((bpp - 12) * (2 / 3.0))));
-		*p++ = (bpp <= 12) ? (-10) : ((bpp >= 15) ? (-8) : (-10 + dsc_roundf((bpp - 12) * (2 / 3.0))));
-		*p++ = -10;
-		*p++ = (bpp <=  6) ? (-12) : ((bpp >=  8) ? (-10) : (-12 + dsc_roundf((bpp -  6) * (2 / 2.0))));
-		*p++ = -12;
-		*p++ = -12;
-		*p++ = -12;
-	} else if (mode == CM_422) {
-		*p++ = (bpp <=  8) ? (2) : ((bpp >= 10) ? (10) : (2 + dsc_roundf((bpp -  8) * (8 / 2.0))));
-		*p++ = (bpp <=  8) ? (0) : ((bpp >= 10) ? (8) : (0 + dsc_roundf((bpp -  8) * (8 / 2.0))));
-		*p++ = (bpp <=  8) ? (0) : ((bpp >= 10) ? (6) : (0 + dsc_roundf((bpp -  8) * (6 / 2.0))));
-		*p++ = (bpp <=  8) ? (-2) : ((bpp >= 10) ? (4) : (-2 + dsc_roundf((bpp -  8) * (6 / 2.0))));
-		*p++ = (bpp <=  8) ? (-4) : ((bpp >= 10) ? (2) : (-4 + dsc_roundf((bpp -  8) * (6 / 2.0))));
-		*p++ = (bpp <=  8) ? (-6) : ((bpp >= 10) ? (0) : (-6 + dsc_roundf((bpp -  8) * (6 / 2.0))));
-		*p++ = (bpp <=  8) ? (-8) : ((bpp >= 10) ? (-2) : (-8 + dsc_roundf((bpp -  8) * (6 / 2.0))));
-		*p++ = (bpp <=  8) ? (-8) : ((bpp >= 10) ? (-4) : (-8 + dsc_roundf((bpp -  8) * (4 / 2.0))));
-		*p++ = (bpp <=  8) ? (-8) : ((bpp >= 10) ? (-6) : (-8 + dsc_roundf((bpp -  8) * (2 / 2.0))));
-		*p++ = (bpp <=  8) ? (-10) : ((bpp >= 10) ? (-8) : (-10 + dsc_roundf((bpp -  8) * (2 / 2.0))));
-		*p++ = -10;
-		*p++ = (bpp <=  6) ? (-12) : ((bpp >= 7) ? (-10) : (-12 + dsc_roundf((bpp -  6) * (2.0 / 1))));
-		*p++ = -12;
-		*p++ = -12;
-		*p++ = -12;
-	} else {
-		*p++ = (bpp <=  6) ? (2) : ((bpp >=  8) ? (10) : (2 + dsc_roundf((bpp -  6) * (8 / 2.0))));
-		*p++ = (bpp <=  6) ? (0) : ((bpp >=  8) ? (8) : (0 + dsc_roundf((bpp -  6) * (8 / 2.0))));
-		*p++ = (bpp <=  6) ? (0) : ((bpp >=  8) ? (6) : (0 + dsc_roundf((bpp -  6) * (6 / 2.0))));
-		*p++ = (bpp <=  6) ? (-2) : ((bpp >=  8) ? (4) : (-2 + dsc_roundf((bpp -  6) * (6 / 2.0))));
-		*p++ = (bpp <=  6) ? (-4) : ((bpp >=  8) ? (2) : (-4 + dsc_roundf((bpp -  6) * (6 / 2.0))));
-		*p++ = (bpp <=  6) ? (-6) : ((bpp >=  8) ? (0) : (-6 + dsc_roundf((bpp -  6) * (6 / 2.0))));
-		*p++ = (bpp <=  6) ? (-8) : ((bpp >=  8) ? (-2) : (-8 + dsc_roundf((bpp -  6) * (6 / 2.0))));
-		*p++ = (bpp <=  6) ? (-8) : ((bpp >=  8) ? (-4) : (-8 + dsc_roundf((bpp -  6) * (4 / 2.0))));
-		*p++ = (bpp <=  6) ? (-8) : ((bpp >=  8) ? (-6) : (-8 + dsc_roundf((bpp -  6) * (2 / 2.0))));
-		*p++ = (bpp <=  6) ? (-10) : ((bpp >=  8) ? (-8) : (-10 + dsc_roundf((bpp -  6) * (2 / 2.0))));
-		*p++ = -10;
-		*p++ = (bpp <=  4) ? (-12) : ((bpp >=  5) ? (-10) : (-12 + dsc_roundf((bpp -  4) * (2 / 1.0))));
-		*p++ = -12;
-		*p++ = -12;
-		*p++ = -12;
-	}
-}
-
-static int median3(int a, int b, int c)
-{
-	if (a > b)
-		swap(a, b);
-	if (b > c)
-		swap(b, c);
-	if (a > b)
-		swap(b, c);
-
-	return b;
-}
-
-static void _do_calc_rc_params(struct rc_params *rc, enum colour_mode cm,
-			       enum bits_per_comp bpc, u16 drm_bpp,
-			       bool is_navite_422_or_420,
-			       int slice_width, int slice_height,
-			       int minor_version)
-{
-	float bpp;
-	float bpp_group;
-	float initial_xmit_delay_factor;
-	int padding_pixels;
-	int i;
-
-	bpp = ((float)drm_bpp / 16.0);
-	/* in native_422 or native_420 modes, the bits_per_pixel is double the
-	 * target bpp (the latter is what calc_rc_params expects)
-	 */
-	if (is_navite_422_or_420)
-		bpp /= 2.0;
-
-	rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
-	rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
-
-	bpp_group = MODE_SELECT(bpp, bpp * 2.0, bpp * 2.0);
-
-	switch (cm) {
-	case CM_420:
-		rc->initial_fullness_offset = (bpp >=  6) ? (2048) : ((bpp <=  4) ? (6144) : ((((bpp >  4) && (bpp <=  5))) ? (6144 - dsc_roundf((bpp - 4) * (512))) : (5632 - dsc_roundf((bpp -  5) * (3584)))));
-		rc->first_line_bpg_offset   = median3(0, (12 + (int) (0.09 *  min(34, slice_height - 8))), (int)((3 * bpc * 3) - (3 * bpp_group)));
-		rc->second_line_bpg_offset  = median3(0, 12, (int)((3 * bpc * 3) - (3 * bpp_group)));
-		break;
-	case CM_422:
-		rc->initial_fullness_offset = (bpp >=  8) ? (2048) : ((bpp <=  7) ? (5632) : (5632 - dsc_roundf((bpp - 7) * (3584))));
-		rc->first_line_bpg_offset   = median3(0, (12 + (int) (0.09 *  min(34, slice_height - 8))), (int)((3 * bpc * 4) - (3 * bpp_group)));
-		rc->second_line_bpg_offset  = 0;
-		break;
-	case CM_444:
-	case CM_RGB:
-		rc->initial_fullness_offset = (bpp >= 12) ? (2048) : ((bpp <=  8) ? (6144) : ((((bpp >  8) && (bpp <= 10))) ? (6144 - dsc_roundf((bpp - 8) * (512 / 2))) : (5632 - dsc_roundf((bpp - 10) * (3584 / 2)))));
-		rc->first_line_bpg_offset   = median3(0, (12 + (int) (0.09 *  min(34, slice_height - 8))), (int)(((3 * bpc + (cm == CM_444 ? 0 : 2)) * 3) - (3 * bpp_group)));
-		rc->second_line_bpg_offset  = 0;
-		break;
-	}
-
-	initial_xmit_delay_factor = (cm == CM_444 || cm == CM_RGB) ? 1.0 : 2.0;
-	rc->initial_xmit_delay = dsc_roundf(8192.0/2.0/bpp/initial_xmit_delay_factor);
-
-	if (cm == CM_422 || cm == CM_420)
-		slice_width /= 2;
-
-	padding_pixels = ((slice_width % 3) != 0) ? (3 - (slice_width % 3)) * (rc->initial_xmit_delay / slice_width) : 0;
-	if (3 * bpp_group >= (((rc->initial_xmit_delay + 2) / 3) * (3 + (cm == CM_422)))) {
-		if ((rc->initial_xmit_delay + padding_pixels) % 3 == 1)
-			rc->initial_xmit_delay++;
-	}
-
-	rc->flatness_min_qp     = ((bpc == BPC_8) ?  (3) : ((bpc == BPC_10) ? (7)  : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
-	rc->flatness_max_qp     = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
-	rc->flatness_det_thresh = 2 << (bpc - 8);
-
-	get_qp_set(rc->qp_min, cm, bpc, DAL_MM_MIN, bpp);
-	get_qp_set(rc->qp_max, cm, bpc, DAL_MM_MAX, bpp);
-	if (cm == CM_444 && minor_version == 1) {
-		for (i = 0; i < QP_SET_SIZE; ++i) {
-			rc->qp_min[i] = rc->qp_min[i] > 0 ? rc->qp_min[i] - 1 : 0;
-			rc->qp_max[i] = rc->qp_max[i] > 0 ? rc->qp_max[i] - 1 : 0;
-		}
-	}
-	get_ofs_set(rc->ofs, cm, bpp);
-
-	/* fixed parameters */
-	rc->rc_model_size    = 8192;
-	rc->rc_edge_factor   = 6;
-	rc->rc_tgt_offset_hi = 3;
-	rc->rc_tgt_offset_lo = 3;
-
-	rc->rc_buf_thresh[0] = 896;
-	rc->rc_buf_thresh[1] = 1792;
-	rc->rc_buf_thresh[2] = 2688;
-	rc->rc_buf_thresh[3] = 3584;
-	rc->rc_buf_thresh[4] = 4480;
-	rc->rc_buf_thresh[5] = 5376;
-	rc->rc_buf_thresh[6] = 6272;
-	rc->rc_buf_thresh[7] = 6720;
-	rc->rc_buf_thresh[8] = 7168;
-	rc->rc_buf_thresh[9] = 7616;
-	rc->rc_buf_thresh[10] = 7744;
-	rc->rc_buf_thresh[11] = 7872;
-	rc->rc_buf_thresh[12] = 8000;
-	rc->rc_buf_thresh[13] = 8064;
-}
-
-static u32 _do_bytes_per_pixel_calc(int slice_width, u16 drm_bpp,
-				    bool is_navite_422_or_420)
-{
-	float bpp;
-	u32 bytes_per_pixel;
-	double d_bytes_per_pixel;
-
-	bpp = ((float)drm_bpp / 16.0);
-	d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width;
-	// TODO: Make sure the formula for calculating this is precise (ceiling
-	// vs. floor, and at what point they should be applied)
-	if (is_navite_422_or_420)
-		d_bytes_per_pixel /= 2;
-
-	bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000);
-
-	return bytes_per_pixel;
-}
 
 /**
  * calc_rc_params - reads the user's cmdline mode
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
index 262f06afcbf9..c2340e001b57 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
@@ -27,55 +27,7 @@
 #ifndef __RC_CALC_H__
 #define __RC_CALC_H__
 
-
-#define QP_SET_SIZE 15
-
-typedef int qp_set[QP_SET_SIZE];
-
-struct rc_params {
-	int      rc_quant_incr_limit0;
-	int      rc_quant_incr_limit1;
-	int      initial_fullness_offset;
-	int      initial_xmit_delay;
-	int      first_line_bpg_offset;
-	int      second_line_bpg_offset;
-	int      flatness_min_qp;
-	int      flatness_max_qp;
-	int      flatness_det_thresh;
-	qp_set   qp_min;
-	qp_set   qp_max;
-	qp_set   ofs;
-	int      rc_model_size;
-	int      rc_edge_factor;
-	int      rc_tgt_offset_hi;
-	int      rc_tgt_offset_lo;
-	int      rc_buf_thresh[QP_SET_SIZE - 1];
-};
-
-enum colour_mode {
-	CM_RGB,   /* 444 RGB */
-	CM_444,   /* 444 YUV or simple 422 */
-	CM_422,   /* native 422 */
-	CM_420    /* native 420 */
-};
-
-enum bits_per_comp {
-	BPC_8  =  8,
-	BPC_10 = 10,
-	BPC_12 = 12
-};
-
-enum max_min {
-	DAL_MM_MIN = 0,
-	DAL_MM_MAX = 1
-};
-
-struct qp_entry {
-	float         bpp;
-	const qp_set  qps;
-};
-
-typedef struct qp_entry qp_table[];
+#include "dml/dsc/rc_calc_fpu.h"
 
 void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps);
 u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps);
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
index ef830aded5b1..1e19dd674e5a 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
@@ -22,7 +22,6 @@
  * Authors: AMD
  *
  */
-#include "os_types.h"
 #include <drm/drm_dsc.h>
 #include "dscc_types.h"
 #include "rc_calc.h"
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 07/33] drm/amd/display: fix a crash on USB4 over C20 PHY
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (5 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 06/33] drm/amd/display: move FPU associated DSC code to DML folder Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 08/33] drm/amd/display: Set i2c memory to light sleep during hw init Rodrigo Siqueira
                   ` (26 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Ahmad Othman, Nikola Cornij, Wenjing Liu

From: Ahmad Othman <Ahmad.Othman@amd.com>

[Why]
Crash when USB4 is connected.

[How]
Added an ASIC specific code guard.

Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Ahmad Othman <Ahmad.Othman@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 25 +++++++++++++++----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 42f96de496cb..c278d134c44b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3604,6 +3604,14 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 			link_enc = pipe_ctx->stream->link->link_enc;
 			config.dio_output_type = pipe_ctx->stream->link->ep_type;
 			config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
+			if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY)
+				link_enc = pipe_ctx->stream->link->link_enc;
+			else if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
+				if (pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) {
+					link_enc = link_enc_cfg_get_link_enc_used_by_stream(
+							pipe_ctx->stream->ctx->dc,
+							pipe_ctx->stream);
+			}
 			// Initialize PHY ID with ABCDE - 01234 mapping except when it is B0
 			config.phy_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
 
@@ -3613,14 +3621,21 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
 					link_enc_assign = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i];
 				}
 			}
-
-			if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0)
+			// Add flag to guard new A0 DIG mapping
+			if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true) {
 				config.dig_be = link_enc_assign.eng_id;
+				config.dio_output_type = pipe_ctx->stream->link->ep_type;
+				config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A;
+			} else {
+				config.dio_output_type = 0;
+				config.dio_output_idx = 0;
+			}
 
-			// Add RegKey to guard B0 implementation
-			if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 && link_enc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+			// Add flag to guard B0 implementation
+			if (pipe_ctx->stream->ctx->dc->enable_c20_dtm_b0 == true &&
+					link_enc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
 				if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
-					link_enc = pipe_ctx->stream->link->link_enc;
+					link_enc = link_enc_assign.stream->link_enc;
 
 					// enum ID 1-4 maps to DPIA PHY ID 0-3
 					config.phy_idx = link_enc_assign.ep_id.link_id.enum_id - ENUM_ID_1;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 08/33] drm/amd/display: Set i2c memory to light sleep during hw init
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (6 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 07/33] drm/amd/display: fix a crash on USB4 over C20 PHY Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 09/33] drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate Rodrigo Siqueira
                   ` (25 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Michael Strauss, Haonan Wang

From: Michael Strauss <michael.strauss@amd.com>

[WHY]
i2c memory doesn't get set to light sleep on hw init as intended

[HOW]
Set i2c to light sleep after reg gets zeroed, ensuring memory power
control doesn't get disabled for any other DIO memory

Reviewed-by: Haonan Wang <Haonan.Wang2@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h        | 3 ++-
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c    | 5 +++++
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 3 ++-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
index 296b2f80a1ec..989f5b6907e2 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -1151,7 +1151,8 @@ struct dce_hwseq_registers {
 	type DOMAIN_POWER_GATE;\
 	type DOMAIN_PGFSM_PWR_STATUS;\
 	type HPO_HDMISTREAMCLK_G_GATE_DIS;\
-	type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;
+	type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;\
+	type I2C_LIGHT_SLEEP_FORCE;
 
 struct dce_hwseq_shift {
 	HWSEQ_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
index 9a6ad1cebc85..d24ad7754d71 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -50,6 +50,7 @@
 #include "dcn10/dcn10_hw_sequencer.h"
 #include "inc/link_enc_cfg.h"
 #include "dcn30/dcn30_vpg.h"
+#include "dce/dce_i2c_hw.h"
 
 #define DC_LOGGER_INIT(logger)
 
@@ -259,6 +260,10 @@ void dcn31_init_hw(struct dc *dc)
 	/* power AFMT HDMI memory TODO: may move to dis/en output save power*/
 	REG_WRITE(DIO_MEM_PWR_CTRL, 0);
 
+	// Set i2c to light sleep until engine is setup
+	if (dc->debug.enable_mem_low_power.bits.i2c)
+		REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);
+
 	if (!dc->debug.disable_clock_gate) {
 		/* enable all DCN clock gating */
 		REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 12ebd9f8912f..8b4a97e39f1a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -899,7 +899,8 @@ static const struct dce_hwseq_registers hwseq_reg = {
 	HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \
 	HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \
 	HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \
-	HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh)
+	HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \
+	HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh)
 
 static const struct dce_hwseq_shift hwseq_shift = {
 		HWSEQ_DCN31_MASK_SH_LIST(__SHIFT)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 09/33] drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (7 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 08/33] drm/amd/display: Set i2c memory to light sleep during hw init Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 10/33] drm/amd/display: clean up dcn31 revision check Rodrigo Siqueira
                   ` (24 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Michael Strauss, Haonan Wang

From: Michael Strauss <michael.strauss@amd.com>

[WHY]
Every other CM LUT power down sequence is deferred to next vupdate as
memory powerdown updates immediately while selecting LUTs is double
buffered.  Previous update to defer LUT power down missed GAMCOR and
DSCL, causing some visible flicker when entering/exiting fullscreen
video playback.

[HOW]
Update dpp deferred update loop to check for valid DPPs in res_pool
instead of referencing dcn_ip which turns out to not be populated during
runtime.  Move GAMCOR and DSCL powerdown to dpp deferred updates.

Reviewed-by: Haonan Wang <Haonan.Wang2@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c           |  6 ++++--
 .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c  | 12 ++++++++++--
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c   | 14 ++++++++++++++
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c    |  8 ++++++--
 .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c  |  2 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h        |  2 ++
 6 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index a575d372ef5f..6dbcb1b1eb5c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1897,12 +1897,14 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
 static void process_deferred_updates(struct dc *dc)
 {
 #ifdef CONFIG_DRM_AMD_DC_DCN
-	int i;
+	int i = 0;
 
-	if (dc->debug.enable_mem_low_power.bits.cm)
+	if (dc->debug.enable_mem_low_power.bits.cm) {
+		ASSERT(dc->dcn_ip->max_num_dpp);
 		for (i = 0; i < dc->dcn_ip->max_num_dpp; i++)
 			if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update)
 				dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]);
+	}
 #endif
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
index cb9767ddf93d..44293d66b46b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
@@ -205,9 +205,17 @@ static void dpp1_power_on_dscl(
 	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) {
-		REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, power_on ? 0 : 3);
-		if (power_on)
+		if (power_on) {
+			REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0);
 			REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5);
+		} else {
+			if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) {
+				dpp->base.ctx->dc->optimized_required = true;
+				dpp->base.deferred_reg_writes.bits.disable_dscl = true;
+			} else {
+				REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
+			}
+		}
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index ef5f6da5248a..c1d967ed6551 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -494,6 +494,20 @@ void dpp3_deferred_update(
 	int bypass_state;
 	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
+	if (dpp_base->deferred_reg_writes.bits.disable_dscl) {
+		REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
+		dpp_base->deferred_reg_writes.bits.disable_dscl = false;
+	}
+
+	if (dpp_base->deferred_reg_writes.bits.disable_gamcor) {
+		REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state);
+		if (bypass_state == 0) {	// only program if bypass was latched
+			REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3);
+		} else
+			ASSERT(0); // LUT select was updated again before vupdate
+		dpp_base->deferred_reg_writes.bits.disable_gamcor = false;
+	}
+
 	if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
 		REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
 		if (bypass_state == 0) {	// only program if bypass was latched
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
index 72c5687adc68..387eec616162 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c
@@ -136,9 +136,13 @@ static void dpp3_power_on_gamcor_lut(
 	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
 	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
-		REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, power_on ? 0 : 3);
-		if (power_on)
+		if (power_on) {
+			REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0);
 			REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5);
+		} else {
+			dpp_base->ctx->dc->optimized_required = true;
+			dpp_base->deferred_reg_writes.bits.disable_gamcor = true;
+		}
 	} else
 		REG_SET(CM_MEM_PWR_CTRL, 0,
 				GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 8b4a97e39f1a..abbfb5aeff2a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -2454,6 +2454,8 @@ static bool dcn31_resource_construct(
 
 	dc->cap_funcs = cap_funcs;
 
+	dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp;
+
 	DC_FP_END();
 
 	return true;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index 9f12792b7e59..3ef7faa92052 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -34,6 +34,8 @@ union defer_reg_writes {
 		bool disable_blnd_lut:1;
 		bool disable_3dlut:1;
 		bool disable_shaper:1;
+		bool disable_gamcor:1;
+		bool disable_dscl:1;
 	} bits;
 	uint32_t raw;
 };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 10/33] drm/amd/display: clean up dcn31 revision check
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (8 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 09/33] drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 11/33] drm/amd/display: restyle dcn31 resource header inline with other asics Rodrigo Siqueira
                   ` (23 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Dmytro Laktyushkin, Nicholas Kazlauskas

From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>

This is unnecessary in clk_mgr

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 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 acbda3962650..26f96ee32472 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
@@ -285,13 +285,8 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
 			BREAK_TO_DEBUGGER();
 			return NULL;
 		}
-		if (ASICREV_IS_YELLOW_CARP(asic_id.hw_internal_rev)) {
-			/* TODO: to add DCN31 clk_mgr support, once CLK IP header files are available,
-			 * for now use DCN3.0 clk mgr.
-			 */
-			dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
-			return &clk_mgr->base.base;
-		}
+
+		dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
 		return &clk_mgr->base.base;
 	}
 #endif
@@ -328,7 +323,6 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base)
 		break;
 
 	case FAMILY_YELLOW_CARP:
-		if (ASICREV_IS_YELLOW_CARP(clk_mgr_base->ctx->asic_id.hw_internal_rev))
 			dcn31_clk_mgr_destroy(clk_mgr);
 		break;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 11/33] drm/amd/display: restyle dcn31 resource header inline with other asics
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (9 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 10/33] drm/amd/display: clean up dcn31 revision check Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 12/33] drm/amd/display: Implement fixed DP drive settings Rodrigo Siqueira
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Dmytro Laktyushkin, Nicholas Kazlauskas

From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>

Style change for better consistency across codebase

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |  4 ++--
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h | 10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index abbfb5aeff2a..2de731e3e639 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1828,7 +1828,7 @@ static int dcn31_populate_dml_pipes_from_context(
 	return pipe_cnt;
 }
 
-static void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
+void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
 {
 	if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) {
 		context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us;
@@ -1972,7 +1972,7 @@ static void dcn31_calculate_wm_and_dlg_fp(
 	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
 }
 
-static void dcn31_calculate_wm_and_dlg(
+void dcn31_calculate_wm_and_dlg(
 		struct dc *dc, struct dc_state *context,
 		display_e2e_pipe_params_st *pipes,
 		int pipe_cnt,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
index 93571c976996..416fe7a721d8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h
@@ -35,6 +35,16 @@ struct dcn31_resource_pool {
 	struct resource_pool base;
 };
 
+bool dcn31_validate_bandwidth(struct dc *dc,
+		struct dc_state *context,
+		bool fast_validate);
+void dcn31_calculate_wm_and_dlg(
+		struct dc *dc, struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt,
+		int vlevel);
+void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context);
+
 struct resource_pool *dcn31_create_resource_pool(
 		const struct dc_init_data *init_data,
 		struct dc *dc);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 12/33] drm/amd/display: Implement fixed DP drive settings
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (10 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 11/33] drm/amd/display: restyle dcn31 resource header inline with other asics Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 13/33] drm/amd/display: Add comment for preferred_training_settings Rodrigo Siqueira
                   ` (21 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, George Shen, Wenjing Liu

From: George Shen <george.shen@amd.com>

[Why]
Currently there are use cases that require DP link to maintain fixed VS
and PE in HW regardless of what the sink requests. BIOS integrated info
table will specify whether we need to use the fixed drive settings, and
the drive settings to use.

[How]
Implement changes to parse the integrated info table and set the fixed
drive settings accordingly.

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: George Shen <george.shen@amd.com>
---
 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c        | 2 ++
 drivers/gpu/drm/amd/display/dc/core/dc_link.c             | 8 ++++++++
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c          | 8 +++++++-
 drivers/gpu/drm/amd/display/dc/dc_link.h                  | 3 +++
 .../gpu/drm/amd/display/include/grph_object_ctrl_defs.h   | 1 +
 drivers/gpu/drm/amd/display/include/link_service_types.h  | 6 ++++++
 6 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index c17732fba039..a4bef4364afd 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -2321,6 +2321,8 @@ static enum bp_result get_integrated_info_v2_2(
 
 	info->ext_disp_conn_info.checksum =
 		info_v2_2->extdispconninfo.checksum;
+	info->ext_disp_conn_info.fixdpvoltageswing =
+		info_v2_2->extdispconninfo.fixdpvoltageswing;
 
 	info->edp1_info.edp_backlight_pwm_hz =
 	le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index c278d134c44b..b36678669283 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1660,6 +1660,14 @@ static bool dc_link_construct_legacy(struct dc_link *link,
 				DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw);
 				DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps);
 			}
+
+			if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) {
+				link->bios_forced_drive_settings.VOLTAGE_SWING =
+						(info->ext_disp_conn_info.fixdpvoltageswing & 0x3);
+				link->bios_forced_drive_settings.PRE_EMPHASIS =
+						((info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3);
+			}
+
 			break;
 		}
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 3819eb58a9e5..ec269b7e91c3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1661,7 +1661,13 @@ static void override_training_settings(
 	if (overrides->ffe_preset != NULL)
 		lt_settings->ffe_preset = overrides->ffe_preset;
 #endif
-
+	/* Override HW lane settings with BIOS forced values if present */
+	if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN &&
+			link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
+		lt_settings->voltage_swing = &link->bios_forced_drive_settings.VOLTAGE_SWING;
+		lt_settings->pre_emphasis = &link->bios_forced_drive_settings.PRE_EMPHASIS;
+		lt_settings->always_match_dpcd_with_hw_lane_settings = false;
+	}
 	for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
 		lt_settings->lane_settings[lane].VOLTAGE_SWING =
 			lt_settings->voltage_swing != NULL ?
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index eaff496690af..16c6dc5c3bfb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -178,6 +178,9 @@ struct dc_link {
 
 	struct psr_settings psr_settings;
 
+	/* Drive settings read from integrated info table */
+	struct dc_lane_settings bios_forced_drive_settings;
+
 	/* MST record stream using this link */
 	struct link_flags {
 		bool dp_keep_receiver_powered;
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
index 792652236c61..dd974c428d23 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
@@ -328,6 +328,7 @@ struct integrated_info {
 
 		uint8_t gu_id[NUMBER_OF_UCHAR_FOR_GUID];
 		uint8_t checksum;
+		uint8_t fixdpvoltageswing;
 	} ext_disp_conn_info; /* exiting long long time */
 
 	struct available_s_clk_list {
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 9ffea7b40545..9a16fc855254 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -117,6 +117,12 @@ struct link_training_settings {
 	bool enhanced_framing;
 	bool allow_invalid_msa_timing_param;
 	enum lttpr_mode lttpr_mode;
+
+	/* disallow different lanes to have different lane settings */
+	bool disallow_per_lane_settings;
+	/* dpcd lane settings will always use the same hw lane settings
+	 * even if it doesn't match requested lane adjust */
+	bool always_match_dpcd_with_hw_lane_settings;
 };
 
 /*TODO: Move this enum test harness*/
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 13/33] drm/amd/display: Add comment for preferred_training_settings
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (11 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 12/33] drm/amd/display: Implement fixed DP drive settings Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 14/33] drm/amd/display: Handle I2C-over-AUX write channel status update Rodrigo Siqueira
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, George Shen, Wenjing Liu

From: George Shen <george.shen@amd.com>

[Why]
Currently the naming of preferred_training_settings is ambiguous and has
caused confusion regarding its purpose and usage.

[How]
Add comment to clarify the intention.

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: George Shen <george.shen@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_link.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 16c6dc5c3bfb..b975d1307eff 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -124,6 +124,10 @@ struct dc_link {
 	struct dc_link_settings cur_link_settings;
 	struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX];
 	struct dc_link_settings preferred_link_setting;
+	/* preferred_training_settings are override values that
+	 * come from DM. DM is responsible for the memory
+	 * management of the override pointers.
+	 */
 	struct dc_link_training_overrides preferred_training_settings;
 	struct dp_audio_test_data audio_test_data;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 14/33] drm/amd/display: Handle I2C-over-AUX write channel status update
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (12 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 13/33] drm/amd/display: Add comment for preferred_training_settings Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 15/33] drm/amd/display: [FW Promotion] Release 0.0.89 Rodrigo Siqueira
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Aric Cyr, Martin Leung

From: Aric Cyr <aric.cyr@amd.com>

[Why]
When writing long AUX commands some sinks will respond will write status
update requiring source to read status.

[How]
When a write request is replied with data (AUX_ACK_M), retry a read of
write status to determine when the write is completed.

Reviewed-by: Martin Leung <Martin.Leung@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@amd.com>
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  2 ++
 .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 15 ++++----
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  | 34 +++++++++++++++++--
 .../amd/display/include/i2caux_interface.h    |  3 ++
 4 files changed, 44 insertions(+), 10 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 1a99fcc27078..874a49b605c7 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
@@ -64,6 +64,8 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
 	payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0;
 	payload.write = (msg->request & DP_AUX_I2C_READ) == 0;
 	payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0;
+	payload.write_status_update =
+			(msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0;
 	payload.defer_delay = 0;
 
 	result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index 471a67a64299..60539b1f2a80 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -554,6 +554,7 @@ bool dal_ddc_service_query_ddc_data(
 		payload.address = address;
 		payload.reply = NULL;
 		payload.defer_delay = get_defer_delay(ddc);
+		payload.write_status_update = false;
 
 		if (write_size != 0) {
 			payload.write = true;
@@ -625,24 +626,24 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
 	do {
 		struct aux_payload current_payload;
 		bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >=
-			payload->length;
+				payload->length ? true : false;
+		uint32_t payload_length = is_end_of_payload ?
+				payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE;
 
 		current_payload.address = payload->address;
 		current_payload.data = &payload->data[retrieved];
 		current_payload.defer_delay = payload->defer_delay;
 		current_payload.i2c_over_aux = payload->i2c_over_aux;
-		current_payload.length = is_end_of_payload ?
-			payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE;
-		/* set mot (middle of transaction) to false
-		 * if it is the last payload
-		 */
+		current_payload.length = payload_length;
+		/* set mot (middle of transaction) to false if it is the last payload */
 		current_payload.mot = is_end_of_payload ? payload->mot:true;
+		current_payload.write_status_update = false;
 		current_payload.reply = payload->reply;
 		current_payload.write = payload->write;
 
 		ret = dc_link_aux_transfer_with_retries(ddc, &current_payload);
 
-		retrieved += current_payload.length;
+		retrieved += payload_length;
 	} while (retrieved < payload->length && ret == true);
 
 	return ret;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index 95cb4d7cc76a..6d42a9cc9916 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -534,17 +534,26 @@ struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine
 static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload)
 {
 	if (payload->i2c_over_aux) {
+		if (payload->write_status_update) {
+			if (payload->mot)
+				return I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT;
+			else
+				return I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST;
+		}
 		if (payload->write) {
 			if (payload->mot)
 				return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
-			return I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
+			else
+				return I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
 		}
 		if (payload->mot)
 			return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
+
 		return I2CAUX_TRANSACTION_ACTION_I2C_READ;
 	}
 	if (payload->write)
 		return I2CAUX_TRANSACTION_ACTION_DP_WRITE;
+
 	return I2CAUX_TRANSACTION_ACTION_DP_READ;
 }
 
@@ -698,7 +707,8 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
 		aux_defer_retries = 0,
 		aux_i2c_defer_retries = 0,
 		aux_timeout_retries = 0,
-		aux_invalid_reply_retries = 0;
+		aux_invalid_reply_retries = 0,
+		aux_ack_m_retries = 0;
 
 	if (ddc_pin) {
 		aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
@@ -758,9 +768,27 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
 									aux_defer_retries,
 									AUX_MAX_RETRIES);
 						goto fail;
-					} else {
+					} else 
 						udelay(300);
+				} else if (payload->write && ret > 0) {
+					/* sink requested more time to complete the write via AUX_ACKM */
+					if (++aux_ack_m_retries >= AUX_MAX_RETRIES) {
+						DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR,
+								LOG_FLAG_Error_I2cAux,
+								"dce_aux_transfer_with_retries: FAILURE: aux_ack_m_retries=%d >= AUX_MAX_RETRIES=%d",
+								aux_ack_m_retries,
+								AUX_MAX_RETRIES);
+						goto fail;
 					}
+
+					/* retry reading the write status until complete
+					 * NOTE: payload is modified here
+					 */
+					payload->write = false;
+					payload->write_status_update = true;
+					payload->length = 0;
+					udelay(300);
+
 				} else
 					return true;
 			break;
diff --git a/drivers/gpu/drm/amd/display/include/i2caux_interface.h b/drivers/gpu/drm/amd/display/include/i2caux_interface.h
index c7fbb9c3ad6b..418fbf8c5c3a 100644
--- a/drivers/gpu/drm/amd/display/include/i2caux_interface.h
+++ b/drivers/gpu/drm/amd/display/include/i2caux_interface.h
@@ -41,6 +41,8 @@ struct aux_payload {
 	 * reset it to read data */
 	bool write;
 	bool mot;
+	bool write_status_update;
+
 	uint32_t address;
 	uint32_t length;
 	uint8_t *data;
@@ -53,6 +55,7 @@ struct aux_payload {
 	 * zero means "use default value"
 	 */
 	uint32_t defer_delay;
+
 };
 
 struct aux_command {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 15/33] drm/amd/display: [FW Promotion] Release 0.0.89
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (13 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 14/33] drm/amd/display: Handle I2C-over-AUX write channel status update Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 16/33] drm/amd/display: 3.2.158 Rodrigo Siqueira
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Anthony Koo

From: Anthony Koo <Anthony.Koo@amd.com>

- Add flag to control root clock gating in init_hw
- Add flag to indicate a diags environment is being used

Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

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 f4bd9ece2af2..9e8ffbf47e63 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -47,10 +47,10 @@
 
 /* Firmware versioning. */
 #ifdef DMUB_EXPOSE_VERSION
-#define DMUB_FW_VERSION_GIT_HASH 0xd146258f
+#define DMUB_FW_VERSION_GIT_HASH 0xdd808d7b
 #define DMUB_FW_VERSION_MAJOR 0
 #define DMUB_FW_VERSION_MINOR 0
-#define DMUB_FW_VERSION_REVISION 88
+#define DMUB_FW_VERSION_REVISION 89
 #define DMUB_FW_VERSION_TEST 0
 #define DMUB_FW_VERSION_VBIOS 0
 #define DMUB_FW_VERSION_HOTFIX 0
@@ -372,7 +372,10 @@ union dmub_fw_boot_options {
 		uint32_t enable_dpia: 1; /**< 1 if DPIA should be enabled */
 		uint32_t invalid_vbios_data: 1; /**< 1 if VBIOS data table is invalid */
 		uint32_t reserved_unreleased2: 1; /**< reserved for an unreleased feature */
-		uint32_t reserved : 22; /**< reserved */
+		uint32_t root_clock_gating: 1; /**< 1 if all root clock gating is enabled */
+		uint32_t diag_env: 1; /* 1 if diagnostic environment */
+
+		uint32_t reserved : 19; /**< reserved */
 	} bits; /**< boot bits */
 	uint32_t all; /**< 32-bit access to bits */
 };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 16/33] drm/amd/display: 3.2.158
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (14 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 15/33] drm/amd/display: [FW Promotion] Release 0.0.89 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 17/33] drm/amd/display: Fix 3DLUT skipped programming Rodrigo Siqueira
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Aric Cyr

From: Aric Cyr <aric.cyr@amd.com>

Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@amd.com>
---
 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 23977de4811b..4cd04a78f926 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -47,7 +47,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.157"
+#define DC_VER "3.2.158"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 17/33] drm/amd/display: Fix 3DLUT skipped programming
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (15 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 16/33] drm/amd/display: 3.2.158 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 18/33] drm/amd/display: set Layout properly for 8ch audio at timing validation Rodrigo Siqueira
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Aric Cyr

From: Aric Cyr <aric.cyr@amd.com>

This reverts commit 3ae5ca4b92a5c230c3fe25956996ae4bf1875422.

We found a compilation error that we thought was caused by the 3DLUT
patch; later on, we figured out the root cause of the problem, but we
already applied the revert in the wrong patch. This commit brings it
back  the 3DLUT fix.

Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++++
 drivers/gpu/drm/amd/display/dc/dc.h      | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 6dbcb1b1eb5c..6d33ff2bbebe 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2285,6 +2285,9 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
 			update_flags->bits.gamma_change = 1;
 	}
 
+	if (u->lut3d_func || u->func_shaper)
+		update_flags->bits.lut_3d = 1;
+
 	if (u->hdr_mult.value)
 		if (u->hdr_mult.value != u->surface->hdr_mult.value) {
 			update_flags->bits.hdr_mult = 1;
@@ -2298,6 +2301,7 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
 
 	if (update_flags->bits.input_csc_change
 			|| update_flags->bits.coeff_reduction_change
+			|| update_flags->bits.lut_3d
 			|| update_flags->bits.gamma_change
 			|| update_flags->bits.gamut_remap_change) {
 		type = UPDATE_TYPE_FULL;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 4cd04a78f926..1225406d3381 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -940,6 +940,7 @@ union surface_update_flags {
 		uint32_t bandwidth_change:1;
 		uint32_t clock_change:1;
 		uint32_t stereo_format_change:1;
+		uint32_t lut_3d:1;
 		uint32_t full_update:1;
 	} bits;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 18/33] drm/amd/display: set Layout properly for 8ch audio at timing validation
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (16 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 17/33] drm/amd/display: Fix 3DLUT skipped programming Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 19/33] drm/amd/display: allow windowed mpo + odm Rodrigo Siqueira
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Guo, Bing, Chris Park

From: "Guo, Bing" <Bing.Guo@amd.com>

Why:
For audio packet type 0x02, there are 2 Layouts:
   Layout = 0 for 2 channels
and Layout = 1 for > 2 channels.
Layout will affect bandwidth check.

Currently, for HDMI FRL, Layout field isn't set and has a default value
of 0, so theoretically only 2-channel audio for audio packet type 0x02
is supported now.

How:
1. Set Layout properly according to maximum audio channel numbers for
audios with audio packet type 0x02.
2. 8ch LPCM audio is not supported for timing modes with v_active <= 576.

Reviewed-by: Chris Park <chris.park@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Bing Guo <Bing.Guo@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_audio.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 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 7866cf2a668f..27218ede150a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -514,13 +514,15 @@ void dce_aud_az_configure(
 			union audio_sample_rates sample_rates =
 					audio_mode->sample_rates;
 			uint8_t byte2 = audio_mode->max_bit_rate;
+			uint8_t channel_count = audio_mode->channel_count;
 
 			/* adjust specific properties */
 			switch (audio_format_code) {
 			case AUDIO_FORMAT_CODE_LINEARPCM: {
+
 				check_audio_bandwidth(
 					crtc_info,
-					audio_mode->channel_count,
+					channel_count,
 					signal,
 					&sample_rates);
 
@@ -548,7 +550,7 @@ void dce_aud_az_configure(
 
 			/* fill audio format data */
 			set_reg_field_value(value,
-					audio_mode->channel_count - 1,
+					channel_count - 1,
 					AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
 					MAX_CHANNELS);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 19/33] drm/amd/display: allow windowed mpo + odm
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (17 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 18/33] drm/amd/display: set Layout properly for 8ch audio at timing validation Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 20/33] drm/amd/display: Remove unused macros Rodrigo Siqueira
                   ` (14 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Dmytro Laktyushkin, Aric Cyr

From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>

This change adds a config flag to allow non fullscreen MPO during ODM.
Scaling calculation will still fail configurations where video is only
one one side of the screen.

Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 14 +++++++--
 drivers/gpu/drm/amd/display/dc/dc.h           |  1 +
 .../drm/amd/display/dc/dcn30/dcn30_resource.c | 30 ++++++++++---------
 3 files changed, 28 insertions(+), 17 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 9e83fd54e2ca..c32fdccd4d92 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1155,9 +1155,17 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 			pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width;
 	}
 
-	if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
-			pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
-		res = false;
+	if (!pipe_ctx->stream->ctx->dc->config.enable_windowed_mpo_odm) {
+		if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
+				pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
+			res = false;
+	} else {
+		/* Clamp minimum viewport size */
+		if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE)
+			pipe_ctx->plane_res.scl_data.viewport.height = MIN_VIEWPORT_SIZE;
+		if (pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
+			pipe_ctx->plane_res.scl_data.viewport.width = MIN_VIEWPORT_SIZE;
+	}
 
 	DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d  Recout: height:%d width:%d x:%d y:%d  HACTIVE:%d VACTIVE:%d\n"
 			"src_rect: height:%d width:%d x:%d y:%d  dst_rect: height:%d width:%d x:%d y:%d  clip_rect: height:%d width:%d x:%d y:%d\n",
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 1225406d3381..4cd26ca26fe0 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -323,6 +323,7 @@ struct dc_config {
 	bool multi_mon_pp_mclk_switch;
 	bool disable_dmcu;
 	bool enable_4to1MPC;
+	bool enable_windowed_mpo_odm;
 	bool allow_edp_hotplug_detection;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	bool clamp_min_dcfclk;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 3a8a3214f770..6d70ccb108af 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1929,23 +1929,25 @@ noinline bool dcn30_internal_validate_bw(
 	if (vlevel == context->bw_ctx.dml.soc.num_states)
 		goto validate_fail;
 
-	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
-		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-		struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
+	if (!dc->config.enable_windowed_mpo_odm) {
+		for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+			struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+			struct pipe_ctx *mpo_pipe = pipe->bottom_pipe;
 
-		if (!pipe->stream)
-			continue;
+			if (!pipe->stream)
+				continue;
 
-		/* We only support full screen mpo with ODM */
-		if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
-				&& pipe->plane_state && mpo_pipe
-				&& memcmp(&mpo_pipe->plane_res.scl_data.recout,
-						&pipe->plane_res.scl_data.recout,
-						sizeof(struct rect)) != 0) {
-			ASSERT(mpo_pipe->plane_state != pipe->plane_state);
-			goto validate_fail;
+			/* We only support full screen mpo with ODM */
+			if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled
+					&& pipe->plane_state && mpo_pipe
+					&& memcmp(&mpo_pipe->plane_res.scl_data.recout,
+							&pipe->plane_res.scl_data.recout,
+							sizeof(struct rect)) != 0) {
+				ASSERT(mpo_pipe->plane_state != pipe->plane_state);
+				goto validate_fail;
+			}
+			pipe_idx++;
 		}
-		pipe_idx++;
 	}
 
 	/* merge pipes if necessary */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 20/33] drm/amd/display: Remove unused macros
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (18 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 19/33] drm/amd/display: allow windowed mpo + odm Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 21/33] drm/amd/display: [FW Promotion] Release 0.0.90 Rodrigo Siqueira
                   ` (13 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez

From: Anson Jacob <Anson.Jacob@amd.com>

fixed16_to_double & fixed16_to_double_to_cpu are not used.

Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Anson Jacob <Anson.Jacob@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 3 ---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 3 ---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 2 --
 3 files changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 001737487800..3883f918b3bb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -3660,9 +3660,6 @@ static enum dml_project get_dml_project_version(uint32_t hw_internal_rev)
 	return DML_PROJECT_NAVI10v2;
 }
 
-#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
-#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
-
 static bool init_soc_bounding_box(struct dc *dc,
 				  struct dcn20_resource_pool *pool)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 6d70ccb108af..6dda20f3741c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1707,9 +1707,6 @@ bool dcn30_release_post_bldn_3dlut(
 	return ret;
 }
 
-#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
-#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
-
 static bool is_soc_bounding_box_valid(struct dc *dc)
 {
 	uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 2de731e3e639..6d8a5ffce1d3 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -101,8 +101,6 @@
 #include "link_enc_cfg.h"
 
 #define DC_LOGGER_INIT(logger)
-#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
-#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
 
 #define DCN3_1_DEFAULT_DET_SIZE 384
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 21/33] drm/amd/display: [FW Promotion] Release 0.0.90
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (19 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 20/33] drm/amd/display: Remove unused macros Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 22/33] drm/amd/display: 3.2.159 Rodrigo Siqueira
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Anthony Koo

From: Anthony Koo <Anthony.Koo@amd.com>

Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 9e8ffbf47e63..e0bbfd1b7a2d 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -47,10 +47,10 @@
 
 /* Firmware versioning. */
 #ifdef DMUB_EXPOSE_VERSION
-#define DMUB_FW_VERSION_GIT_HASH 0xdd808d7b
+#define DMUB_FW_VERSION_GIT_HASH 0x9525efb5
 #define DMUB_FW_VERSION_MAJOR 0
 #define DMUB_FW_VERSION_MINOR 0
-#define DMUB_FW_VERSION_REVISION 89
+#define DMUB_FW_VERSION_REVISION 90
 #define DMUB_FW_VERSION_TEST 0
 #define DMUB_FW_VERSION_VBIOS 0
 #define DMUB_FW_VERSION_HOTFIX 0
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 22/33] drm/amd/display: 3.2.159
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (20 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 21/33] drm/amd/display: [FW Promotion] Release 0.0.90 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 23/33] drm/amd/display: Manually adjust strobe for DCN303 Rodrigo Siqueira
                   ` (11 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Aric Cyr

From: Aric Cyr <aric.cyr@amd.com>

This new DC version brings improvements in the following areas:
- Improvements for USB4;
- Isolate FPU code for DCN20, DCN301, and DSC;
- Fixes on Linking training;
- Refactoring some parts of the code, such as PSR;

Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@amd.com>
---
 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 4cd26ca26fe0..33c4f74a0add 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -47,7 +47,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.158"
+#define DC_VER "3.2.159"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 23/33] drm/amd/display: Manually adjust strobe for DCN303
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (21 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 22/33] drm/amd/display: 3.2.159 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 24/33] drm/amd/display: Set phy_mux_sel bit in dmub scratch register Rodrigo Siqueira
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Martin Leung, Jun Lei

From: Martin Leung <Martin.Leung@amd.com>

why:
DCN303's 4 channel SOC BB causes problems at strobe

how:
workaround to manually adjust strobe calculation using FCLK
restrict.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com>
Signed-off-by: Martin Leung <Martin.Leung@amd.com>
---
 .../drm/amd/display/dc/dcn303/dcn303_resource.c    | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
index 2ce6eae7535d..4a9b64023675 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
@@ -1344,6 +1344,20 @@ void dcn303_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
 			dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz;
 			dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz;
 		}
+
+		// WA: patch strobe modes to compensate for DCN303 BW issue
+		if (dcn3_03_soc.num_chans <= 4) {
+			for (i = 0; i < dcn3_03_soc.num_states; i++) {
+				if (dcn3_03_soc.clock_limits[i].dram_speed_mts > 1700)
+					break;
+
+				if (dcn3_03_soc.clock_limits[i].dram_speed_mts >= 1500) {
+					dcn3_03_soc.clock_limits[i].dcfclk_mhz = 100;
+					dcn3_03_soc.clock_limits[i].fabricclk_mhz = 100;
+				}
+			}
+		}
+
 		/* re-init DML with updated bb */
 		dml_init_instance(&dc->dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30);
 		if (dc->current_state)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 24/33] drm/amd/display: Set phy_mux_sel bit in dmub scratch register
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (22 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 23/33] drm/amd/display: Manually adjust strobe for DCN303 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 25/33] drm/amd/display: Add workaround flag for EDID read on certain docks Rodrigo Siqueira
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Hansen, Charlene Liu

From: Hansen <Hansen.Dsouza@amd.com>

[Why]
B0 has pipe mux for DIGC and DIGD which can be connected to PHYF/PHYG or
PHYC/PHY D.

[How]
Based on chip internal hardware revision id determine it is B0 and set
DMUB scratch register so DMUBFW can connect the display pipe is
connected correctly to the dig.

Cc: Wayne Lin <wayne.lin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Hansen <Hansen.Dsouza@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h       | 1 +
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 4 ++--
 drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 2 ++
 drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c   | 1 +
 5 files changed, 7 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 e56f73e299ef..8a8a5ace1040 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1792,7 +1792,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 		break;
 	case IP_VERSION(3, 1, 2):
 	case IP_VERSION(3, 1, 3):
-		dmub_asic = DMUB_ASIC_DCN31;
+		dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31;
 		fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB;
 		break;
 
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 365fbc4758e1..6c4f0ada163f 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -97,6 +97,7 @@ enum dmub_asic {
 	DMUB_ASIC_DCN302,
 	DMUB_ASIC_DCN303,
 	DMUB_ASIC_DCN31,
+	DMUB_ASIC_DCN31B,
 	DMUB_ASIC_MAX,
 };
 
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 e0bbfd1b7a2d..7e22293e78f6 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -374,8 +374,8 @@ union dmub_fw_boot_options {
 		uint32_t reserved_unreleased2: 1; /**< reserved for an unreleased feature */
 		uint32_t root_clock_gating: 1; /**< 1 if all root clock gating is enabled */
 		uint32_t diag_env: 1; /* 1 if diagnostic environment */
-
-		uint32_t reserved : 19; /**< reserved */
+		uint32_t sel_mux_phy_c_d_phy_f_g: 1; /**< 1 if PHYF/PHYG should be enabled */
+		uint32_t reserved : 21; /**< reserved */
 	} bits; /**< boot bits */
 	uint32_t all; /**< 32-bit access to bits */
 };
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
index 3988f65f1ea4..5df990277dd4 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c
@@ -340,6 +340,8 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu
 	boot_options.bits.z10_disable = params->disable_z10;
 	boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1;
 
+	boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0;
+
 	REG_WRITE(DMCUB_SCRATCH14, boot_options.all);
 }
 
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 77c67222cabd..56d400ffa7ac 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -208,6 +208,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
 		break;
 
 	case DMUB_ASIC_DCN31:
+	case DMUB_ASIC_DCN31B:
 		dmub->regs_dcn31 = &dmub_srv_dcn31_regs;
 		funcs->reset = dmub_dcn31_reset;
 		funcs->reset_release = dmub_dcn31_reset_release;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 25/33] drm/amd/display: Add workaround flag for EDID read on certain docks
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (23 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 24/33] drm/amd/display: Set phy_mux_sel bit in dmub scratch register Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 26/33] drm/amd/display: FEC configuration for dpia links Rodrigo Siqueira
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Jimmy Kizito, Jun Lei

From: Jimmy Kizito <Jimmy.Kizito@amd.com>

[Why]
Certain docks appear to NAK I2C writes to the segment pointer with the
MOT (middle of transaction) bit clear. This behaviour can cause EDID
reads from higher segments to fail.

[How]
Add workaround flag for links which connect to docks exhibiting this
issue.

Cc: Wayne Lin <wayne.lin@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 3 +++
 drivers/gpu/drm/amd/display/dc/dc_link.h      | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index b36678669283..e475fbd4d341 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1765,6 +1765,9 @@ static bool dc_link_construct_dpia(struct dc_link *link,
 
 	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
 
+	/* Some docks seem to NAK I2C writes to segment pointer with mot=0. */
+	link->wa_flags.dp_mot_reset_segment = true;
+
 	return true;
 
 ddc_create_fail:
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index b975d1307eff..1327624548a3 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -190,6 +190,7 @@ struct dc_link {
 		bool dp_keep_receiver_powered;
 		bool dp_skip_DID2;
 		bool dp_skip_reset_segment;
+		bool dp_mot_reset_segment;
 	} wa_flags;
 	struct link_mst_stream_allocation_table mst_stream_alloc_table;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 26/33] drm/amd/display: FEC configuration for dpia links
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (24 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 25/33] drm/amd/display: Add workaround flag for EDID read on certain docks Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 27/33] drm/amd/display: FEC configuration for dpia links in MST mode Rodrigo Siqueira
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Meenakshikumar Somasundaram, Jimmy Kizito

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[Why]
To fix the check condition for fec enable for dpia links.

[How]
dc_link_should_enable_fec() to be used to check whether fec should be
enabled.

Cc: Wayne Lin <wayne.lin@amd.com>
Reviewed-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index 8f8eee475144..19b085d84b1f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -431,7 +431,7 @@ void dcn31_link_encoder_enable_dp_output(
 
 		if (link) {
 			dpia_control.dpia_id = link->ddc_hw_inst;
-			dpia_control.fec_rdy = link->fec_state == dc_link_fec_ready ? 1 : 0;
+			dpia_control.fec_rdy = dc_link_should_enable_fec(link);
 		} else {
 			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
 			BREAK_TO_DEBUGGER();
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 27/33] drm/amd/display: FEC configuration for dpia links in MST mode
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (25 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 26/33] drm/amd/display: FEC configuration for dpia links Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 28/33] drm/amd/display: adopt DP2.0 LT SCR revision 8 Rodrigo Siqueira
                   ` (6 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Meenakshikumar Somasundaram, Jimmy Kizito

From: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>

[Why]
To fix the check condition for fec enable for dpia links in MST mode.

[How]
dc_link_should_enable_fec() to be used to check whether fec should be
enabled in MST mode.

Cc: Wayne Lin <wayne.lin@amd.com>
Reviewed-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
index 19b085d84b1f..ee6f13bef377 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
@@ -476,7 +476,7 @@ void dcn31_link_encoder_enable_dp_mst_output(
 
 		if (link) {
 			dpia_control.dpia_id = link->ddc_hw_inst;
-			dpia_control.fec_rdy = link->fec_state == dc_link_fec_ready ? 1 : 0;
+			dpia_control.fec_rdy = dc_link_should_enable_fec(link);
 		} else {
 			DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
 			BREAK_TO_DEBUGGER();
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 28/33] drm/amd/display: adopt DP2.0 LT SCR revision 8
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (26 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 27/33] drm/amd/display: FEC configuration for dpia links in MST mode Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 29/33] drm/amd/display: implement decide lane settings Rodrigo Siqueira
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Wenjing Liu

From: Wenjing Liu <wenjing.liu@amd.com>

[how]
revision 8 SCR requires DP Source to write TPS2 and FFE lane adjustment
in one 5 byte write aux transaction.
It specifies to read aux rd interval value as soon as we turn on TPS1
pattern.

Cc: Wayne Lin <wayne.lin@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 21 ++++++++++++-------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index ec269b7e91c3..a7ed88b75042 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -2080,7 +2080,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 		struct dc_link *link,
 		struct link_training_settings *lt_settings)
 {
-	uint8_t loop_count = 0;
+	uint8_t loop_count;
 	uint32_t aux_rd_interval = 0;
 	uint32_t wait_time = 0;
 	struct link_training_settings req_settings;
@@ -2088,25 +2088,29 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
 	enum link_training_result status = LINK_TRAINING_SUCCESS;
 
-	/* Transmit 128b/132b_TPS1 over Main-Link and Set TRAINING_PATTERN_SET to 01h */
+	/* Transmit 128b/132b_TPS1 over Main-Link */
 	dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, DPRX);
+	/* Set TRAINING_PATTERN_SET to 01h */
 	dpcd_set_training_pattern(link, lt_settings->pattern_for_cr);
 
-	/* Adjust TX_FFE_PRESET_VALUE as requested */
+	/* Adjust TX_FFE_PRESET_VALUE and Transmit 128b/132b_TPS2 over Main-Link */
+	dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
 	dp_get_lane_status_and_drive_settings(link, lt_settings, dpcd_lane_status,
 			&dpcd_lane_status_updated, &req_settings, DPRX);
 	dp_update_drive_settings(lt_settings, req_settings);
-	dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
 	dp_set_hw_lane_settings(link, lt_settings, DPRX);
-	dpcd_set_lane_settings(link, lt_settings, DPRX);
 
-	/* Transmit 128b/132b_TPS2 over Main-Link and Set TRAINING_PATTERN_SET to 02h */
 	dp_set_hw_training_pattern(link, lt_settings->pattern_for_eq, DPRX);
-	dpcd_set_training_pattern(link, lt_settings->pattern_for_eq);
+
+	/* Set loop counter to start from 1 */
+	loop_count = 1;
+
+	/* Set TRAINING_PATTERN_SET to 02h and TX_FFE_PRESET_VALUE in one AUX transaction */
+	dpcd_set_lt_pattern_and_lane_settings(link, lt_settings,
+			lt_settings->pattern_for_eq, DPRX);
 
 	/* poll for channel EQ done */
 	while (status == LINK_TRAINING_SUCCESS) {
-		loop_count++;
 		dp_wait_for_training_aux_rd_interval(link, aux_rd_interval);
 		wait_time += aux_rd_interval;
 		dp_get_lane_status_and_drive_settings(link, lt_settings, dpcd_lane_status,
@@ -2125,6 +2129,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 			dp_set_hw_lane_settings(link, lt_settings, DPRX);
 			dpcd_set_lane_settings(link, lt_settings, DPRX);
 		}
+		loop_count++;
 	}
 
 	/* poll for EQ interlane align done */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 29/33] drm/amd/display: implement decide lane settings
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (27 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 28/33] drm/amd/display: adopt DP2.0 LT SCR revision 8 Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 30/33] drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings Rodrigo Siqueira
                   ` (4 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Wenjing Liu, Jun Lei

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
Decouple lane settings decision logic all to its own function. The
function takes in lane adjust array and link training settings and
decide what hw lane setting and dpcd lane setting should be used.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 292 ++++++------------
 .../drm/amd/display/dc/core/dc_link_dpia.c    |  62 ++--
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |  16 +-
 .../amd/display/include/link_service_types.h  |  17 +
 4 files changed, 155 insertions(+), 232 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index a7ed88b75042..fff238f07b9e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -106,7 +106,8 @@ static bool decide_fallback_link_setting(
 static struct dc_link_settings get_common_supported_link_settings(
 		struct dc_link_settings link_setting_a,
 		struct dc_link_settings link_setting_b);
-
+static void maximize_lane_settings(const struct link_training_settings *lt_settings,
+		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
 static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
 		const struct dc_link_settings *link_settings)
 {
@@ -711,34 +712,37 @@ void dp_hw_to_dpcd_lane_settings(
 	}
 }
 
-void dp_update_drive_settings(
-		struct link_training_settings *dest,
-		struct link_training_settings src)
+void dp_decide_lane_settings(
+		const struct link_training_settings *lt_settings,
+		const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
+		struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
+		union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX])
 {
 	uint32_t lane;
-	for (lane = 0; lane < src.link_settings.lane_count; lane++) {
-		if (dest->voltage_swing == NULL)
-			dest->lane_settings[lane].VOLTAGE_SWING = src.lane_settings[lane].VOLTAGE_SWING;
-		else
-			dest->lane_settings[lane].VOLTAGE_SWING = *dest->voltage_swing;
-
-		if (dest->pre_emphasis == NULL)
-			dest->lane_settings[lane].PRE_EMPHASIS = src.lane_settings[lane].PRE_EMPHASIS;
-		else
-			dest->lane_settings[lane].PRE_EMPHASIS = *dest->pre_emphasis;
-
-		if (dest->post_cursor2 == NULL)
-			dest->lane_settings[lane].POST_CURSOR2 = src.lane_settings[lane].POST_CURSOR2;
-		else
-			dest->lane_settings[lane].POST_CURSOR2 = *dest->post_cursor2;
 
+	for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
+		if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
+				DP_8b_10b_ENCODING) {
+			hw_lane_settings[lane].VOLTAGE_SWING =
+					(enum dc_voltage_swing)(ln_adjust[lane].bits.
+							VOLTAGE_SWING_LANE);
+			hw_lane_settings[lane].PRE_EMPHASIS =
+					(enum dc_pre_emphasis)(ln_adjust[lane].bits.
+							PRE_EMPHASIS_LANE);
+		}
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-		if (dest->ffe_preset == NULL)
-			dest->lane_settings[lane].FFE_PRESET = src.lane_settings[lane].FFE_PRESET;
-		else
-			dest->lane_settings[lane].FFE_PRESET = *dest->ffe_preset;
+		else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
+				DP_128b_132b_ENCODING) {
+			hw_lane_settings[lane].FFE_PRESET.raw =
+					ln_adjust[lane].tx_ffe.PRESET_VALUE;
+		}
 #endif
 	}
+
+	/* we find the maximum of the requested settings across all lanes*/
+	/* and set this maximum for all lanes*/
+	maximize_lane_settings(lt_settings, hw_lane_settings);
+	dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
 }
 
 static uint8_t get_nibble_at_index(const uint8_t *buf,
@@ -768,55 +772,29 @@ static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing(
 
 }
 
-static void find_max_drive_settings(
-	const struct link_training_settings *link_training_setting,
-	struct link_training_settings *max_lt_setting)
+static void maximize_lane_settings(const struct link_training_settings *lt_settings,
+		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
 {
 	uint32_t lane;
 	struct dc_lane_settings max_requested;
 
-	max_requested.VOLTAGE_SWING =
-		link_training_setting->
-		lane_settings[0].VOLTAGE_SWING;
-	max_requested.PRE_EMPHASIS =
-		link_training_setting->
-		lane_settings[0].PRE_EMPHASIS;
-	/*max_requested.postCursor2 =
-	 * link_training_setting->laneSettings[0].postCursor2;*/
+	max_requested.VOLTAGE_SWING = lane_settings[0].VOLTAGE_SWING;
+	max_requested.PRE_EMPHASIS = lane_settings[0].PRE_EMPHASIS;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-	max_requested.FFE_PRESET =
-		link_training_setting->lane_settings[0].FFE_PRESET;
+	max_requested.FFE_PRESET = lane_settings[0].FFE_PRESET;
 #endif
 
 	/* Determine what the maximum of the requested settings are*/
-	for (lane = 1; lane < link_training_setting->link_settings.lane_count;
-			lane++) {
-		if (link_training_setting->lane_settings[lane].VOLTAGE_SWING >
-			max_requested.VOLTAGE_SWING)
-
-			max_requested.VOLTAGE_SWING =
-			link_training_setting->
-			lane_settings[lane].VOLTAGE_SWING;
-
-		if (link_training_setting->lane_settings[lane].PRE_EMPHASIS >
-				max_requested.PRE_EMPHASIS)
-			max_requested.PRE_EMPHASIS =
-			link_training_setting->
-			lane_settings[lane].PRE_EMPHASIS;
+	for (lane = 1; lane < lt_settings->link_settings.lane_count; lane++) {
+		if (lane_settings[lane].VOLTAGE_SWING > max_requested.VOLTAGE_SWING)
+			max_requested.VOLTAGE_SWING = lane_settings[lane].VOLTAGE_SWING;
 
-		/*
-		if (link_training_setting->laneSettings[lane].postCursor2 >
-		 max_requested.postCursor2)
-		{
-		max_requested.postCursor2 =
-		link_training_setting->laneSettings[lane].postCursor2;
-		}
-		*/
+		if (lane_settings[lane].PRE_EMPHASIS > max_requested.PRE_EMPHASIS)
+			max_requested.PRE_EMPHASIS = lane_settings[lane].PRE_EMPHASIS;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-		if (link_training_setting->lane_settings[lane].FFE_PRESET.settings.level >
+		if (lane_settings[lane].FFE_PRESET.settings.level >
 				max_requested.FFE_PRESET.settings.level)
 			max_requested.FFE_PRESET.settings.level =
-					link_training_setting->
 					lane_settings[lane].FFE_PRESET.settings.level;
 #endif
 	}
@@ -828,10 +806,6 @@ static void find_max_drive_settings(
 
 	if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
 		max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
-	/*
-	if (max_requested.postCursor2 > PostCursor2_MaxLevel)
-	max_requested.postCursor2 = PostCursor2_MaxLevel;
-	*/
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 	if (max_requested.FFE_PRESET.settings.level > DP_FFE_PRESET_MAX_LEVEL)
 		max_requested.FFE_PRESET.settings.level = DP_FFE_PRESET_MAX_LEVEL;
@@ -845,61 +819,30 @@ static void find_max_drive_settings(
 		get_max_pre_emphasis_for_voltage_swing(
 			max_requested.VOLTAGE_SWING);
 
-	/*
-	 * Post Cursor2 levels are completely independent from
-	 * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels
-	 * can only be applied to each allowable combination of voltage
-	 * swing and pre-emphasis levels */
-	 /* if ( max_requested.postCursor2 >
-	  *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing))
-	  *  max_requested.postCursor2 =
-	  *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing);
-	  */
-
-	max_lt_setting->link_settings.link_rate =
-		link_training_setting->link_settings.link_rate;
-	max_lt_setting->link_settings.lane_count =
-	link_training_setting->link_settings.lane_count;
-	max_lt_setting->link_settings.link_spread =
-		link_training_setting->link_settings.link_spread;
-
-	for (lane = 0; lane <
-		link_training_setting->link_settings.lane_count;
-		lane++) {
-		max_lt_setting->lane_settings[lane].VOLTAGE_SWING =
-			max_requested.VOLTAGE_SWING;
-		max_lt_setting->lane_settings[lane].PRE_EMPHASIS =
-			max_requested.PRE_EMPHASIS;
-		/*max_lt_setting->laneSettings[lane].postCursor2 =
-		 * max_requested.postCursor2;
-		 */
+	for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
+		lane_settings[lane].VOLTAGE_SWING = max_requested.VOLTAGE_SWING;
+		lane_settings[lane].PRE_EMPHASIS = max_requested.PRE_EMPHASIS;
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-		max_lt_setting->lane_settings[lane].FFE_PRESET =
-			max_requested.FFE_PRESET;
+		lane_settings[lane].FFE_PRESET = max_requested.FFE_PRESET;
 #endif
 	}
-
 }
 
-enum dc_status dp_get_lane_status_and_drive_settings(
+enum dc_status dp_get_lane_status_and_lane_adjust(
 	struct dc_link *link,
 	const struct link_training_settings *link_training_setting,
-	union lane_status *ln_status,
-	union lane_align_status_updated *ln_status_updated,
-	struct link_training_settings *req_settings,
+	union lane_status ln_status[LANE_COUNT_DP_MAX],
+	union lane_align_status_updated *ln_align,
+	union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
 	uint32_t offset)
 {
 	unsigned int lane01_status_address = DP_LANE0_1_STATUS;
 	uint8_t lane_adjust_offset = 4;
 	unsigned int lane01_adjust_address;
 	uint8_t dpcd_buf[6] = {0};
-	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-	struct link_training_settings request_settings = { {0} };
 	uint32_t lane;
 	enum dc_status status;
 
-	memset(req_settings, '\0', sizeof(struct link_training_settings));
-
 	if (is_repeater(link, offset)) {
 		lane01_status_address =
 				DP_LANE0_1_STATUS_PHY_REPEATER1 +
@@ -919,11 +862,11 @@ enum dc_status dp_get_lane_status_and_drive_settings(
 
 		ln_status[lane].raw =
 			get_nibble_at_index(&dpcd_buf[0], lane);
-		dpcd_lane_adjust[lane].raw =
+		ln_adjust[lane].raw =
 			get_nibble_at_index(&dpcd_buf[lane_adjust_offset], lane);
 	}
 
-	ln_status_updated->raw = dpcd_buf[2];
+	ln_align->raw = dpcd_buf[2];
 
 	if (is_repeater(link, offset)) {
 		DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
@@ -962,55 +905,6 @@ enum dc_status dp_get_lane_status_and_drive_settings(
 			dpcd_buf[lane_adjust_offset + 1]);
 	}
 
-	/*copy to req_settings*/
-	request_settings.link_settings.lane_count =
-		link_training_setting->link_settings.lane_count;
-	request_settings.link_settings.link_rate =
-		link_training_setting->link_settings.link_rate;
-	request_settings.link_settings.link_spread =
-		link_training_setting->link_settings.link_spread;
-
-	for (lane = 0; lane <
-		(uint32_t)(link_training_setting->link_settings.lane_count);
-		lane++) {
-
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-		if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
-				DP_128b_132b_ENCODING) {
-			request_settings.lane_settings[lane].FFE_PRESET.raw =
-					dpcd_lane_adjust[lane].tx_ffe.PRESET_VALUE;
-		} else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
-				DP_8b_10b_ENCODING) {
-			request_settings.lane_settings[lane].VOLTAGE_SWING =
-					(enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits.
-							VOLTAGE_SWING_LANE);
-			request_settings.lane_settings[lane].PRE_EMPHASIS =
-					(enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits.
-							PRE_EMPHASIS_LANE);
-		}
-#else
-		request_settings.lane_settings[lane].VOLTAGE_SWING =
-			(enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits.
-				VOLTAGE_SWING_LANE);
-		request_settings.lane_settings[lane].PRE_EMPHASIS =
-			(enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits.
-				PRE_EMPHASIS_LANE);
-#endif
-	}
-
-	/*Note: for postcursor2, read adjusted
-	 * postcursor2 settings from*/
-	/*DpcdAddress_AdjustRequestPostCursor2 =
-	 *0x020C (not implemented yet)*/
-
-	/* we find the maximum of the requested settings across all lanes*/
-	/* and set this maximum for all lanes*/
-	find_max_drive_settings(&request_settings, req_settings);
-
-	/* if post cursor 2 is needed in the future,
-	 * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
-	 */
-
 	return status;
 }
 
@@ -1140,17 +1034,18 @@ static bool perform_post_lt_adj_req_sequence(
 			adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
 			adj_req_timer++) {
 
-			struct link_training_settings req_settings;
 			union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
 			union lane_align_status_updated
 				dpcd_lane_status_updated;
+			union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
+			union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
-			dp_get_lane_status_and_drive_settings(
+			dp_get_lane_status_and_lane_adjust(
 				link,
 				lt_settings,
 				dpcd_lane_status,
 				&dpcd_lane_status_updated,
-				&req_settings,
+				dpcd_lane_adjust,
 				DPRX);
 
 			if (dpcd_lane_status_updated.bits.
@@ -1169,10 +1064,9 @@ static bool perform_post_lt_adj_req_sequence(
 
 				if (lt_settings->
 				lane_settings[lane].VOLTAGE_SWING !=
-				req_settings.lane_settings[lane].
-				VOLTAGE_SWING ||
+				dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_LANE ||
 				lt_settings->lane_settings[lane].PRE_EMPHASIS !=
-				req_settings.lane_settings[lane].PRE_EMPHASIS) {
+				dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_LANE) {
 
 					req_drv_setting_changed = true;
 					break;
@@ -1180,8 +1074,8 @@ static bool perform_post_lt_adj_req_sequence(
 			}
 
 			if (req_drv_setting_changed) {
-				dp_update_drive_settings(
-					lt_settings, req_settings);
+				dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+						lt_settings->lane_settings, dpcd_lane_settings);
 
 				dc_link_dp_set_drive_settings(link,
 						lt_settings);
@@ -1261,13 +1155,14 @@ static enum link_training_result perform_channel_equalization_sequence(
 	struct link_training_settings *lt_settings,
 	uint32_t offset)
 {
-	struct link_training_settings req_settings;
 	enum dc_dp_training_pattern tr_pattern;
 	uint32_t retries_ch_eq;
 	uint32_t wait_time_microsec;
 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 	union lane_align_status_updated dpcd_lane_status_updated = {0};
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	/* Note: also check that TPS4 is a supported feature*/
 
@@ -1316,12 +1211,12 @@ static enum link_training_result perform_channel_equalization_sequence(
 		/* 4. Read lane status and requested
 		 * drive settings as set by the sink*/
 
-		dp_get_lane_status_and_drive_settings(
+		dp_get_lane_status_and_lane_adjust(
 			link,
 			lt_settings,
 			dpcd_lane_status,
 			&dpcd_lane_status_updated,
-			&req_settings,
+			dpcd_lane_adjust,
 			offset);
 
 		/* 5. check CR done*/
@@ -1335,7 +1230,8 @@ static enum link_training_result perform_channel_equalization_sequence(
 			return LINK_TRAINING_SUCCESS;
 
 		/* 7. update VS/PE/PC2 in lt_settings*/
-		dp_update_drive_settings(lt_settings, req_settings);
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->lane_settings, dpcd_lane_settings);
 	}
 
 	return LINK_TRAINING_EQ_FAIL_EQ;
@@ -1361,10 +1257,10 @@ static enum link_training_result perform_clock_recovery_sequence(
 	uint32_t retries_cr;
 	uint32_t retry_count;
 	uint32_t wait_time_microsec;
-	struct link_training_settings req_settings;
 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
 	union lane_align_status_updated dpcd_lane_status_updated;
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	retries_cr = 0;
 	retry_count = 0;
@@ -1418,12 +1314,12 @@ static enum link_training_result perform_clock_recovery_sequence(
 		/* 4. Read lane status and requested drive
 		* settings as set by the sink
 		*/
-		dp_get_lane_status_and_drive_settings(
+		dp_get_lane_status_and_lane_adjust(
 				link,
 				lt_settings,
 				dpcd_lane_status,
 				&dpcd_lane_status_updated,
-				&req_settings,
+				dpcd_lane_adjust,
 				offset);
 
 		/* 5. check CR done*/
@@ -1441,33 +1337,25 @@ static enum link_training_result perform_clock_recovery_sequence(
 			break;
 #endif
 
-#if defined(CONFIG_DRM_AMD_DC_DCN)
-		if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_128b_132b_ENCODING) &&
-				lt_settings->lane_settings[0].FFE_PRESET.settings.level ==
-						req_settings.lane_settings[0].FFE_PRESET.settings.level)
-			retries_cr++;
-		else if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_8b_10b_ENCODING) &&
-				lt_settings->lane_settings[0].VOLTAGE_SWING ==
-						req_settings.lane_settings[0].VOLTAGE_SWING)
-			retries_cr++;
-		else
-			retries_cr = 0;
-#else
 		/* 7. same lane settings*/
 		/* Note: settings are the same for all lanes,
 		 * so comparing first lane is sufficient*/
-		if ((lt_settings->lane_settings[0].VOLTAGE_SWING ==
-			req_settings.lane_settings[0].VOLTAGE_SWING)
-			&& (lt_settings->lane_settings[0].PRE_EMPHASIS ==
-				req_settings.lane_settings[0].PRE_EMPHASIS))
+		if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_8b_10b_ENCODING) &&
+				lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
+						dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
 			retries_cr++;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		else if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_128b_132b_ENCODING) &&
+				lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE ==
+						dpcd_lane_adjust[0].tx_ffe.PRESET_VALUE)
+			retries_cr++;
+#endif
 		else
 			retries_cr = 0;
-#endif
 
 		/* 8. update VS/PE/PC2 in lt_settings*/
-		dp_update_drive_settings(lt_settings, req_settings);
-
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 		retry_count++;
 	}
 
@@ -2083,10 +1971,11 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 	uint8_t loop_count;
 	uint32_t aux_rd_interval = 0;
 	uint32_t wait_time = 0;
-	struct link_training_settings req_settings;
 	union lane_align_status_updated dpcd_lane_status_updated = {0};
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
 	enum link_training_result status = LINK_TRAINING_SUCCESS;
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	/* Transmit 128b/132b_TPS1 over Main-Link */
 	dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, DPRX);
@@ -2095,11 +1984,11 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 
 	/* Adjust TX_FFE_PRESET_VALUE and Transmit 128b/132b_TPS2 over Main-Link */
 	dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
-	dp_get_lane_status_and_drive_settings(link, lt_settings, dpcd_lane_status,
-			&dpcd_lane_status_updated, &req_settings, DPRX);
-	dp_update_drive_settings(lt_settings, req_settings);
+	dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
+			&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
+	dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+			lt_settings->lane_settings, dpcd_lane_settings);
 	dp_set_hw_lane_settings(link, lt_settings, DPRX);
-
 	dp_set_hw_training_pattern(link, lt_settings->pattern_for_eq, DPRX);
 
 	/* Set loop counter to start from 1 */
@@ -2113,9 +2002,10 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 	while (status == LINK_TRAINING_SUCCESS) {
 		dp_wait_for_training_aux_rd_interval(link, aux_rd_interval);
 		wait_time += aux_rd_interval;
-		dp_get_lane_status_and_drive_settings(link, lt_settings, dpcd_lane_status,
-				&dpcd_lane_status_updated, &req_settings, DPRX);
-		dp_update_drive_settings(lt_settings, req_settings);
+		dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
+				&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->lane_settings, dpcd_lane_settings);
 		dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
 		if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count,
 				dpcd_lane_status)) {
@@ -2145,8 +2035,8 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 			dp_wait_for_training_aux_rd_interval(link,
 					lt_settings->eq_pattern_time);
 			wait_time += lt_settings->eq_pattern_time;
-			dp_get_lane_status_and_drive_settings(link, lt_settings, dpcd_lane_status,
-					&dpcd_lane_status_updated, &req_settings, DPRX);
+			dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
+					&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
 		}
 	}
 
@@ -2159,9 +2049,9 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
 {
 	/* Assumption: assume hardware has transmitted eq pattern */
 	enum link_training_result status = LINK_TRAINING_SUCCESS;
-	struct link_training_settings req_settings;
 	union lane_align_status_updated dpcd_lane_status_updated = {0};
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
 	uint32_t wait_time = 0;
 
 	/* initiate CDS done sequence */
@@ -2172,8 +2062,8 @@ static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
 		dp_wait_for_training_aux_rd_interval(link,
 				lt_settings->cds_pattern_time);
 		wait_time += lt_settings->cds_pattern_time;
-		dp_get_lane_status_and_drive_settings(link, lt_settings, dpcd_lane_status,
-						&dpcd_lane_status_updated, &req_settings, DPRX);
+		dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
+						&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
 		if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) &&
 				dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b) {
 			/* pass */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index e9006d099393..c971f8c761ca 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -263,10 +263,12 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
 	uint32_t retry_count = 0;
 	/* From DP spec, CR read interval is always 100us. */
 	uint32_t wait_time_microsec = TRAINING_AUX_RD_INTERVAL;
-	struct link_training_settings req_settings;
 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
+
 	uint8_t set_cfg_data;
 	enum dpia_set_config_ts ts;
 
@@ -345,11 +347,12 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
 		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
 
 		/* Read status and adjustment requests from DPCD. */
-		status = dp_get_lane_status_and_drive_settings(link,
+		status = dp_get_lane_status_and_lane_adjust(
+				link,
 				lt_settings,
 				dpcd_lane_status,
 				&dpcd_lane_status_updated,
-				&req_settings,
+				dpcd_lane_adjust,
 				hop);
 		if (status != DC_OK) {
 			result = LINK_TRAINING_ABORT;
@@ -371,16 +374,18 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
 		 * Note: settings are the same for all lanes,
 		 * so comparing first lane is sufficient.
 		 */
-		if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
-			req_settings.lane_settings[0].VOLTAGE_SWING &&
-			lt_settings->lane_settings[0].PRE_EMPHASIS ==
-			req_settings.lane_settings[0].PRE_EMPHASIS)
+		if ((lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
+				dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
+				&& (lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET ==
+						dpcd_lane_adjust[0].bits.PRE_EMPHASIS_LANE))
 			retries_cr++;
 		else
 			retries_cr = 0;
 
 		/* Update VS/PE. */
-		dp_update_drive_settings(lt_settings, req_settings);
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->lane_settings,
+				dpcd_lane_settings);
 		retry_count++;
 	}
 
@@ -416,10 +421,11 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li
 	uint32_t retries_cr = 0; /* Number of consecutive attempts with same VS or PE. */
 	uint32_t retry_count = 0;
 	uint32_t wait_time_microsec = lt_settings->cr_pattern_time;
-	struct link_training_settings req_settings;
 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	/* Cap of LINK_TRAINING_MAX_CR_RETRY attempts at clock recovery.
 	 * Fix inherited from perform_clock_recovery_sequence() -
@@ -445,11 +451,12 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li
 		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
 
 		/* Read status and adjustment requests from DPCD. */
-		status = dp_get_lane_status_and_drive_settings(link,
+		status = dp_get_lane_status_and_lane_adjust(
+				link,
 				lt_settings,
 				dpcd_lane_status,
 				&dpcd_lane_status_updated,
-				&req_settings,
+				dpcd_lane_adjust,
 				DPRX);
 		if (status != DC_OK) {
 			result = LINK_TRAINING_ABORT;
@@ -471,16 +478,17 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li
 		 * Note: settings are the same for all lanes,
 		 * so comparing first lane is sufficient.
 		 */
-		if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
-			req_settings.lane_settings[0].VOLTAGE_SWING &&
-			lt_settings->lane_settings[0].PRE_EMPHASIS ==
-			req_settings.lane_settings[0].PRE_EMPHASIS)
+		if ((lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
+				dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
+				&& (lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET ==
+						dpcd_lane_adjust[0].bits.PRE_EMPHASIS_LANE))
 			retries_cr++;
 		else
 			retries_cr = 0;
 
 		/* Update VS/PE. */
-		dp_update_drive_settings(lt_settings, req_settings);
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 		retry_count++;
 	}
 
@@ -566,10 +574,11 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
 	enum dc_status status;
 	enum dc_dp_training_pattern tr_pattern;
 	uint32_t wait_time_microsec;
-	struct link_training_settings req_settings;
 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 	uint8_t set_cfg_data;
 	enum dpia_set_config_ts ts;
 
@@ -639,11 +648,12 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
 		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
 
 		/* Read status and adjustment requests from DPCD. */
-		status = dp_get_lane_status_and_drive_settings(link,
+		status = dp_get_lane_status_and_lane_adjust(
+				link,
 				lt_settings,
 				dpcd_lane_status,
 				&dpcd_lane_status_updated,
-				&req_settings,
+				dpcd_lane_adjust,
 				hop);
 		if (status != DC_OK) {
 			result = LINK_TRAINING_ABORT;
@@ -664,7 +674,8 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
 		}
 
 		/* Update VS/PE. */
-		dp_update_drive_settings(lt_settings, req_settings);
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->lane_settings, dpcd_lane_settings);
 	}
 
 	/* Abort link training if equalization failed due to HPD unplug. */
@@ -701,10 +712,11 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
 	enum dc_status status;
 	enum dc_dp_training_pattern tr_pattern = lt_settings->pattern_for_eq;
 	uint32_t wait_time_microsec;
-	struct link_training_settings req_settings;
 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
+	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	wait_time_microsec = dpia_get_eq_aux_rd_interval(link, lt_settings, DPRX);
 
@@ -720,11 +732,12 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
 		dp_wait_for_training_aux_rd_interval(link, wait_time_microsec);
 
 		/* Read status and adjustment requests from DPCD. */
-		status = dp_get_lane_status_and_drive_settings(link,
+		status = dp_get_lane_status_and_lane_adjust(
+				link,
 				lt_settings,
 				dpcd_lane_status,
 				&dpcd_lane_status_updated,
-				&req_settings,
+				dpcd_lane_adjust,
 				DPRX);
 		if (status != DC_OK) {
 			result = LINK_TRAINING_ABORT;
@@ -745,7 +758,8 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
 		}
 
 		/* Update VS/PE. */
-		dp_update_drive_settings(lt_settings, req_settings);
+		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
+				lt_settings->lane_settings, dpcd_lane_settings);
 	}
 
 	/* Abort link training if equalization failed due to HPD unplug. */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index c70375117519..a6d3d859754a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -121,12 +121,12 @@ enum dc_status dpcd_set_lane_settings(
 	const struct link_training_settings *link_training_setting,
 	uint32_t offset);
 /* Read training status and adjustment requests from DPCD. */
-enum dc_status dp_get_lane_status_and_drive_settings(
+enum dc_status dp_get_lane_status_and_lane_adjust(
 	struct dc_link *link,
 	const struct link_training_settings *link_training_setting,
-	union lane_status *ln_status,
-	union lane_align_status_updated *ln_status_updated,
-	struct link_training_settings *req_settings,
+	union lane_status ln_status[LANE_COUNT_DP_MAX],
+	union lane_align_status_updated *ln_align,
+	union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
 	uint32_t offset);
 
 void dp_wait_for_training_aux_rd_interval(
@@ -151,9 +151,11 @@ void dp_hw_to_dpcd_lane_settings(
 	const struct link_training_settings *lt_settings,
 	const struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
 	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]);
-void dp_update_drive_settings(
-	struct link_training_settings *dest,
-	struct link_training_settings src);
+void dp_decide_lane_settings(
+	const struct link_training_settings *lt_settings,
+	const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
+	struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]);
 
 uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval);
 
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 9a16fc855254..dc30dcd918bb 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -123,6 +123,23 @@ struct link_training_settings {
 	/* dpcd lane settings will always use the same hw lane settings
 	 * even if it doesn't match requested lane adjust */
 	bool always_match_dpcd_with_hw_lane_settings;
+
+	/*****************************************************************
+	* training states - parameters that can change in link training
+	*****************************************************************/
+	/* TODO: Move hw_lane_settings and dpcd_lane_settings
+	 * along with lane adjust, lane align, offset and all
+	 * other training states into a new structure called
+	 * training states, so link_training_settings becomes
+	 * a constant input pre-decided prior to link training.
+	 *
+	 * The goal is to strictly decouple link training settings
+	 * decision making process from link training states to
+	 * prevent it from messy code practice of changing training
+	 * decision on the fly.
+	 */
+	struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX];
+	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX];
 };
 
 /*TODO: Move this enum test harness*/
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 30/33] drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (28 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 29/33] drm/amd/display: implement decide lane settings Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 31/33] drm/amd/display: add two lane settings training options Rodrigo Siqueira
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Wenjing Liu, Jun Lei

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
As DP features expands, we have encountered many situations where we
must configure a different DPCD lane setting from hw lane settings we
output.  The change is to decouple hw lane settings from dpcd lane
settings to provide flexibility to configure dpcd and hw individually.

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 148 +++++++-----------
 .../drm/amd/display/dc/core/dc_link_dpia.c    |  11 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |   5 -
 .../amd/display/include/link_service_types.h  |   5 +-
 4 files changed, 63 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index fff238f07b9e..8f27097d56cc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -516,8 +516,6 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 	enum dc_dp_training_pattern pattern,
 	uint32_t offset)
 {
-	union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } };
-
 	uint32_t dpcd_base_lt_offset;
 
 	uint8_t dpcd_lt_buffer[5] = {0};
@@ -555,16 +553,14 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 			dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
 	}
 
-	dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->lane_settings, dpcd_lane);
-
 	/* concatenate everything into one buffer*/
-
-	size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]);
+	size_in_bytes = lt_settings->link_settings.lane_count *
+			sizeof(lt_settings->dpcd_lane_settings[0]);
 
 	 // 0x00103 - 0x00102
 	memmove(
 		&dpcd_lt_buffer[DP_TRAINING_LANE0_SET - DP_TRAINING_PATTERN_SET],
-		dpcd_lane,
+		lt_settings->dpcd_lane_settings,
 		size_in_bytes);
 
 	if (is_repeater(link, offset)) {
@@ -576,7 +572,7 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 					__func__,
 					offset,
 					dpcd_base_lt_offset,
-					dpcd_lane[0].tx_ffe.PRESET_VALUE);
+					lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
 		else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
 				DP_8b_10b_ENCODING)
 #endif
@@ -585,10 +581,10 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 			__func__,
 			offset,
 			dpcd_base_lt_offset,
-			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
-			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
-			dpcd_lane[0].bits.MAX_SWING_REACHED,
-			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
+			lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
+			lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
+			lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
+			lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
 	} else {
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 		if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
@@ -596,17 +592,17 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 			DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
 					__func__,
 					dpcd_base_lt_offset,
-					dpcd_lane[0].tx_ffe.PRESET_VALUE);
+					lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
 		else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
 				DP_8b_10b_ENCODING)
 #endif
 		DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
 			__func__,
 			dpcd_base_lt_offset,
-			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
-			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
-			dpcd_lane[0].bits.MAX_SWING_REACHED,
-			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
+			lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
+			lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
+			lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
+			lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
 	}
 	if (edp_workaround) {
 		/* for eDP write in 2 parts because the 5-byte burst is
@@ -621,7 +617,7 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 		core_link_write_dpcd(
 			link,
 			DP_TRAINING_LANE0_SET,
-			(uint8_t *)(dpcd_lane),
+			(uint8_t *)(lt_settings->dpcd_lane_settings),
 			size_in_bytes);
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -913,7 +909,6 @@ enum dc_status dpcd_set_lane_settings(
 	const struct link_training_settings *link_training_setting,
 	uint32_t offset)
 {
-	union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
 	unsigned int lane0_set_address;
 	enum dc_status status;
 
@@ -923,34 +918,11 @@ enum dc_status dpcd_set_lane_settings(
 		lane0_set_address = DP_TRAINING_LANE0_SET_PHY_REPEATER1 +
 		((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
 
-	dp_hw_to_dpcd_lane_settings(link_training_setting,
-			link_training_setting->lane_settings,
-			dpcd_lane);
-
 	status = core_link_write_dpcd(link,
 		lane0_set_address,
-		(uint8_t *)(dpcd_lane),
+		(uint8_t *)(link_training_setting->dpcd_lane_settings),
 		link_training_setting->link_settings.lane_count);
 
-	/*
-	if (LTSettings.link.rate == LinkRate_High2)
-	{
-		DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0};
-		for ( uint32_t lane = 0;
-		lane < lane_count_DPMax; lane++)
-		{
-			dpcd_lane2[lane].bits.post_cursor2_set =
-			static_cast<unsigned char>(
-			LTSettings.laneSettings[lane].postCursor2);
-			dpcd_lane2[lane].bits.max_post_cursor2_reached = 0;
-		}
-		m_pDpcdAccessSrv->WriteDpcdData(
-		DpcdAddress_Lane0Set2,
-		reinterpret_cast<unsigned char*>(dpcd_lane2),
-		LTSettings.link.lanes);
-	}
-	*/
-
 	if (is_repeater(link, offset)) {
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 		if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
@@ -960,7 +932,7 @@ enum dc_status dpcd_set_lane_settings(
 					__func__,
 					offset,
 					lane0_set_address,
-					dpcd_lane[0].tx_ffe.PRESET_VALUE);
+					link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
 		else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
 				DP_8b_10b_ENCODING)
 #endif
@@ -969,10 +941,10 @@ enum dc_status dpcd_set_lane_settings(
 			__func__,
 			offset,
 			lane0_set_address,
-			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
-			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
-			dpcd_lane[0].bits.MAX_SWING_REACHED,
-			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
+			link_training_setting->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
+			link_training_setting->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
+			link_training_setting->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
+			link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
 
 	} else {
 #if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -981,17 +953,17 @@ enum dc_status dpcd_set_lane_settings(
 			DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
 					__func__,
 					lane0_set_address,
-					dpcd_lane[0].tx_ffe.PRESET_VALUE);
+					link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
 		else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
 				DP_8b_10b_ENCODING)
 #endif
 		DC_LOG_HW_LINK_TRAINING("%s\n 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
 			__func__,
 			lane0_set_address,
-			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
-			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
-			dpcd_lane[0].bits.MAX_SWING_REACHED,
-			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
+			link_training_setting->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
+			link_training_setting->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
+			link_training_setting->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
+			link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
 	}
 
 	return status;
@@ -1004,7 +976,7 @@ bool dp_is_max_vs_reached(
 	for (lane = 0; lane <
 		(uint32_t)(lt_settings->link_settings.lane_count);
 		lane++) {
-		if (lt_settings->lane_settings[lane].VOLTAGE_SWING
+		if (lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET
 			== VOLTAGE_SWING_MAX_LEVEL)
 			return true;
 	}
@@ -1038,7 +1010,6 @@ static bool perform_post_lt_adj_req_sequence(
 			union lane_align_status_updated
 				dpcd_lane_status_updated;
 			union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-			union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 			dp_get_lane_status_and_lane_adjust(
 				link,
@@ -1063,9 +1034,9 @@ static bool perform_post_lt_adj_req_sequence(
 			for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
 
 				if (lt_settings->
-				lane_settings[lane].VOLTAGE_SWING !=
+				dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET !=
 				dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_LANE ||
-				lt_settings->lane_settings[lane].PRE_EMPHASIS !=
+				lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET !=
 				dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_LANE) {
 
 					req_drv_setting_changed = true;
@@ -1075,7 +1046,7 @@ static bool perform_post_lt_adj_req_sequence(
 
 			if (req_drv_setting_changed) {
 				dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
-						lt_settings->lane_settings, dpcd_lane_settings);
+						lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 
 				dc_link_dp_set_drive_settings(link,
 						lt_settings);
@@ -1162,10 +1133,8 @@ static enum link_training_result perform_channel_equalization_sequence(
 	union lane_align_status_updated dpcd_lane_status_updated = {0};
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
-	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	/* Note: also check that TPS4 is a supported feature*/
-
 	tr_pattern = lt_settings->pattern_for_eq;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -1231,7 +1200,7 @@ static enum link_training_result perform_channel_equalization_sequence(
 
 		/* 7. update VS/PE/PC2 in lt_settings*/
 		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
-				lt_settings->lane_settings, dpcd_lane_settings);
+				lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 	}
 
 	return LINK_TRAINING_EQ_FAIL_EQ;
@@ -1484,6 +1453,7 @@ static inline void decide_8b_10b_training_settings(
 	lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting);
 	lt_settings->enhanced_framing = 1;
 	lt_settings->should_set_fec_ready = true;
+	dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 }
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
@@ -1509,6 +1479,8 @@ static inline void decide_128b_132b_training_settings(struct dc_link *link,
 			link->dpcd_caps.lttpr_caps.phy_repeater_cnt) + 1) * 20000;
 	lt_settings->lttpr_mode = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) ?
 			LTTPR_MODE_NON_TRANSPARENT : LTTPR_MODE_TRANSPARENT;
+	dp_hw_to_dpcd_lane_settings(lt_settings,
+			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 }
 #endif
 
@@ -1571,6 +1543,9 @@ static void override_training_settings(
 			: POST_CURSOR2_DISABLED;
 	}
 
+	dp_hw_to_dpcd_lane_settings(lt_settings,
+			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
+
 	/* Initialize training timings */
 	if (overrides->cr_pattern_time != NULL)
 		lt_settings->cr_pattern_time = *overrides->cr_pattern_time;
@@ -1841,6 +1816,9 @@ void dc_link_dp_set_drive_settings(
 	/* program ASIC PHY settings*/
 	dp_set_hw_lane_settings(link, lt_settings, DPRX);
 
+	dp_hw_to_dpcd_lane_settings(lt_settings,
+			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
+
 	/* Notify DP sink the PHY settings from source */
 	dpcd_set_lane_settings(link, lt_settings, DPRX);
 }
@@ -1975,7 +1953,6 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
 	enum link_training_result status = LINK_TRAINING_SUCCESS;
 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
-	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	/* Transmit 128b/132b_TPS1 over Main-Link */
 	dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, DPRX);
@@ -1987,7 +1964,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 	dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
 			&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
 	dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
-			lt_settings->lane_settings, dpcd_lane_settings);
+			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 	dp_set_hw_lane_settings(link, lt_settings, DPRX);
 	dp_set_hw_training_pattern(link, lt_settings->pattern_for_eq, DPRX);
 
@@ -2005,7 +1982,7 @@ static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
 		dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
 				&dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
 		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
-				lt_settings->lane_settings, dpcd_lane_settings);
+			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 		dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
 		if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count,
 				dpcd_lane_status)) {
@@ -2120,7 +2097,7 @@ static enum link_training_result dp_perform_8b_10b_link_training(
 		}
 
 		for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++)
-			lt_settings->lane_settings[lane].VOLTAGE_SWING = VOLTAGE_SWING_LEVEL0;
+			lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET = VOLTAGE_SWING_LEVEL0;
 	}
 
 	if (status == LINK_TRAINING_SUCCESS) {
@@ -3496,15 +3473,13 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
 #endif
 	unsigned int test_pattern_size = 0;
 	enum dp_test_pattern test_pattern;
-	struct dc_link_training_settings link_settings;
 	union lane_adjust dpcd_lane_adjust;
 	unsigned int lane;
 	struct link_training_settings link_training_settings;
-	int i = 0;
 
 	dpcd_test_pattern.raw = 0;
 	memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
-	memset(&link_settings, 0, sizeof(link_settings));
+	memset(&link_training_settings, 0, sizeof(link_training_settings));
 
 	/* get phy test pattern and pattern parameters from DP receiver */
 	core_link_read_dpcd(
@@ -3625,48 +3600,37 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
 #endif
 
 	/* prepare link training settings */
-	link_settings.link = link->cur_link_settings;
+	link_training_settings.link_settings = link->cur_link_settings;
 
 	for (lane = 0; lane <
 		(unsigned int)(link->cur_link_settings.lane_count);
 		lane++) {
 		dpcd_lane_adjust.raw =
 			get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
 		if (dp_get_link_encoding_format(&link->cur_link_settings) ==
-				DP_128b_132b_ENCODING) {
-			link_settings.lane_settings[lane].FFE_PRESET.raw =
-					dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
-		} else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
 				DP_8b_10b_ENCODING) {
-			link_settings.lane_settings[lane].VOLTAGE_SWING =
+			link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING =
 				(enum dc_voltage_swing)
 				(dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
-			link_settings.lane_settings[lane].PRE_EMPHASIS =
+			link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS =
 				(enum dc_pre_emphasis)
 				(dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
-			link_settings.lane_settings[lane].POST_CURSOR2 =
+			link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
 				(enum dc_post_cursor2)
 				((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
 		}
-#else
-		link_settings.lane_settings[lane].VOLTAGE_SWING =
-			(enum dc_voltage_swing)
-			(dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
-		link_settings.lane_settings[lane].PRE_EMPHASIS =
-			(enum dc_pre_emphasis)
-			(dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
-		link_settings.lane_settings[lane].POST_CURSOR2 =
-			(enum dc_post_cursor2)
-			((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+		else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
+				DP_128b_132b_ENCODING) {
+			link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw =
+					dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
+		}
 #endif
 	}
 
-	for (i = 0; i < 4; i++)
-		link_training_settings.lane_settings[i] =
-				link_settings.lane_settings[i];
-	link_training_settings.link_settings = link_settings.link;
-	link_training_settings.allow_invalid_msa_timing_param = false;
+	dp_hw_to_dpcd_lane_settings(&link_training_settings,
+			link_training_settings.hw_lane_settings,
+			link_training_settings.dpcd_lane_settings);
 	/*Usage: Measure DP physical lane signal
 	 * by DP SI test equipment automatically.
 	 * PHY test pattern request is generated by equipment via HPD interrupt.
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index c971f8c761ca..b1c9f77d6bf4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -267,8 +267,6 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
-
 	uint8_t set_cfg_data;
 	enum dpia_set_config_ts ts;
 
@@ -385,7 +383,7 @@ static enum link_training_result dpia_training_cr_non_transparent(struct dc_link
 		/* Update VS/PE. */
 		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
 				lt_settings->lane_settings,
-				dpcd_lane_settings);
+				lt_settings->dpcd_lane_settings);
 		retry_count++;
 	}
 
@@ -425,7 +423,6 @@ static enum link_training_result dpia_training_cr_transparent(struct dc_link *li
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	/* Cap of LINK_TRAINING_MAX_CR_RETRY attempts at clock recovery.
 	 * Fix inherited from perform_clock_recovery_sequence() -
@@ -578,7 +575,6 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 	uint8_t set_cfg_data;
 	enum dpia_set_config_ts ts;
 
@@ -675,7 +671,7 @@ static enum link_training_result dpia_training_eq_non_transparent(struct dc_link
 
 		/* Update VS/PE. */
 		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
-				lt_settings->lane_settings, dpcd_lane_settings);
+				lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 	}
 
 	/* Abort link training if equalization failed due to HPD unplug. */
@@ -716,7 +712,6 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
-	union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX] = { { {0} } };
 
 	wait_time_microsec = dpia_get_eq_aux_rd_interval(link, lt_settings, DPRX);
 
@@ -759,7 +754,7 @@ static enum link_training_result dpia_training_eq_transparent(struct dc_link *li
 
 		/* Update VS/PE. */
 		dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
-				lt_settings->lane_settings, dpcd_lane_settings);
+				lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 	}
 
 	/* Abort link training if equalization failed due to HPD unplug. */
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index a23937e1dc5c..bc87ea0adf94 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -174,11 +174,6 @@ struct dc_lane_settings {
 #endif
 };
 
-struct dc_link_training_settings {
-	struct dc_link_settings link;
-	struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
-};
-
 struct dc_link_training_overrides {
 	enum dc_voltage_swing *voltage_swing;
 	enum dc_pre_emphasis *pre_emphasis;
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 dc30dcd918bb..622c03f15df2 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -90,8 +90,11 @@ enum lttpr_mode {
 
 struct link_training_settings {
 	struct dc_link_settings link_settings;
-	struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
 
+	/* TODO: turn lane settings below into mandatory fields
+	 * as initial lane configuration
+	 */
+	struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
 	enum dc_voltage_swing *voltage_swing;
 	enum dc_pre_emphasis *pre_emphasis;
 	enum dc_post_cursor2 *post_cursor2;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 31/33] drm/amd/display: add two lane settings training options
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (29 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 30/33] drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-24 13:31 ` [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane Rodrigo Siqueira
                   ` (2 subsequent siblings)
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Wenjing Liu, Jun Lei

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
option 1: disallow different lanes to have different lane settings
option 2: dpcd lane settings will always use the same hw lane settings
even if it doesn't match requested lane adjust

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   | 14 +++++++++++++-
 .../drm/amd/display/include/link_service_types.h   |  1 -
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 8f27097d56cc..653279ab96f4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -737,8 +737,17 @@ void dp_decide_lane_settings(
 
 	/* we find the maximum of the requested settings across all lanes*/
 	/* and set this maximum for all lanes*/
-	maximize_lane_settings(lt_settings, hw_lane_settings);
 	dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
+
+	if (lt_settings->disallow_per_lane_settings) {
+		/* we find the maximum of the requested settings across all lanes*/
+		/* and set this maximum for all lanes*/
+		maximize_lane_settings(lt_settings, hw_lane_settings);
+
+		if (lt_settings->always_match_dpcd_with_hw_lane_settings)
+			dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
+	}
+
 }
 
 static uint8_t get_nibble_at_index(const uint8_t *buf,
@@ -1453,6 +1462,8 @@ static inline void decide_8b_10b_training_settings(
 	lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting);
 	lt_settings->enhanced_framing = 1;
 	lt_settings->should_set_fec_ready = true;
+	lt_settings->disallow_per_lane_settings = true;
+	lt_settings->always_match_dpcd_with_hw_lane_settings = true;
 	dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 }
 
@@ -1479,6 +1490,7 @@ static inline void decide_128b_132b_training_settings(struct dc_link *link,
 			link->dpcd_caps.lttpr_caps.phy_repeater_cnt) + 1) * 20000;
 	lt_settings->lttpr_mode = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) ?
 			LTTPR_MODE_NON_TRANSPARENT : LTTPR_MODE_TRANSPARENT;
+	lt_settings->disallow_per_lane_settings = true;
 	dp_hw_to_dpcd_lane_settings(lt_settings,
 			lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
 }
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 622c03f15df2..424bccd36434 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -118,7 +118,6 @@ struct link_training_settings {
 #endif
 
 	bool enhanced_framing;
-	bool allow_invalid_msa_timing_param;
 	enum lttpr_mode lttpr_mode;
 
 	/* disallow different lanes to have different lane settings */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (30 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 31/33] drm/amd/display: add two lane settings training options Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-25 11:25   ` Paul Menzel
  2021-10-24 13:31 ` [PATCH 33/33] drm/amd/display: move FPU associated DCN301 code to DML folder Rodrigo Siqueira
  2021-10-25 13:07 ` [PATCH 00/33] DC Patches October 24, 2020 Wheeler, Daniel
  33 siblings, 1 reply; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Wenjing Liu, Eric Yang

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
We have a regression that cause maximize lane settings to use
uninitialized data from unused lanes.
This will cause link training to fail for 1 or 2 lanes because the lane
adjust is populated incorrectly sometimes.

Reviewed-by: Eric Yang <eric.yang2@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 653279ab96f4..f6ba7c734f54 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -108,6 +108,9 @@ static struct dc_link_settings get_common_supported_link_settings(
 		struct dc_link_settings link_setting_b);
 static void maximize_lane_settings(const struct link_training_settings *lt_settings,
 		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
+static void override_lane_settings(const struct link_training_settings *lt_settings,
+		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
+
 static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
 		const struct dc_link_settings *link_settings)
 {
@@ -734,15 +737,13 @@ void dp_decide_lane_settings(
 		}
 #endif
 	}
-
-	/* we find the maximum of the requested settings across all lanes*/
-	/* and set this maximum for all lanes*/
 	dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
 
 	if (lt_settings->disallow_per_lane_settings) {
 		/* we find the maximum of the requested settings across all lanes*/
 		/* and set this maximum for all lanes*/
 		maximize_lane_settings(lt_settings, hw_lane_settings);
+		override_lane_settings(lt_settings, hw_lane_settings);
 
 		if (lt_settings->always_match_dpcd_with_hw_lane_settings)
 			dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
@@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
 	}
 }
 
+static void override_lane_settings(const struct link_training_settings *lt_settings,
+		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
+{
+	uint32_t lane;
+
+	if (lt_settings->voltage_swing == NULL &&
+			lt_settings->pre_emphasis == NULL &&
+#if defined(CONFIG_DRM_AMD_DC_DP2_0)
+			lt_settings->ffe_preset == NULL &&
+#endif
+			lt_settings->post_cursor2 == NULL)
+
+		return;
+
+	for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
+		if (lt_settings->voltage_swing)
+			lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing;
+		if (lt_settings->pre_emphasis)
+			lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
+		if (lt_settings->post_cursor2)
+			lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
+#if defined(CONFIG_DRM_AMD_DC_DP2_0)
+		if (lt_settings->ffe_preset)
+			lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
+#endif
+	}
+}
+
 enum dc_status dp_get_lane_status_and_lane_adjust(
 	struct dc_link *link,
 	const struct link_training_settings *link_training_setting,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH 33/33] drm/amd/display: move FPU associated DCN301 code to DML folder
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (31 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane Rodrigo Siqueira
@ 2021-10-24 13:31 ` Rodrigo Siqueira
  2021-10-25 13:07 ` [PATCH 00/33] DC Patches October 24, 2020 Wheeler, Daniel
  33 siblings, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira @ 2021-10-24 13:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Rodrigo.Siqueira,
	Aurabindo.Pillai, qingqing.zhuo, mikita.lipski, roman.li,
	Anson.Jacob, wayne.lin, stylon.wang, solomon.chiu, pavle.kotarac,
	agustin.gutierrez, Qingqing Zhuo, Christian König,
	Harry Wentland, Zhan Liu

From: Qingqing Zhuo <Qingqing.Zhuo@amd.com>

[Why & How]
As part of the FPU isolation work documented in
https://patchwork.freedesktop.org/series/93042/, isolate
code that uses FPU in DCN301 to DML, where all FPU code
should locate.

Cc: Christian König <christian.koenig@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Tested-by: Zhan Liu <Zhan.Liu@amd.com>
Signed-off-by: Qingqing Zhuo <Qingqing.Zhuo@amd.com>
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
---
 .../drm/amd/display/dc/dcn30/dcn30_resource.c |   2 +
 .../gpu/drm/amd/display/dc/dcn301/Makefile    |  26 --
 .../amd/display/dc/dcn301/dcn301_resource.c   | 349 +---------------
 .../amd/display/dc/dcn301/dcn301_resource.h   |   3 +
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |   3 +
 .../amd/display/dc/dml/dcn301/dcn301_fpu.c    | 390 ++++++++++++++++++
 .../amd/display/dc/dml/dcn301/dcn301_fpu.h    |  42 ++
 7 files changed, 450 insertions(+), 365 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 6dda20f3741c..e50c695e3c96 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -2322,7 +2322,9 @@ bool dcn30_validate_bandwidth(struct dc *dc,
 		goto validate_out;
 	}
 
+	DC_FP_START();
 	dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
+	DC_FP_END();
 
 	BW_VAL_TRACE_END_WATERMARKS();
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile
index 09264716d1dc..7aa628c21973 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile
@@ -13,32 +13,6 @@
 DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \
 		dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o
 
-ifdef CONFIG_X86
-CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse
-endif
-
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec
-endif
-
-ifdef CONFIG_CC_IS_GCC
-ifeq ($(call cc-ifversion, -lt, 0701, y), y)
-IS_OLD_GCC = 1
-endif
-CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float
-endif
-
-ifdef CONFIG_X86
-ifdef IS_OLD_GCC
-# Stack alignment mismatch, proceed with caution.
-# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3
-# (8B stack alignment).
-CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mpreferred-stack-boundary=4
-else
-CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -msse2
-endif
-endif
-
 AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_DCN301)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index 5350c93d7772..fbaa03f26d8b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -82,6 +82,7 @@
 #include "dce/dce_i2c.h"
 
 #include "dml/dcn30/display_mode_vba_30.h"
+#include "dml/dcn301/dcn301_fpu.h"
 #include "vm_helper.h"
 #include "dcn20/dcn20_vmid.h"
 #include "amdgpu_socbb.h"
@@ -91,184 +92,6 @@
 
 #define DC_LOGGER_INIT(logger)
 
-struct _vcs_dpi_ip_params_st dcn3_01_ip = {
-	.odm_capable = 1,
-	.gpuvm_enable = 1,
-	.hostvm_enable = 1,
-	.gpuvm_max_page_table_levels = 1,
-	.hostvm_max_page_table_levels = 2,
-	.hostvm_cached_page_table_levels = 0,
-	.pte_group_size_bytes = 2048,
-	.num_dsc = 3,
-	.rob_buffer_size_kbytes = 184,
-	.det_buffer_size_kbytes = 184,
-	.dpte_buffer_size_in_pte_reqs_luma = 64,
-	.dpte_buffer_size_in_pte_reqs_chroma = 32,
-	.pde_proc_buffer_size_64k_reqs = 48,
-	.dpp_output_buffer_pixels = 2560,
-	.opp_output_buffer_lines = 1,
-	.pixel_chunk_size_kbytes = 8,
-	.meta_chunk_size_kbytes = 2,
-	.writeback_chunk_size_kbytes = 8,
-	.line_buffer_size_bits = 789504,
-	.is_line_buffer_bpp_fixed = 0,  // ?
-	.line_buffer_fixed_bpp = 48,     // ?
-	.dcc_supported = true,
-	.writeback_interface_buffer_size_kbytes = 90,
-	.writeback_line_buffer_buffer_size = 656640,
-	.max_line_buffer_lines = 12,
-	.writeback_luma_buffer_size_kbytes = 12,  // writeback_line_buffer_buffer_size = 656640
-	.writeback_chroma_buffer_size_kbytes = 8,
-	.writeback_chroma_line_buffer_width_pixels = 4,
-	.writeback_max_hscl_ratio = 1,
-	.writeback_max_vscl_ratio = 1,
-	.writeback_min_hscl_ratio = 1,
-	.writeback_min_vscl_ratio = 1,
-	.writeback_max_hscl_taps = 1,
-	.writeback_max_vscl_taps = 1,
-	.writeback_line_buffer_luma_buffer_size = 0,
-	.writeback_line_buffer_chroma_buffer_size = 14643,
-	.cursor_buffer_size = 8,
-	.cursor_chunk_size = 2,
-	.max_num_otg = 4,
-	.max_num_dpp = 4,
-	.max_num_wb = 1,
-	.max_dchub_pscl_bw_pix_per_clk = 4,
-	.max_pscl_lb_bw_pix_per_clk = 2,
-	.max_lb_vscl_bw_pix_per_clk = 4,
-	.max_vscl_hscl_bw_pix_per_clk = 4,
-	.max_hscl_ratio = 6,
-	.max_vscl_ratio = 6,
-	.hscl_mults = 4,
-	.vscl_mults = 4,
-	.max_hscl_taps = 8,
-	.max_vscl_taps = 8,
-	.dispclk_ramp_margin_percent = 1,
-	.underscan_factor = 1.11,
-	.min_vblank_lines = 32,
-	.dppclk_delay_subtotal = 46,
-	.dynamic_metadata_vm_enabled = true,
-	.dppclk_delay_scl_lb_only = 16,
-	.dppclk_delay_scl = 50,
-	.dppclk_delay_cnvc_formatter = 27,
-	.dppclk_delay_cnvc_cursor = 6,
-	.dispclk_delay_subtotal = 119,
-	.dcfclk_cstate_latency = 5.2, // SRExitTime
-	.max_inter_dcn_tile_repeaters = 8,
-	.max_num_hdmi_frl_outputs = 0,
-	.odm_combine_4to1_supported = true,
-
-	.xfc_supported = false,
-	.xfc_fill_bw_overhead_percent = 10.0,
-	.xfc_fill_constant_bytes = 0,
-	.gfx7_compat_tiling_supported = 0,
-	.number_of_cursors = 1,
-};
-
-struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = {
-	.clock_limits = {
-			{
-				.state = 0,
-				.dram_speed_mts = 2400.0,
-				.fabricclk_mhz = 600,
-				.socclk_mhz = 278.0,
-				.dcfclk_mhz = 400.0,
-				.dscclk_mhz = 206.0,
-				.dppclk_mhz = 1015.0,
-				.dispclk_mhz = 1015.0,
-				.phyclk_mhz = 600.0,
-			},
-			{
-				.state = 1,
-				.dram_speed_mts = 2400.0,
-				.fabricclk_mhz = 688,
-				.socclk_mhz = 278.0,
-				.dcfclk_mhz = 400.0,
-				.dscclk_mhz = 206.0,
-				.dppclk_mhz = 1015.0,
-				.dispclk_mhz = 1015.0,
-				.phyclk_mhz = 600.0,
-			},
-			{
-				.state = 2,
-				.dram_speed_mts = 4267.0,
-				.fabricclk_mhz = 1067,
-				.socclk_mhz = 278.0,
-				.dcfclk_mhz = 608.0,
-				.dscclk_mhz = 296.0,
-				.dppclk_mhz = 1015.0,
-				.dispclk_mhz = 1015.0,
-				.phyclk_mhz = 810.0,
-			},
-
-			{
-				.state = 3,
-				.dram_speed_mts = 4267.0,
-				.fabricclk_mhz = 1067,
-				.socclk_mhz = 715.0,
-				.dcfclk_mhz = 676.0,
-				.dscclk_mhz = 338.0,
-				.dppclk_mhz = 1015.0,
-				.dispclk_mhz = 1015.0,
-				.phyclk_mhz = 810.0,
-			},
-
-			{
-				.state = 4,
-				.dram_speed_mts = 4267.0,
-				.fabricclk_mhz = 1067,
-				.socclk_mhz = 953.0,
-				.dcfclk_mhz = 810.0,
-				.dscclk_mhz = 338.0,
-				.dppclk_mhz = 1015.0,
-				.dispclk_mhz = 1015.0,
-				.phyclk_mhz = 810.0,
-			},
-		},
-
-	.sr_exit_time_us = 9.0,
-	.sr_enter_plus_exit_time_us = 11.0,
-	.urgent_latency_us = 4.0,
-	.urgent_latency_pixel_data_only_us = 4.0,
-	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
-	.urgent_latency_vm_data_only_us = 4.0,
-	.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
-	.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
-	.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
-	.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
-	.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
-	.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
-	.max_avg_sdp_bw_use_normal_percent = 60.0,
-	.max_avg_dram_bw_use_normal_percent = 60.0,
-	.writeback_latency_us = 12.0,
-	.max_request_size_bytes = 256,
-	.dram_channel_width_bytes = 4,
-	.fabric_datapath_to_dcn_data_return_bytes = 32,
-	.dcn_downspread_percent = 0.5,
-	.downspread_percent = 0.38,
-	.dram_page_open_time_ns = 50.0,
-	.dram_rw_turnaround_time_ns = 17.5,
-	.dram_return_buffer_per_channel_bytes = 8192,
-	.round_trip_ping_latency_dcfclk_cycles = 191,
-	.urgent_out_of_order_return_per_channel_bytes = 4096,
-	.channel_interleave_bytes = 256,
-	.num_banks = 8,
-	.num_chans = 4,
-	.gpuvm_min_page_size_bytes = 4096,
-	.hostvm_min_page_size_bytes = 4096,
-	.dram_clock_change_latency_us = 23.84,
-	.writeback_dram_clock_change_latency_us = 23.0,
-	.return_bus_width_bytes = 64,
-	.dispclk_dppclk_vco_speed_mhz = 3550,
-	.xfc_bus_transport_time_us = 20,      // ?
-	.xfc_xbuf_latency_tolerance_us = 4,  // ?
-	.use_urgent_burst_bw = 1,            // ?
-	.num_states = 5,
-	.do_urgent_latency_adjustment = false,
-	.urgent_latency_adjustment_fabric_clock_component_us = 0,
-	.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
-};
-
 enum dcn301_clk_src_array_id {
 	DCN301_CLK_SRC_PLL0,
 	DCN301_CLK_SRC_PLL1,
@@ -1480,8 +1303,6 @@ static struct dc_cap_funcs cap_funcs = {
 	.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
 };
 
-#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16)))
-#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x))
 
 static bool is_soc_bounding_box_valid(struct dc *dc)
 {
@@ -1508,26 +1329,24 @@ static bool init_soc_bounding_box(struct dc *dc,
 
 	loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator;
 	loaded_ip->max_num_dpp = pool->base.pipe_count;
+	DC_FP_START();
 	dcn20_patch_bounding_box(dc, loaded_bb);
+	DC_FP_END();
 
 	if (dc->ctx->dc_bios->funcs->get_soc_bb_info) {
 		struct bp_soc_bb_info bb_info = {0};
 
 		if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) {
-			if (bb_info.dram_clock_change_latency_100ns > 0)
-				dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
-
-			if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
-				dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
-
-			if (bb_info.dram_sr_exit_latency_100ns > 0)
-				dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
+			DC_FP_START();
+			dcn301_fpu_init_soc_bounding_box(bb_info);
+			DC_FP_END();
 		}
 	}
 
 	return true;
 }
 
+
 static void set_wm_ranges(
 		struct pp_smu_funcs *pp_smu,
 		struct _vcs_dpi_soc_bounding_box_st *loaded_bb)
@@ -1550,9 +1369,9 @@ static void set_wm_ranges(
 			ranges.reader_wm_sets[i].wm_inst = i;
 			ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN;
 			ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
-			ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
-			ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
-
+			DC_FP_START();
+			dcn301_fpu_set_wm_ranges(i, &ranges, loaded_bb);
+			DC_FP_END();
 			ranges.num_reader_wm_sets = i + 1;
 		}
 
@@ -1572,154 +1391,6 @@ static void set_wm_ranges(
 	pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges);
 }
 
-static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
-{
-	struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool);
-	struct clk_limit_table *clk_table = &bw_params->clk_table;
-	struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
-	unsigned int i, closest_clk_lvl;
-	int j;
-
-	// Default clock levels are used for diags, which may lead to overclocking.
-	if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
-		dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
-		dcn3_01_ip.max_num_dpp = pool->base.pipe_count;
-		dcn3_01_soc.num_chans = bw_params->num_channels;
-
-		ASSERT(clk_table->num_entries);
-		for (i = 0; i < clk_table->num_entries; i++) {
-			/* loop backwards*/
-			for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) {
-				if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
-					closest_clk_lvl = j;
-					break;
-				}
-			}
-
-			clock_limits[i].state = i;
-			clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
-			clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
-			clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
-			clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
-
-			clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
-			clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
-			clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
-			clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
-			clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
-			clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
-			clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
-		}
-		for (i = 0; i < clk_table->num_entries; i++)
-			dcn3_01_soc.clock_limits[i] = clock_limits[i];
-		if (clk_table->num_entries) {
-			dcn3_01_soc.num_states = clk_table->num_entries;
-			/* duplicate last level */
-			dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1];
-			dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states;
-		}
-	}
-
-	dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
-	dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
-
-	dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
-}
-
-static void calculate_wm_set_for_vlevel(
-		int vlevel,
-		struct wm_range_table_entry *table_entry,
-		struct dcn_watermarks *wm_set,
-		struct display_mode_lib *dml,
-		display_e2e_pipe_params_st *pipes,
-		int pipe_cnt)
-{
-	double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
-
-	ASSERT(vlevel < dml->soc.num_states);
-	/* only pipe 0 is read for voltage and dcf/soc clocks */
-	pipes[0].clks_cfg.voltage = vlevel;
-	pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
-	pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
-
-	dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
-	dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
-	dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
-
-	wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
-	wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
-	wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
-	wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
-	wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
-	wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
-	wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
-	wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
-	dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
-
-}
-
-static void dcn301_calculate_wm_and_dlg(
-		struct dc *dc, struct dc_state *context,
-		display_e2e_pipe_params_st *pipes,
-		int pipe_cnt,
-		int vlevel_req)
-{
-	int i, pipe_idx;
-	int vlevel, vlevel_max;
-	struct wm_range_table_entry *table_entry;
-	struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
-
-	ASSERT(bw_params);
-
-	vlevel_max = bw_params->clk_table.num_entries - 1;
-
-	/* WM Set D */
-	table_entry = &bw_params->wm_table.entries[WM_D];
-	if (table_entry->wm_type == WM_TYPE_RETRAINING)
-		vlevel = 0;
-	else
-		vlevel = vlevel_max;
-	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
-						&context->bw_ctx.dml, pipes, pipe_cnt);
-	/* WM Set C */
-	table_entry = &bw_params->wm_table.entries[WM_C];
-	vlevel = min(max(vlevel_req, 2), vlevel_max);
-	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
-						&context->bw_ctx.dml, pipes, pipe_cnt);
-	/* WM Set B */
-	table_entry = &bw_params->wm_table.entries[WM_B];
-	vlevel = min(max(vlevel_req, 1), vlevel_max);
-	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
-						&context->bw_ctx.dml, pipes, pipe_cnt);
-
-	/* WM Set A */
-	table_entry = &bw_params->wm_table.entries[WM_A];
-	vlevel = min(vlevel_req, vlevel_max);
-	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
-						&context->bw_ctx.dml, pipes, pipe_cnt);
-
-	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
-		if (!context->res_ctx.pipe_ctx[i].stream)
-			continue;
-
-		pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
-		pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
-
-		if (dc->config.forced_clocks) {
-			pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
-			pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
-		}
-		if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
-			pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
-		if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
-			pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
-
-		pipe_idx++;
-	}
-
-	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
-}
-
 static struct resource_funcs dcn301_res_pool_funcs = {
 	.destroy = dcn301_destroy_resource_pool,
 	.link_enc_create = dcn301_link_encoder_create,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h
index 17e4e91ff4b8..ae8672680cdd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h
@@ -32,6 +32,9 @@ struct dc;
 struct resource_pool;
 struct _vcs_dpi_display_pipe_params_st;
 
+extern struct _vcs_dpi_ip_params_st dcn3_01_ip;
+extern struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc;
+
 struct dcn301_resource_pool {
 	struct resource_pool base;
 };
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index e7bb69ec99b6..eee6672bd32d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -70,6 +70,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(fram
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag)
 CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags)
+CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags)
@@ -84,6 +85,7 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_rcflags)
+CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_rcflags)
 CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o  := $(dml_rcflags)
 endif
@@ -101,6 +103,7 @@ DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
 DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o
 DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o
 DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o
+DML += dcn301/dcn301_fpu.o
 DML += dsc/rc_calc_fpu.o
 endif
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
new file mode 100644
index 000000000000..94c32832a0e7
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2019-2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include "resource.h"
+#include "clk_mgr.h"
+#include "dcn20/dcn20_resource.h"
+#include "dcn301/dcn301_resource.h"
+
+#include "dml/dcn20/dcn20_fpu.h"
+#include "dcn301_fpu.h"
+
+#define TO_DCN301_RES_POOL(pool)\
+	container_of(pool, struct dcn301_resource_pool, base)
+
+/* Based on: //vidip/dc/dcn3/doc/architecture/DCN3x_Display_Mode.xlsm#83 */
+struct _vcs_dpi_ip_params_st dcn3_01_ip = {
+	.odm_capable = 1,
+	.gpuvm_enable = 1,
+	.hostvm_enable = 1,
+	.gpuvm_max_page_table_levels = 1,
+	.hostvm_max_page_table_levels = 2,
+	.hostvm_cached_page_table_levels = 0,
+	.pte_group_size_bytes = 2048,
+	.num_dsc = 3,
+	.rob_buffer_size_kbytes = 184,
+	.det_buffer_size_kbytes = 184,
+	.dpte_buffer_size_in_pte_reqs_luma = 64,
+	.dpte_buffer_size_in_pte_reqs_chroma = 32,
+	.pde_proc_buffer_size_64k_reqs = 48,
+	.dpp_output_buffer_pixels = 2560,
+	.opp_output_buffer_lines = 1,
+	.pixel_chunk_size_kbytes = 8,
+	.meta_chunk_size_kbytes = 2,
+	.writeback_chunk_size_kbytes = 8,
+	.line_buffer_size_bits = 789504,
+	.is_line_buffer_bpp_fixed = 0,  // ?
+	.line_buffer_fixed_bpp = 48,     // ?
+	.dcc_supported = true,
+	.writeback_interface_buffer_size_kbytes = 90,
+	.writeback_line_buffer_buffer_size = 656640,
+	.max_line_buffer_lines = 12,
+	.writeback_luma_buffer_size_kbytes = 12,  // writeback_line_buffer_buffer_size = 656640
+	.writeback_chroma_buffer_size_kbytes = 8,
+	.writeback_chroma_line_buffer_width_pixels = 4,
+	.writeback_max_hscl_ratio = 1,
+	.writeback_max_vscl_ratio = 1,
+	.writeback_min_hscl_ratio = 1,
+	.writeback_min_vscl_ratio = 1,
+	.writeback_max_hscl_taps = 1,
+	.writeback_max_vscl_taps = 1,
+	.writeback_line_buffer_luma_buffer_size = 0,
+	.writeback_line_buffer_chroma_buffer_size = 14643,
+	.cursor_buffer_size = 8,
+	.cursor_chunk_size = 2,
+	.max_num_otg = 4,
+	.max_num_dpp = 4,
+	.max_num_wb = 1,
+	.max_dchub_pscl_bw_pix_per_clk = 4,
+	.max_pscl_lb_bw_pix_per_clk = 2,
+	.max_lb_vscl_bw_pix_per_clk = 4,
+	.max_vscl_hscl_bw_pix_per_clk = 4,
+	.max_hscl_ratio = 6,
+	.max_vscl_ratio = 6,
+	.hscl_mults = 4,
+	.vscl_mults = 4,
+	.max_hscl_taps = 8,
+	.max_vscl_taps = 8,
+	.dispclk_ramp_margin_percent = 1,
+	.underscan_factor = 1.11,
+	.min_vblank_lines = 32,
+	.dppclk_delay_subtotal = 46,
+	.dynamic_metadata_vm_enabled = true,
+	.dppclk_delay_scl_lb_only = 16,
+	.dppclk_delay_scl = 50,
+	.dppclk_delay_cnvc_formatter = 27,
+	.dppclk_delay_cnvc_cursor = 6,
+	.dispclk_delay_subtotal = 119,
+	.dcfclk_cstate_latency = 5.2, // SRExitTime
+	.max_inter_dcn_tile_repeaters = 8,
+	.max_num_hdmi_frl_outputs = 0,
+	.odm_combine_4to1_supported = true,
+
+	.xfc_supported = false,
+	.xfc_fill_bw_overhead_percent = 10.0,
+	.xfc_fill_constant_bytes = 0,
+	.gfx7_compat_tiling_supported = 0,
+	.number_of_cursors = 1,
+};
+
+struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = {
+	.clock_limits = {
+		{
+			.state = 0,
+			.dram_speed_mts = 2400.0,
+			.fabricclk_mhz = 600,
+			.socclk_mhz = 278.0,
+			.dcfclk_mhz = 400.0,
+			.dscclk_mhz = 206.0,
+			.dppclk_mhz = 1015.0,
+			.dispclk_mhz = 1015.0,
+			.phyclk_mhz = 600.0,
+		},
+
+		{
+			.state = 1,
+			.dram_speed_mts = 2400.0,
+			.fabricclk_mhz = 688,
+			.socclk_mhz = 278.0,
+			.dcfclk_mhz = 400.0,
+			.dscclk_mhz = 206.0,
+			.dppclk_mhz = 1015.0,
+			.dispclk_mhz = 1015.0,
+			.phyclk_mhz = 600.0,
+		},
+
+		{
+			.state = 2,
+			.dram_speed_mts = 4267.0,
+			.fabricclk_mhz = 1067,
+			.socclk_mhz = 278.0,
+			.dcfclk_mhz = 608.0,
+			.dscclk_mhz = 296.0,
+			.dppclk_mhz = 1015.0,
+			.dispclk_mhz = 1015.0,
+			.phyclk_mhz = 810.0,
+		},
+
+		{
+			.state = 3,
+			.dram_speed_mts = 4267.0,
+			.fabricclk_mhz = 1067,
+			.socclk_mhz = 715.0,
+			.dcfclk_mhz = 676.0,
+			.dscclk_mhz = 338.0,
+			.dppclk_mhz = 1015.0,
+			.dispclk_mhz = 1015.0,
+			.phyclk_mhz = 810.0,
+		},
+
+		{
+			.state = 4,
+			.dram_speed_mts = 4267.0,
+			.fabricclk_mhz = 1067,
+			.socclk_mhz = 953.0,
+			.dcfclk_mhz = 810.0,
+			.dscclk_mhz = 338.0,
+			.dppclk_mhz = 1015.0,
+			.dispclk_mhz = 1015.0,
+			.phyclk_mhz = 810.0,
+		},
+	},
+
+	.sr_exit_time_us = 9.0,
+	.sr_enter_plus_exit_time_us = 11.0,
+	.urgent_latency_us = 4.0,
+	.urgent_latency_pixel_data_only_us = 4.0,
+	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+	.urgent_latency_vm_data_only_us = 4.0,
+	.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
+	.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
+	.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
+	.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0,
+	.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0,
+	.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0,
+	.max_avg_sdp_bw_use_normal_percent = 60.0,
+	.max_avg_dram_bw_use_normal_percent = 60.0,
+	.writeback_latency_us = 12.0,
+	.max_request_size_bytes = 256,
+	.dram_channel_width_bytes = 4,
+	.fabric_datapath_to_dcn_data_return_bytes = 32,
+	.dcn_downspread_percent = 0.5,
+	.downspread_percent = 0.38,
+	.dram_page_open_time_ns = 50.0,
+	.dram_rw_turnaround_time_ns = 17.5,
+	.dram_return_buffer_per_channel_bytes = 8192,
+	.round_trip_ping_latency_dcfclk_cycles = 191,
+	.urgent_out_of_order_return_per_channel_bytes = 4096,
+	.channel_interleave_bytes = 256,
+	.num_banks = 8,
+	.num_chans = 4,
+	.gpuvm_min_page_size_bytes = 4096,
+	.hostvm_min_page_size_bytes = 4096,
+	.dram_clock_change_latency_us = 23.84,
+	.writeback_dram_clock_change_latency_us = 23.0,
+	.return_bus_width_bytes = 64,
+	.dispclk_dppclk_vco_speed_mhz = 3550,
+	.xfc_bus_transport_time_us = 20,      // ?
+	.xfc_xbuf_latency_tolerance_us = 4,  // ?
+	.use_urgent_burst_bw = 1,            // ?
+	.num_states = 5,
+	.do_urgent_latency_adjustment = false,
+	.urgent_latency_adjustment_fabric_clock_component_us = 0,
+	.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+};
+
+static void calculate_wm_set_for_vlevel(int vlevel,
+		struct wm_range_table_entry *table_entry,
+		struct dcn_watermarks *wm_set,
+		struct display_mode_lib *dml,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt)
+{
+	double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
+
+	ASSERT(vlevel < dml->soc.num_states);
+	/* only pipe 0 is read for voltage and dcf/soc clocks */
+	pipes[0].clks_cfg.voltage = vlevel;
+	pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
+	pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
+
+	dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
+	dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
+	dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
+
+	wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
+	wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
+	wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
+	wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
+	wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
+	wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
+	wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
+	wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
+	dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
+
+}
+
+void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+	struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool);
+	struct clk_limit_table *clk_table = &bw_params->clk_table;
+	struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
+	unsigned int i, closest_clk_lvl;
+	int j;
+
+	dc_assert_fp_enabled();
+
+	/* Default clock levels are used for diags, which may lead to overclocking. */
+	if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
+		dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
+		dcn3_01_ip.max_num_dpp = pool->base.pipe_count;
+		dcn3_01_soc.num_chans = bw_params->num_channels;
+
+		ASSERT(clk_table->num_entries);
+		for (i = 0; i < clk_table->num_entries; i++) {
+			/* loop backwards*/
+			for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) {
+				if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
+					closest_clk_lvl = j;
+					break;
+				}
+			}
+
+			clock_limits[i].state = i;
+			clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
+			clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
+			clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
+			clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
+
+			clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
+			clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
+			clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
+			clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
+			clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
+			clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
+			clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
+		}
+
+		for (i = 0; i < clk_table->num_entries; i++)
+			dcn3_01_soc.clock_limits[i] = clock_limits[i];
+
+		if (clk_table->num_entries) {
+			dcn3_01_soc.num_states = clk_table->num_entries;
+			/* duplicate last level */
+			dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1];
+			dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states;
+		}
+	}
+
+	dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+	dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
+
+	dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
+}
+
+void dcn301_fpu_set_wm_ranges(int i,
+	struct pp_smu_wm_range_sets *ranges,
+	struct _vcs_dpi_soc_bounding_box_st *loaded_bb)
+{
+	dc_assert_fp_enabled();
+
+	ranges->reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0;
+	ranges->reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16;
+}
+
+void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info)
+{
+	dc_assert_fp_enabled();
+
+	if (bb_info.dram_clock_change_latency_100ns > 0)
+		dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10;
+
+	if (bb_info.dram_sr_enter_exit_latency_100ns > 0)
+		dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10;
+
+	if (bb_info.dram_sr_exit_latency_100ns > 0)
+		dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10;
+}
+
+void dcn301_calculate_wm_and_dlg(struct dc *dc,
+		struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt,
+		int vlevel_req)
+{
+	int i, pipe_idx;
+	int vlevel, vlevel_max;
+	struct wm_range_table_entry *table_entry;
+	struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
+
+	ASSERT(bw_params);
+	dc_assert_fp_enabled();
+
+	vlevel_max = bw_params->clk_table.num_entries - 1;
+
+	/* WM Set D */
+	table_entry = &bw_params->wm_table.entries[WM_D];
+	if (table_entry->wm_type == WM_TYPE_RETRAINING)
+		vlevel = 0;
+	else
+		vlevel = vlevel_max;
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+	/* WM Set C */
+	table_entry = &bw_params->wm_table.entries[WM_C];
+	vlevel = min(max(vlevel_req, 2), vlevel_max);
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+	/* WM Set B */
+	table_entry = &bw_params->wm_table.entries[WM_B];
+	vlevel = min(max(vlevel_req, 1), vlevel_max);
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+
+	/* WM Set A */
+	table_entry = &bw_params->wm_table.entries[WM_A];
+	vlevel = min(vlevel_req, vlevel_max);
+	calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
+						&context->bw_ctx.dml, pipes, pipe_cnt);
+
+	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
+		if (!context->res_ctx.pipe_ctx[i].stream)
+			continue;
+
+		pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
+		pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+
+		if (dc->config.forced_clocks) {
+			pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+			pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+		}
+		if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
+			pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
+		if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
+			pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
+		pipe_idx++;
+	}
+
+	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
new file mode 100644
index 000000000000..fc7065d17842
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019-2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DCN301_FPU_H__
+#define __DCN301_FPU_H__
+
+void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
+
+void dcn301_fpu_set_wm_ranges(int i,
+	struct pp_smu_wm_range_sets *ranges,
+	struct _vcs_dpi_soc_bounding_box_st *loaded_bb);
+
+void dcn301_fpu_init_soc_bounding_box(struct bp_soc_bb_info bb_info);
+
+void dcn301_calculate_wm_and_dlg(struct dc *dc,
+		struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt,
+		int vlevel_req);
+#endif /* __DCN301_FPU_H__*/
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-24 13:31 ` [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane Rodrigo Siqueira
@ 2021-10-25 11:25   ` Paul Menzel
  2021-10-25 13:58     ` Harry Wentland
  2021-10-25 14:56     ` Rodrigo Siqueira Jordao
  0 siblings, 2 replies; 41+ messages in thread
From: Paul Menzel @ 2021-10-25 11:25 UTC (permalink / raw)
  To: Rodrigo Siqueira, amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Aurabindo.Pillai,
	qingqing.zhuo, mikita.lipski, roman.li, Anson.Jacob, wayne.lin,
	stylon.wang, solomon.chiu, pavle.kotarac, agustin.gutierrez,
	Wenjing Liu, Eric Yang

Dear Wenjing, dear Rodrigo,


On 24.10.21 15:31, Rodrigo Siqueira wrote:
> From: Wenjing Liu <wenjing.liu@amd.com>
> 
> [why]
> We have a regression that cause maximize lane settings to use
> uninitialized data from unused lanes.

Which commit caused the regression? Please amend the commit message.

> This will cause link training to fail for 1 or 2 lanes because the lane
> adjust is populated incorrectly sometimes.

On what card did you test this, and how can it be reproduced?

Please describe the fix/implemantation in the commit message.

> Reviewed-by: Eric Yang <eric.yang2@amd.com>
> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
> ---
>   .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
>   1 file changed, 32 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> index 653279ab96f4..f6ba7c734f54 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> @@ -108,6 +108,9 @@ static struct dc_link_settings get_common_supported_link_settings(
>   		struct dc_link_settings link_setting_b);
>   static void maximize_lane_settings(const struct link_training_settings *lt_settings,
>   		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
> +static void override_lane_settings(const struct link_training_settings *lt_settings,
> +		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
> +
>   static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
>   		const struct dc_link_settings *link_settings)
>   {
> @@ -734,15 +737,13 @@ void dp_decide_lane_settings(
>   		}
>   #endif
>   	}
> -
> -	/* we find the maximum of the requested settings across all lanes*/
> -	/* and set this maximum for all lanes*/
>   	dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>   
>   	if (lt_settings->disallow_per_lane_settings) {
>   		/* we find the maximum of the requested settings across all lanes*/
>   		/* and set this maximum for all lanes*/
>   		maximize_lane_settings(lt_settings, hw_lane_settings);
> +		override_lane_settings(lt_settings, hw_lane_settings);
>   
>   		if (lt_settings->always_match_dpcd_with_hw_lane_settings)
>   			dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
> @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
>   	}
>   }
>   
> +static void override_lane_settings(const struct link_training_settings *lt_settings,
> +		struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
> +{
> +	uint32_t lane;
> +
> +	if (lt_settings->voltage_swing == NULL &&
> +			lt_settings->pre_emphasis == NULL &&
> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
> +			lt_settings->ffe_preset == NULL &&
> +#endif
> +			lt_settings->post_cursor2 == NULL)
> +
> +		return;
> +
> +	for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
> +		if (lt_settings->voltage_swing)
> +			lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing;
> +		if (lt_settings->pre_emphasis)
> +			lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
> +		if (lt_settings->post_cursor2)
> +			lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
> +		if (lt_settings->ffe_preset)
> +			lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
> +#endif

Normally these checks should be done in C and not the preprocessor. `if 
CONFIG(DRM_AMD_DC_DP2_0)` or similar should work.

> +	}
> +}
> +
>   enum dc_status dp_get_lane_status_and_lane_adjust(
>   	struct dc_link *link,
>   	const struct link_training_settings *link_training_setting,
> 


Kind regards,

Paul

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 00/33] DC Patches October 24, 2020
  2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
                   ` (32 preceding siblings ...)
  2021-10-24 13:31 ` [PATCH 33/33] drm/amd/display: move FPU associated DCN301 code to DML folder Rodrigo Siqueira
@ 2021-10-25 13:07 ` Wheeler, Daniel
  33 siblings, 0 replies; 41+ messages in thread
From: Wheeler, Daniel @ 2021-10-25 13:07 UTC (permalink / raw)
  To: Siqueira, Rodrigo, amd-gfx
  Cc: Wentland, Harry, Li, Sun peng (Leo),
	Lakha, Bhawanpreet, Siqueira, Rodrigo, Pillai, Aurabindo, Zhuo,
	Qingqing, Lipski, Mikita, Li, Roman, Jacob, Anson, Lin, Wayne,
	Wang, Chao-kai (Stylon),
	Chiu, Solomon, Kotarac, Pavle, Gutierrez,  Agustin

[Public]

Hi all,
 
This week this patchset was tested on the following systems:
 
HP Envy 360, with Ryzen 5 4500U, with the following display types: eDP 1080p 60hz, 4k 60hz  (via USB-C to DP/HDMI), 1440p 144hz (via USB-C to DP/HDMI), 1680*1050 60hz (via USB-C to DP and then DP to DVI/VGA)
 
AMD Ryzen 9 5900H, with the following display types: eDP 1080p 60hz, 4k 60hz  (via USB-C to DP/HDMI), 1440p 144hz (via USB-C to DP/HDMI), 1680*1050 60hz (via USB-C to DP and then DP to DVI/VGA)
 
Sapphire Pulse RX5700XT with the following display types:
4k 60hz  (via DP/HDMI), 1440p 144hz (via DP/HDMI), 1680*1050 60hz (via DP to DVI/VGA)
 
Reference AMD RX6800 with the following display types:
4k 60hz  (via DP/HDMI and USB-C to DP/HDMI), 1440p 144hz (via USB-C to DP/HDMI and USB-C to DP/HDMI), 1680*1050 60hz (via DP to DVI/VGA)
 
Included testing using a Startech DP 1.4 MST hub at 2x 4k 60hz, and 3x 1080p 60hz on all systems. Also tested DSC via USB-C to DP DSC Hub with 3x 4k 60hz on Ryzen 9 5900h and Ryzen 5 4500u.
 
 
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
 
 
Thank you,
 
Dan Wheeler
Technologist  |  AMD
SW Display
------------------------------------------------------------------------------------------------------------------
1 Commerce Valley Dr E, Thornhill, ON L3T 7X6
Facebook |  Twitter |  amd.com  

-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Rodrigo Siqueira
Sent: October 24, 2021 9:31 AM
To: amd-gfx@lists.freedesktop.org
Cc: Wentland, Harry <Harry.Wentland@amd.com>; Li, Sun peng (Leo) <Sunpeng.Li@amd.com>; Lakha, Bhawanpreet <Bhawanpreet.Lakha@amd.com>; Siqueira, Rodrigo <Rodrigo.Siqueira@amd.com>; Pillai, Aurabindo <Aurabindo.Pillai@amd.com>; Zhuo, Qingqing <Qingqing.Zhuo@amd.com>; Lipski, Mikita <Mikita.Lipski@amd.com>; Li, Roman <Roman.Li@amd.com>; Jacob, Anson <Anson.Jacob@amd.com>; Lin, Wayne <Wayne.Lin@amd.com>; Wang, Chao-kai (Stylon) <Stylon.Wang@amd.com>; Chiu, Solomon <Solomon.Chiu@amd.com>; Kotarac, Pavle <Pavle.Kotarac@amd.com>; Gutierrez, Agustin <Agustin.Gutierrez@amd.com>
Subject: [PATCH 00/33] DC Patches October 24, 2020

This new DC version brings improvements in the following areas:
- Improvements for USB4;
- Isolate FPU code for DCN20, DCN301, and DSC;
- Fixes on Linking training;
- Refactoring some parts of the code, such as PSR;

Thanks

Ahmad Othman (2):
  drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1
  drm/amd/display: fix a crash on USB4 over C20 PHY

Anson Jacob (2):
  drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
  drm/amd/display: Remove unused macros

Anthony Koo (2):
  drm/amd/display: [FW Promotion] Release 0.0.89
  drm/amd/display: [FW Promotion] Release 0.0.90

Aric Cyr (4):
  drm/amd/display: Handle I2C-over-AUX write channel status update
  drm/amd/display: 3.2.158
  drm/amd/display: Fix 3DLUT skipped programming
  drm/amd/display: 3.2.159

Dmytro Laktyushkin (3):
  drm/amd/display: clean up dcn31 revision check
  drm/amd/display: restyle dcn31 resource header inline with other asics
  drm/amd/display: allow windowed mpo + odm

George Shen (2):
  drm/amd/display: Implement fixed DP drive settings
  drm/amd/display: Add comment for preferred_training_settings

Guo, Bing (2):
  drm/amd/display: Get ceiling for v_total calc
  drm/amd/display: set Layout properly for 8ch audio at timing
    validation

Hansen (1):
  drm/amd/display: Set phy_mux_sel bit in dmub scratch register

Jimmy Kizito (1):
  drm/amd/display: Add workaround flag for EDID read on certain docks

Lewis Huang (1):
  drm/amd/display: Align bw context with hw config when system resume

Martin Leung (1):
  drm/amd/display: Manually adjust strobe for DCN303

Meenakshikumar Somasundaram (2):
  drm/amd/display: FEC configuration for dpia links
  drm/amd/display: FEC configuration for dpia links in MST mode

Michael Strauss (2):
  drm/amd/display: Set i2c memory to light sleep during hw init
  drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate

Qingqing Zhuo (2):
  drm/amd/display: move FPU associated DSC code to DML folder
  drm/amd/display: move FPU associated DCN301 code to DML folder

Robin Chen (1):
  drm/amd/display: dc_link_set_psr_allow_active refactoring

Wenjing Liu (5):
  drm/amd/display: adopt DP2.0 LT SCR revision 8
  drm/amd/display: implement decide lane settings
  drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings
  drm/amd/display: add two lane settings training options
  drm/amd/display: fix link training regression for 1 or 2 lane

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   2 +
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c |  10 +-
 .../drm/amd/display/dc/bios/bios_parser2.c    |   2 +
 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |  16 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  17 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 118 ++++-  .../gpu/drm/amd/display/dc/core/dc_link_ddc.c |  15 +-  .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 498 +++++++-----------
 .../drm/amd/display/dc/core/dc_link_dpia.c    |  57 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  14 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |  23 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |   5 -
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  13 +-
 .../gpu/drm/amd/display/dc/dce/dce_audio.c    |   6 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |  34 +-
 .../gpu/drm/amd/display/dc/dce/dce_hwseq.h    |   3 +-
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c |  20 +
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h |   1 +
 .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c |  12 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   6 +
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |  19 +-  .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c  |  14 +
 .../drm/amd/display/dc/dcn30/dcn30_dpp_cm.c   |   8 +-
 .../drm/amd/display/dc/dcn30/dcn30_resource.c |  35 +-
 .../gpu/drm/amd/display/dc/dcn301/Makefile    |  26 -
 .../amd/display/dc/dcn301/dcn301_resource.c   | 349 +-----------
 .../amd/display/dc/dcn301/dcn301_resource.h   |   3 +
 .../amd/display/dc/dcn303/dcn303_resource.c   |  14 +
 .../display/dc/dcn31/dcn31_dio_link_encoder.c |   4 +-
 .../drm/amd/display/dc/dcn31/dcn31_hwseq.c    |   5 +
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |  11 +-  .../drm/amd/display/dc/dcn31/dcn31_resource.h |  10 +
 drivers/gpu/drm/amd/display/dc/dm_cp_psp.h    |   2 +
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |   6 +
 .../amd/display/dc/dml/dcn301/dcn301_fpu.c    | 390 ++++++++++++++
 .../amd/display/dc/dml/dcn301/dcn301_fpu.h    |  42 ++
 .../amd/display/dc/{ => dml}/dsc/qp_tables.h  |   0
 .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.c  | 291 ++++++++++  .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.h  |  94 ++++
 drivers/gpu/drm/amd/display/dc/dsc/Makefile   |  29 -
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c  | 259 ---------  drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h  |  50 +-
 .../gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c  |   1 -
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |  16 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |   2 +
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |   1 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |  55 +-
 .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c |   2 +
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c   |   1 +
 .../display/include/grph_object_ctrl_defs.h   |   1 +
 .../amd/display/include/i2caux_interface.h    |   3 +
 .../amd/display/include/link_service_types.h  |  29 +-
 .../amd/display/modules/freesync/freesync.c   |  15 +-
 .../drm/amd/display/modules/inc/mod_hdcp.h    |   2 +
 55 files changed, 1529 insertions(+), 1134 deletions(-)  create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.h
 rename drivers/gpu/drm/amd/display/dc/{ => dml}/dsc/qp_tables.h (100%)  create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h

--
2.25.1

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-25 11:25   ` Paul Menzel
@ 2021-10-25 13:58     ` Harry Wentland
  2021-10-25 14:42       ` Kazlauskas, Nicholas
  2021-10-25 14:56     ` Rodrigo Siqueira Jordao
  1 sibling, 1 reply; 41+ messages in thread
From: Harry Wentland @ 2021-10-25 13:58 UTC (permalink / raw)
  To: Paul Menzel, Rodrigo Siqueira, amd-gfx
  Cc: Sunpeng.Li, Bhawanpreet.Lakha, Aurabindo.Pillai, qingqing.zhuo,
	mikita.lipski, roman.li, Anson.Jacob, wayne.lin, stylon.wang,
	solomon.chiu, pavle.kotarac, agustin.gutierrez, Wenjing Liu,
	Eric Yang



On 2021-10-25 07:25, Paul Menzel wrote:
> Dear Wenjing, dear Rodrigo,
> 
> 
> On 24.10.21 15:31, Rodrigo Siqueira wrote:
>> From: Wenjing Liu <wenjing.liu@amd.com>
>>
>> [why]
>> We have a regression that cause maximize lane settings to use
>> uninitialized data from unused lanes.
> 
> Which commit caused the regression? Please amend the commit message.
> 
>> This will cause link training to fail for 1 or 2 lanes because the lane
>> adjust is populated incorrectly sometimes.
> 
> On what card did you test this, and how can it be reproduced?
> 
> Please describe the fix/implemantation in the commit message.
> 
>> Reviewed-by: Eric Yang <eric.yang2@amd.com>
>> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
>> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
>> ---
>>   .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
>>   1 file changed, 32 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> index 653279ab96f4..f6ba7c734f54 100644
>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> @@ -108,6 +108,9 @@ static struct dc_link_settings get_common_supported_link_settings(
>>           struct dc_link_settings link_setting_b);
>>   static void maximize_lane_settings(const struct link_training_settings *lt_settings,
>>           struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>> +static void override_lane_settings(const struct link_training_settings *lt_settings,
>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>> +
>>   static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
>>           const struct dc_link_settings *link_settings)
>>   {
>> @@ -734,15 +737,13 @@ void dp_decide_lane_settings(
>>           }
>>   #endif
>>       }
>> -
>> -    /* we find the maximum of the requested settings across all lanes*/
>> -    /* and set this maximum for all lanes*/
>>       dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>>         if (lt_settings->disallow_per_lane_settings) {
>>           /* we find the maximum of the requested settings across all lanes*/
>>           /* and set this maximum for all lanes*/
>>           maximize_lane_settings(lt_settings, hw_lane_settings);
>> +        override_lane_settings(lt_settings, hw_lane_settings);
>>             if (lt_settings->always_match_dpcd_with_hw_lane_settings)
>>               dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>> @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
>>       }
>>   }
>>   +static void override_lane_settings(const struct link_training_settings *lt_settings,
>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
>> +{
>> +    uint32_t lane;
>> +
>> +    if (lt_settings->voltage_swing == NULL &&
>> +            lt_settings->pre_emphasis == NULL &&
>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>> +            lt_settings->ffe_preset == NULL &&
>> +#endif
>> +            lt_settings->post_cursor2 == NULL)
>> +
>> +        return;
>> +
>> +    for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
>> +        if (lt_settings->voltage_swing)
>> +            lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing;
>> +        if (lt_settings->pre_emphasis)
>> +            lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
>> +        if (lt_settings->post_cursor2)
>> +            lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>> +        if (lt_settings->ffe_preset)
>> +            lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
>> +#endif
> 
> Normally these checks should be done in C and not the preprocessor. `if CONFIG(DRM_AMD_DC_DP2_0)` or similar should work.
> 

Interesting. I've never seen this before. Do you have an example or link to a doc? A cursory search doesn't yield any results but I might not be searching for the right thing.

Harry

>> +    }
>> +}
>> +
>>   enum dc_status dp_get_lane_status_and_lane_adjust(
>>       struct dc_link *link,
>>       const struct link_training_settings *link_training_setting,
>>
> 
> 
> Kind regards,
> 
> Paul


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-25 13:58     ` Harry Wentland
@ 2021-10-25 14:42       ` Kazlauskas, Nicholas
  2021-10-25 15:12         ` Paul Menzel
  0 siblings, 1 reply; 41+ messages in thread
From: Kazlauskas, Nicholas @ 2021-10-25 14:42 UTC (permalink / raw)
  To: Harry Wentland, Paul Menzel, Rodrigo Siqueira, amd-gfx
  Cc: Sunpeng.Li, Bhawanpreet.Lakha, Aurabindo.Pillai, qingqing.zhuo,
	mikita.lipski, roman.li, Anson.Jacob, wayne.lin, stylon.wang,
	solomon.chiu, pavle.kotarac, agustin.gutierrez, Wenjing Liu,
	Eric Yang

On 2021-10-25 9:58 a.m., Harry Wentland wrote:
> 
> 
> On 2021-10-25 07:25, Paul Menzel wrote:
>> Dear Wenjing, dear Rodrigo,
>>
>>
>> On 24.10.21 15:31, Rodrigo Siqueira wrote:
>>> From: Wenjing Liu <wenjing.liu@amd.com>
>>>
>>> [why]
>>> We have a regression that cause maximize lane settings to use
>>> uninitialized data from unused lanes.
>>
>> Which commit caused the regression? Please amend the commit message.
>>
>>> This will cause link training to fail for 1 or 2 lanes because the lane
>>> adjust is populated incorrectly sometimes.
>>
>> On what card did you test this, and how can it be reproduced?
>>
>> Please describe the fix/implemantation in the commit message.
>>
>>> Reviewed-by: Eric Yang <eric.yang2@amd.com>
>>> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
>>> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
>>> ---
>>>    .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
>>>    1 file changed, 32 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> index 653279ab96f4..f6ba7c734f54 100644
>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>> @@ -108,6 +108,9 @@ static struct dc_link_settings get_common_supported_link_settings(
>>>            struct dc_link_settings link_setting_b);
>>>    static void maximize_lane_settings(const struct link_training_settings *lt_settings,
>>>            struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>>> +static void override_lane_settings(const struct link_training_settings *lt_settings,
>>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>>> +
>>>    static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
>>>            const struct dc_link_settings *link_settings)
>>>    {
>>> @@ -734,15 +737,13 @@ void dp_decide_lane_settings(
>>>            }
>>>    #endif
>>>        }
>>> -
>>> -    /* we find the maximum of the requested settings across all lanes*/
>>> -    /* and set this maximum for all lanes*/
>>>        dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>>>          if (lt_settings->disallow_per_lane_settings) {
>>>            /* we find the maximum of the requested settings across all lanes*/
>>>            /* and set this maximum for all lanes*/
>>>            maximize_lane_settings(lt_settings, hw_lane_settings);
>>> +        override_lane_settings(lt_settings, hw_lane_settings);
>>>              if (lt_settings->always_match_dpcd_with_hw_lane_settings)
>>>                dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>>> @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
>>>        }
>>>    }
>>>    +static void override_lane_settings(const struct link_training_settings *lt_settings,
>>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
>>> +{
>>> +    uint32_t lane;
>>> +
>>> +    if (lt_settings->voltage_swing == NULL &&
>>> +            lt_settings->pre_emphasis == NULL &&
>>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>>> +            lt_settings->ffe_preset == NULL &&
>>> +#endif
>>> +            lt_settings->post_cursor2 == NULL)
>>> +
>>> +        return;
>>> +
>>> +    for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
>>> +        if (lt_settings->voltage_swing)
>>> +            lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing;
>>> +        if (lt_settings->pre_emphasis)
>>> +            lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
>>> +        if (lt_settings->post_cursor2)
>>> +            lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
>>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>>> +        if (lt_settings->ffe_preset)
>>> +            lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
>>> +#endif
>>
>> Normally these checks should be done in C and not the preprocessor. `if CONFIG(DRM_AMD_DC_DP2_0)` or similar should work.
>>
> 
> Interesting. I've never seen this before. Do you have an example or link to a doc? A cursory search doesn't yield any results but I might not be searching for the right thing.
> 
> Harry

I'm curious about this too. The compiler with optimizations should 
remove the constant check, but technically the C standard only permits 
it - it doesn't guarantee that it happens.

However, this patch should actually be changed to drop these 
CONFIG_DRM_AMD_DC_DP2_0 guards - this isn't a Kconfig option nor will 
there be one specifically for DP2. This should be folded under the DCN 
support.

Regards,
Nicholas Kazlauskas

> 
>>> +    }
>>> +}
>>> +
>>>    enum dc_status dp_get_lane_status_and_lane_adjust(
>>>        struct dc_link *link,
>>>        const struct link_training_settings *link_training_setting,
>>>
>>
>>
>> Kind regards,
>>
>> Paul
> 


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-25 11:25   ` Paul Menzel
  2021-10-25 13:58     ` Harry Wentland
@ 2021-10-25 14:56     ` Rodrigo Siqueira Jordao
  1 sibling, 0 replies; 41+ messages in thread
From: Rodrigo Siqueira Jordao @ 2021-10-25 14:56 UTC (permalink / raw)
  To: Paul Menzel, Rodrigo Siqueira, amd-gfx
  Cc: Harry.Wentland, Sunpeng.Li, Bhawanpreet.Lakha, Aurabindo.Pillai,
	qingqing.zhuo, mikita.lipski, roman.li, Anson.Jacob, wayne.lin,
	stylon.wang, solomon.chiu, pavle.kotarac, agustin.gutierrez,
	Wenjing Liu, Eric Yang

Hi Paul,

First of all, thanks for your feedback.

Before I address your comments, I just want to give you some background 
about this type of patchset.

All patches in this series are from a week ago and came from all display 
teams in AMD. Keep in mind that we share our display core with other OS; 
as a result, we have multiple updates every week. To keep the upstream 
aligned with the Display core, we run a weekly process where we extract 
patches made for other people who might be a good candidates to be sent 
to the upstream. The process looks like this (oversimplified):

1. Run a script to check which commit from last week is a good candidate 
to go upstream - finally, port all of those patches to the upstream 
(this is a manual task).
2. Prepare a branch based on amd-staging-drm-next with all the new 
patches on top of it.
3. Send it to our validation team to run an extensive set of tests in 
the new series.
4. If everything is ok, send the patchset to amdgfx.
5. If the test results are positive, we merge this series in the upstream.

Again, that's just a summary; we have way more steps here...

On 2021-10-25 7:25 a.m., Paul Menzel wrote:
> Dear Wenjing, dear Rodrigo,
> 
> 
> On 24.10.21 15:31, Rodrigo Siqueira wrote:
>> From: Wenjing Liu <wenjing.liu@amd.com>
>>
>> [why]
>> We have a regression that cause maximize lane settings to use
>> uninitialized data from unused lanes.
> 
> Which commit caused the regression? Please amend the commit message.

This is one of the situations where the week interval creates some 
descriptions that might sound a little bit different. Basically, this 
patch refers to the patch "implement decide lane settings", in this 
series; however, we noticed that this is not reverted, and that's why we 
decided to keep both patches in this series.

>> This will cause link training to fail for 1 or 2 lanes because the lane
>> adjust is populated incorrectly sometimes.
> 
> On what card did you test this, and how can it be reproduced?

Our DQE team validates this series using multiple ASICs. See the final 
report from Daniel in reply to this series cover letter for more details.

> Please describe the fix/implemantation in the commit message.
> 
>> Reviewed-by: Eric Yang <eric.yang2@amd.com>
>> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
>> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
>> ---
>>   .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
>>   1 file changed, 32 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> index 653279ab96f4..f6ba7c734f54 100644
>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>> @@ -108,6 +108,9 @@ static struct dc_link_settings 
>> get_common_supported_link_settings(
>>           struct dc_link_settings link_setting_b);
>>   static void maximize_lane_settings(const struct 
>> link_training_settings *lt_settings,
>>           struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>> +static void override_lane_settings(const struct 
>> link_training_settings *lt_settings,
>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>> +
>>   static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
>>           const struct dc_link_settings *link_settings)
>>   {
>> @@ -734,15 +737,13 @@ void dp_decide_lane_settings(
>>           }
>>   #endif
>>       }
>> -
>> -    /* we find the maximum of the requested settings across all lanes*/
>> -    /* and set this maximum for all lanes*/
>>       dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, 
>> dpcd_lane_settings);
>>       if (lt_settings->disallow_per_lane_settings) {
>>           /* we find the maximum of the requested settings across all 
>> lanes*/
>>           /* and set this maximum for all lanes*/
>>           maximize_lane_settings(lt_settings, hw_lane_settings);
>> +        override_lane_settings(lt_settings, hw_lane_settings);
>>           if (lt_settings->always_match_dpcd_with_hw_lane_settings)
>>               dp_hw_to_dpcd_lane_settings(lt_settings, 
>> hw_lane_settings, dpcd_lane_settings);
>> @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct 
>> link_training_settings *lt_setti
>>       }
>>   }
>> +static void override_lane_settings(const struct 
>> link_training_settings *lt_settings,
>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
>> +{
>> +    uint32_t lane;
>> +
>> +    if (lt_settings->voltage_swing == NULL &&
>> +            lt_settings->pre_emphasis == NULL &&
>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>> +            lt_settings->ffe_preset == NULL &&
>> +#endif
>> +            lt_settings->post_cursor2 == NULL)
>> +
>> +        return;
>> +
>> +    for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
>> +        if (lt_settings->voltage_swing)
>> +            lane_settings[lane].VOLTAGE_SWING = 
>> *lt_settings->voltage_swing;
>> +        if (lt_settings->pre_emphasis)
>> +            lane_settings[lane].PRE_EMPHASIS = 
>> *lt_settings->pre_emphasis;
>> +        if (lt_settings->post_cursor2)
>> +            lane_settings[lane].POST_CURSOR2 = 
>> *lt_settings->post_cursor2;
>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>> +        if (lt_settings->ffe_preset)
>> +            lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
>> +#endif
> 
> Normally these checks should be done in C and not the preprocessor. `if 
> CONFIG(DRM_AMD_DC_DP2_0)` or similar should work.

Nice catch! I'm going to drop this CONFIG_DRM_AMD_DC_DP2_0 line.

Thanks
Siqueira

>> +    }
>> +}
>> +
>>   enum dc_status dp_get_lane_status_and_lane_adjust(
>>       struct dc_link *link,
>>       const struct link_training_settings *link_training_setting,
>>
> 
> 
> Kind regards,
> 
> Paul


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-25 14:42       ` Kazlauskas, Nicholas
@ 2021-10-25 15:12         ` Paul Menzel
  2021-10-25 15:25           ` Harry Wentland
  0 siblings, 1 reply; 41+ messages in thread
From: Paul Menzel @ 2021-10-25 15:12 UTC (permalink / raw)
  To: Kazlauskas, Nicholas, Harry Wentland, Rodrigo Siqueira, amd-gfx
  Cc: Sunpeng.Li, Bhawanpreet.Lakha, Aurabindo.Pillai, qingqing.zhuo,
	mikita.lipski, roman.li, Anson.Jacob, wayne.lin, stylon.wang,
	solomon.chiu, pavle.kotarac, agustin.gutierrez, Wenjing Liu,
	Eric Yang

Dear Nicholas, dear Harry,


On 25.10.21 16:42, Kazlauskas, Nicholas wrote:
> On 2021-10-25 9:58 a.m., Harry Wentland wrote:

>> On 2021-10-25 07:25, Paul Menzel wrote:

>>> On 24.10.21 15:31, Rodrigo Siqueira wrote:
>>>> From: Wenjing Liu <wenjing.liu@amd.com>
>>>>
>>>> [why]
>>>> We have a regression that cause maximize lane settings to use
>>>> uninitialized data from unused lanes.
>>>
>>> Which commit caused the regression? Please amend the commit message.
>>>
>>>> This will cause link training to fail for 1 or 2 lanes because the lane
>>>> adjust is populated incorrectly sometimes.
>>>
>>> On what card did you test this, and how can it be reproduced?
>>>
>>> Please describe the fix/implemantation in the commit message.
>>>
>>>> Reviewed-by: Eric Yang <eric.yang2@amd.com>
>>>> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
>>>> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
>>>> ---
>>>>    .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
>>>>    1 file changed, 32 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
>>>> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> index 653279ab96f4..f6ba7c734f54 100644
>>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>> @@ -108,6 +108,9 @@ static struct dc_link_settings 
>>>> get_common_supported_link_settings(
>>>>            struct dc_link_settings link_setting_b);
>>>>    static void maximize_lane_settings(const struct 
>>>> link_training_settings *lt_settings,
>>>>            struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>>>> +static void override_lane_settings(const struct 
>>>> link_training_settings *lt_settings,
>>>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>>>> +
>>>>    static uint32_t get_cr_training_aux_rd_interval(struct dc_link 
>>>> *link,
>>>>            const struct dc_link_settings *link_settings)
>>>>    {
>>>> @@ -734,15 +737,13 @@ void dp_decide_lane_settings(
>>>>            }
>>>>    #endif
>>>>        }
>>>> -
>>>> -    /* we find the maximum of the requested settings across all 
>>>> lanes*/
>>>> -    /* and set this maximum for all lanes*/
>>>>        dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, 
>>>> dpcd_lane_settings);
>>>>          if (lt_settings->disallow_per_lane_settings) {
>>>>            /* we find the maximum of the requested settings across 
>>>> all lanes*/
>>>>            /* and set this maximum for all lanes*/
>>>>            maximize_lane_settings(lt_settings, hw_lane_settings);
>>>> +        override_lane_settings(lt_settings, hw_lane_settings);
>>>>              if (lt_settings->always_match_dpcd_with_hw_lane_settings)
>>>>                dp_hw_to_dpcd_lane_settings(lt_settings, 
>>>> hw_lane_settings, dpcd_lane_settings);
>>>> @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct 
>>>> link_training_settings *lt_setti
>>>>        }
>>>>    }
>>>>    +static void override_lane_settings(const struct 
>>>> link_training_settings *lt_settings,
>>>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
>>>> +{
>>>> +    uint32_t lane;
>>>> +
>>>> +    if (lt_settings->voltage_swing == NULL &&
>>>> +            lt_settings->pre_emphasis == NULL &&
>>>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>>>> +            lt_settings->ffe_preset == NULL &&
>>>> +#endif
>>>> +            lt_settings->post_cursor2 == NULL)
>>>> +
>>>> +        return;
>>>> +
>>>> +    for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
>>>> +        if (lt_settings->voltage_swing)
>>>> +            lane_settings[lane].VOLTAGE_SWING = 
>>>> *lt_settings->voltage_swing;
>>>> +        if (lt_settings->pre_emphasis)
>>>> +            lane_settings[lane].PRE_EMPHASIS = 
>>>> *lt_settings->pre_emphasis;
>>>> +        if (lt_settings->post_cursor2)
>>>> +            lane_settings[lane].POST_CURSOR2 = 
>>>> *lt_settings->post_cursor2;
>>>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>>>> +        if (lt_settings->ffe_preset)
>>>> +            lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
>>>> +#endif
>>>
>>> Normally these checks should be done in C and not the preprocessor. 
>>> `if CONFIG(DRM_AMD_DC_DP2_0)` or similar should work.
>>>
>>
>> Interesting. I've never seen this before. Do you have an example or 
>> link to a doc? A cursory search doesn't yield any results but I might 
>> not be searching for the right thing.
>>
>> Harry
> 
> I'm curious about this too. The compiler with optimizations should 
> remove the constant check, but technically the C standard only permits 
> it - it doesn't guarantee that it happens.
> 
> However, this patch should actually be changed to drop these 
> CONFIG_DRM_AMD_DC_DP2_0 guards - this isn't a Kconfig option nor will 
> there be one specifically for DP2. This should be folded under the DCN 
> support.

 From the Linux kernel coding style [1][2]:

> Within code, where possible, use the IS_ENABLED macro to convert a
> Kconfig symbol into a C boolean expression, and use it in a normal C
> conditional:
> 
> if (IS_ENABLED(CONFIG_SOMETHING)) {
>         ...
> }


Kind regards,

Paul


>>>> +    }
>>>> +}
>>>> +
>>>>    enum dc_status dp_get_lane_status_and_lane_adjust(
>>>>        struct dc_link *link,
>>>>        const struct link_training_settings *link_training_setting,

[1]: 
https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation
[2]: Documentation/process/coding-style.rst

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane
  2021-10-25 15:12         ` Paul Menzel
@ 2021-10-25 15:25           ` Harry Wentland
  0 siblings, 0 replies; 41+ messages in thread
From: Harry Wentland @ 2021-10-25 15:25 UTC (permalink / raw)
  To: Paul Menzel, Kazlauskas, Nicholas, Rodrigo Siqueira, amd-gfx
  Cc: Sunpeng.Li, Bhawanpreet.Lakha, Aurabindo.Pillai, qingqing.zhuo,
	mikita.lipski, roman.li, Anson.Jacob, wayne.lin, stylon.wang,
	solomon.chiu, pavle.kotarac, agustin.gutierrez, Wenjing Liu,
	Eric Yang



On 2021-10-25 11:12, Paul Menzel wrote:
> Dear Nicholas, dear Harry,
> 
> 
> On 25.10.21 16:42, Kazlauskas, Nicholas wrote:
>> On 2021-10-25 9:58 a.m., Harry Wentland wrote:
> 
>>> On 2021-10-25 07:25, Paul Menzel wrote:
> 
>>>> On 24.10.21 15:31, Rodrigo Siqueira wrote:
>>>>> From: Wenjing Liu <wenjing.liu@amd.com>
>>>>>
>>>>> [why]
>>>>> We have a regression that cause maximize lane settings to use
>>>>> uninitialized data from unused lanes.
>>>>
>>>> Which commit caused the regression? Please amend the commit message.
>>>>
>>>>> This will cause link training to fail for 1 or 2 lanes because the lane
>>>>> adjust is populated incorrectly sometimes.
>>>>
>>>> On what card did you test this, and how can it be reproduced?
>>>>
>>>> Please describe the fix/implemantation in the commit message.
>>>>
>>>>> Reviewed-by: Eric Yang <eric.yang2@amd.com>
>>>>> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
>>>>> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
>>>>> ---
>>>>>    .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 35 +++++++++++++++++--
>>>>>    1 file changed, 32 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>>> index 653279ab96f4..f6ba7c734f54 100644
>>>>> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>>> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
>>>>> @@ -108,6 +108,9 @@ static struct dc_link_settings get_common_supported_link_settings(
>>>>>            struct dc_link_settings link_setting_b);
>>>>>    static void maximize_lane_settings(const struct link_training_settings *lt_settings,
>>>>>            struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>>>>> +static void override_lane_settings(const struct link_training_settings *lt_settings,
>>>>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
>>>>> +
>>>>>    static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
>>>>>            const struct dc_link_settings *link_settings)
>>>>>    {
>>>>> @@ -734,15 +737,13 @@ void dp_decide_lane_settings(
>>>>>            }
>>>>>    #endif
>>>>>        }
>>>>> -
>>>>> -    /* we find the maximum of the requested settings across all lanes*/
>>>>> -    /* and set this maximum for all lanes*/
>>>>>        dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>>>>>          if (lt_settings->disallow_per_lane_settings) {
>>>>>            /* we find the maximum of the requested settings across all lanes*/
>>>>>            /* and set this maximum for all lanes*/
>>>>>            maximize_lane_settings(lt_settings, hw_lane_settings);
>>>>> +        override_lane_settings(lt_settings, hw_lane_settings);
>>>>>              if (lt_settings->always_match_dpcd_with_hw_lane_settings)
>>>>>                dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
>>>>> @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti
>>>>>        }
>>>>>    }
>>>>>    +static void override_lane_settings(const struct link_training_settings *lt_settings,
>>>>> +        struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
>>>>> +{
>>>>> +    uint32_t lane;
>>>>> +
>>>>> +    if (lt_settings->voltage_swing == NULL &&
>>>>> +            lt_settings->pre_emphasis == NULL &&
>>>>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>>>>> +            lt_settings->ffe_preset == NULL &&
>>>>> +#endif
>>>>> +            lt_settings->post_cursor2 == NULL)
>>>>> +
>>>>> +        return;
>>>>> +
>>>>> +    for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
>>>>> +        if (lt_settings->voltage_swing)
>>>>> +            lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing;
>>>>> +        if (lt_settings->pre_emphasis)
>>>>> +            lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
>>>>> +        if (lt_settings->post_cursor2)
>>>>> +            lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
>>>>> +#if defined(CONFIG_DRM_AMD_DC_DP2_0)
>>>>> +        if (lt_settings->ffe_preset)
>>>>> +            lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
>>>>> +#endif
>>>>
>>>> Normally these checks should be done in C and not the preprocessor. `if CONFIG(DRM_AMD_DC_DP2_0)` or similar should work.
>>>>
>>>
>>> Interesting. I've never seen this before. Do you have an example or link to a doc? A cursory search doesn't yield any results but I might not be searching for the right thing.
>>>
>>> Harry
>>
>> I'm curious about this too. The compiler with optimizations should remove the constant check, but technically the C standard only permits it - it doesn't guarantee that it happens.
>>
>> However, this patch should actually be changed to drop these CONFIG_DRM_AMD_DC_DP2_0 guards - this isn't a Kconfig option nor will there be one specifically for DP2. This should be folded under the DCN support.
> 
> From the Linux kernel coding style [1][2]:
> 
>> Within code, where possible, use the IS_ENABLED macro to convert a
>> Kconfig symbol into a C boolean expression, and use it in a normal C
>> conditional:
>>
>> if (IS_ENABLED(CONFIG_SOMETHING)) {
>>         ...
>> }
> 
> 
> Kind regards,
> 

Interesting. Thanks for sharing. I wasn't aware of that.

Unfortunately a lot of our configs fall into this category
for which ifdef is still needed:

> However, this approach still allows the C compiler to
> see the code inside the block, and check it for correctness
> (syntax, types, symbol references, etc). Thus, you still
> have to use an #ifdef if the code inside the block references
> symbols that will not exist if the condition is not met.

I'll keep an eye out for where we can use the C check instead
of macros in the future.

Harry

> Paul
> 
> 
>>>>> +    }
>>>>> +}
>>>>> +
>>>>>    enum dc_status dp_get_lane_status_and_lane_adjust(
>>>>>        struct dc_link *link,
>>>>>        const struct link_training_settings *link_training_setting,
> 
> [1]: https://www.kernel.org/doc/html/latest/process/coding-style.html#conditional-compilation>> [2]: Documentation/process/coding-style.rst


^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2021-10-25 15:25 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-24 13:31 [PATCH 00/33] DC Patches October 24, 2020 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 01/33] drm/amd/display: Align bw context with hw config when system resume Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 02/33] drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 03/33] drm/amd/display: Get ceiling for v_total calc Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 04/33] drm/amd/display: dc_link_set_psr_allow_active refactoring Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 05/33] drm/amd/display: Add support for USB4 on C20 PHY for DCN3.1 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 06/33] drm/amd/display: move FPU associated DSC code to DML folder Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 07/33] drm/amd/display: fix a crash on USB4 over C20 PHY Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 08/33] drm/amd/display: Set i2c memory to light sleep during hw init Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 09/33] drm/amd/display: Defer GAMCOR and DSCL power down sequence to vupdate Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 10/33] drm/amd/display: clean up dcn31 revision check Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 11/33] drm/amd/display: restyle dcn31 resource header inline with other asics Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 12/33] drm/amd/display: Implement fixed DP drive settings Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 13/33] drm/amd/display: Add comment for preferred_training_settings Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 14/33] drm/amd/display: Handle I2C-over-AUX write channel status update Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 15/33] drm/amd/display: [FW Promotion] Release 0.0.89 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 16/33] drm/amd/display: 3.2.158 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 17/33] drm/amd/display: Fix 3DLUT skipped programming Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 18/33] drm/amd/display: set Layout properly for 8ch audio at timing validation Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 19/33] drm/amd/display: allow windowed mpo + odm Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 20/33] drm/amd/display: Remove unused macros Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 21/33] drm/amd/display: [FW Promotion] Release 0.0.90 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 22/33] drm/amd/display: 3.2.159 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 23/33] drm/amd/display: Manually adjust strobe for DCN303 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 24/33] drm/amd/display: Set phy_mux_sel bit in dmub scratch register Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 25/33] drm/amd/display: Add workaround flag for EDID read on certain docks Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 26/33] drm/amd/display: FEC configuration for dpia links Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 27/33] drm/amd/display: FEC configuration for dpia links in MST mode Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 28/33] drm/amd/display: adopt DP2.0 LT SCR revision 8 Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 29/33] drm/amd/display: implement decide lane settings Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 30/33] drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 31/33] drm/amd/display: add two lane settings training options Rodrigo Siqueira
2021-10-24 13:31 ` [PATCH 32/33] drm/amd/display: fix link training regression for 1 or 2 lane Rodrigo Siqueira
2021-10-25 11:25   ` Paul Menzel
2021-10-25 13:58     ` Harry Wentland
2021-10-25 14:42       ` Kazlauskas, Nicholas
2021-10-25 15:12         ` Paul Menzel
2021-10-25 15:25           ` Harry Wentland
2021-10-25 14:56     ` Rodrigo Siqueira Jordao
2021-10-24 13:31 ` [PATCH 33/33] drm/amd/display: move FPU associated DCN301 code to DML folder Rodrigo Siqueira
2021-10-25 13:07 ` [PATCH 00/33] DC Patches October 24, 2020 Wheeler, Daniel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.