All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/87] DC Patches 15 Jul, 2019
@ 2019-07-15 21:19 sunpeng.li-5C7GfCeVMHo
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li

From: Leo Li <sunpeng.li@amd.com>

Lots of patches this time, sorry for the volume! Regular DC promotions
were put on hold while Navi was being reviewed and upstreamed. These
patches were what accumulated during that period.

Summary of change:
* Implement DPRX CRC source capture
* Implement CRC source readback
* Navi Bandwidth calcs refactor
* Misc fixes for Navi:
    * Dual GPU boot black screen
    * Flip timeouts
    * Workaround for p-state hangs on high-bandwidth timings


Alvin Lee (4):
  drm/amd/display: Disable Audio on reinitialize hardware
  drm/amd/display: Remove second initialization of pp_smu
  drm/amd/display: Wait for flip to complete
  drm/amd/display: Only enable audio if speaker allocation exists

Anthony Koo (1):
  drm/amd/display: add monitor patch to add T7 delay

Aric Cyr (7):
  drm/amd/display: 3.2.36
  drm/amd/display: 3.2.37
  drm/amd/display: 3.2.38
  drm/amd/display: 3.2.39
  drm/amd/display: 3.2.40
  drm/amd/display: 3.2.41
  drm/amd/display: 3.2.42

Charlene Liu (4):
  drm/amd/display: Split out common HUBP registers and code
  drm/amd/display: Do not fill Null packet in the blank period
  drm/amd/display: add set and get clock for testing purposes
  drm/amd/display: add a option to force the clock at every mode change.

Chiawen Huang (1):
  drm/amd/display: Add aux tracing log in dce

Dale Zhao (1):
  drm/amd/display: handle active dongle port type is DP++ or DP case

David Francis (1):
  drm/amd/display: Update drm_dsc to reflect native 4.2.0 DSC spec

David Galiffi (2):
  drm/amd/display: Add ability to set preferred link training
    parameters.
  drm/amd/display: Incorrect Read Interval Time For CR Sequence

Derek Lai (2):
  drm/amd/display: Read max down spread
  drm/amd/display: allocate 4 ddc engines for RV2

Dingchen Zhang (3):
  drm/amd/display: add functionality to grab DPRX CRC entries.
  drm/amd/display: add functionality to get pipe CRC source.
  drm/amd/display: add pipe CRC sources without disabling dithering.

Dmytro Laktyushkin (6):
  drm/amd/display: fix dsc disable
  drm/amd/display: Set default block_size, even in unexpected cases
  drm/amd/display: add hdmi2.1 dsc pps packet programming
  drm/amd/display: Remove dsc disable_ich flag programming.
  drm/amd/display: use min disp and dpp clk debug option for dcn2
  drm/amd/display: add dcc programming for dual plane

Eric Bernstein (1):
  drm/amd/display: Use helper for determining HDMI signal

Eric Yang (5):
  drm/amd/display: move bw calc code into helpers
  drm/amd/display: early return when pipe_cnt is 0 in bw validation
  drm/amd/display: put back front end initialization sequence
  drm/amd/display: do not read link setting if edp not connected
  drm/amd/display: fix mpcc assert condition

Fatemeh Darbehani (2):
  drm/amd/display: Change min_h_sync_width from 8 to 4
  drm/amd/display: Add SMU version field to clk_mgr_internal

Harmanprit Tatla (1):
  drm/amd/display: No audio endpoint for Dell MST display

Harry Wentland (1):
  drm/amd/display: Remove unnecessary NULL check in
    set_preferred_link_settings

Ilya Bakoulin (5):
  drm/amd/display: Expose enc2_set_dynamic_metadata
  drm/amd/display: Check for valid stream_encode
  drm/amd/display: Fix some HUBP programming issues
  drm/amd/display: Cache the use_pitch_c conditional
  drm/amd/display: Fixes for some MPO cases

Joshua Aberback (1):
  drm/amd/display: Add debug option to disable timing sync

Julian Parkin (3):
  drm/amd/display: Poll for GPUVM context ready
  drm/amd/display: Fix dc_create failure handling and 666 color depths
  drm/amd/display: Clean up dynamic metadata logic

Jun Lei (6):
  drm/amd/display: initialize p_state to proper value
  drm/amd/display: fix up HUBBUB hw programming for VM
  drm/amd/display: cap DCFCLK hardmin to 507 for NV10
  drm/amd/display: swap system aperture high/low
  drm/amd/display: populate last calculated bb state with max clocks
  drm/amd/display: support "dummy pstate"

Krunoslav Kovac (1):
  drm/amd/display: Optimize gamma calculations

Lewis Huang (1):
  drm/amd/display: Add debug entry to destroy disconnected edp link

Murton Liu (4):
  drm/amd/display: Clock does not lower in Updateplanes
  drm/amd/display: Implement generic MUX registers
  drm/amd/display: Hook up calls to do stereo mux and dig programming to
    stereo control interface
  drm/amd/display: Change offset_to_id to reflect what id_to_offset
    returns

Nevenko Stupar (2):
  drm/amd/display:Use Pixel clock in 100Hz units for HDMI Audio wall
    clock DTO
  drm/amd/display: Add DIG_CLOCK_PATTERN register

Nicholas Kazlauskas (4):
  drm/amd/display: Copy max_clks_by_state after dce_clk_mgr_construct
  drm/amd/display: Set enabled to false at start of audio disable
  drm/amd/display: Copy GSL groups when committing a new context
  drm/amd/display: Force uclk to max for every state

Nikola Cornij (4):
  drm/amd/display: Set one 4:2:0-related PPS field as recommended by DSC
    spec
  drm/amd/display: Power-gate all DSCs at driver init time
  drm/amd/display: Set FEC_READY always before link training
  drm/amd/display: Clear FEC_READY shadow register if DPCD write fails

Qingqing Zhuo (1):
  drm/amd/display: Add CM_BYPASS via debug option

Reza Amini (1):
  drm/amd/display: Implement DAL3 GPU Integer Scaling

Samson Tam (1):
  drm/amd/display: skip retrain in dc_link_set_preferred_link_settings()
    if using passive dongle

SivapiriyanKumarasamy (1):
  drm/amd/display: Wait for backlight programming completion in set
    backlight level

Su Sung Chung (2):
  drm/amd/display: refactor dump_clk_registers
  drm/amd/display: fix not calling ppsmu to trigger PME

Tai Man (2):
  drm/amd/display: use encoder's engine id to find matched free audio
    device
  drm/amd/display: Increase size of audios array

Tony Cheng (1):
  drm/amd/display: avoid power gate domains that doesn't exist

Vitaly Prosyak (1):
  drm/amd/display: Add MPC 3DLUT resource management

Wenjing Liu (1):
  drm/amd/display: wait for the whole frame after global unlock

Zhan Liu (1):
  drm/amd/display: drop ASSERT() if eDP panel is not connected

Zi Yu Liao (1):
  drm/amd/display: fix DMCU hang when going into Modern Standby

hersen wu (1):
  drm/amd/display: init res_pool dccg_ref, dchub_ref with xtalin_freq

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |    1 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   60 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   16 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |  139 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h |   61 +
 .../amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c  |    6 +-
 .../gpu/drm/amd/display/dc/calcs/dce_calcs.c  |    2 +-
 .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c  |    2 +-
 .../dc/clk_mgr/dce110/dce110_clk_mgr.c        |    4 +-
 .../dc/clk_mgr/dce112/dce112_clk_mgr.c        |    4 +-
 .../dc/clk_mgr/dce120/dce120_clk_mgr.c        |    4 +-
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |   39 +-
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h  |    5 +
 drivers/gpu/drm/amd/display/dc/core/dc.c      |   96 +-
 .../gpu/drm/amd/display/dc/core/dc_debug.c    |   40 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  101 +-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  |  394 +-
 .../drm/amd/display/dc/core/dc_link_hwss.c    |   45 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   69 +-
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |   26 +-
 .../gpu/drm/amd/display/dc/core/dc_surface.c  |    3 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |   44 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |   21 +
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   56 +-
 drivers/gpu/drm/amd/display/dc/dc_link.h      |   11 +
 drivers/gpu/drm/amd/display/dc/dc_types.h     |   14 +
 drivers/gpu/drm/amd/display/dc/dce/dce_abm.c  |    4 +
 .../gpu/drm/amd/display/dc/dce/dce_audio.c    |   28 +-
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c  |    9 +-
 .../gpu/drm/amd/display/dc/dce/dce_hwseq.h    |    7 +-
 .../drm/amd/display/dc/dce/dce_mem_input.c    |   10 +-
 .../amd/display/dc/dce/dce_stream_encoder.c   |   30 +-
 .../display/dc/dce110/dce110_hw_sequencer.c   |   70 +-
 .../display/dc/dce110/dce110_mem_input_v.c    |   42 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c |   70 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h |   27 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |   85 +-
 .../dc/dcn10/dcn10_hw_sequencer_debug.c       |    2 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c  |    2 +-
 .../drm/amd/display/dc/dcn10/dcn10_resource.c |    2 +-
 .../display/dc/dcn10/dcn10_stream_encoder.c   |   33 +-
 .../display/dc/dcn10/dcn10_stream_encoder.h   |   16 +-
 .../drm/amd/display/dc/dcn20/dcn20_dpp_cm.c   |    7 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c  |    8 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h  |    4 +-
 .../drm/amd/display/dc/dcn20/dcn20_hubbub.c   |   29 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c |  688 ++-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h |   62 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  221 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.h    |   14 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c  |   34 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c |    2 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |  356 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.h |   12 +
 .../display/dc/dcn20/dcn20_stream_encoder.c   |    2 +-
 .../display/dc/dcn20/dcn20_stream_encoder.h   |    5 +
 .../gpu/drm/amd/display/dc/dcn20/dcn20_vmid.c |   35 +
 drivers/gpu/drm/amd/display/dc/dm_services.h  |    1 +
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |    3 +
 .../dc/dml/dcn20/display_mode_vba_20v2.c      | 5109 +++++++++++++++++
 .../dc/dml/dcn20/display_mode_vba_20v2.h      |   32 +
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c   | 1701 ++++++
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.h   |   74 +
 .../drm/amd/display/dc/dml/display_mode_lib.c |   12 +
 .../drm/amd/display/dc/dml/display_mode_lib.h |    1 +
 .../amd/display/dc/dml/display_mode_structs.h |    1 +
 .../drm/amd/display/dc/dml/display_mode_vba.c |    8 +-
 .../gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c   |   79 +-
 drivers/gpu/drm/amd/display/dc/gpio/Makefile  |    2 +-
 .../display/dc/gpio/dcn10/hw_factory_dcn10.c  |   42 +-
 .../display/dc/gpio/dcn20/hw_factory_dcn20.c  |   41 +-
 .../dc/gpio/dcn20/hw_translate_dcn20.c        |    2 +-
 .../dc/gpio/diagnostics/hw_factory_diag.c     |    1 +
 .../drm/amd/display/dc/gpio/generic_regs.h    |   66 +
 .../drm/amd/display/dc/gpio/gpio_service.c    |   68 +
 .../gpu/drm/amd/display/dc/gpio/hw_factory.h  |    3 +
 .../gpu/drm/amd/display/dc/gpio/hw_generic.c  |  132 +
 .../gpu/drm/amd/display/dc/gpio/hw_generic.h  |   46 +
 .../gpu/drm/amd/display/dc/inc/core_status.h  |    3 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |    2 +-
 .../gpu/drm/amd/display/dc/inc/dc_link_dp.h   |    1 +
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |    7 +
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |    3 +
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h  |    4 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |    1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h  |    2 +-
 .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h |    1 +
 .../gpu/drm/amd/display/dc/inc/hw/mem_input.h |    2 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   |    1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |   10 +
 .../gpu/drm/amd/display/dc/inc/link_hwss.h    |    2 +-
 .../gpu/drm/amd/display/include/audio_types.h |    4 +-
 .../gpu/drm/amd/display/include/dpcd_defs.h   |    2 +-
 .../display/include/gpio_service_interface.h  |   18 +-
 .../amd/display/include/link_service_types.h  |   17 +-
 .../amd/display/modules/color/color_gamma.c   |  163 +-
 .../amd/display/modules/color/color_gamma.h   |    9 +
 97 files changed, 10040 insertions(+), 815 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h

-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 01/87] drm/amd/display: initialize p_state to proper value
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 02/87] drm/amd/display: Add ability to set preferred link training parameters sunpeng.li-5C7GfCeVMHo
                     ` (85 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Tony Cheng

From: Jun Lei <Jun.Lei@amd.com>

[why]
On some modes SMU will be in infinite loop state at boot, this is
because driver assumes p_state_support is false, but this is the
opposite of the assumed boot state by SMU.  we optimize away
notifying SMU about no pstate, and so they will get stuck

[how]
when we init clk manager, init pstate to true, so it matches driver load
assumption

Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 08a774fc7b67..740f5db22bb5 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -301,6 +301,8 @@ void dcn2_update_clocks_fpga(struct clk_mgr *clk_mgr,
 void dcn2_init_clocks(struct clk_mgr *clk_mgr)
 {
 	memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
+	// Assumption is that boot state always supports pstate
+	clk_mgr->clks.p_state_change_support = true;
 }
 
 void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base)
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 02/87] drm/amd/display: Add ability to set preferred link training parameters.
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
  2019-07-15 21:19   ` [PATCH 01/87] drm/amd/display: initialize p_state to proper value sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 03/87] drm/amd/display: 3.2.36 sunpeng.li-5C7GfCeVMHo
                     ` (84 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Tony Cheng, David Galiffi, Anthony Koo

From: David Galiffi <David.Galiffi@amd.com>

[WHY]
To add support for OS requirement to set preferred link training
parameters.

[HOW]
Create new structure of dp link training overrides. During link training
processes, these values should be used instead of the default training
parameters.

Signed-off-by: David Galiffi <David.Galiffi@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  46 ++-
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 337 +++++++++++++-----
 .../drm/amd/display/dc/core/dc_link_hwss.c    |  28 +-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |  21 ++
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  11 +
 .../gpu/drm/amd/display/dc/inc/link_hwss.h    |   2 +-
 .../amd/display/include/link_service_types.h  |  17 +-
 7 files changed, 338 insertions(+), 124 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 6167e1cb0b48..0918c334f0e2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1187,6 +1187,9 @@ static bool construct(
 	link->ctx = dc_ctx;
 	link->link_index = init_params->link_index;
 
+	memset(&link->preferred_training_settings, 0, sizeof(struct dc_link_training_overrides));
+	memset(&link->preferred_link_setting, 0, sizeof(struct dc_link_settings));
+
 	link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
 
 	if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
@@ -1465,6 +1468,9 @@ static enum dc_status enable_link_dp(
 	struct dc_link *link = stream->link;
 	struct dc_link_settings link_settings = {0};
 	enum dp_panel_mode panel_mode;
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	bool fec_enable;
+#endif
 
 	/* get link settings for video mode timing */
 	decide_link_settings(stream, &link_settings);
@@ -1509,10 +1515,20 @@ static enum dc_status enable_link_dp(
 			skip_video_pattern = false;
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	dp_set_fec_ready(link, true);
+	if (link->preferred_training_settings.fec_enable != NULL)
+		fec_enable = *link->preferred_training_settings.fec_enable;
+	else
+		fec_enable = true;
+
+	dp_set_fec_ready(link, fec_enable);
 #endif
 
-	if (perform_link_training_with_retries(
+	if (link->aux_access_disabled) {
+		dc_link_dp_perform_link_training_skip_aux(link, &link_settings);
+
+		link->cur_link_settings = link_settings;
+		status = DC_OK;
+	} else if (perform_link_training_with_retries(
 			link,
 			&link_settings,
 			skip_video_pattern,
@@ -1524,7 +1540,7 @@ static enum dc_status enable_link_dp(
 		status = DC_FAIL_DP_LINK_TRAINING;
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	dp_set_fec_enable(link, true);
+	dp_set_fec_enable(link, fec_enable);
 #endif
 	return status;
 }
@@ -3012,6 +3028,29 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
 		dp_retrain_link_dp_test(link, &store_settings, false);
 }
 
+void dc_link_set_preferred_training_settings(struct dc *dc,
+						 struct dc_link_settings *link_setting,
+						 struct dc_link_training_overrides *lt_overrides,
+						 struct dc_link *link,
+						 bool skip_immediate_retrain)
+{
+	if (lt_overrides != NULL)
+		link->preferred_training_settings = *lt_overrides;
+	else
+		memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
+
+	if (link_setting != NULL) {
+		link->preferred_link_setting = *link_setting;
+	} else {
+		link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
+		link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
+	}
+
+	/* Retrain now, or wait until next stream update to apply */
+	if (skip_immediate_retrain == false)
+		dc_link_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
+}
+
 void dc_link_enable_hpd(const struct dc_link *link)
 {
 	dc_link_dp_enable_hpd(link);
@@ -3022,7 +3061,6 @@ void dc_link_disable_hpd(const struct dc_link *link)
 	dc_link_dp_disable_hpd(link);
 }
 
-
 void dc_link_set_test_pattern(struct dc_link *link,
 			      enum dp_test_pattern test_pattern,
 			      const struct link_training_settings *p_link_settings,
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 056be4c34a98..3f8a8f61cd76 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
@@ -49,7 +49,7 @@ 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 wait_for_training_aux_rd_interval(
+static uint32_t get_training_aux_rd_interval(
 	struct dc_link *link,
 	uint32_t default_wait_in_micro_secs)
 {
@@ -68,15 +68,21 @@ static void wait_for_training_aux_rd_interval(
 			sizeof(training_rd_interval));
 
 		if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
-			default_wait_in_micro_secs =
-				training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
+			default_wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
 	}
 
-	udelay(default_wait_in_micro_secs);
+	return default_wait_in_micro_secs;
+}
+
+static void wait_for_training_aux_rd_interval(
+	struct dc_link *link,
+	uint32_t wait_in_micro_secs)
+{
+	udelay(wait_in_micro_secs);
 
 	DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
 		__func__,
-		default_wait_in_micro_secs);
+		wait_in_micro_secs);
 }
 
 static void dpcd_set_training_pattern(
@@ -95,27 +101,27 @@ static void dpcd_set_training_pattern(
 		dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
 }
 
-static enum hw_dp_training_pattern get_supported_tp(struct dc_link *link)
+static enum dc_dp_training_pattern get_supported_tp(struct dc_link *link)
 {
-	enum hw_dp_training_pattern highest_tp = HW_DP_TRAINING_PATTERN_2;
+	enum dc_dp_training_pattern highest_tp = DP_TRAINING_PATTERN_SEQUENCE_2;
 	struct encoder_feature_support *features = &link->link_enc->features;
 	struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
 
 	if (features->flags.bits.IS_TPS3_CAPABLE)
-		highest_tp = HW_DP_TRAINING_PATTERN_3;
+		highest_tp = DP_TRAINING_PATTERN_SEQUENCE_3;
 
 	if (features->flags.bits.IS_TPS4_CAPABLE)
-		highest_tp = HW_DP_TRAINING_PATTERN_4;
+		highest_tp = DP_TRAINING_PATTERN_SEQUENCE_4;
 
 	if (dpcd_caps->max_down_spread.bits.TPS4_SUPPORTED &&
-		highest_tp >= HW_DP_TRAINING_PATTERN_4)
-		return HW_DP_TRAINING_PATTERN_4;
+		highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_4)
+		return DP_TRAINING_PATTERN_SEQUENCE_4;
 
 	if (dpcd_caps->max_ln_count.bits.TPS3_SUPPORTED &&
-		highest_tp >= HW_DP_TRAINING_PATTERN_3)
-		return HW_DP_TRAINING_PATTERN_3;
+		highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_3)
+		return DP_TRAINING_PATTERN_SEQUENCE_3;
 
-	return HW_DP_TRAINING_PATTERN_2;
+	return DP_TRAINING_PATTERN_SEQUENCE_2;
 }
 
 static void dpcd_set_link_settings(
@@ -126,7 +132,7 @@ static void dpcd_set_link_settings(
 
 	union down_spread_ctrl downspread = { {0} };
 	union lane_count_set lane_count_set = { {0} };
-	enum hw_dp_training_pattern hw_tr_pattern;
+	enum dc_dp_training_pattern dp_tr_pattern;
 
 	downspread.raw = (uint8_t)
 	(lt_settings->link_settings.link_spread);
@@ -134,21 +140,21 @@ static void dpcd_set_link_settings(
 	lane_count_set.bits.LANE_COUNT_SET =
 	lt_settings->link_settings.lane_count;
 
-	lane_count_set.bits.ENHANCED_FRAMING = 1;
-
+	lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
 	lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
 
-	hw_tr_pattern = get_supported_tp(link);
-	if (hw_tr_pattern != HW_DP_TRAINING_PATTERN_4) {
+	dp_tr_pattern = get_supported_tp(link);
+
+	if (dp_tr_pattern != DP_TRAINING_PATTERN_SEQUENCE_4) {
 		lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
 				link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
 	}
 
 	core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
-	&downspread.raw, sizeof(downspread));
+		&downspread.raw, sizeof(downspread));
 
 	core_link_write_dpcd(link, DP_LANE_COUNT_SET,
-	&lane_count_set.raw, 1);
+		&lane_count_set.raw, 1);
 
 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
 			lt_settings->link_settings.use_link_rate_set == true) {
@@ -162,46 +168,47 @@ static void dpcd_set_link_settings(
 	}
 
 	if (rate) {
-		DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n",
+		DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
 			__func__,
 			DP_LINK_BW_SET,
 			lt_settings->link_settings.link_rate,
 			DP_LANE_COUNT_SET,
 			lt_settings->link_settings.lane_count,
+			lt_settings->enhanced_framing,
 			DP_DOWNSPREAD_CTRL,
 			lt_settings->link_settings.link_spread);
 	} else {
-		DC_LOG_HW_LINK_TRAINING("%s\n %x rate set = %x\n %x lane = %x\n %x spread = %x\n",
+		DC_LOG_HW_LINK_TRAINING("%s\n %x rate set = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
 			__func__,
 			DP_LINK_RATE_SET,
 			lt_settings->link_settings.link_rate_set,
 			DP_LANE_COUNT_SET,
 			lt_settings->link_settings.lane_count,
+			lt_settings->enhanced_framing,
 			DP_DOWNSPREAD_CTRL,
 			lt_settings->link_settings.link_spread);
 	}
-
 }
 
 static enum dpcd_training_patterns
-	hw_training_pattern_to_dpcd_training_pattern(
+	dc_dp_training_pattern_to_dpcd_training_pattern(
 	struct dc_link *link,
-	enum hw_dp_training_pattern pattern)
+	enum dc_dp_training_pattern pattern)
 {
 	enum dpcd_training_patterns dpcd_tr_pattern =
 	DPCD_TRAINING_PATTERN_VIDEOIDLE;
 
 	switch (pattern) {
-	case HW_DP_TRAINING_PATTERN_1:
+	case DP_TRAINING_PATTERN_SEQUENCE_1:
 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
 		break;
-	case HW_DP_TRAINING_PATTERN_2:
+	case DP_TRAINING_PATTERN_SEQUENCE_2:
 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
 		break;
-	case HW_DP_TRAINING_PATTERN_3:
+	case DP_TRAINING_PATTERN_SEQUENCE_3:
 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
 		break;
-	case HW_DP_TRAINING_PATTERN_4:
+	case DP_TRAINING_PATTERN_SEQUENCE_4:
 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
 		break;
 	default:
@@ -212,13 +219,12 @@ static enum dpcd_training_patterns
 	}
 
 	return dpcd_tr_pattern;
-
 }
 
 static void dpcd_set_lt_pattern_and_lane_settings(
 	struct dc_link *link,
 	const struct link_training_settings *lt_settings,
-	enum hw_dp_training_pattern pattern)
+	enum dc_dp_training_pattern pattern)
 {
 	union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } };
 	const uint32_t dpcd_base_lt_offset =
@@ -233,7 +239,7 @@ static void dpcd_set_lt_pattern_and_lane_settings(
 	* DpcdAddress_TrainingPatternSet
 	*****************************************************************/
 	dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
-		hw_training_pattern_to_dpcd_training_pattern(link, pattern);
+		dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
 
 	dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - dpcd_base_lt_offset]
 		= dpcd_pattern.raw;
@@ -346,12 +352,20 @@ static void update_drive_settings(
 {
 	uint32_t lane;
 	for (lane = 0; lane < src.link_settings.lane_count; lane++) {
-		dest->lane_settings[lane].VOLTAGE_SWING =
-			src.lane_settings[lane].VOLTAGE_SWING;
-		dest->lane_settings[lane].PRE_EMPHASIS =
-			src.lane_settings[lane].PRE_EMPHASIS;
-		dest->lane_settings[lane].POST_CURSOR2 =
-			src.lane_settings[lane].POST_CURSOR2;
+		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;
 	}
 }
 
@@ -754,15 +768,15 @@ static enum link_training_result perform_channel_equalization_sequence(
 	struct link_training_settings *lt_settings)
 {
 	struct link_training_settings req_settings;
-	enum hw_dp_training_pattern hw_tr_pattern;
+	enum dc_dp_training_pattern tr_pattern;
 	uint32_t retries_ch_eq;
 	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} } };
 
-	hw_tr_pattern = get_supported_tp(link);
+	tr_pattern = lt_settings->pattern_for_eq;
 
-	dp_set_hw_training_pattern(link, hw_tr_pattern);
+	dp_set_hw_training_pattern(link, tr_pattern);
 
 	for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
 		retries_ch_eq++) {
@@ -776,12 +790,12 @@ static enum link_training_result perform_channel_equalization_sequence(
 			dpcd_set_lt_pattern_and_lane_settings(
 				link,
 				lt_settings,
-				hw_tr_pattern);
+				tr_pattern);
 		else
 			dpcd_set_lane_settings(link, lt_settings);
 
 		/* 3. wait for receiver to lock-on*/
-		wait_for_training_aux_rd_interval(link, 400);
+		wait_for_training_aux_rd_interval(link, lt_settings->eq_pattern_time);
 
 		/* 4. Read lane status and requested
 		 * drive settings as set by the sink*/
@@ -817,27 +831,16 @@ static enum link_training_result perform_clock_recovery_sequence(
 {
 	uint32_t retries_cr;
 	uint32_t retry_count;
-	uint32_t lane;
 	struct link_training_settings req_settings;
-	enum dc_lane_count lane_count =
-	lt_settings->link_settings.lane_count;
-	enum hw_dp_training_pattern hw_tr_pattern = HW_DP_TRAINING_PATTERN_1;
+	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
+	enum dc_dp_training_pattern tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_1;
 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
 	union lane_align_status_updated dpcd_lane_status_updated;
 
 	retries_cr = 0;
 	retry_count = 0;
-	/* initial drive setting (VS/PE/PC2)*/
-	for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
-		lt_settings->lane_settings[lane].VOLTAGE_SWING =
-		VOLTAGE_SWING_LEVEL0;
-		lt_settings->lane_settings[lane].PRE_EMPHASIS =
-		PRE_EMPHASIS_DISABLED;
-		lt_settings->lane_settings[lane].POST_CURSOR2 =
-		POST_CURSOR2_DISABLED;
-	}
 
-	dp_set_hw_training_pattern(link, hw_tr_pattern);
+	dp_set_hw_training_pattern(link, tr_pattern);
 
 	/* najeeb - The synaptics MST hub can put the LT in
 	* infinite loop by switching the VS
@@ -845,7 +848,7 @@ static enum link_training_result perform_clock_recovery_sequence(
 	/* between level 0 and level 1 continuously, here
 	* we try for CR lock for LinkTrainingMaxCRRetry count*/
 	while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
-	(retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
+		(retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
 
 		memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
 		memset(&dpcd_lane_status_updated, '\0',
@@ -863,7 +866,7 @@ static enum link_training_result perform_clock_recovery_sequence(
 			dpcd_set_lt_pattern_and_lane_settings(
 					link,
 					lt_settings,
-					hw_tr_pattern);
+					tr_pattern);
 		else
 			dpcd_set_lane_settings(
 					link,
@@ -872,7 +875,7 @@ static enum link_training_result perform_clock_recovery_sequence(
 		/* 3. wait receiver to lock-on*/
 		wait_for_training_aux_rd_interval(
 				link,
-				100);
+				lt_settings->cr_pattern_time);
 
 		/* 4. Read lane status and requested drive
 		* settings as set by the sink
@@ -939,7 +942,7 @@ static inline enum link_training_result perform_link_training_int(
 	 * TPS4 must be used instead of POST_LT_ADJ_REQ.
 	 */
 	if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
-			get_supported_tp(link) == HW_DP_TRAINING_PATTERN_4)
+			get_supported_tp(link) == DP_TRAINING_PATTERN_SEQUENCE_4)
 		return status;
 
 	if (status == LINK_TRAINING_SUCCESS &&
@@ -947,7 +950,7 @@ static inline enum link_training_result perform_link_training_int(
 		status = LINK_TRAINING_LQA_FAIL;
 
 	lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
-	lane_count_set.bits.ENHANCED_FRAMING = 1;
+	lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
 	lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
 
 	core_link_write_dpcd(
@@ -959,24 +962,28 @@ static inline enum link_training_result perform_link_training_int(
 	return status;
 }
 
-enum link_training_result dc_link_dp_perform_link_training(
-	struct dc_link *link,
+static void initialize_training_settings(
+	 struct dc_link *link,
 	const struct dc_link_settings *link_setting,
-	bool skip_video_pattern)
+	struct link_training_settings *lt_settings)
 {
-	enum link_training_result status = LINK_TRAINING_SUCCESS;
+	uint32_t lane;
 
-	char *link_rate = "Unknown";
-	char *lt_result = "Unknown";
+	memset(lt_settings, '\0', sizeof(struct link_training_settings));
 
-	struct link_training_settings lt_settings;
+	/* Initialize link settings */
+	lt_settings->link_settings.use_link_rate_set = link_setting->use_link_rate_set;
+	lt_settings->link_settings.link_rate_set = link_setting->link_rate_set;
 
-	memset(&lt_settings, '\0', sizeof(lt_settings));
+	if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
+		lt_settings->link_settings.link_rate = link->preferred_link_setting.link_rate;
+	else
+		lt_settings->link_settings.link_rate = link_setting->link_rate;
 
-	lt_settings.link_settings.link_rate = link_setting->link_rate;
-	lt_settings.link_settings.lane_count = link_setting->lane_count;
-	lt_settings.link_settings.use_link_rate_set = link_setting->use_link_rate_set;
-	lt_settings.link_settings.link_rate_set = link_setting->link_rate_set;
+	if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN)
+		lt_settings->link_settings.lane_count = link->preferred_link_setting.lane_count;
+	else
+		lt_settings->link_settings.lane_count = link_setting->lane_count;
 
 	/*@todo[vdevulap] move SS to LS, should not be handled by displaypath*/
 
@@ -987,31 +994,75 @@ enum link_training_result dc_link_dp_perform_link_training(
 	 * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
 	 * LINK_SPREAD_DISABLED;
 	 */
+	/* Initialize link spread */
 	if (link->dp_ss_off)
-		lt_settings.link_settings.link_spread = LINK_SPREAD_DISABLED;
+		lt_settings->link_settings.link_spread = LINK_SPREAD_DISABLED;
+	else if (link->preferred_training_settings.downspread != NULL)
+		lt_settings->link_settings.link_spread
+			= *link->preferred_training_settings.downspread
+			? LINK_SPREAD_05_DOWNSPREAD_30KHZ
+			: LINK_SPREAD_DISABLED;
 	else
-		lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
+		lt_settings->link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
 
-	/* 1. set link rate, lane count and spread*/
-	dpcd_set_link_settings(link, &lt_settings);
+	/* Initialize lane settings overrides */
+	if (link->preferred_training_settings.voltage_swing != NULL)
+		lt_settings->voltage_swing = link->preferred_training_settings.voltage_swing;
 
-	/* 2. perform link training (set link training done
-	 *  to false is done as well)*/
-	status = perform_clock_recovery_sequence(link, &lt_settings);
-	if (status == LINK_TRAINING_SUCCESS) {
-		status = perform_channel_equalization_sequence(link,
-				&lt_settings);
-	}
+	if (link->preferred_training_settings.pre_emphasis != NULL)
+		lt_settings->pre_emphasis = link->preferred_training_settings.pre_emphasis;
 
-	if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
-		status = perform_link_training_int(link,
-				&lt_settings,
-				status);
+	if (link->preferred_training_settings.post_cursor2 != NULL)
+		lt_settings->post_cursor2 = link->preferred_training_settings.post_cursor2;
+
+	/* Initialize lane settings (VS/PE/PC2) */
+	for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
+		lt_settings->lane_settings[lane].VOLTAGE_SWING =
+			lt_settings->voltage_swing != NULL ?
+			*lt_settings->voltage_swing :
+			VOLTAGE_SWING_LEVEL0;
+		lt_settings->lane_settings[lane].PRE_EMPHASIS =
+			lt_settings->pre_emphasis != NULL ?
+			*lt_settings->pre_emphasis
+			: PRE_EMPHASIS_DISABLED;
+		lt_settings->lane_settings[lane].POST_CURSOR2 =
+			lt_settings->post_cursor2 != NULL ?
+			*lt_settings->post_cursor2
+			: POST_CURSOR2_DISABLED;
 	}
 
-	/* 6. print status message*/
-	switch (lt_settings.link_settings.link_rate) {
+	/* Initialize training timings */
+	if (link->preferred_training_settings.cr_pattern_time != NULL)
+		lt_settings->cr_pattern_time = *link->preferred_training_settings.cr_pattern_time;
+	else
+		lt_settings->cr_pattern_time = get_training_aux_rd_interval(link, 100);
+
+	if (link->preferred_training_settings.eq_pattern_time != NULL)
+		lt_settings->eq_pattern_time = *link->preferred_training_settings.eq_pattern_time;
+	else
+		lt_settings->eq_pattern_time = get_training_aux_rd_interval(link, 400);
+
+	if (link->preferred_training_settings.pattern_for_eq != NULL)
+		lt_settings->pattern_for_eq = *link->preferred_training_settings.pattern_for_eq;
+	else
+		lt_settings->pattern_for_eq = get_supported_tp(link);
+
+	if (link->preferred_training_settings.enhanced_framing != NULL)
+		lt_settings->enhanced_framing = *link->preferred_training_settings.enhanced_framing;
+	else
+		lt_settings->enhanced_framing = 1;
+}
+
+static void print_status_message(
+	struct dc_link *link,
+	const struct link_training_settings *lt_settings,
+	enum link_training_result status)
+{
+	char *link_rate = "Unknown";
+	char *lt_result = "Unknown";
+	char *lt_spread = "Disabled";
 
+	switch (lt_settings->link_settings.link_rate) {
 	case LINK_RATE_LOW:
 		link_rate = "RBR";
 		break;
@@ -1057,13 +1108,102 @@ enum link_training_result dc_link_dp_perform_link_training(
 		break;
 	}
 
+	switch (lt_settings->link_settings.link_spread) {
+	case LINK_SPREAD_DISABLED:
+		lt_spread = "Disabled";
+		break;
+	case LINK_SPREAD_05_DOWNSPREAD_30KHZ:
+		lt_spread = "0.5% 30KHz";
+		break;
+	case LINK_SPREAD_05_DOWNSPREAD_33KHZ:
+		lt_spread = "0.5% 33KHz";
+		break;
+	default:
+		break;
+	}
+
 	/* Connectivity log: link training */
-	CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d",
-			link_rate,
-			lt_settings.link_settings.lane_count,
-			lt_result,
-			lt_settings.lane_settings[0].VOLTAGE_SWING,
-			lt_settings.lane_settings[0].PRE_EMPHASIS);
+	CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d, DS=%s",
+				link_rate,
+				lt_settings->link_settings.lane_count,
+				lt_result,
+				lt_settings->lane_settings[0].VOLTAGE_SWING,
+				lt_settings->lane_settings[0].PRE_EMPHASIS,
+				lt_spread);
+}
+
+bool dc_link_dp_perform_link_training_skip_aux(
+	struct dc_link *link,
+	const struct dc_link_settings *link_setting)
+{
+	struct link_training_settings lt_settings;
+	enum dc_dp_training_pattern pattern_for_cr = DP_TRAINING_PATTERN_SEQUENCE_1;
+
+	initialize_training_settings(link, link_setting, &lt_settings);
+
+	/* 1. Perform_clock_recovery_sequence. */
+
+	/* transmit training pattern for clock recovery */
+	dp_set_hw_training_pattern(link, pattern_for_cr);
+
+	/* call HWSS to set lane settings*/
+	dp_set_hw_lane_settings(link, &lt_settings);
+
+	/* wait receiver to lock-on*/
+	wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
+
+	/* 2. Perform_channel_equalization_sequence. */
+
+	/* transmit training pattern for channel equalization. */
+	dp_set_hw_training_pattern(link, lt_settings.pattern_for_eq);
+
+	/* call HWSS to set lane settings*/
+	dp_set_hw_lane_settings(link, &lt_settings);
+
+	/* wait receiver to lock-on. */
+	wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
+
+	/* 3. Perform_link_training_int. */
+
+	/* Mainlink output idle pattern. */
+	dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
+
+	print_status_message(link, &lt_settings, LINK_TRAINING_SUCCESS);
+
+	return true;
+}
+
+enum link_training_result dc_link_dp_perform_link_training(
+	struct dc_link *link,
+	const struct dc_link_settings *link_setting,
+	bool skip_video_pattern)
+{
+	enum link_training_result status = LINK_TRAINING_SUCCESS;
+
+	struct link_training_settings lt_settings;
+
+	initialize_training_settings(link, link_setting, &lt_settings);
+
+	/* 1. set link rate, lane count and spread. */
+	dpcd_set_link_settings(link, &lt_settings);
+
+	/* 2. perform link training (set link training done
+	 *  to false is done as well)
+	 */
+	status = perform_clock_recovery_sequence(link, &lt_settings);
+	if (status == LINK_TRAINING_SUCCESS) {
+		status = perform_channel_equalization_sequence(link,
+				&lt_settings);
+	}
+
+	if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
+		status = perform_link_training_int(link,
+				&lt_settings,
+				status);
+	}
+
+	/* 6. print status message*/
+	print_status_message(link, &lt_settings, status);
 
 	if (status != LINK_TRAINING_SUCCESS)
 		link->ctx->dc->debug_data.ltFailCount++;
@@ -1071,7 +1211,6 @@ enum link_training_result dc_link_dp_perform_link_training(
 	return status;
 }
 
-
 bool perform_link_training_with_retries(
 	struct dc_link *link,
 	const struct dc_link_settings *link_setting,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 2d019e1f6135..211fadefe2f5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -25,10 +25,11 @@ enum dc_status core_link_read_dpcd(
 	uint8_t *data,
 	uint32_t size)
 {
-	if (!dm_helpers_dp_read_dpcd(link->ctx,
-			link,
-			address, data, size))
-			return DC_ERROR_UNEXPECTED;
+	if (!link->aux_access_disabled &&
+			!dm_helpers_dp_read_dpcd(link->ctx,
+			link, address, data, size)) {
+		return DC_ERROR_UNEXPECTED;
+	}
 
 	return DC_OK;
 }
@@ -39,10 +40,11 @@ enum dc_status core_link_write_dpcd(
 	const uint8_t *data,
 	uint32_t size)
 {
-	if (!dm_helpers_dp_write_dpcd(link->ctx,
-			link,
-			address, data, size))
-				return DC_ERROR_UNEXPECTED;
+	if (!link->aux_access_disabled &&
+			!dm_helpers_dp_write_dpcd(link->ctx,
+			link, address, data, size)) {
+		return DC_ERROR_UNEXPECTED;
+	}
 
 	return DC_OK;
 }
@@ -203,21 +205,21 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal)
 
 bool dp_set_hw_training_pattern(
 	struct dc_link *link,
-	enum hw_dp_training_pattern pattern)
+	enum dc_dp_training_pattern pattern)
 {
 	enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
 
 	switch (pattern) {
-	case HW_DP_TRAINING_PATTERN_1:
+	case DP_TRAINING_PATTERN_SEQUENCE_1:
 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
 		break;
-	case HW_DP_TRAINING_PATTERN_2:
+	case DP_TRAINING_PATTERN_SEQUENCE_2:
 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
 		break;
-	case HW_DP_TRAINING_PATTERN_3:
+	case DP_TRAINING_PATTERN_SEQUENCE_3:
 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
 		break;
-	case HW_DP_TRAINING_PATTERN_4:
+	case DP_TRAINING_PATTERN_SEQUENCE_4:
 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
 		break;
 	default:
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 dfcec4d3e9c0..efa7a47f6b7e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -90,6 +90,13 @@ enum dc_post_cursor2 {
 	POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
 };
 
+enum dc_dp_training_pattern {
+	DP_TRAINING_PATTERN_SEQUENCE_1 = 0,
+	DP_TRAINING_PATTERN_SEQUENCE_2,
+	DP_TRAINING_PATTERN_SEQUENCE_3,
+	DP_TRAINING_PATTERN_SEQUENCE_4,
+};
+
 struct dc_link_settings {
 	enum dc_lane_count lane_count;
 	enum dc_link_rate link_rate;
@@ -109,6 +116,20 @@ struct dc_link_training_settings {
 	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;
+	enum dc_post_cursor2 *post_cursor2;
+
+	uint16_t *cr_pattern_time;
+	uint16_t *eq_pattern_time;
+	enum dc_dp_training_pattern *pattern_for_eq;
+
+	enum dc_link_spread *downspread;
+	bool *alternate_scrambler_reset;
+	bool *enhanced_framing;
+	bool *fec_enable;
+};
 
 union dpcd_rev {
 	struct {
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 6f0b80111e58..d6ff5af70c71 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -83,6 +83,7 @@ struct dc_link {
 	bool is_hpd_filter_disabled;
 	bool dp_ss_off;
 	bool link_state_valid;
+	bool aux_access_disabled;
 
 	/* caps is the same as reported_link_cap. link_traing use
 	 * reported_link_cap. Will clean up.  TODO
@@ -92,6 +93,7 @@ struct dc_link {
 	struct dc_link_settings cur_link_settings;
 	struct dc_lane_settings cur_lane_setting;
 	struct dc_link_settings preferred_link_setting;
+	struct dc_link_training_overrides preferred_training_settings;
 
 	uint8_t ddc_hw_inst;
 
@@ -217,6 +219,10 @@ void dc_link_dp_set_drive_settings(
 	struct dc_link *link,
 	struct link_training_settings *lt_settings);
 
+bool dc_link_dp_perform_link_training_skip_aux(
+	struct dc_link *link,
+	const struct dc_link_settings *link_setting);
+
 enum link_training_result dc_link_dp_perform_link_training(
 	struct dc_link *link,
 	const struct dc_link_settings *link_setting,
@@ -251,6 +257,11 @@ void dc_link_perform_link_training(struct dc *dc,
 void dc_link_set_preferred_link_settings(struct dc *dc,
 					 struct dc_link_settings *link_setting,
 					 struct dc_link *link);
+void dc_link_set_preferred_training_settings(struct dc *dc,
+					struct dc_link_settings *link_setting,
+					struct dc_link_training_overrides *lt_overrides,
+					struct dc_link *link,
+					bool skip_immediate_retrain);
 void dc_link_enable_hpd(const struct dc_link *link);
 void dc_link_disable_hpd(const struct dc_link *link);
 void dc_link_set_test_pattern(struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
index 30be7bb4a01a..3680846674e8 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
@@ -60,7 +60,7 @@ void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal);
 
 bool dp_set_hw_training_pattern(
 	struct dc_link *link,
-	enum hw_dp_training_pattern pattern);
+	enum dc_dp_training_pattern pattern);
 
 void dp_set_hw_lane_settings(
 	struct dc_link *link,
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 80f0d93cfd94..876b0b3e1a9c 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -71,14 +71,17 @@ enum link_training_result {
 struct link_training_settings {
 	struct dc_link_settings link_settings;
 	struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX];
-	bool allow_invalid_msa_timing_param;
-};
 
-enum hw_dp_training_pattern {
-	HW_DP_TRAINING_PATTERN_1 = 0,
-	HW_DP_TRAINING_PATTERN_2,
-	HW_DP_TRAINING_PATTERN_3,
-	HW_DP_TRAINING_PATTERN_4
+	enum dc_voltage_swing *voltage_swing;
+	enum dc_pre_emphasis *pre_emphasis;
+	enum dc_post_cursor2 *post_cursor2;
+
+	uint16_t cr_pattern_time;
+	uint16_t eq_pattern_time;
+	enum dc_dp_training_pattern pattern_for_eq;
+
+	bool enhanced_framing;
+	bool allow_invalid_msa_timing_param;
 };
 
 /*TODO: Move this enum test harness*/
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 03/87] drm/amd/display: 3.2.36
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
  2019-07-15 21:19   ` [PATCH 01/87] drm/amd/display: initialize p_state to proper value sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 02/87] drm/amd/display: Add ability to set preferred link training parameters sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 04/87] drm/amd/display: fix up HUBBUB hw programming for VM sunpeng.li-5C7GfCeVMHo
                     ` (83 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 e513028faefa..2a7f25d372e1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.35"
+#define DC_VER "3.2.36"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 04/87] drm/amd/display: fix up HUBBUB hw programming for VM
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (2 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 03/87] drm/amd/display: 3.2.36 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 05/87] drm/amd/display: fix dsc disable sunpeng.li-5C7GfCeVMHo
                     ` (82 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Anthony Koo

From: Jun Lei <jun.lei@amd.com>

[why]
Some values were not being converted or bit-shifted properly for
HW registers, causing black screen

[how]
Fix up the values before programming HW

Signed-off-by: Jun Lei <jun.lei@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 17 ++++++++---------
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h    |  4 ++--
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
index ece6e136437b..c72a9ff57f15 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -366,25 +366,24 @@ int hubbub2_init_dchub_sys_ctx(struct hubbub *hubbub,
 	struct dcn_vmid_page_table_config phys_config;
 
 	REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
-			FB_BASE, pa_config->system_aperture.fb_base);
+			FB_BASE, pa_config->system_aperture.fb_base >> 24);
 	REG_SET(DCN_VM_FB_LOCATION_TOP, 0,
-			FB_TOP, pa_config->system_aperture.fb_top);
+			FB_TOP, pa_config->system_aperture.fb_top >> 24);
 	REG_SET(DCN_VM_FB_OFFSET, 0,
-			FB_OFFSET, pa_config->system_aperture.fb_offset);
+			FB_OFFSET, pa_config->system_aperture.fb_offset >> 24);
 	REG_SET(DCN_VM_AGP_BOT, 0,
-			AGP_BOT, pa_config->system_aperture.agp_bot);
+			AGP_BOT, pa_config->system_aperture.agp_bot >> 24);
 	REG_SET(DCN_VM_AGP_TOP, 0,
-			AGP_TOP, pa_config->system_aperture.agp_top);
+			AGP_TOP, pa_config->system_aperture.agp_top >> 24);
 	REG_SET(DCN_VM_AGP_BASE, 0,
-			AGP_BASE, pa_config->system_aperture.agp_base);
+			AGP_BASE, pa_config->system_aperture.agp_base >> 24);
 
 	if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) {
-		phys_config.depth = 1;
-		phys_config.block_size = 4096;
 		phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12;
 		phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12;
 		phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
-
+		phys_config.depth = 0;
+		phys_config.block_size = 0;
 		// Init VMID 0 based on PA config
 		dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config);
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 959f5b654611..1ea505f7a05a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -61,8 +61,8 @@ enum dcn_hubbub_page_table_depth {
 };
 
 enum dcn_hubbub_page_table_block_size {
-	DCN_PAGE_TABLE_BLOCK_SIZE_4KB,
-	DCN_PAGE_TABLE_BLOCK_SIZE_64KB
+	DCN_PAGE_TABLE_BLOCK_SIZE_4KB = 0,
+	DCN_PAGE_TABLE_BLOCK_SIZE_64KB = 4
 };
 
 struct dcn_hubbub_phys_addr_config {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 05/87] drm/amd/display: fix dsc disable
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (3 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 04/87] drm/amd/display: fix up HUBBUB hw programming for VM sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 06/87] drm/amd/display: 3.2.37 sunpeng.li-5C7GfCeVMHo
                     ` (81 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Dmytro Laktyushkin, Nikola Cornij

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

A regression caused dsc to never get disabled in certain situations.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 6925d25d2457..45f9dad95644 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1715,8 +1715,11 @@ static void dcn20_reset_back_end_for_pipe(
 		else if (pipe_ctx->stream_res.audio) {
 			dc->hwss.disable_audio_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
 		}
-
 	}
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	else if (pipe_ctx->stream_res.dsc)
+		dp_set_dsc_enable(pipe_ctx, false);
+#endif
 
 	/* by upper caller loop, parent pipe: pipe0, will be reset last.
 	 * back end share by all pipes and will be disable only when disable
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 06/87] drm/amd/display: 3.2.37
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (4 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 05/87] drm/amd/display: fix dsc disable sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 07/87] drm/amd/display: move bw calc code into helpers sunpeng.li-5C7GfCeVMHo
                     ` (80 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 2a7f25d372e1..c0ebb77fab70 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.36"
+#define DC_VER "3.2.37"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 07/87] drm/amd/display: move bw calc code into helpers
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (5 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 06/87] drm/amd/display: 3.2.37 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
       [not found]     ` <20190715212049.4584-8-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
  2019-07-15 21:19   ` [PATCH 08/87] drm/amd/display: cap DCFCLK hardmin to 507 for NV10 sunpeng.li-5C7GfCeVMHo
                     ` (79 subsequent siblings)
  86 siblings, 1 reply; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Fatemeh Darbehani, Eric Yang

From: Eric Yang <Eric.Yang2@amd.com>

[Why]
For better readability and reusability

[How]
Move snippets of BW calculation code into helpers.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Fatemeh Darbehani <Fatemeh.Darbehani@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    |   1 +
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |   2 -
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 250 +++++++++++-------
 .../drm/amd/display/dc/dcn20/dcn20_resource.h |  11 +
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |   2 +
 5 files changed, 167 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 086d2f3b0db3..e9ccf41e31ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -126,6 +126,7 @@ static DEVICE_ATTR(pcie_replay_count, S_IRUGO,
 		amdgpu_device_get_pcie_replay_count, NULL);
 
 static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
+static void amdgpu_device_parse_faked_did(struct amdgpu_device *adev);
 
 /**
  * amdgpu_device_is_px - Is the device is a dGPU with HG/PX power control
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 740f5db22bb5..614a941eb9f2 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -26,8 +26,6 @@
 #include "dccg.h"
 #include "clk_mgr_internal.h"
 
-
-#include "dcn20/dcn20_clk_mgr.h"
 #include "dce100/dce_clk_mgr.h"
 #include "reg_helper.h"
 #include "core_types.h"
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 20cf98f090b0..842f48403226 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2016,15 +2016,16 @@ static bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
 }
 #endif
 
-bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
-		bool fast_validate)
+bool dcn20_fast_validate_bw(
+		struct dc *dc,
+		struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int *pipe_split_from,
+		int *vlevel_out)
 {
 	bool out = false;
 
-	BW_VAL_TRACE_SETUP();
-
 	int pipe_cnt, i, pipe_idx, vlevel, vlevel_unsplit;
-	int pipe_split_from[MAX_PIPES];
 	bool odm_capable = context->bw_ctx.dml.ip.odm_capable;
 	bool force_split = false;
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
@@ -2032,10 +2033,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 #endif
 	int split_threshold = dc->res_pool->pipe_count / 2;
 	bool avoid_split = dc->debug.pipe_split_policy != MPC_SPLIT_DYNAMIC;
-	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
-	DC_LOGGER_INIT(dc->ctx->logger);
 
-	BW_VAL_TRACE_COUNT();
 
 	ASSERT(pipes);
 	if (!pipes)
@@ -2075,7 +2073,6 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 			&context->res_ctx, pipes);
 
 	if (!pipe_cnt) {
-		BW_VAL_TRACE_SKIP(pass);
 		out = true;
 		goto validate_out;
 	}
@@ -2240,101 +2237,128 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 	}
 #endif
 
-	BW_VAL_TRACE_END_VOLTAGE_LEVEL();
+	*vlevel_out = vlevel;
 
-	if (fast_validate) {
-		BW_VAL_TRACE_SKIP(fast);
-		out = true;
-		goto validate_out;
-	}
+	out = true;
+	goto validate_out;
+
+validate_fail:
+	out = false;
+
+validate_out:
+	return out;
+}
+
+void dcn20_calculate_wm(
+		struct dc *dc, struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int *out_pipe_cnt,
+		int *pipe_split_from,
+		int vlevel)
+{
+	int pipe_cnt, i, pipe_idx;
 
 	for (i = 0, pipe_idx = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
-		if (!context->res_ctx.pipe_ctx[i].stream)
-			continue;
+			if (!context->res_ctx.pipe_ctx[i].stream)
+				continue;
 
-		pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
-		pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+			pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
+			pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.vba.RequiredDISPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
 
-		if (pipe_split_from[i] < 0) {
-			pipes[pipe_cnt].clks_cfg.dppclk_mhz =
-					context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
-			if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
-				pipes[pipe_cnt].pipe.dest.odm_combine =
-						context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
-			else
-				pipes[pipe_cnt].pipe.dest.odm_combine = 0;
-			pipe_idx++;
-		} else {
-			pipes[pipe_cnt].clks_cfg.dppclk_mhz =
-					context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
-			if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
-				pipes[pipe_cnt].pipe.dest.odm_combine =
-						context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
+			if (pipe_split_from[i] < 0) {
+				pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+						context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx];
+				if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_idx] == pipe_idx)
+					pipes[pipe_cnt].pipe.dest.odm_combine =
+							context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
+				else
+					pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+				pipe_idx++;
+			} else {
+				pipes[pipe_cnt].clks_cfg.dppclk_mhz =
+						context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_split_from[i]];
+				if (context->bw_ctx.dml.vba.BlendingAndTiming[pipe_split_from[i]] == pipe_split_from[i])
+					pipes[pipe_cnt].pipe.dest.odm_combine =
+							context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_split_from[i]];
+				else
+					pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+			}
+
+			if (dc->config.forced_clocks) {
+				pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
+				pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+			}
+
+			pipe_cnt++;
+		}
+
+		if (pipe_cnt != pipe_idx) {
+			if (dc->res_pool->funcs->populate_dml_pipes)
+				pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
+					&context->res_ctx, pipes);
 			else
-				pipes[pipe_cnt].pipe.dest.odm_combine = 0;
+				pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
+					&context->res_ctx, pipes);
 		}
-		if (dc->config.forced_clocks) {
-			pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
-			pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
+
+		*out_pipe_cnt = pipe_cnt;
+
+		pipes[0].clks_cfg.voltage = vlevel;
+		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
+		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+
+		/* only pipe 0 is read for voltage and dcf/soc clocks */
+		if (vlevel < 1) {
+			pipes[0].clks_cfg.voltage = 1;
+			pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
+			pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
 		}
-		pipe_cnt++;
-	}
+		context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+		if (vlevel < 2) {
+			pipes[0].clks_cfg.voltage = 2;
+			pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+			pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
+		}
+		context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+		if (vlevel < 3) {
+			pipes[0].clks_cfg.voltage = 3;
+			pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
+			pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
+		}
+		context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+
+		pipes[0].clks_cfg.voltage = vlevel;
+		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
+		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
+		context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+		context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
+}
+
+void dcn20_calculate_dlg_params(
+		struct dc *dc, struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt,
+		int vlevel)
+{
+	int i, pipe_idx;
 
-	if (pipe_cnt != pipe_idx) {
-		if (dc->res_pool->funcs->populate_dml_pipes)
-			pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc,
-				&context->res_ctx, pipes);
-		else
-			pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
-				&context->res_ctx, pipes);
-	}
-
-	pipes[0].clks_cfg.voltage = vlevel;
-	pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
-	pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
-
-	/* only pipe 0 is read for voltage and dcf/soc clocks */
-	if (vlevel < 1) {
-		pipes[0].clks_cfg.voltage = 1;
-		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].dcfclk_mhz;
-		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[1].socclk_mhz;
-	}
-	context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-
-	if (vlevel < 2) {
-		pipes[0].clks_cfg.voltage = 2;
-		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
-		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
-	}
-	context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-
-	if (vlevel < 3) {
-		pipes[0].clks_cfg.voltage = 3;
-		pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].dcfclk_mhz;
-		pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[2].socclk_mhz;
-	}
-	context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-
-	pipes[0].clks_cfg.voltage = vlevel;
-	pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].dcfclk_mhz;
-	pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz;
-	context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
-	context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;
 	/* Writeback MCIF_WB arbitration parameters */
 	dc->res_pool->funcs->set_mcif_arb_params(dc, context, pipes, pipe_cnt);
 
@@ -2349,7 +2373,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 							!= dm_dram_clock_change_unsupported;
 	context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
 
-	BW_VAL_TRACE_END_WATERMARKS();
+
 
 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
 		if (!context->res_ctx.pipe_ctx[i].stream)
@@ -2391,8 +2415,40 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 				pipes[pipe_idx].pipe);
 		pipe_idx++;
 	}
+}
+
+bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+		bool fast_validate)
+{
+	bool out = false;
+
+	BW_VAL_TRACE_SETUP();
+
+	int vlevel = 0;
+	int pipe_split_from[MAX_PIPES];
+	int pipe_cnt = 0;
+	display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL);
+	DC_LOGGER_INIT(dc->ctx->logger);
+
+	BW_VAL_TRACE_COUNT();
+
+	out = dcn20_fast_validate_bw(dc, context, pipes, pipe_split_from, &vlevel);
+
+	if (!out)
+		goto validate_fail;
+
+	BW_VAL_TRACE_END_VOLTAGE_LEVEL();
+
+	if (fast_validate) {
+		BW_VAL_TRACE_SKIP(fast);
+		goto validate_out;
+	}
+
+	dcn20_calculate_wm(dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel);
+	dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+
+	BW_VAL_TRACE_END_WATERMARKS();
 
-	out = true;
 	goto validate_out;
 
 validate_fail:
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
index b5a75289f444..2b3692e0c48d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
@@ -116,6 +116,17 @@ void dcn20_set_mcif_arb_params(
 		display_e2e_pipe_params_st *pipes,
 		int pipe_cnt);
 bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate);
+bool dcn20_fast_validate_bw(
+		struct dc *dc,
+		struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int *pipe_split_from,
+		int *vlevel_out);
+void dcn20_calculate_dlg_params(
+		struct dc *dc, struct dc_state *context,
+		display_e2e_pipe_params_st *pipes,
+		int pipe_cnt,
+		int vlevel);
 
 enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream);
 enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
index 0835ac041acf..3c105124dcdd 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
@@ -64,6 +64,8 @@ enum dentist_divider_range {
  ***************************************************************************************
  */
 
+/* Macros */
+
 #define TO_CLK_MGR_INTERNAL(clk_mgr)\
 	container_of(clk_mgr, struct clk_mgr_internal, base)
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 08/87] drm/amd/display: cap DCFCLK hardmin to 507 for NV10
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (6 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 07/87] drm/amd/display: move bw calc code into helpers sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 09/87] drm/amd/display: No audio endpoint for Dell MST display sunpeng.li-5C7GfCeVMHo
                     ` (78 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Eric Yang

From: Jun Lei <Jun.Lei@amd.com>

[why]
Due to limitation in SMU/PPLIB, it is not possible to know Fmax @ Vmin for DCFCLK.
This causes issues at high display configurations where extra headroom of DCFCLK
can enable P-state switching

[how]
Use existing override logic.  If override not defined, then force
min = 507

Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Eric Yang <eric.yang2@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 ++++
 1 file changed, 4 insertions(+)

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 842f48403226..d07d35a9dd0a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2704,6 +2704,10 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
 
 	if (dc->bb_overrides.min_dcfclk_mhz > 0)
 		min_dcfclk = dc->bb_overrides.min_dcfclk_mhz;
+	else
+		// Accounting for SOC/DCF relationship, we can go as high as
+		// 506Mhz in Vmin.  We need to code 507 since SMU will round down to 506.
+		min_dcfclk = 507;
 
 	for (i = 0; i < num_states; i++) {
 		int min_fclk_required_by_uclk;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 09/87] drm/amd/display: No audio endpoint for Dell MST display
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (7 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 08/87] drm/amd/display: cap DCFCLK hardmin to 507 for NV10 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 10/87] drm/amd/display: Add aux tracing log in dce sunpeng.li-5C7GfCeVMHo
                     ` (77 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Harmanprit Tatla, Aric Cyr, Anthony Koo

From: Harmanprit Tatla <harmanprit.tatla@amd.com>

[Why]
There are certain MST displays (i.e. Dell P2715Q)
that although have the MST feature set to off may still
report it is a branch device and a non-zero
value for downstream port present.
This can lead to us incorrectly classifying a
dp dongle connection as being active and
disabling the audio endpoint for the display.

[How]
Modified the placement and
condition used to assign
the is_branch_dev bit.

Signed-off-by: Harmanprit Tatla <harmanprit.tatla@amd.com>
Reviewed-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

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 3f8a8f61cd76..fca1bfc901b6 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
@@ -2369,11 +2369,18 @@ static void get_active_converter_info(
 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
 		ddc_service_set_dongle_type(link->ddc,
 				link->dpcd_caps.dongle_type);
+		link->dpcd_caps.is_branch_dev = false;
 		return;
 	}
 
 	/* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
-	link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
+	if (ds_port.fields.PORT_TYPE == DOWNSTREAM_DP) {
+		link->dpcd_caps.is_branch_dev = false;
+	}
+
+	else {
+		link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
+	}
 
 	switch (ds_port.fields.PORT_TYPE) {
 	case DOWNSTREAM_VGA:
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 10/87] drm/amd/display: Add aux tracing log in dce
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (8 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 09/87] drm/amd/display: No audio endpoint for Dell MST display sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 11/87] drm/amd/display: Update drm_dsc to reflect native 4.2.0 DSC spec sunpeng.li-5C7GfCeVMHo
                     ` (76 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Tony Cheng, Chiawen Huang

From: Chiawen Huang <chiawen.huang@amd.com>

[Why]
dce was re-arch'd, therefore adding aux tracing log into new dce

[How]
The porting from submit_channel_request/process_channel_reply of aux_engine_dce110.c

Signed-off-by: Chiawen Huang <chiawen.huang@amd.com>
Reviewed-by: Tony Cheng <tong.cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

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 bd33c47183fc..79a16942ce98 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -27,6 +27,7 @@
 #include "core_types.h"
 #include "dce_aux.h"
 #include "dce/dce_11_0_sh_mask.h"
+#include "dm_event_log.h"
 
 #define CTX \
 	aux110->base.ctx
@@ -249,6 +250,8 @@ static void submit_channel_request(
 	}
 
 	REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
+	EVENT_LOG_AUX_REQ(engine->ddc->pin_data->en, EVENT_LOG_AUX_ORIGIN_NATIVE,
+					request->action, request->address, request->length, request->data);
 }
 
 static int read_channel_reply(struct dce_aux *engine, uint32_t size,
@@ -477,9 +480,13 @@ int dce_aux_transfer_raw(struct ddc_service *ddc,
 	*operation_result = get_channel_status(aux_engine, &returned_bytes);
 
 	if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) {
-		read_channel_reply(aux_engine, payload->length,
+		int bytes_replied = 0;
+		bytes_replied = read_channel_reply(aux_engine, payload->length,
 					 payload->data, payload->reply,
 					 &status);
+		EVENT_LOG_AUX_REP(aux_engine->ddc->pin_data->en,
+					EVENT_LOG_AUX_ORIGIN_NATIVE, *payload->reply,
+					bytes_replied, payload->data);
 		res = returned_bytes;
 	} else {
 		res = -1;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 11/87] drm/amd/display: Update drm_dsc to reflect native 4.2.0 DSC spec
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (9 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 10/87] drm/amd/display: Add aux tracing log in dce sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 12/87] drm/amd/display: early return when pipe_cnt is 0 in bw validation sunpeng.li-5C7GfCeVMHo
                     ` (75 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, David Francis, Nikola Cornij

From: David Francis <David.Francis@amd.com>

[Why]
Some parts of the DSC spec relating to 4.2.0 were not reflected in
drm_dsc_compute_rc_parameters, causing unexpected config failures

[How]
Add nsl_bpg_offset and rbs_min computation

Signed-off-by: David Francis <David.Francis@amd.com>
Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c   | 73 ++++++++++++++++++-
 1 file changed, 69 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c b/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c
index 67089765780b..04c6295f296e 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c
@@ -15,6 +15,7 @@
 #define ERANGE			-1
 #define DRM_DEBUG_KMS(msg)	/* nothing */
 #define cpu_to_be16(__x) little_to_big(__x)
+#define MAX(x, y)		((x) > (y) ? (x) : (y))
 
 static unsigned short little_to_big(int data)
 {
@@ -232,6 +233,38 @@ void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload,
 }
 EXPORT_SYMBOL(drm_dsc_pps_payload_pack);
 
+static int compute_offset(struct drm_dsc_config *vdsc_cfg, int pixels_per_group,
+				int groups_per_line, int grpcnt)
+{
+	int offset = 0;
+	int grpcnt_id = DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay, pixels_per_group);
+
+	if (grpcnt <= grpcnt_id)
+		offset = DIV_ROUND_UP(grpcnt * pixels_per_group * vdsc_cfg->bits_per_pixel, 16);
+	else
+		offset = DIV_ROUND_UP(grpcnt_id * pixels_per_group * vdsc_cfg->bits_per_pixel, 16)
+			- (((grpcnt - grpcnt_id) * vdsc_cfg->slice_bpg_offset) >> 11);
+
+	if (grpcnt <= groups_per_line)
+		offset += grpcnt * vdsc_cfg->first_line_bpg_offset;
+	else
+		offset += groups_per_line * vdsc_cfg->first_line_bpg_offset
+			- (((grpcnt - groups_per_line) * vdsc_cfg->nfl_bpg_offset) >> 11);
+
+	if (vdsc_cfg->native_420) {
+		if (grpcnt <= groups_per_line)
+			offset -= (grpcnt * vdsc_cfg->nsl_bpg_offset) >> 11;
+		else if (grpcnt <= 2 * groups_per_line)
+			offset += (grpcnt - groups_per_line) * vdsc_cfg->second_line_bpg_offset
+				- ((groups_per_line * vdsc_cfg->nsl_bpg_offset) >> 11);
+		else
+			offset += (grpcnt - groups_per_line) * vdsc_cfg->second_line_bpg_offset
+				- (((grpcnt - groups_per_line) * vdsc_cfg->nsl_bpg_offset) >> 11);
+	}
+
+	return offset;
+}
+
 /**
  * drm_dsc_compute_rc_parameters() - Write rate control
  * parameters to the dsc configuration defined in
@@ -251,6 +284,7 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
 	unsigned long hrd_delay = 0;
 	unsigned long final_scale = 0;
 	unsigned long rbs_min = 0;
+	unsigned long max_offset = 0;
 
 	if (vdsc_cfg->native_420 || vdsc_cfg->native_422) {
 		/* Number of groups used to code each line of a slice */
@@ -329,6 +363,17 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
 		return -ERANGE;
 	}
 
+	if (vdsc_cfg->slice_height > 2)
+		vdsc_cfg->nsl_bpg_offset = DIV_ROUND_UP((vdsc_cfg->second_line_bpg_offset << 11),
+							(vdsc_cfg->slice_height - 1));
+	else
+		vdsc_cfg->nsl_bpg_offset = 0;
+
+	if (vdsc_cfg->nsl_bpg_offset > 65535) {
+		DRM_DEBUG_KMS("NslBpgOffset is too large for this slice height\n");
+		return -ERANGE;
+	}
+
 	/* Number of groups used to code the entire slice */
 	groups_total = groups_per_line * vdsc_cfg->slice_height;
 
@@ -348,6 +393,7 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
 		vdsc_cfg->scale_increment_interval =
 				(vdsc_cfg->final_offset * (1 << 11)) /
 				((vdsc_cfg->nfl_bpg_offset +
+				vdsc_cfg->nsl_bpg_offset +
 				vdsc_cfg->slice_bpg_offset) *
 				(final_scale - 9));
 	} else {
@@ -368,10 +414,29 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
 	 * bits/pixel (bpp) rate that is used by the encoder,
 	 * in steps of 1/16 of a bit per pixel
 	 */
-	rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset +
-		DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay *
-			     vdsc_cfg->bits_per_pixel, 16) +
-		groups_per_line * vdsc_cfg->first_line_bpg_offset;
+	if (vdsc_cfg->dsc_version_minor == 2 && (vdsc_cfg->native_420 || vdsc_cfg->native_422)) {
+
+		max_offset = compute_offset(vdsc_cfg, DSC_RC_PIXELS_PER_GROUP, groups_per_line,
+					DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay,
+						DSC_RC_PIXELS_PER_GROUP));
+
+		max_offset = MAX(max_offset,
+				compute_offset(vdsc_cfg, DSC_RC_PIXELS_PER_GROUP, groups_per_line,
+					DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay,
+						groups_per_line)));
+
+		max_offset = MAX(max_offset,
+				compute_offset(vdsc_cfg, DSC_RC_PIXELS_PER_GROUP, groups_per_line,
+					DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay,
+						groups_per_line * 2)));
+
+		rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset + max_offset;
+	} else {
+		rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset +
+			DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay *
+				     vdsc_cfg->bits_per_pixel, 16) +
+			groups_per_line * vdsc_cfg->first_line_bpg_offset;
+	}
 
 	hrd_delay = DIV_ROUND_UP((rbs_min * 16), vdsc_cfg->bits_per_pixel);
 	vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 12/87] drm/amd/display: early return when pipe_cnt is 0 in bw validation
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (10 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 11/87] drm/amd/display: Update drm_dsc to reflect native 4.2.0 DSC spec sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 13/87] drm/amd/display: Set default block_size, even in unexpected cases sunpeng.li-5C7GfCeVMHo
                     ` (74 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Tony Cheng, Eric Yang

From: Eric Yang <Eric.Yang2@amd.com>

[Why]
Unintentionally introduced behaviour change from previous refactor,
which causes clks to be 0 in no stream cases, which will cause
divide by 0.

[How]
Skip calculation of clocks when no stream. Which is the same as old
behaviour.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Tony Cheng <tong.cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 8 +++++++-
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

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 d07d35a9dd0a..022d0f38723b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2020,6 +2020,7 @@ bool dcn20_fast_validate_bw(
 		struct dc *dc,
 		struct dc_state *context,
 		display_e2e_pipe_params_st *pipes,
+		int *pipe_cnt_out,
 		int *pipe_split_from,
 		int *vlevel_out)
 {
@@ -2072,6 +2073,8 @@ bool dcn20_fast_validate_bw(
 		pipe_cnt = dcn20_populate_dml_pipes_from_context(dc,
 			&context->res_ctx, pipes);
 
+	*pipe_cnt_out = pipe_cnt;
+
 	if (!pipe_cnt) {
 		out = true;
 		goto validate_out;
@@ -2432,7 +2435,10 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 
 	BW_VAL_TRACE_COUNT();
 
-	out = dcn20_fast_validate_bw(dc, context, pipes, pipe_split_from, &vlevel);
+	out = dcn20_fast_validate_bw(dc, context, pipes, &pipe_cnt, pipe_split_from, &vlevel);
+
+	if (pipe_cnt == 0)
+		goto validate_out;
 
 	if (!out)
 		goto validate_fail;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
index 2b3692e0c48d..44f95aa0d61e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h
@@ -120,6 +120,7 @@ bool dcn20_fast_validate_bw(
 		struct dc *dc,
 		struct dc_state *context,
 		display_e2e_pipe_params_st *pipes,
+		int *pipe_cnt_out,
 		int *pipe_split_from,
 		int *vlevel_out);
 void dcn20_calculate_dlg_params(
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 13/87] drm/amd/display: Set default block_size, even in unexpected cases
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (11 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 12/87] drm/amd/display: early return when pipe_cnt is 0 in bw validation sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 14/87] drm/amd/display: Set one 4:2:0-related PPS field as recommended by DSC spec sunpeng.li-5C7GfCeVMHo
                     ` (73 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Dmytro Laktyushkin, Eric Bernstein

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

We're not expected to enter the default case, but not returning a
default value here is incorrect.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h    | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
index c72a9ff57f15..6e2dbd03f9bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -337,6 +337,7 @@ static enum dcn_hubbub_page_table_block_size page_table_block_size_to_hw(unsigne
 		break;
 	default:
 		ASSERT(false);
+		block_size = page_table_block_size;
 		break;
 	}
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index 1ea505f7a05a..9502478c4a1b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -62,7 +62,7 @@ enum dcn_hubbub_page_table_depth {
 
 enum dcn_hubbub_page_table_block_size {
 	DCN_PAGE_TABLE_BLOCK_SIZE_4KB = 0,
-	DCN_PAGE_TABLE_BLOCK_SIZE_64KB = 4
+	DCN_PAGE_TABLE_BLOCK_SIZE_64KB = 4,
 };
 
 struct dcn_hubbub_phys_addr_config {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 14/87] drm/amd/display: Set one 4:2:0-related PPS field as recommended by DSC spec
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (12 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 13/87] drm/amd/display: Set default block_size, even in unexpected cases sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 15/87] drm/amd/display: swap system aperture high/low sunpeng.li-5C7GfCeVMHo
                     ` (72 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Eric Bernstein, Nikola Cornij

From: Nikola Cornij <nikola.cornij@amd.com>

[why]
'second_line_offset_adj' was mistakenly left at zero, even though DSC spec
v1.2a recommends setting this field to 512 for 4:2:0.

[how]
Set 'second_line_offset_adj' to 512 for 4:2:0 and leave at zero otherwise

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c b/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c
index 04c6295f296e..fd1fb1653479 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c
@@ -442,6 +442,12 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
 	vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16;
 	vdsc_cfg->initial_dec_delay = hrd_delay - vdsc_cfg->initial_xmit_delay;
 
+	/* As per DSC spec v1.2a recommendation: */
+	if (vdsc_cfg->native_420)
+		vdsc_cfg->second_line_offset_adj = 512;
+	else
+		vdsc_cfg->second_line_offset_adj = 0;
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_dsc_compute_rc_parameters);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 15/87] drm/amd/display: swap system aperture high/low
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (13 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 14/87] drm/amd/display: Set one 4:2:0-related PPS field as recommended by DSC spec sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 16/87] drm/amd/display: skip retrain in dc_link_set_preferred_link_settings() if using passive dongle sunpeng.li-5C7GfCeVMHo
                     ` (71 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Yongqiang Sun

From: Jun Lei <Jun.Lei@amd.com>

[why]
Currently logical values are swapped in HW, causing
system aperture to be undefined, so VA and PA cannot co-exist

[how]
program values correctly

Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 45f9dad95644..8d3bc156de6f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1128,8 +1128,8 @@ void dcn20_enable_plane(
 
 		apt.sys_default.quad_part = 0;
 
-		apt.sys_high.quad_part = dc->vm_pa_config.system_aperture.start_addr;
-		apt.sys_low.quad_part = dc->vm_pa_config.system_aperture.end_addr;
+		apt.sys_low.quad_part = dc->vm_pa_config.system_aperture.start_addr;
+		apt.sys_high.quad_part = dc->vm_pa_config.system_aperture.end_addr;
 
 		// Program system aperture settings
 		pipe_ctx->plane_res.hubp->funcs->hubp_set_vm_system_aperture_settings(pipe_ctx->plane_res.hubp, &apt);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 16/87] drm/amd/display: skip retrain in dc_link_set_preferred_link_settings() if using passive dongle
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (14 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 15/87] drm/amd/display: swap system aperture high/low sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 17/87] drm/amd/display: Split out common HUBP registers and code sunpeng.li-5C7GfCeVMHo
                     ` (70 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Samson Tam

From: Samson Tam <Samson.Tam@amd.com>

[Why]
Fixes issue when we have a display connected using a passive
dongle and then emulate over it using a DP connection at 1 x 1.62 Ghz.
System hangs because register bus returns back 0xFFFFFFFF for all
register reads after setting register DIG_BE_CNTL in
dcn10_link_encoder_connect_dig_be_to_fe().  Hang occurs later
when trying to do a register read.

[How]
At the start of the emulation, dc_link_set_preferred_link_settings()
and dp_retrain_link_dp_test() is called, even though it is connected
using a passive dongle.

Add an extra condition in dp_retrain_link_dp_test() to check for
link->dongle_max_pix_clk > 0.  This is the only way we know if the
connection is using passive dongle so we don't retrain DP.

Signed-off-by: Samson Tam <Samson.Tam@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

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 0918c334f0e2..02a18f6aa009 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2998,8 +2998,10 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
 
 	/* Retrain with preferred link settings only relevant for
 	 * DP signal type
+	 * Check for non-DP signal or if passive dongle present
 	 */
-	if (!dc_is_dp_signal(link->connector_signal))
+	if (!dc_is_dp_signal(link->connector_signal) ||
+		link->dongle_max_pix_clk > 0)
 		return;
 
 	for (i = 0; i < MAX_PIPES; i++) {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 17/87] drm/amd/display: Split out common HUBP registers and code
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (15 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 16/87] drm/amd/display: skip retrain in dc_link_set_preferred_link_settings() if using passive dongle sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 18/87] drm/amd/display: 3.2.38 sunpeng.li-5C7GfCeVMHo
                     ` (69 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

From: Charlene Liu <charlene.liu@amd.com>

There are shared regs and code across DCN generations. Pull them out
into a shared common location.

Also, expose some dcn20 init functions.

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dce/dce_hwseq.h    |  3 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 50 ++++++++++++-------
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h | 23 ++++++---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h | 23 +++++----
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 43 +++++++++++++++-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.h    | 14 ++----
 6 files changed, 109 insertions(+), 47 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 cb0a037b1c4a..3a49f1ffb5dd 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -696,7 +696,8 @@ struct dce_hwseq_registers {
 	type D2VGA_MODE_ENABLE; \
 	type D3VGA_MODE_ENABLE; \
 	type D4VGA_MODE_ENABLE; \
-	type AZALIA_AUDIO_DTO_MODULE;
+	type AZALIA_AUDIO_DTO_MODULE;\
+	type HPO_HDMISTREAMCLK_GATE_DIS;
 
 struct dce_hwseq_shift {
 	HWSEQ_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 934bacc0c6ad..a16128814d62 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -843,7 +843,7 @@ void min_set_viewport(
 		  PRI_VIEWPORT_Y_START_C, viewport_c->y);
 }
 
-void hubp1_read_state(struct hubp *hubp)
+void hubp1_read_state_common(struct hubp *hubp)
 {
 	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	struct dcn_hubp_state *s = &hubp1->state;
@@ -859,24 +859,6 @@ void hubp1_read_state(struct hubp *hubp)
 			PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode,
 			MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode,
 			CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode);
-	REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
-		CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
-		MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
-		META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
-		MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
-		DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
-		MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
-		SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
-		PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
-	REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
-		CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
-		MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
-		META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
-		MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
-		DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
-		MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
-		SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
-		PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
 
 	/* DLG - Per hubp */
 	REG_GET_2(BLANK_OFFSET_0,
@@ -1030,8 +1012,38 @@ void hubp1_read_state(struct hubp *hubp)
 	REG_GET_2(DCN_TTU_QOS_WM,
 			QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
 			QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
+
 }
 
+void hubp1_read_state(struct hubp *hubp)
+{
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+	struct dcn_hubp_state *s = &hubp1->state;
+	struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
+
+	hubp1_read_state_common(hubp);
+
+	REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
+		CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
+		MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
+		META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
+		MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
+		DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
+		MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
+		SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
+		PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
+
+	REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
+		CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
+		MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
+		META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
+		MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
+		DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
+		MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
+		SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
+		PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
+
+}
 enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch)
 {
 	enum cursor_pitch hw_pitch;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 31c8fdd3206c..8f4bcdc74116 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -249,7 +249,8 @@
 	.field_name = reg_name ## __ ## field_name ## post_fix
 
 /* Mask/shift struct generation macro for all ASICs (including those with reduced functionality) */
-#define HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)\
+/*1.x, 2.x, and 3.x*/
+#define HUBP_MASK_SH_LIST_DCN_SHARE_COMMON(mask_sh)\
 	HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\
 	HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\
 	HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\
@@ -265,7 +266,6 @@
 	HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, MAX_COMPRESSED_FRAGS, mask_sh),\
 	HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, SW_MODE, mask_sh),\
 	HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, META_LINEAR, mask_sh),\
-	HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh),\
 	HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, PIPE_ALIGNED, mask_sh),\
 	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, PITCH, mask_sh),\
 	HUBP_SF(HUBPREQ0_DCSURF_SURFACE_PITCH, META_PITCH, mask_sh),\
@@ -372,12 +372,17 @@
 	HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\
 	HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\
 	HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh)
-
-#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
-	HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh),\
+/*2.x and 1.x only*/
+#define HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)\
+	HUBP_MASK_SH_LIST_DCN_SHARE_COMMON(mask_sh),\
+	HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh),\
 	HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\
 	HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh)
 
+/*2.x and 1.x only*/
+#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
+	HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)
+
 /* Mask/shift struct generation macro for ASICs with VM */
 #define HUBP_MASK_SH_LIST_DCN_VM(mask_sh)\
 	HUBP_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\
@@ -434,7 +439,7 @@
 	HUBP_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
 	HUBP_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
 
-#define DCN_HUBP_REG_FIELD_LIST(type) \
+#define DCN_HUBP_REG_FIELD_BASE_LIST(type) \
 	type HUBP_BLANK_EN;\
 	type HUBP_DISABLE;\
 	type HUBP_TTU_DISABLE;\
@@ -459,7 +464,6 @@
 	type ROTATION_ANGLE;\
 	type H_MIRROR_EN;\
 	type SURFACE_PIXEL_FORMAT;\
-	type ALPHA_PLANE_EN;\
 	type SURFACE_FLIP_TYPE;\
 	type SURFACE_FLIP_MODE_FOR_STEREOSYNC;\
 	type SURFACE_FLIP_IN_STEREOSYNC;\
@@ -632,6 +636,10 @@
 	type CURSOR_DST_X_OFFSET; \
 	type OUTPUT_FP
 
+#define DCN_HUBP_REG_FIELD_LIST(type) \
+	DCN_HUBP_REG_FIELD_BASE_LIST(type);\
+	type ALPHA_PLANE_EN
+
 struct dcn_mi_registers {
 	HUBP_COMMON_REG_VARIABLE_LIST;
 };
@@ -760,5 +768,6 @@ void hubp1_vready_workaround(struct hubp *hubp,
 		struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
 
 void hubp1_init(struct hubp *hubp);
+void hubp1_read_state_common(struct hubp *hubp);
 
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
index d5acc348be22..2c6405a62fc1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
@@ -72,8 +72,8 @@
 	SR(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB),\
 	SR(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB)
 
-#define HUBP_MASK_SH_LIST_DCN2_COMMON(mask_sh)\
-	HUBP_MASK_SH_LIST_DCN(mask_sh),\
+#define HUBP_MASK_SH_LIST_DCN2_SHARE_COMMON(mask_sh)\
+	HUBP_MASK_SH_LIST_DCN_SHARE_COMMON(mask_sh),\
 	HUBP_MASK_SH_LIST_DCN_VM(mask_sh),\
 	HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, ROTATION_ANGLE, mask_sh),\
 	HUBP_SF(HUBP0_DCSURF_SURFACE_CONFIG, H_MIRROR_EN, mask_sh),\
@@ -127,13 +127,21 @@
 	HUBP_SF(HUBPREQ0_DCSURF_FLIP_CONTROL2, SURFACE_TRIPLE_BUFFER_ENABLE, mask_sh),\
 	HUBP_SF(HUBPREQ0_VMID_SETTINGS_0, VMID, mask_sh)
 
+/*DCN2.x and DCN1.x*/
+#define HUBP_MASK_SH_LIST_DCN2_COMMON(mask_sh)\
+	HUBP_MASK_SH_LIST_DCN2_SHARE_COMMON(mask_sh),\
+	HUBP_SF(HUBP0_DCSURF_TILING_CONFIG, RB_ALIGNED, mask_sh),\
+	HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\
+	HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh)
+
+/*DCN2.0 specific*/
 #define HUBP_MASK_SH_LIST_DCN20(mask_sh)\
 	HUBP_MASK_SH_LIST_DCN2_COMMON(mask_sh),\
 	HUBP_SF(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, DCN_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
 	HUBP_SF(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
 	HUBP_SF(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh)
 
-
+/*DCN2.x */
 #define DCN2_HUBP_REG_COMMON_VARIABLE_LIST \
 	HUBP_COMMON_REG_VARIABLE_LIST; \
 	uint32_t DMDATA_ADDRESS_HIGH; \
@@ -149,14 +157,11 @@
 	uint32_t FLIP_PARAMETERS_2;\
 	uint32_t DCN_CUR1_TTU_CNTL0;\
 	uint32_t DCN_CUR1_TTU_CNTL1;\
-	uint32_t VMID_SETTINGS_0;\
-	uint32_t FLIP_PARAMETERS_3;\
-	uint32_t FLIP_PARAMETERS_4;\
-	uint32_t VBLANK_PARAMETERS_5;\
-	uint32_t VBLANK_PARAMETERS_6
+	uint32_t VMID_SETTINGS_0
+
 
 #define DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) \
-	DCN_HUBP_REG_FIELD_LIST(type); \
+	DCN_HUBP_REG_FIELD_BASE_LIST(type); \
 	type DMDATA_ADDRESS_HIGH;\
 	type DMDATA_MODE;\
 	type DMDATA_UPDATED;\
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 8d3bc156de6f..f820e9667e3c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -115,7 +115,7 @@ static void enable_power_gating_plane(
 	REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on);
 }
 
-static void dcn20_dccg_init(struct dce_hwseq *hws)
+void dcn20_dccg_init(struct dce_hwseq *hws)
 {
 	/*
 	 * set MICROSECOND_TIME_BASE_DIV
@@ -138,6 +138,45 @@ static void dcn20_dccg_init(struct dce_hwseq *hws)
 	/* This value is dependent on the hardware pipeline delay so set once per SOC */
 	REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x801003c);
 }
+void dcn20_display_init(struct dc *dc)
+{
+	struct dce_hwseq *hws = dc->hwseq;
+
+	/* RBBMIF
+	 * disable RBBMIF timeout detection for all clients
+	 * Ensure RBBMIF does not drop register accesses due to the per-client timeout
+	 */
+	REG_WRITE(RBBMIF_TIMEOUT_DIS, 0xFFFFFFFF);
+	REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF);
+
+	/* DCCG */
+	dcn20_dccg_init(hws);
+
+	/* Disable all memory low power mode. All memories are enabled. */
+	REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
+
+	/* DCHUB/MMHUBBUB
+	 * set global timer refclk divider
+	 * 100Mhz refclk -> 2
+	 * 27Mhz refclk ->  1
+	 * 48Mhz refclk ->  1
+	 */
+	REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
+	REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
+	REG_WRITE(REFCLK_CNTL, 0);
+
+	/* OPTC
+	 * OTG_CONTROL.OTG_DISABLE_POINT_CNTL = 0x3; will be set during optc2_enable_crtc
+	 */
+
+	/* AZ
+	 * default value is 0x64 for 100Mhz ref clock, if the ref clock is 100Mhz, no need to program this regiser,
+	 * if not, it should be programmed according to the ref clock
+	 */
+	REG_UPDATE(AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, 0x64);
+	/* Enable controller clock gating */
+	REG_WRITE(AZALIA_CONTROLLER_CLOCK_GATING, 0x1);
+}
 
 static void disable_vga(
 	struct dce_hwseq *hws)
@@ -163,7 +202,7 @@ void dcn20_program_tripleBuffer(
 }
 
 /* Blank pixel data during initialization */
-static void dcn20_init_blank(
+void dcn20_init_blank(
 		struct dc *dc,
 		struct timing_generator *tg)
 {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h
index 2b0409454073..689c2765b071 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h
@@ -91,13 +91,9 @@ void dcn20_pipe_control_lock_global(
 void dcn20_setup_gsl_group_as_lock(const struct dc *dc,
 				struct pipe_ctx *pipe_ctx,
 				bool enable);
-void dcn20_pipe_control_lock(
-	struct dc *dc,
-	struct pipe_ctx *pipe,
-	bool lock);
-void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx);
-void dcn20_enable_plane(
-	struct dc *dc,
-	struct pipe_ctx *pipe_ctx,
-	struct dc_state *context);
+void dcn20_dccg_init(struct dce_hwseq *hws);
+void dcn20_init_blank(
+	   struct dc *dc,
+	   struct timing_generator *tg);
+void dcn20_display_init(struct dc *dc);
 #endif /* __DC_HWSS_DCN20_H__ */
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 18/87] drm/amd/display: 3.2.38
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (16 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 17/87] drm/amd/display: Split out common HUBP registers and code sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 19/87] drm/amd/display: Incorrect Read Interval Time For CR Sequence sunpeng.li-5C7GfCeVMHo
                     ` (68 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 c0ebb77fab70..a307a3a1cde4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.37"
+#define DC_VER "3.2.38"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 19/87] drm/amd/display: Incorrect Read Interval Time For CR Sequence
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (17 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 18/87] drm/amd/display: 3.2.38 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 20/87] drm/amd/display: Clock does not lower in Updateplanes sunpeng.li-5C7GfCeVMHo
                     ` (67 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Tony Cheng, David Galiffi

From: David Galiffi <david.galiffi@amd.com>

[WHY]
TRAINING_AUX_RD_INTERVAL (DPCD 000Eh) modifies the read interval
for the EQ training sequence. CR read interval should remain 100 us.
Currently, the CR interval is also being modified.

[HOW]
lt_settings->cr_pattern_time should always be 100 us.

Signed-off-by: David Galiffi <David.Galiffi@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 fca1bfc901b6..4442e7b1e5b5 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
@@ -1035,7 +1035,7 @@ static void initialize_training_settings(
 	if (link->preferred_training_settings.cr_pattern_time != NULL)
 		lt_settings->cr_pattern_time = *link->preferred_training_settings.cr_pattern_time;
 	else
-		lt_settings->cr_pattern_time = get_training_aux_rd_interval(link, 100);
+		lt_settings->cr_pattern_time = 100;
 
 	if (link->preferred_training_settings.eq_pattern_time != NULL)
 		lt_settings->eq_pattern_time = *link->preferred_training_settings.eq_pattern_time;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 20/87] drm/amd/display: Clock does not lower in Updateplanes
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (18 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 19/87] drm/amd/display: Incorrect Read Interval Time For CR Sequence sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 21/87] drm/amd/display: Copy max_clks_by_state after dce_clk_mgr_construct sunpeng.li-5C7GfCeVMHo
                     ` (66 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Murton Liu, Tony Cheng

From: Murton Liu <murton.liu@amd.com>

[why]
We reset the optimized_required in atomic_plane_disable
flag immediately after it is set in atomic_plane_disconnect, causing us to
never have flag set during next flip in UpdatePlanes.

[how]
Optimize directly after each time plane is removed.

Signed-off-by: Murton Liu <murton.liu@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@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 3834979e61d0..9f08bfb7f238 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
@@ -2515,6 +2515,12 @@ static void dcn10_apply_ctx_for_surface(
 		if (removed_pipe[i])
 			dcn10_disable_plane(dc, &dc->current_state->res_ctx.pipe_ctx[i]);
 
+	for (i = 0; i < dc->res_pool->pipe_count; i++)
+		if (removed_pipe[i]) {
+			dc->hwss.optimize_bandwidth(dc, context);
+			break;
+		}
+
 	if (dc->hwseq->wa.DEGVIDCN10_254)
 		hubbub1_wm_change_req_wa(dc->res_pool->hubbub);
 }
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 21/87] drm/amd/display: Copy max_clks_by_state after dce_clk_mgr_construct
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (19 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 20/87] drm/amd/display: Clock does not lower in Updateplanes sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 22/87] drm/amd/display:Use Pixel clock in 100Hz units for HDMI Audio wall clock DTO sunpeng.li-5C7GfCeVMHo
                     ` (65 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, David Francis, Nicholas Kazlauskas

From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

[Why]
For DCE110, DCE112 and DCE120 the max_clks_by_state for the clk_mgr are
copied from their respective table before the call to
dce_clk_mgr_construct, but then dce_clk_mgr_construct overwrites
these with the dce80_max_clks_by_state.

[How]
Copy these after we call dce_clk_mgr_construct so we're using the
right tables.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: David Francis <David.Francis@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c    | 4 ++--
 .../gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c    | 4 ++--
 .../gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c    | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
index c1a92c16535c..5cc3acccda2a 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
@@ -262,12 +262,12 @@ void dce110_clk_mgr_construct(
 		struct dc_context *ctx,
 		struct clk_mgr_internal *clk_mgr)
 {
+	dce_clk_mgr_construct(ctx, clk_mgr);
+
 	memcpy(clk_mgr->max_clks_by_state,
 		dce110_max_clks_by_state,
 		sizeof(dce110_max_clks_by_state));
 
-	dce_clk_mgr_construct(ctx, clk_mgr);
-
 	clk_mgr->regs = &disp_clk_regs;
 	clk_mgr->clk_mgr_shift = &disp_clk_shift;
 	clk_mgr->clk_mgr_mask = &disp_clk_mask;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c
index 778392c73187..7c746ef1e32e 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce112/dce112_clk_mgr.c
@@ -226,12 +226,12 @@ void dce112_clk_mgr_construct(
 		struct dc_context *ctx,
 		struct clk_mgr_internal *clk_mgr)
 {
+	dce_clk_mgr_construct(ctx, clk_mgr);
+
 	memcpy(clk_mgr->max_clks_by_state,
 		dce112_max_clks_by_state,
 		sizeof(dce112_max_clks_by_state));
 
-	dce_clk_mgr_construct(ctx, clk_mgr);
-
 	clk_mgr->regs = &disp_clk_regs;
 	clk_mgr->clk_mgr_shift = &disp_clk_shift;
 	clk_mgr->clk_mgr_mask = &disp_clk_mask;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c
index 906310c3e2eb..5399b8cf6b75 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce120/dce120_clk_mgr.c
@@ -127,12 +127,12 @@ static struct clk_mgr_funcs dce120_funcs = {
 
 void dce120_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_mgr)
 {
+	dce_clk_mgr_construct(ctx, clk_mgr);
+
 	memcpy(clk_mgr->max_clks_by_state,
 		dce120_max_clks_by_state,
 		sizeof(dce120_max_clks_by_state));
 
-	dce_clk_mgr_construct(ctx, clk_mgr);
-
 	clk_mgr->base.dprefclk_khz = 600000;
 	clk_mgr->base.funcs = &dce120_funcs;
 }
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 22/87] drm/amd/display:Use Pixel clock in 100Hz units for HDMI Audio wall clock DTO
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (20 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 21/87] drm/amd/display: Copy max_clks_by_state after dce_clk_mgr_construct sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 23/87] drm/amd/display: wait for the whole frame after global unlock sunpeng.li-5C7GfCeVMHo
                     ` (64 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Nevenko Stupar

From: Nevenko Stupar <Nevenko.Stupar@amd.com>

[Why]
-Pass and use pixel clock in 100 Hz to Audio for HDMI
audio DTO for Audio wall clock programming so audio DTO gets
increased precision for timings with /1001 factor.
-For HDMI TMDS for N and CTS ACR tables are based on 10 KHz
units, these does not need to be modified as N and CTS values
are still valid using current tables.

Signed-off-by: Nevenko Stupar <Nevenko.Stupar@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dce/dce_audio.c    | 28 ++++++++---------
 .../amd/display/dc/dce/dce_stream_encoder.c   | 30 +++++++++----------
 .../display/dc/dce110/dce110_hw_sequencer.c   | 22 +++++++-------
 .../display/dc/dcn10/dcn10_stream_encoder.c   | 30 +++++++++----------
 .../display/dc/dcn10/dcn10_stream_encoder.h   |  4 +--
 .../gpu/drm/amd/display/include/audio_types.h |  4 +--
 6 files changed, 59 insertions(+), 59 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 d43d5d924c19..ad7bc7d44268 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -143,20 +143,20 @@ static void check_audio_bandwidth_hdmi(
 	if (channel_count > 2) {
 
 		/* Based on HDMI spec 1.3 Table 7.5 */
-		if ((crtc_info->requested_pixel_clock <= 27000) &&
+		if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
 		(crtc_info->v_active <= 576) &&
 		!(crtc_info->interlaced) &&
 		!(crtc_info->pixel_repetition == 2 ||
 		crtc_info->pixel_repetition == 4)) {
 			limit_freq_to_48_khz = true;
 
-		} else if ((crtc_info->requested_pixel_clock <= 27000) &&
+		} else if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
 				(crtc_info->v_active <= 576) &&
 				(crtc_info->interlaced) &&
 				(crtc_info->pixel_repetition == 2)) {
 			limit_freq_to_88_2_khz = true;
 
-		} else if ((crtc_info->requested_pixel_clock <= 54000) &&
+		} else if ((crtc_info->requested_pixel_clock_100Hz <= 540000) &&
 				(crtc_info->v_active <= 576) &&
 				!(crtc_info->interlaced)) {
 			limit_freq_to_174_4_khz = true;
@@ -735,8 +735,8 @@ void dce_aud_az_configure(
 
 /* search pixel clock value for Azalia HDMI Audio */
 static void get_azalia_clock_info_hdmi(
-	uint32_t crtc_pixel_clock_in_khz,
-	uint32_t actual_pixel_clock_in_khz,
+	uint32_t crtc_pixel_clock_100hz,
+	uint32_t actual_pixel_clock_100Hz,
 	struct azalia_clock_info *azalia_clock_info)
 {
 	/* audio_dto_phase= 24 * 10,000;
@@ -747,11 +747,11 @@ static void get_azalia_clock_info_hdmi(
 	/* audio_dto_module = PCLKFrequency * 10,000;
 	 *  [khz] -> [100Hz] */
 	azalia_clock_info->audio_dto_module =
-			actual_pixel_clock_in_khz * 10;
+			actual_pixel_clock_100Hz;
 }
 
 static void get_azalia_clock_info_dp(
-	uint32_t requested_pixel_clock_in_khz,
+	uint32_t requested_pixel_clock_100Hz,
 	const struct audio_pll_info *pll_info,
 	struct azalia_clock_info *azalia_clock_info)
 {
@@ -790,15 +790,15 @@ void dce_aud_wall_dto_setup(
 
 		/* calculate DTO settings */
 		get_azalia_clock_info_hdmi(
-			crtc_info->requested_pixel_clock,
-			crtc_info->calculated_pixel_clock,
+			crtc_info->requested_pixel_clock_100Hz,
+			crtc_info->calculated_pixel_clock_100Hz,
 			&clock_info);
 
-		DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock = %d"\
-				"calculated_pixel_clock =%d\n"\
+		DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
+				"calculated_pixel_clock_100Hz =%d\n"\
 				"audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
-				crtc_info->requested_pixel_clock,\
-				crtc_info->calculated_pixel_clock,\
+				crtc_info->requested_pixel_clock_100Hz,\
+				crtc_info->calculated_pixel_clock_100Hz,\
 				clock_info.audio_dto_module,\
 				clock_info.audio_dto_phase);
 
@@ -831,7 +831,7 @@ void dce_aud_wall_dto_setup(
 
 		calculate DTO settings */
 		get_azalia_clock_info_dp(
-			crtc_info->requested_pixel_clock,
+			crtc_info->requested_pixel_clock_100Hz,
 			pll_info,
 			&clock_info);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
index 3690ca957282..fb2fd141e16a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
@@ -1249,13 +1249,13 @@ static uint32_t calc_max_audio_packets_per_line(
 
 static void get_audio_clock_info(
 	enum dc_color_depth color_depth,
-	uint32_t crtc_pixel_clock_in_khz,
-	uint32_t actual_pixel_clock_in_khz,
+	uint32_t crtc_pixel_clock_100Hz,
+	uint32_t actual_pixel_clock_100Hz,
 	struct audio_clock_info *audio_clock_info)
 {
 	const struct audio_clock_info *clock_info;
 	uint32_t index;
-	uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_in_khz / 10;
+	uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_100Hz / 100;
 	uint32_t audio_array_size;
 
 	switch (color_depth) {
@@ -1292,16 +1292,16 @@ static void get_audio_clock_info(
 	}
 
 	/* not found */
-	if (actual_pixel_clock_in_khz == 0)
-		actual_pixel_clock_in_khz = crtc_pixel_clock_in_khz;
+	if (actual_pixel_clock_100Hz == 0)
+		actual_pixel_clock_100Hz = crtc_pixel_clock_100Hz;
 
 	/* See HDMI spec  the table entry under
 	 *  pixel clock of "Other". */
 	audio_clock_info->pixel_clock_in_10khz =
-			actual_pixel_clock_in_khz / 10;
-	audio_clock_info->cts_32khz = actual_pixel_clock_in_khz;
-	audio_clock_info->cts_44khz = actual_pixel_clock_in_khz;
-	audio_clock_info->cts_48khz = actual_pixel_clock_in_khz;
+			actual_pixel_clock_100Hz / 100;
+	audio_clock_info->cts_32khz = actual_pixel_clock_100Hz / 10;
+	audio_clock_info->cts_44khz = actual_pixel_clock_100Hz / 10;
+	audio_clock_info->cts_48khz = actual_pixel_clock_100Hz / 10;
 
 	audio_clock_info->n_32khz = 4096;
 	audio_clock_info->n_44khz = 6272;
@@ -1367,14 +1367,14 @@ static void dce110_se_setup_hdmi_audio(
 
 	/* Program audio clock sample/regeneration parameters */
 	get_audio_clock_info(crtc_info->color_depth,
-			     crtc_info->requested_pixel_clock,
-			     crtc_info->calculated_pixel_clock,
+			     crtc_info->requested_pixel_clock_100Hz,
+			     crtc_info->calculated_pixel_clock_100Hz,
 			     &audio_clock_info);
 	DC_LOG_HW_AUDIO(
-			"\n%s:Input::requested_pixel_clock = %d"	\
-			"calculated_pixel_clock = %d \n", __func__,	\
-			crtc_info->requested_pixel_clock,		\
-			crtc_info->calculated_pixel_clock);
+			"\n%s:Input::requested_pixel_clock_100Hz = %d"	\
+			"calculated_pixel_clock_100Hz = %d \n", __func__,	\
+			crtc_info->requested_pixel_clock_100Hz,		\
+			crtc_info->calculated_pixel_clock_100Hz);
 
 	/* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
 	REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 84d90b475e2a..6fa1f6b5375b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -1159,27 +1159,27 @@ static void build_audio_output(
 			stream->timing.flags.INTERLACE;
 
 	audio_output->crtc_info.refresh_rate =
-		(stream->timing.pix_clk_100hz*10000)/
+		(stream->timing.pix_clk_100hz*100)/
 		(stream->timing.h_total*stream->timing.v_total);
 
 	audio_output->crtc_info.color_depth =
 		stream->timing.display_color_depth;
 
-	audio_output->crtc_info.requested_pixel_clock =
-			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
+	audio_output->crtc_info.requested_pixel_clock_100Hz =
+			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
 
-	audio_output->crtc_info.calculated_pixel_clock =
-			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
+	audio_output->crtc_info.calculated_pixel_clock_100Hz =
+			pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz;
 
 /*for HDMI, audio ACR is with deep color ratio factor*/
 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal) &&
-		audio_output->crtc_info.requested_pixel_clock ==
-				(stream->timing.pix_clk_100hz / 10)) {
+		audio_output->crtc_info.requested_pixel_clock_100Hz ==
+				(stream->timing.pix_clk_100hz)) {
 		if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
-			audio_output->crtc_info.requested_pixel_clock =
-					audio_output->crtc_info.requested_pixel_clock/2;
-			audio_output->crtc_info.calculated_pixel_clock =
-					pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/20;
+			audio_output->crtc_info.requested_pixel_clock_100Hz =
+					audio_output->crtc_info.requested_pixel_clock_100Hz/2;
+			audio_output->crtc_info.calculated_pixel_clock_100Hz =
+					pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2;
 
 		}
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
index 2d15ae664226..64adb9fb300c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
@@ -1195,13 +1195,13 @@ static union audio_cea_channels speakers_to_channels(
 
 void get_audio_clock_info(
 	enum dc_color_depth color_depth,
-	uint32_t crtc_pixel_clock_in_khz,
-	uint32_t actual_pixel_clock_in_khz,
+	uint32_t crtc_pixel_clock_100Hz,
+	uint32_t actual_pixel_clock_100Hz,
 	struct audio_clock_info *audio_clock_info)
 {
 	const struct audio_clock_info *clock_info;
 	uint32_t index;
-	uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_in_khz / 10;
+	uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_100Hz / 100;
 	uint32_t audio_array_size;
 
 	switch (color_depth) {
@@ -1238,16 +1238,16 @@ void get_audio_clock_info(
 	}
 
 	/* not found */
-	if (actual_pixel_clock_in_khz == 0)
-		actual_pixel_clock_in_khz = crtc_pixel_clock_in_khz;
+	if (actual_pixel_clock_100Hz == 0)
+		actual_pixel_clock_100Hz = crtc_pixel_clock_100Hz;
 
 	/* See HDMI spec  the table entry under
 	 *  pixel clock of "Other". */
 	audio_clock_info->pixel_clock_in_10khz =
-			actual_pixel_clock_in_khz / 10;
-	audio_clock_info->cts_32khz = actual_pixel_clock_in_khz;
-	audio_clock_info->cts_44khz = actual_pixel_clock_in_khz;
-	audio_clock_info->cts_48khz = actual_pixel_clock_in_khz;
+			actual_pixel_clock_100Hz / 100;
+	audio_clock_info->cts_32khz = actual_pixel_clock_100Hz / 10;
+	audio_clock_info->cts_44khz = actual_pixel_clock_100Hz / 10;
+	audio_clock_info->cts_48khz = actual_pixel_clock_100Hz / 10;
 
 	audio_clock_info->n_32khz = 4096;
 	audio_clock_info->n_44khz = 6272;
@@ -1307,14 +1307,14 @@ static void enc1_se_setup_hdmi_audio(
 
 	/* Program audio clock sample/regeneration parameters */
 	get_audio_clock_info(crtc_info->color_depth,
-			     crtc_info->requested_pixel_clock,
-			     crtc_info->calculated_pixel_clock,
+			     crtc_info->requested_pixel_clock_100Hz,
+			     crtc_info->calculated_pixel_clock_100Hz,
 			     &audio_clock_info);
 	DC_LOG_HW_AUDIO(
-			"\n%s:Input::requested_pixel_clock = %d"	\
-			"calculated_pixel_clock = %d \n", __func__,	\
-			crtc_info->requested_pixel_clock,		\
-			crtc_info->calculated_pixel_clock);
+			"\n%s:Input::requested_pixel_clock_100Hz = %d"	\
+			"calculated_pixel_clock_100Hz = %d \n", __func__,	\
+			crtc_info->requested_pixel_clock_100Hz,		\
+			crtc_info->calculated_pixel_clock_100Hz);
 
 	/* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
 	REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
index bc2b4af9543b..075e49c1283a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -605,8 +605,8 @@ void enc1_se_enable_dp_audio(
 
 void get_audio_clock_info(
 	enum dc_color_depth color_depth,
-	uint32_t crtc_pixel_clock_in_khz,
-	uint32_t actual_pixel_clock_in_khz,
+	uint32_t crtc_pixel_clock_100Hz,
+	uint32_t actual_pixel_clock_100Hz,
 	struct audio_clock_info *audio_clock_info);
 
 #endif /* __DC_STREAM_ENCODER_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/include/audio_types.h b/drivers/gpu/drm/amd/display/include/audio_types.h
index 6364fbc24cfe..66a54da0641c 100644
--- a/drivers/gpu/drm/amd/display/include/audio_types.h
+++ b/drivers/gpu/drm/amd/display/include/audio_types.h
@@ -38,8 +38,8 @@ struct audio_crtc_info {
 	uint32_t h_active;
 	uint32_t v_active;
 	uint32_t pixel_repetition;
-	uint32_t requested_pixel_clock; /* in KHz */
-	uint32_t calculated_pixel_clock; /* in KHz */
+	uint32_t requested_pixel_clock_100Hz; /* in 100Hz */
+	uint32_t calculated_pixel_clock_100Hz; /* in 100Hz */
 	uint32_t refresh_rate;
 	enum dc_color_depth color_depth;
 	bool interlaced;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 23/87] drm/amd/display: wait for the whole frame after global unlock
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (21 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 22/87] drm/amd/display:Use Pixel clock in 100Hz units for HDMI Audio wall clock DTO sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 24/87] drm/amd/display: refactor dump_clk_registers sunpeng.li-5C7GfCeVMHo
                     ` (63 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Wenjing Liu

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

[why]
The current code will not wait for the entire frame
 after global unlock.
This causes dsc dynamic target bpp update corruption when
there is a surface update immediately happens after this.

[how]
Wait for the entire whole frame after unlock before continuing
the rest of stream and surface update.

Signed-off-by: Wenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index f820e9667e3c..7c08f81000c5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1256,6 +1256,8 @@ void dcn20_pipe_control_lock_global(
 				CRTC_STATE_VACTIVE);
 		pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg,
 				CRTC_STATE_VBLANK);
+		pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg,
+				CRTC_STATE_VACTIVE);
 		pipe->stream_res.tg->funcs->lock_doublebuffer_disable(
 				pipe->stream_res.tg);
 	}
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 24/87] drm/amd/display: refactor dump_clk_registers
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (22 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 23/87] drm/amd/display: wait for the whole frame after global unlock sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 25/87] drm/amd/display: add hdmi2.1 dsc pps packet programming sunpeng.li-5C7GfCeVMHo
                     ` (62 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Tony Cheng, Su Sung Chung

From: Su Sung Chung <Su.Chung@amd.com>

[why]
for 2 purposes:

1. get raw register value dumped on the log, which will make it easier
to talk to other team who only knows about the register

2. enable other HW to be able to use the same interface as raven to log
clock register data

Signed-off-by: Su Sung Chung <Su.Chung@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c | 2 +-
 drivers/gpu/drm/amd/display/dc/dm_services.h                    | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
index 6e47444109d7..7f4766e45dff 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c
@@ -45,7 +45,7 @@
 #include "dcn10_cm_common.h"
 #include "clk_mgr.h"
 
-static unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...)
+unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...)
 {
 	unsigned int ret_vsnprintf;
 	unsigned int chars_printed;
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h
index b426ba02b793..1a0429744630 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services.h
@@ -151,6 +151,7 @@ void generic_reg_wait(const struct dc_context *ctx,
 	unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
 	const char *func_name, int line);
 
+unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...);
 
 /* These macros need to be used with soc15 registers in order to retrieve
  * the actual offset.
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 25/87] drm/amd/display: add hdmi2.1 dsc pps packet programming
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (23 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 24/87] drm/amd/display: refactor dump_clk_registers sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 26/87] drm/amd/display: add monitor patch to add T7 delay sunpeng.li-5C7GfCeVMHo
                     ` (61 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

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

This change adds EMP packet programming for enabling dsc with
hdmi. The packets are structured according to VESA HDMI 2.1x
r2 spec, section 10.10.2.2.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c      | 14 +++++++-------
 drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 13 ++++++-------
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |  3 ++-
 drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h    |  1 +
 4 files changed, 16 insertions(+), 15 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 02a18f6aa009..1e051e953610 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2769,10 +2769,10 @@ void core_link_enable_stream(
 			allocate_mst_payload(pipe_ctx);
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-		if (pipe_ctx->stream->timing.flags.DSC &&
-				(dc_is_dp_signal(pipe_ctx->stream->signal) ||
-				dc_is_virtual_signal(pipe_ctx->stream->signal))) {
-			dp_set_dsc_enable(pipe_ctx, true);
+		if (pipe_ctx->stream->timing.flags.DSC) {
+			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
+					dc_is_virtual_signal(pipe_ctx->stream->signal))
+				dp_set_dsc_enable(pipe_ctx, true);
 			pipe_ctx->stream_res.tg->funcs->wait_for_state(
 					pipe_ctx->stream_res.tg,
 					CRTC_STATE_VBLANK);
@@ -2833,9 +2833,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
 
 	disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal);
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	if (pipe_ctx->stream->timing.flags.DSC &&
-			dc_is_dp_signal(pipe_ctx->stream->signal)) {
-		dp_set_dsc_enable(pipe_ctx, false);
+	if (pipe_ctx->stream->timing.flags.DSC) {
+		if (dc_is_dp_signal(pipe_ctx->stream->signal))
+			dp_set_dsc_enable(pipe_ctx, false);
 	}
 #endif
 }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 211fadefe2f5..46257f0fcbe7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -396,7 +396,7 @@ static bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
 
 /* This has to be done after DSC was enabled on RX first, i.e. after dp_enable_dsc_on_rx() had been called
  */
-static void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
+void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
 	struct dc *core_dc = pipe_ctx->stream->ctx->dc;
@@ -435,7 +435,7 @@ static void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 
 		dsc_optc_config_log(dsc, &dsc_optc_cfg);
 		/* Enable DSC in encoder */
-		if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment) && pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config)
+		if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
 			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
 									optc_dsc_mode,
 									dsc_optc_cfg.bytes_per_pixel,
@@ -454,11 +454,10 @@ static void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 				OPTC_DSC_DISABLED, 0, 0);
 
 		/* disable DSC in stream encoder */
-		if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
+		if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment))
 			pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
 					pipe_ctx->stream_res.stream_enc,
 					OPTC_DSC_DISABLED, 0, 0, NULL);
-		}
 
 		/* disable DSC block */
 		pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
@@ -479,12 +478,12 @@ bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
 
 	if (enable) {
 		if (dp_set_dsc_on_rx(pipe_ctx, true)) {
-			dp_set_dsc_on_stream(pipe_ctx, true);
+			set_dsc_on_stream(pipe_ctx, true);
 			result = true;
 		}
 	} else {
 		dp_set_dsc_on_rx(pipe_ctx, false);
-		dp_set_dsc_on_stream(pipe_ctx, false);
+		set_dsc_on_stream(pipe_ctx, false);
 		result = true;
 	}
 out:
@@ -500,7 +499,7 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
 	if (!dsc)
 		return false;
 
-	dp_set_dsc_on_stream(pipe_ctx, true);
+	set_dsc_on_stream(pipe_ctx, true);
 	return true;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 7c08f81000c5..db57c2a99a15 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1758,8 +1758,9 @@ static void dcn20_reset_back_end_for_pipe(
 		}
 	}
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	else if (pipe_ctx->stream_res.dsc)
+	else if (pipe_ctx->stream_res.dsc) {
 		dp_set_dsc_enable(pipe_ctx, false);
+	}
 #endif
 
 	/* by upper caller loop, parent pipe: pipe0, will be reset last.
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 2d95eff94239..c5293f9508fa 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
@@ -66,6 +66,7 @@ void dp_enable_mst_on_sink(struct dc_link *link, bool enable);
 void dp_set_fec_ready(struct dc_link *link, bool ready);
 void dp_set_fec_enable(struct dc_link *link, bool enable);
 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
+void set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
 #endif
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 26/87] drm/amd/display: add monitor patch to add T7 delay
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (24 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 25/87] drm/amd/display: add hdmi2.1 dsc pps packet programming sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 27/87] drm/amd/display: Poll for GPUVM context ready sunpeng.li-5C7GfCeVMHo
                     ` (60 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Anthony Koo

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

[Why]
Specifically to one panel,
TCON is able to accept active video signal quickly, but
the Source Driver requires 2-3 frames of extra time.

It is a Panel issue since TCON needs to take care of
all Sink requirements including Source Driver. But in
this case it does not.

Customer is asking to add fixed T7 delay as panel
workaround.

[How]
Add monitor specific patch to add T7 delay

Signed-off-by: Anthony Koo <anthony.koo@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 4 ++++
 drivers/gpu/drm/amd/display/dc/dc_types.h          | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 46257f0fcbe7..878f47b59d5a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -162,6 +162,10 @@ bool edp_receiver_ready_T7(struct dc_link *link)
 			break;
 		udelay(25); //MAx T7 is 50ms
 	} while (++tries < 300);
+
+	if (link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
+		udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
+
 	return result;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 6eabb6491a3d..ce6d73d21cca 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -202,6 +202,7 @@ struct dc_panel_patch {
 	unsigned int dppowerup_delay;
 	unsigned int extra_t12_ms;
 	unsigned int extra_delay_backlight_off;
+	unsigned int extra_t7_ms;
 };
 
 struct dc_edid_caps {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 27/87] drm/amd/display: Poll for GPUVM context ready
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (25 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 26/87] drm/amd/display: add monitor patch to add T7 delay sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 28/87] drm/amd/display: add functionality to grab DPRX CRC entries sunpeng.li-5C7GfCeVMHo
                     ` (59 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Julian Parkin

From: Julian Parkin <julian.parkin@amd.com>

[Why]
Hardware docs state that we must wait until the GPUVM context is ready
after programming it.

[How]
Poll until the valid bit of PAGE_TABLE_BASE_ADDR_LO32 is set to 1 after
programming it.

Signed-off-by: Julian Parkin <julian.parkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_vmid.c | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_vmid.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_vmid.c
index 27679ef6ebe8..84512e646f87 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_vmid.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_vmid.c
@@ -36,6 +36,38 @@
 #define FN(reg_name, field_name) \
 	vmid->shifts->field_name, vmid->masks->field_name
 
+static void dcn20_wait_for_vmid_ready(struct dcn20_vmid *vmid)
+{
+	/* According the hardware spec, we need to poll for the lowest
+	 * bit of PAGE_TABLE_BASE_ADDR_LO32 = 1 any time a GPUVM
+	 * context is updated. We can't use REG_WAIT here since we
+	 * don't have a seperate field to wait on.
+	 *
+	 * TODO: Confirm timeout / poll interval with hardware team
+	 */
+
+	int max_times = 10000;
+	int delay_us  = 5;
+	int i;
+
+	for (i = 0; i < max_times; ++i) {
+		uint32_t entry_lo32;
+
+		REG_GET(PAGE_TABLE_BASE_ADDR_LO32,
+			VM_CONTEXT0_PAGE_DIRECTORY_ENTRY_LO32,
+			&entry_lo32);
+
+		if (entry_lo32 & 0x1)
+			return;
+
+		udelay(delay_us);
+	}
+
+	/* VM setup timed out */
+	DC_LOG_WARNING("Timeout while waiting for GPUVM context update\n");
+	ASSERT(0);
+}
+
 void dcn20_vmid_setup(struct dcn20_vmid *vmid, const struct dcn_vmid_page_table_config *config)
 {
 	REG_SET(PAGE_TABLE_START_ADDR_HI32, 0,
@@ -54,6 +86,9 @@ void dcn20_vmid_setup(struct dcn20_vmid *vmid, const struct dcn_vmid_page_table_
 
 	REG_SET(PAGE_TABLE_BASE_ADDR_HI32, 0,
 			VM_CONTEXT0_PAGE_DIRECTORY_ENTRY_HI32, (config->page_table_base_addr >> 32) & 0xFFFFFFFF);
+	/* Note: per hardware spec PAGE_TABLE_BASE_ADDR_LO32 must be programmed last in sequence */
 	REG_SET(PAGE_TABLE_BASE_ADDR_LO32, 0,
 			VM_CONTEXT0_PAGE_DIRECTORY_ENTRY_LO32, config->page_table_base_addr & 0xFFFFFFFF);
+
+	dcn20_wait_for_vmid_ready(vmid);
 }
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 28/87] drm/amd/display: add functionality to grab DPRX CRC entries.
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (26 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 27/87] drm/amd/display: Poll for GPUVM context ready sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 29/87] drm/amd/display: add functionality to get pipe CRC source sunpeng.li-5C7GfCeVMHo
                     ` (58 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Harry Wentland, Dingchen Zhang

From: Dingchen Zhang <dingchen.zhang@amd.com>

[Why]
We need to compare DPRX CRCs with framebuffer CRCs for digital bypass mode.

[How]
Hook into DRM to grab DP receiver CRCs through drm_dp_start_crc.

Signed-off-by: Dingchen Zhang <dingchen.zhang@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 17 ++--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 16 +---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 91 ++++++++++++++-----
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 56 ++++++++++++
 4 files changed, 136 insertions(+), 44 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h

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 9ef785497eb5..b2e2ca657998 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3736,7 +3736,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
 	state->abm_level = cur->abm_level;
 	state->vrr_supported = cur->vrr_supported;
 	state->freesync_config = cur->freesync_config;
-	state->crc_enabled = cur->crc_enabled;
+	state->crc_src = cur->crc_src;
 	state->cm_has_degamma = cur->cm_has_degamma;
 	state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb;
 
@@ -5936,6 +5936,7 @@ static void amdgpu_dm_enable_crtc_interrupts(struct drm_device *dev,
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 	int i;
+	enum amdgpu_dm_pipe_crc_source source;
 
 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
 				      new_crtc_state, i) {
@@ -5961,9 +5962,13 @@ static void amdgpu_dm_enable_crtc_interrupts(struct drm_device *dev,
 
 #ifdef CONFIG_DEBUG_FS
 		/* The stream has changed so CRC capture needs to re-enabled. */
-		if (dm_new_crtc_state->crc_enabled) {
-			dm_new_crtc_state->crc_enabled = false;
-			amdgpu_dm_crtc_set_crc_source(crtc, "auto");
+		source = dm_new_crtc_state->crc_src;
+		if (amdgpu_dm_is_valid_crc_source(source)) {
+			dm_new_crtc_state->crc_src = AMDGPU_DM_PIPE_CRC_SOURCE_NONE;
+			if (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC)
+				amdgpu_dm_crtc_set_crc_source(crtc, "crtc");
+			else if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX)
+				amdgpu_dm_crtc_set_crc_source(crtc, "dprx");
 		}
 #endif
 	}
@@ -6019,7 +6024,7 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
 			 * Drop the extra vblank reference added by CRC
 			 * capture if applicable.
 			 */
-			if (dm_new_crtc_state->crc_enabled)
+			if (amdgpu_dm_is_valid_crc_source(dm_new_crtc_state->crc_src))
 				drm_crtc_vblank_put(crtc);
 
 			/*
@@ -6027,7 +6032,7 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
 			 * still a stream for the CRTC.
 			 */
 			if (!dm_new_crtc_state->stream)
-				dm_new_crtc_state->crc_enabled = false;
+				dm_new_crtc_state->crc_src = AMDGPU_DM_PIPE_CRC_SOURCE_NONE;
 
 			manage_dm_interrupts(adev, acrtc, false);
 		}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index c7cd0cd4a85c..da48a857949f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -47,6 +47,7 @@
 
 #include "irq_types.h"
 #include "signal_types.h"
+#include "amdgpu_dm_crc.h"
 
 /* Forward declarations */
 struct amdgpu_device;
@@ -310,7 +311,7 @@ struct dm_crtc_state {
 	bool interrupts_enabled;
 
 	int crc_skip_count;
-	bool crc_enabled;
+	enum amdgpu_dm_pipe_crc_source crc_src;
 
 	bool freesync_timing_changed;
 	bool freesync_vrr_info_changed;
@@ -378,19 +379,6 @@ void dm_restore_drm_connector_state(struct drm_device *dev,
 void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 					struct edid *edid);
 
-/* amdgpu_dm_crc.c */
-#ifdef CONFIG_DEBUG_FS
-int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name);
-int amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc,
-				     const char *src_name,
-				     size_t *values_cnt);
-void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc);
-#else
-#define amdgpu_dm_crtc_set_crc_source NULL
-#define amdgpu_dm_crtc_verify_crc_source NULL
-#define amdgpu_dm_crtc_handle_crc_irq(x)
-#endif
-
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index a10e3a50d9ef..5293045b0164 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -29,19 +29,14 @@
 #include "amdgpu_dm.h"
 #include "dc.h"
 
-enum amdgpu_dm_pipe_crc_source {
-	AMDGPU_DM_PIPE_CRC_SOURCE_NONE = 0,
-	AMDGPU_DM_PIPE_CRC_SOURCE_AUTO,
-	AMDGPU_DM_PIPE_CRC_SOURCE_MAX,
-	AMDGPU_DM_PIPE_CRC_SOURCE_INVALID = -1,
-};
-
 static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
 {
 	if (!source || !strcmp(source, "none"))
 		return AMDGPU_DM_PIPE_CRC_SOURCE_NONE;
-	if (!strcmp(source, "auto"))
-		return AMDGPU_DM_PIPE_CRC_SOURCE_AUTO;
+	if (!strcmp(source, "auto") || !strcmp(source, "crtc"))
+		return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC;
+	if (!strcmp(source, "dprx"))
+		return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX;
 
 	return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID;
 }
@@ -67,7 +62,10 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 	struct amdgpu_device *adev = crtc->dev->dev_private;
 	struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
 	struct dc_stream_state *stream_state = crtc_state->stream;
-	bool enable;
+	struct amdgpu_dm_connector *aconn;
+	struct drm_dp_aux *aux = NULL;
+	bool enable = false;
+	bool enabled = false;
 
 	enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
 
@@ -82,13 +80,42 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 		return -EINVAL;
 	}
 
-	enable = (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO);
+	enable = amdgpu_dm_is_valid_crc_source(source);
 
 	mutex_lock(&adev->dm.dc_lock);
-	if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
-				     enable, enable)) {
-		mutex_unlock(&adev->dm.dc_lock);
-		return -EINVAL;
+	/*
+	 * USER REQ SRC | CURRENT SRC | BEHAVIOR
+	 * -----------------------------
+	 * None         | None        | Do nothing
+	 * None         | CRTC        | Disable CRTC CRC
+	 * None         | DPRX        | Disable DPRX CRC, need 'aux'
+	 * CRTC         | XXXX        | Enable CRTC CRC, configure DC strm
+	 * DPRX         | XXXX        | Enable DPRX CRC, need 'aux'
+	 */
+	if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX ||
+		(source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE &&
+		 crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX)) {
+		aconn = stream_state->link->priv;
+
+		if (!aconn) {
+			DRM_DEBUG_DRIVER("No amd connector matching CRTC-%d\n", crtc->index);
+			mutex_unlock(&adev->dm.dc_lock);
+			return -EINVAL;
+		}
+
+		aux = &aconn->dm_dp_aux.aux;
+
+		if (!aux) {
+			DRM_DEBUG_DRIVER("No dp aux for amd connector\n");
+			mutex_unlock(&adev->dm.dc_lock);
+			return -EINVAL;
+		}
+	} else if (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) {
+		if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
+					     enable, enable)) {
+			mutex_unlock(&adev->dm.dc_lock);
+			return -EINVAL;
+		}
 	}
 
 	/* When enabling CRC, we should also disable dithering. */
@@ -102,12 +129,26 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 	 * Reading the CRC requires the vblank interrupt handler to be
 	 * enabled. Keep a reference until CRC capture stops.
 	 */
-	if (!crtc_state->crc_enabled && enable)
+	enabled = amdgpu_dm_is_valid_crc_source(crtc_state->crc_src);
+	if (!enabled && enable) {
 		drm_crtc_vblank_get(crtc);
-	else if (crtc_state->crc_enabled && !enable)
+		if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) {
+			if (drm_dp_start_crc(aux, crtc)) {
+				DRM_DEBUG_DRIVER("dp start crc failed\n");
+				return -EINVAL;
+			}
+		}
+	} else if (enabled && !enable) {
 		drm_crtc_vblank_put(crtc);
+		if (crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) {
+			if (drm_dp_stop_crc(aux)) {
+				DRM_DEBUG_DRIVER("dp stop crc failed\n");
+				return -EINVAL;
+			}
+		}
+	}
 
-	crtc_state->crc_enabled = enable;
+	crtc_state->crc_src = source;
 
 	/* Reset crc_skipped on dm state */
 	crtc_state->crc_skip_count = 0;
@@ -134,7 +175,7 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
 	stream_state = crtc_state->stream;
 
 	/* Early return if CRC capture is not enabled. */
-	if (!crtc_state->crc_enabled)
+	if (!amdgpu_dm_is_valid_crc_source(crtc_state->crc_src))
 		return;
 
 	/*
@@ -148,10 +189,12 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
 		return;
 	}
 
-	if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
-			       &crcs[0], &crcs[1], &crcs[2]))
-		return;
+	if (crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) {
+		if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
+				       &crcs[0], &crcs[1], &crcs[2]))
+			return;
 
-	drm_crtc_add_crc_entry(crtc, true,
-			       drm_crtc_accurate_vblank_count(crtc), crcs);
+		drm_crtc_add_crc_entry(crtc, true,
+				       drm_crtc_accurate_vblank_count(crtc), crcs);
+	}
 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
new file mode 100644
index 000000000000..3793dc872436
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2019 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 AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_
+#define AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_
+
+enum amdgpu_dm_pipe_crc_source {
+	AMDGPU_DM_PIPE_CRC_SOURCE_NONE = 0,
+	AMDGPU_DM_PIPE_CRC_SOURCE_CRTC,
+	AMDGPU_DM_PIPE_CRC_SOURCE_DPRX,
+	AMDGPU_DM_PIPE_CRC_SOURCE_MAX,
+	AMDGPU_DM_PIPE_CRC_SOURCE_INVALID = -1,
+};
+
+static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source source)
+{
+	return (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) ||
+		   (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX);
+}
+
+/* amdgpu_dm_crc.c */
+#ifdef CONFIG_DEBUG_FS
+int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name);
+int amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc,
+				     const char *src_name,
+				     size_t *values_cnt);
+void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc);
+#else
+#define amdgpu_dm_crtc_set_crc_source NULL
+#define amdgpu_dm_crtc_verify_crc_source NULL
+#define amdgpu_dm_crtc_handle_crc_irq(x)
+#endif
+
+#endif /* AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_ */
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 29/87] drm/amd/display: add functionality to get pipe CRC source.
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (27 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 28/87] drm/amd/display: add functionality to grab DPRX CRC entries sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 30/87] drm/amd/display: Wait for backlight programming completion in set backlight level sunpeng.li-5C7GfCeVMHo
                     ` (57 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Dingchen Zhang, Nicholas Kazlauskas

From: Dingchen Zhang <dingchen.zhang@amd.com>

[Why]
We need to check the pipe crc source through debugfs for bypass mode test.

[How]
add implementation of amdgpu_dm_crtc_get_crc_sources and hook into drm_crtc
callback get_crc_sources.

Signed-off-by: Dingchen Zhang <dingchen.zhang@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  1 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c  | 14 ++++++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h  |  3 +++
 3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index b2e2ca657998..96b32c203561 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3806,6 +3806,7 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
 	.atomic_destroy_state = dm_crtc_destroy_state,
 	.set_crc_source = amdgpu_dm_crtc_set_crc_source,
 	.verify_crc_source = amdgpu_dm_crtc_verify_crc_source,
+	.get_crc_sources = amdgpu_dm_crtc_get_crc_sources,
 	.enable_vblank = dm_enable_vblank,
 	.disable_vblank = dm_disable_vblank,
 };
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 5293045b0164..7436c2e5a0a9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -29,6 +29,13 @@
 #include "amdgpu_dm.h"
 #include "dc.h"
 
+static const char *const pipe_crc_sources[] = {
+	"none",
+	"crtc",
+	"dprx",
+	"auto",
+};
+
 static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
 {
 	if (!source || !strcmp(source, "none"))
@@ -41,6 +48,13 @@ static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
 	return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID;
 }
 
+const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc,
+						  size_t *count)
+{
+	*count = ARRAY_SIZE(pipe_crc_sources);
+	return pipe_crc_sources;
+}
+
 int
 amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name,
 				 size_t *values_cnt)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
index 3793dc872436..b63a9011f511 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
@@ -46,10 +46,13 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name);
 int amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc,
 				     const char *src_name,
 				     size_t *values_cnt);
+const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc,
+						  size_t *count);
 void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc);
 #else
 #define amdgpu_dm_crtc_set_crc_source NULL
 #define amdgpu_dm_crtc_verify_crc_source NULL
+#define amdgpu_dm_crtc_get_crc_sources NULL
 #define amdgpu_dm_crtc_handle_crc_irq(x)
 #endif
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 30/87] drm/amd/display: Wait for backlight programming completion in set backlight level
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (28 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 29/87] drm/amd/display: add functionality to get pipe CRC source sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 31/87] drm/amd/display: 3.2.39 sunpeng.li-5C7GfCeVMHo
                     ` (56 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Anthony Koo, SivapiriyanKumarasamy

From: SivapiriyanKumarasamy <sivapiriyan.kumarasamy@amd.com>

[WHY]
Currently we don't wait for blacklight programming completion in DMCU
when setting backlight level. Some sequences such as PSR static screen
event trigger reprogramming requires it to be complete.

[How]
Add generic wait for dmcu command completion in set backlight level.

Signed-off-by: SivapiriyanKumarasamy <sivapiriyan.kumarasamy@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
index 3d87a8800300..adde7a5760bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -237,6 +237,10 @@ static void dmcu_set_backlight_level(
 	s2 |= (backlight_8_bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
 
 	REG_WRITE(BIOS_SCRATCH_2, s2);
+
+	/* waitDMCUReadyForCmd */
+	REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT,
+			0, 1, 80000);
 }
 
 static void dce_abm_init(struct abm *abm)
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 31/87] drm/amd/display: 3.2.39
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (29 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 30/87] drm/amd/display: Wait for backlight programming completion in set backlight level sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 32/87] drm/amd/display: Expose enc2_set_dynamic_metadata sunpeng.li-5C7GfCeVMHo
                     ` (55 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 a307a3a1cde4..0aad22b1ef36 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.38"
+#define DC_VER "3.2.39"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 32/87] drm/amd/display: Expose enc2_set_dynamic_metadata
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (30 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 31/87] drm/amd/display: 3.2.39 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 33/87] drm/amd/display: Check for valid stream_encode sunpeng.li-5C7GfCeVMHo
                     ` (54 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Ilya Bakoulin, Leo Li, Eric Bernstein

From: Ilya Bakoulin <Ilya.Bakoulin@amd.com>

[Why]
Need to implement register programming for HDR dynamic
metadata transmission and tests.

Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com>
Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c | 2 +-
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
index 791aa745efd2..403f1f865a06 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c
@@ -371,7 +371,7 @@ static void enc2_read_state(struct stream_encoder *enc, struct enc_state *s)
  *
  *   Ensure the OTG master update lock is set when changing DME configuration.
  */
-static void enc2_set_dynamic_metadata(struct stream_encoder *enc,
+void enc2_set_dynamic_metadata(struct stream_encoder *enc,
 		bool enable_dme,
 		uint32_t hubp_requestor_id,
 		enum dynamic_metadata_mode dmdata_mode)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h
index 6d40e8c9b78f..3f94a9f13c4a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h
@@ -104,4 +104,9 @@ void enc2_stream_encoder_dp_unblank(
 	struct stream_encoder *enc,
 	const struct encoder_unblank_param *param);
 
+void enc2_set_dynamic_metadata(struct stream_encoder *enc,
+		bool enable_dme,
+		uint32_t hubp_requestor_id,
+		enum dynamic_metadata_mode dmdata_mode);
+
 #endif /* __DC_STREAM_ENCODER_DCN20_H__ */
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 33/87] drm/amd/display: Check for valid stream_encode
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (31 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 32/87] drm/amd/display: Expose enc2_set_dynamic_metadata sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 34/87] drm/amd/display: Fix some HUBP programming issues sunpeng.li-5C7GfCeVMHo
                     ` (53 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Ilya Bakoulin, Leo Li, Eric Bernstein

From: Ilya Bakoulin <Ilya.Bakoulin@amd.com>

Before accessing it's vtable, check that stream_encoder is non-null.

Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com>
Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 1bc19d42fc9f..35d697dd5808 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -609,7 +609,8 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
 
 	pipe_ctx->stream->dmdata_address = attr->address;
 
-	if (pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL) {
+	if (pipe_ctx->stream_res.stream_enc &&
+			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL) {
 		if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
 			/* if using dynamic meta, don't set up generic infopackets */
 			pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 34/87] drm/amd/display: Fix some HUBP programming issues
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (32 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 33/87] drm/amd/display: Check for valid stream_encode sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 35/87] drm/amd/display: Read max down spread sunpeng.li-5C7GfCeVMHo
                     ` (52 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Ilya Bakoulin, Charlene Liu, Leo Li

From: Ilya Bakoulin <Ilya.Bakoulin@amd.com>

[Why]
A hubp pointer was being passed to DCN1 functions, which
expect the enclosing structure (for the purpose of container_of macros)
to be dcn10_hubp, but the actual type was dcn20_hubp.

[How]
Copy existing DCN1 functions and alter them slightly for use with
dcn20_hubp.

Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 682 +++++++++++++++++-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h |  37 +
 2 files changed, 705 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index d3f7dd374d50..02e8c0c6a233 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -156,7 +156,85 @@ void hubp2_program_deadline(
 {
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-	hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
+	/* DLG - Per hubp */
+	REG_SET_2(BLANK_OFFSET_0, 0,
+		REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
+		DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
+
+	REG_SET(BLANK_OFFSET_1, 0,
+		MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
+
+	REG_SET(DST_DIMENSIONS, 0,
+		REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
+
+	REG_SET_2(DST_AFTER_SCALER, 0,
+		REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
+		DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
+
+	REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
+		REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
+
+	/* DLG - Per luma/chroma */
+	REG_SET(VBLANK_PARAMETERS_1, 0,
+		REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
+
+	if (REG(NOM_PARAMETERS_0))
+		REG_SET(NOM_PARAMETERS_0, 0,
+			DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
+
+	if (REG(NOM_PARAMETERS_1))
+		REG_SET(NOM_PARAMETERS_1, 0,
+			REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
+
+	REG_SET(NOM_PARAMETERS_4, 0,
+		DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
+
+	REG_SET(NOM_PARAMETERS_5, 0,
+		REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
+
+	REG_SET_2(PER_LINE_DELIVERY, 0,
+		REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
+		REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
+
+	REG_SET(VBLANK_PARAMETERS_2, 0,
+		REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
+
+	if (REG(NOM_PARAMETERS_2))
+		REG_SET(NOM_PARAMETERS_2, 0,
+			DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
+
+	if (REG(NOM_PARAMETERS_3))
+		REG_SET(NOM_PARAMETERS_3, 0,
+			REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
+
+	REG_SET(NOM_PARAMETERS_6, 0,
+		DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
+
+	REG_SET(NOM_PARAMETERS_7, 0,
+		REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
+
+	/* TTU - per hubp */
+	REG_SET_2(DCN_TTU_QOS_WM, 0,
+		QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
+		QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
+
+	/* TTU - per luma/chroma */
+	/* Assumed surf0 is luma and 1 is chroma */
+
+	REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
+		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
+		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
+		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
+
+	REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
+		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
+		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
+		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
+
+	REG_SET_3(DCN_CUR0_TTU_CNTL0, 0,
+		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0,
+		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0,
+		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0);
 
 	REG_SET(FLIP_PARAMETERS_1, 0,
 		REFCYC_PER_PTE_GROUP_FLIP_L, dlg_attr->refcyc_per_pte_group_flip_l);
@@ -184,6 +262,39 @@ void hubp2_vready_at_or_After_vsync(struct hubp *hubp,
 	REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, value);
 }
 
+void hubp2_program_requestor(
+		struct hubp *hubp,
+		struct _vcs_dpi_display_rq_regs_st *rq_regs)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+	REG_UPDATE(HUBPRET_CONTROL,
+			DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
+	REG_SET_4(DCN_EXPANSION_MODE, 0,
+			DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
+			PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
+			MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
+			CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
+	REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0,
+		CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
+		MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
+		META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size,
+		MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size,
+		DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
+		MPTE_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
+		SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
+		PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
+	REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0,
+		CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
+		MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
+		META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size,
+		MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size,
+		DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
+		MPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.mpte_group_size,
+		SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
+		PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
+}
+
 static void hubp2_setup(
 		struct hubp *hubp,
 		struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
@@ -196,7 +307,7 @@ static void hubp2_setup(
 	 */
 
 	hubp2_vready_at_or_After_vsync(hubp, pipe_dest);
-	hubp1_program_requestor(hubp, rq_regs);
+	hubp2_program_requestor(hubp, rq_regs);
 	hubp2_program_deadline(hubp, dlg_attr, ttu_attr);
 
 }
@@ -283,6 +394,196 @@ static void hubp2_program_tiling(
 			PIPE_ALIGNED, 0);
 }
 
+void hubp2_program_size(
+	struct hubp *hubp,
+	enum surface_pixel_format format,
+	const union plane_size *plane_size,
+	struct dc_plane_dcc_param *dcc)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c;
+
+	/* Program data and meta surface pitch (calculation from addrlib)
+	 * 444 or 420 luma
+	 */
+	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) {
+		ASSERT(plane_size->video.chroma_pitch != 0);
+		/* Chroma pitch zero can cause system hang! */
+
+		pitch = plane_size->video.luma_pitch - 1;
+		meta_pitch = dcc->video.meta_pitch_l - 1;
+		pitch_c = plane_size->video.chroma_pitch - 1;
+		meta_pitch_c = dcc->video.meta_pitch_c - 1;
+	} else {
+		pitch = plane_size->grph.surface_pitch - 1;
+		meta_pitch = dcc->grph.meta_pitch - 1;
+		pitch_c = 0;
+		meta_pitch_c = 0;
+	}
+
+	if (!dcc->enable) {
+		meta_pitch = 0;
+		meta_pitch_c = 0;
+	}
+
+	REG_UPDATE_2(DCSURF_SURFACE_PITCH,
+			PITCH, pitch, META_PITCH, meta_pitch);
+
+	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
+		REG_UPDATE_2(DCSURF_SURFACE_PITCH_C,
+			PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c);
+}
+
+void hubp2_program_rotation(
+	struct hubp *hubp,
+	enum dc_rotation_angle rotation,
+	bool horizontal_mirror)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	uint32_t mirror;
+
+
+	if (horizontal_mirror)
+		mirror = 1;
+	else
+		mirror = 0;
+
+	/* Program rotation angle and horz mirror - no mirror */
+	if (rotation == ROTATION_ANGLE_0)
+		REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
+				ROTATION_ANGLE, 0,
+				H_MIRROR_EN, mirror);
+	else if (rotation == ROTATION_ANGLE_90)
+		REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
+				ROTATION_ANGLE, 1,
+				H_MIRROR_EN, mirror);
+	else if (rotation == ROTATION_ANGLE_180)
+		REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
+				ROTATION_ANGLE, 2,
+				H_MIRROR_EN, mirror);
+	else if (rotation == ROTATION_ANGLE_270)
+		REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
+				ROTATION_ANGLE, 3,
+				H_MIRROR_EN, mirror);
+}
+
+void hubp2_dcc_control(struct hubp *hubp, bool enable,
+		bool independent_64b_blks)
+{
+	uint32_t dcc_en = enable ? 1 : 0;
+	uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+	REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
+			PRIMARY_SURFACE_DCC_EN, dcc_en,
+			PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk,
+			SECONDARY_SURFACE_DCC_EN, dcc_en,
+			SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
+}
+
+void hubp2_program_pixel_format(
+	struct hubp *hubp,
+	enum surface_pixel_format format)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	uint32_t red_bar = 3;
+	uint32_t blue_bar = 2;
+
+	/* swap for ABGR format */
+	if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
+			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
+			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
+			|| format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
+		red_bar = 2;
+		blue_bar = 3;
+	}
+
+	REG_UPDATE_2(HUBPRET_CONTROL,
+			CROSSBAR_SRC_CB_B, blue_bar,
+			CROSSBAR_SRC_CR_R, red_bar);
+
+	/* Mapping is same as ipp programming (cnvc) */
+
+	switch (format)	{
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 1);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 3);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 8);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 10);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 22);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
+	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 24);
+		break;
+
+	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 65);
+		break;
+	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 64);
+		break;
+	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 67);
+		break;
+	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 66);
+		break;
+	case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 12);
+		break;
+#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
+	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 112);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 113);
+		break;
+	case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 114);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 118);
+		break;
+	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
+		REG_UPDATE(DCSURF_SURFACE_CONFIG,
+				SURFACE_PIXEL_FORMAT, 119);
+		break;
+#endif
+	default:
+		BREAK_TO_DEBUGGER();
+		break;
+	}
+
+	/* don't see the need of program the xbar in DCN 1.0 */
+}
+
 void hubp2_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
@@ -295,11 +596,11 @@ void hubp2_program_surface_config(
 {
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-	hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
+	hubp2_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
 	hubp2_program_tiling(hubp2, tiling_info, format);
-	hubp1_program_size(hubp, format, plane_size, dcc);
-	hubp1_program_rotation(hubp, rotation, horizontal_mirror);
-	hubp1_program_pixel_format(hubp, format);
+	hubp2_program_size(hubp, format, plane_size, dcc);
+	hubp2_program_rotation(hubp, rotation, horizontal_mirror);
+	hubp2_program_pixel_format(hubp, format);
 }
 
 enum cursor_lines_per_chunk hubp2_get_lines_per_chunk(
@@ -652,28 +953,381 @@ void hubp2_set_flip_control_surface_gsl(struct hubp *hubp, bool enable)
 	REG_UPDATE(DCSURF_FLIP_CONTROL2, SURFACE_GSL_ENABLE, enable ? 1 : 0);
 }
 
+bool hubp2_is_flip_pending(struct hubp *hubp)
+{
+	uint32_t flip_pending = 0;
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	struct dc_plane_address earliest_inuse_address;
+
+	REG_GET(DCSURF_FLIP_CONTROL,
+			SURFACE_FLIP_PENDING, &flip_pending);
+
+	REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
+			SURFACE_EARLIEST_INUSE_ADDRESS, &earliest_inuse_address.grph.addr.low_part);
+
+	REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
+			SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &earliest_inuse_address.grph.addr.high_part);
+
+	if (flip_pending)
+		return true;
+
+	if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+		return true;
+
+	return false;
+}
+
+void hubp2_set_blank(struct hubp *hubp, bool blank)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	uint32_t blank_en = blank ? 1 : 0;
+
+	REG_UPDATE_2(DCHUBP_CNTL,
+			HUBP_BLANK_EN, blank_en,
+			HUBP_TTU_DISABLE, blank_en);
+
+	if (blank) {
+		uint32_t reg_val = REG_READ(DCHUBP_CNTL);
+
+		if (reg_val) {
+			/* init sequence workaround: in case HUBP is
+			 * power gated, this wait would timeout.
+			 *
+			 * we just wrote reg_val to non-0, if it stay 0
+			 * it means HUBP is gated
+			 */
+			REG_WAIT(DCHUBP_CNTL,
+					HUBP_NO_OUTSTANDING_REQ, 1,
+					1, 200);
+		}
+
+		hubp->mpcc_id = 0xf;
+		hubp->opp_id = OPP_ID_INVALID;
+	}
+}
+
+void hubp2_cursor_set_position(
+		struct hubp *hubp,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
+	int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
+	int x_hotspot = pos->x_hotspot;
+	int y_hotspot = pos->y_hotspot;
+	uint32_t dst_x_offset;
+	uint32_t cur_en = pos->enable ? 1 : 0;
+
+	/*
+	 * Guard aganst cursor_set_position() from being called with invalid
+	 * attributes
+	 *
+	 * TODO: Look at combining cursor_set_position() and
+	 * cursor_set_attributes() into cursor_update()
+	 */
+	if (hubp->curs_attr.address.quad_part == 0)
+		return;
+
+	if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
+		src_x_offset = pos->y - pos->y_hotspot - param->viewport.x;
+		y_hotspot = pos->x_hotspot;
+		x_hotspot = pos->y_hotspot;
+	}
+
+	if (param->mirror) {
+		x_hotspot = param->viewport.width - x_hotspot;
+		src_x_offset = param->viewport.x + param->viewport.width - src_x_offset;
+	}
+
+	dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
+	dst_x_offset *= param->ref_clk_khz;
+	dst_x_offset /= param->pixel_clk_khz;
+
+	ASSERT(param->h_scale_ratio.value);
+
+	if (param->h_scale_ratio.value)
+		dst_x_offset = dc_fixpt_floor(dc_fixpt_div(
+				dc_fixpt_from_int(dst_x_offset),
+				param->h_scale_ratio));
+
+	if (src_x_offset >= (int)param->viewport.width)
+		cur_en = 0;  /* not visible beyond right edge*/
+
+	if (src_x_offset + (int)hubp->curs_attr.width <= 0)
+		cur_en = 0;  /* not visible beyond left edge*/
+
+	if (src_y_offset >= (int)param->viewport.height)
+		cur_en = 0;  /* not visible beyond bottom edge*/
+
+	if (src_y_offset + (int)hubp->curs_attr.height <= 0)
+		cur_en = 0;  /* not visible beyond top edge*/
+
+	if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+		hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
+
+	REG_UPDATE(CURSOR_CONTROL,
+			CURSOR_ENABLE, cur_en);
+
+	REG_SET_2(CURSOR_POSITION, 0,
+			CURSOR_X_POSITION, pos->x,
+			CURSOR_Y_POSITION, pos->y);
+
+	REG_SET_2(CURSOR_HOT_SPOT, 0,
+			CURSOR_HOT_SPOT_X, x_hotspot,
+			CURSOR_HOT_SPOT_Y, y_hotspot);
+
+	REG_SET(CURSOR_DST_OFFSET, 0,
+			CURSOR_DST_X_OFFSET, dst_x_offset);
+	/* TODO Handle surface pixel formats other than 4:4:4 */
+}
+
+void hubp2_clk_cntl(struct hubp *hubp, bool enable)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	uint32_t clk_enable = enable ? 1 : 0;
+
+	REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable);
+}
+
+void hubp2_vtg_sel(struct hubp *hubp, uint32_t otg_inst)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+	REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst);
+}
+
+void hubp2_clear_underflow(struct hubp *hubp)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+	REG_UPDATE(DCHUBP_CNTL, HUBP_UNDERFLOW_CLEAR, 1);
+}
+
+void hubp2_read_state_common(struct hubp *hubp)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	struct dcn_hubp_state *s = &hubp2->state;
+	struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr;
+	struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr;
+	struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
+
+	/* Requester */
+	REG_GET(HUBPRET_CONTROL,
+			DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address);
+	REG_GET_4(DCN_EXPANSION_MODE,
+			DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode,
+			PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode,
+			MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode,
+			CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode);
+
+	/* DLG - Per hubp */
+	REG_GET_2(BLANK_OFFSET_0,
+		REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end,
+		DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end);
+
+	REG_GET(BLANK_OFFSET_1,
+		MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start);
+
+	REG_GET(DST_DIMENSIONS,
+		REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal);
+
+	REG_GET_2(DST_AFTER_SCALER,
+		REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler,
+		DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler);
+
+	if (REG(PREFETCH_SETTINS))
+		REG_GET_2(PREFETCH_SETTINS,
+			DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
+			VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
+	else
+		REG_GET_2(PREFETCH_SETTINGS,
+			DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
+			VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
+
+	REG_GET_2(VBLANK_PARAMETERS_0,
+		DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank,
+		DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank);
+
+	REG_GET(REF_FREQ_TO_PIX_FREQ,
+		REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq);
+
+	/* DLG - Per luma/chroma */
+	REG_GET(VBLANK_PARAMETERS_1,
+		REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l);
+
+	REG_GET(VBLANK_PARAMETERS_3,
+		REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l);
+
+	if (REG(NOM_PARAMETERS_0))
+		REG_GET(NOM_PARAMETERS_0,
+			DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l);
+
+	if (REG(NOM_PARAMETERS_1))
+		REG_GET(NOM_PARAMETERS_1,
+			REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l);
+
+	REG_GET(NOM_PARAMETERS_4,
+		DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l);
+
+	REG_GET(NOM_PARAMETERS_5,
+		REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l);
+
+	REG_GET_2(PER_LINE_DELIVERY_PRE,
+		REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l,
+		REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c);
+
+	REG_GET_2(PER_LINE_DELIVERY,
+		REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l,
+		REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c);
+
+	if (REG(PREFETCH_SETTINS_C))
+		REG_GET(PREFETCH_SETTINS_C,
+			VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
+	else
+		REG_GET(PREFETCH_SETTINGS_C,
+			VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
+
+	REG_GET(VBLANK_PARAMETERS_2,
+		REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c);
+
+	REG_GET(VBLANK_PARAMETERS_4,
+		REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c);
+
+	if (REG(NOM_PARAMETERS_2))
+		REG_GET(NOM_PARAMETERS_2,
+			DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c);
+
+	if (REG(NOM_PARAMETERS_3))
+		REG_GET(NOM_PARAMETERS_3,
+			REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c);
+
+	REG_GET(NOM_PARAMETERS_6,
+		DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c);
+
+	REG_GET(NOM_PARAMETERS_7,
+		REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c);
+
+	/* TTU - per hubp */
+	REG_GET_2(DCN_TTU_QOS_WM,
+		QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm,
+		QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm);
+
+	REG_GET_2(DCN_GLOBAL_TTU_CNTL,
+		MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank,
+		QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip);
+
+	/* TTU - per luma/chroma */
+	/* Assumed surf0 is luma and 1 is chroma */
+
+	REG_GET_3(DCN_SURF0_TTU_CNTL0,
+		REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l,
+		QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l,
+		QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l);
+
+	REG_GET(DCN_SURF0_TTU_CNTL1,
+		REFCYC_PER_REQ_DELIVERY_PRE,
+		&ttu_attr->refcyc_per_req_delivery_pre_l);
+
+	REG_GET_3(DCN_SURF1_TTU_CNTL0,
+		REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c,
+		QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c,
+		QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c);
+
+	REG_GET(DCN_SURF1_TTU_CNTL1,
+		REFCYC_PER_REQ_DELIVERY_PRE,
+		&ttu_attr->refcyc_per_req_delivery_pre_c);
+
+	/* Rest of hubp */
+	REG_GET(DCSURF_SURFACE_CONFIG,
+			SURFACE_PIXEL_FORMAT, &s->pixel_format);
+
+	REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
+			SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi);
+
+	REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
+			SURFACE_EARLIEST_INUSE_ADDRESS, &s->inuse_addr_lo);
+
+	REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION,
+			PRI_VIEWPORT_WIDTH, &s->viewport_width,
+			PRI_VIEWPORT_HEIGHT, &s->viewport_height);
+
+	REG_GET_2(DCSURF_SURFACE_CONFIG,
+			ROTATION_ANGLE, &s->rotation_angle,
+			H_MIRROR_EN, &s->h_mirror_en);
+
+	REG_GET(DCSURF_TILING_CONFIG,
+			SW_MODE, &s->sw_mode);
+
+	REG_GET(DCSURF_SURFACE_CONTROL,
+			PRIMARY_SURFACE_DCC_EN, &s->dcc_en);
+
+	REG_GET_3(DCHUBP_CNTL,
+			HUBP_BLANK_EN, &s->blank_en,
+			HUBP_TTU_DISABLE, &s->ttu_disable,
+			HUBP_UNDERFLOW_STATUS, &s->underflow_status);
+
+	REG_GET(DCN_GLOBAL_TTU_CNTL,
+			MIN_TTU_VBLANK, &s->min_ttu_vblank);
+
+	REG_GET_2(DCN_TTU_QOS_WM,
+			QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
+			QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
+
+}
+
+void hubp2_read_state(struct hubp *hubp)
+{
+	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+	struct dcn_hubp_state *s = &hubp2->state;
+	struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
+
+	hubp2_read_state_common(hubp);
+
+	REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
+		CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
+		MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
+		META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
+		MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
+		DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
+		MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
+		SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
+		PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
+
+	REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
+		CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
+		MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
+		META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
+		MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
+		DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
+		MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
+		SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
+		PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
+
+}
+
 static struct hubp_funcs dcn20_hubp_funcs = {
 	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
 	.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
 	.hubp_program_surface_flip_and_addr = hubp2_program_surface_flip_and_addr,
 	.hubp_program_surface_config = hubp2_program_surface_config,
-	.hubp_is_flip_pending = hubp1_is_flip_pending,
+	.hubp_is_flip_pending = hubp2_is_flip_pending,
 	.hubp_setup = hubp2_setup,
 	.hubp_setup_interdependent = hubp2_setup_interdependent,
 	.hubp_set_vm_system_aperture_settings = hubp2_set_vm_system_aperture_settings,
-	.set_blank = hubp1_set_blank,
-	.dcc_control = hubp1_dcc_control,
+	.set_blank = hubp2_set_blank,
+	.dcc_control = hubp2_dcc_control,
 	.hubp_update_dchub = hubp2_update_dchub,
 	.mem_program_viewport = min_set_viewport,
 	.set_cursor_attributes	= hubp2_cursor_set_attributes,
-	.set_cursor_position	= hubp1_cursor_set_position,
-	.hubp_clk_cntl = hubp1_clk_cntl,
-	.hubp_vtg_sel = hubp1_vtg_sel,
+	.set_cursor_position	= hubp2_cursor_set_position,
+	.hubp_clk_cntl = hubp2_clk_cntl,
+	.hubp_vtg_sel = hubp2_vtg_sel,
 	.dmdata_set_attributes = hubp2_dmdata_set_attributes,
 	.dmdata_load = hubp2_dmdata_load,
 	.dmdata_status_done = hubp2_dmdata_status_done,
-	.hubp_read_state = hubp1_read_state,
-	.hubp_clear_underflow = hubp1_clear_underflow,
+	.hubp_read_state = hubp2_read_state,
+	.hubp_clear_underflow = hubp2_clear_underflow,
 	.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
 	.hubp_init = hubp1_init,
 };
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
index 2c6405a62fc1..c8418235e154 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
@@ -267,6 +267,24 @@ bool hubp2_program_surface_flip_and_addr(
 	const struct dc_plane_address *address,
 	bool flip_immediate);
 
+void hubp2_dcc_control(struct hubp *hubp, bool enable,
+		bool independent_64b_blks);
+
+void hubp2_program_size(
+	struct hubp *hubp,
+	enum surface_pixel_format format,
+	const union plane_size *plane_size,
+	struct dc_plane_dcc_param *dcc);
+
+void hubp2_program_rotation(
+	struct hubp *hubp,
+	enum dc_rotation_angle rotation,
+	bool horizontal_mirror);
+
+void hubp2_program_pixel_format(
+	struct hubp *hubp,
+	enum surface_pixel_format format);
+
 void hubp2_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
@@ -277,6 +295,25 @@ void hubp2_program_surface_config(
 	bool horizontal_mirror,
 	unsigned int compat_level);
 
+bool hubp2_is_flip_pending(struct hubp *hubp);
+
+void hubp2_set_blank(struct hubp *hubp, bool blank);
+
+void hubp2_cursor_set_position(
+		struct hubp *hubp,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param);
+
+void hubp2_clk_cntl(struct hubp *hubp, bool enable);
+
+void hubp2_vtg_sel(struct hubp *hubp, uint32_t otg_inst);
+
+void hubp2_clear_underflow(struct hubp *hubp);
+
+void hubp2_read_state_common(struct hubp *hubp);
+
+void hubp2_read_state(struct hubp *hubp);
+
 #endif /* __DC_MEM_INPUT_DCN20_H__ */
 
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 35/87] drm/amd/display: Read max down spread
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (33 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 34/87] drm/amd/display: Fix some HUBP programming issues sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 36/87] drm/amd/display: Remove dsc disable_ich flag programming sunpeng.li-5C7GfCeVMHo
                     ` (51 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Derek Lai, Tony Cheng

From: Derek Lai <Derek.Lai@amd.com>

[Why]
When launch D10.2, driver will write DPCD 0x107 with 0x00

[How]
Read MAX_DOWNSPREAD (0x0003h) then keep in current
link settings

Signed-off-by: Derek Lai <Derek.Lai@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 7 +++++++
 1 file changed, 7 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 1e051e953610..4b82b86f1e6a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -530,6 +530,7 @@ static void read_edp_current_link_settings_on_detect(struct dc_link *link)
 	uint32_t read_dpcd_retry_cnt = 10;
 	enum dc_status status = DC_ERROR_UNEXPECTED;
 	int i;
+	union max_down_spread max_down_spread = { {0} };
 
 	// Read DPCD 00101h to find out the number of lanes currently set
 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
@@ -574,6 +575,12 @@ static void read_edp_current_link_settings_on_detect(struct dc_link *link)
 		link->cur_link_settings.link_rate = link_bw_set;
 		link->cur_link_settings.use_link_rate_set = false;
 	}
+	// Read DPCD 00003h to find the max down spread.
+	core_link_read_dpcd(link, DP_MAX_DOWNSPREAD,
+			&max_down_spread.raw, sizeof(max_down_spread));
+	link->cur_link_settings.link_spread =
+		max_down_spread.bits.MAX_DOWN_SPREAD ?
+		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
 }
 
 static bool detect_dp(
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 36/87] drm/amd/display: Remove dsc disable_ich flag programming.
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (34 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 35/87] drm/amd/display: Read max down spread sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:19   ` [PATCH 37/87] drm/amd/display: Power-gate all DSCs at driver init time sunpeng.li-5C7GfCeVMHo
                     ` (50 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

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

Current default is sufficient for a flag that does not change.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c | 8 +++++---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h | 4 ++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
index ffd0014ec3b5..e870caa8d4fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
@@ -436,7 +436,7 @@ static void dsc_init_reg_values(struct dsc_reg_values *reg_vals)
 	reg_vals->ich_reset_at_eol            = 0;
 	reg_vals->alternate_ich_encoding_en   = 0;
 	reg_vals->rc_buffer_model_size        = 0;
-	reg_vals->disable_ich                 = 0;
+	/*reg_vals->disable_ich                 = 0;*/
 	reg_vals->dsc_dbg_en                  = 0;
 
 	for (i = 0; i < 4; i++)
@@ -518,9 +518,11 @@ static void dsc_write_to_registers(struct display_stream_compressor *dsc, const
 		ALTERNATE_ICH_ENCODING_EN, reg_vals->alternate_ich_encoding_en,
 		NUMBER_OF_SLICES_IN_VERTICAL_DIRECTION, reg_vals->num_slices_v - 1);
 
-	REG_SET_2(DSCC_CONFIG1, 0,
+	REG_SET(DSCC_CONFIG1, 0,
+			DSCC_RATE_CONTROL_BUFFER_MODEL_SIZE, reg_vals->rc_buffer_model_size);
+	/*REG_SET_2(DSCC_CONFIG1, 0,
 		DSCC_RATE_CONTROL_BUFFER_MODEL_SIZE, reg_vals->rc_buffer_model_size,
-		DSCC_DISABLE_ICH, reg_vals->disable_ich);
+		DSCC_DISABLE_ICH, reg_vals->disable_ich);*/
 
 	REG_SET_4(DSCC_INTERRUPT_CONTROL_STATUS, 0,
 		DSCC_RATE_CONTROL_BUFFER_MODEL0_OVERFLOW_OCCURRED_INT_EN, reg_vals->rc_buffer_model_overflow_int_en[0],
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h
index 168865a16288..4e2fb38390a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.h
@@ -103,7 +103,7 @@
 	DSC_SF(DSCC0_DSCC_CONFIG0, ALTERNATE_ICH_ENCODING_EN, mask_sh), \
 	DSC_SF(DSCC0_DSCC_CONFIG0, NUMBER_OF_SLICES_IN_VERTICAL_DIRECTION, mask_sh), \
 	DSC_SF(DSCC0_DSCC_CONFIG1, DSCC_RATE_CONTROL_BUFFER_MODEL_SIZE, mask_sh), \
-	DSC_SF(DSCC0_DSCC_CONFIG1, DSCC_DISABLE_ICH, mask_sh), \
+	/*DSC_SF(DSCC0_DSCC_CONFIG1, DSCC_DISABLE_ICH, mask_sh),*/ \
 	DSC_SF(DSCC0_DSCC_STATUS, DSCC_DOUBLE_BUFFER_REG_UPDATE_PENDING, mask_sh), \
 	DSC_SF(DSCC0_DSCC_INTERRUPT_CONTROL_STATUS, DSCC_RATE_BUFFER0_OVERFLOW_OCCURRED, mask_sh), \
 	DSC_SF(DSCC0_DSCC_INTERRUPT_CONTROL_STATUS, DSCC_RATE_BUFFER1_OVERFLOW_OCCURRED, mask_sh), \
@@ -278,7 +278,7 @@
 	type ALTERNATE_ICH_ENCODING_EN; \
 	type NUMBER_OF_SLICES_IN_VERTICAL_DIRECTION; \
 	type DSCC_RATE_CONTROL_BUFFER_MODEL_SIZE; \
-	type DSCC_DISABLE_ICH; \
+	/*type DSCC_DISABLE_ICH;*/ \
 	type DSCC_DOUBLE_BUFFER_REG_UPDATE_PENDING; \
 	type DSCC_RATE_BUFFER0_OVERFLOW_OCCURRED; \
 	type DSCC_RATE_BUFFER1_OVERFLOW_OCCURRED; \
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 37/87] drm/amd/display: Power-gate all DSCs at driver init time
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (35 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 36/87] drm/amd/display: Remove dsc disable_ich flag programming sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:19   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 38/87] drm/amd/display: Disable Audio on reinitialize hardware sunpeng.li-5C7GfCeVMHo
                     ` (49 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:19 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Nevenko Stupar, Nikola Cornij

From: Nikola Cornij <nikola.cornij@amd.com>

[why]
DSC should be powered-on only on as-needed basis, i.e. if the mode
requires it

[how]
Loop over all the DSCs at driver init time and power-gate each

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Nevenko Stupar <Nevenko.Stupar@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index db57c2a99a15..a918f2770c38 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -599,6 +599,10 @@ static void dcn20_init_hw(struct dc *dc)
 		}
 	}
 
+	/* Power gate DSCs */
+	for (i = 0; i < res_pool->res_cap->num_dsc; i++)
+		dcn20_dsc_pg_control(hws, res_pool->dscs[i]->inst, false);
+
 	/* Blank pixel data with OPP DPG */
 	for (i = 0; i < dc->res_pool->timing_generator_count; i++) {
 		struct timing_generator *tg = dc->res_pool->timing_generators[i];
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 38/87] drm/amd/display: Disable Audio on reinitialize hardware
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (36 preceding siblings ...)
  2019-07-15 21:19   ` [PATCH 37/87] drm/amd/display: Power-gate all DSCs at driver init time sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 39/87] drm/amd/display: fix DMCU hang when going into Modern Standby sunpeng.li-5C7GfCeVMHo
                     ` (48 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Alvin Lee

From: Alvin Lee <alvin.lee2@amd.com>

[Why]
When we recover from hang, we do not want to skip the audio enable call.

[How]
Disable audio in dc_reinitialize_hardware

Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |  1 +
 .../display/dc/dce110/dce110_hw_sequencer.c   | 20 +++++++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 614a941eb9f2..e9a7a7af11df 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -331,6 +331,7 @@ void dcn20_clk_mgr_construct(
 		struct dccg *dccg)
 {
 	clk_mgr->base.ctx = ctx;
+	clk_mgr->pp_smu = pp_smu;
 	clk_mgr->base.funcs = &dcn2_funcs;
 	clk_mgr->regs = &clk_mgr_regs;
 	clk_mgr->clk_mgr_shift = &clk_mgr_shift;
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 6fa1f6b5375b..fedbc6d0c40d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -962,11 +962,17 @@ void hwss_edp_backlight_control(
 void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
 {
 	/* notify audio driver for audio modes of monitor */
-	struct dc *core_dc = pipe_ctx->stream->ctx->dc;
+	struct dc *core_dc;
 	struct pp_smu_funcs *pp_smu = NULL;
-	struct clk_mgr *clk_mgr = core_dc->clk_mgr;
+	struct clk_mgr *clk_mgr;
 	unsigned int i, num_audio = 1;
 
+	if (!pipe_ctx->stream)
+		return;
+
+	core_dc = pipe_ctx->stream->ctx->dc;
+	clk_mgr = core_dc->clk_mgr;
+
 	if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
 		return;
 
@@ -996,9 +1002,15 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
 
 void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option)
 {
-	struct dc *dc = pipe_ctx->stream->ctx->dc;
+	struct dc *dc;
 	struct pp_smu_funcs *pp_smu = NULL;
-	struct clk_mgr *clk_mgr = dc->clk_mgr;
+	struct clk_mgr *clk_mgr;
+
+	if (!pipe_ctx || !pipe_ctx->stream)
+		return;
+
+	dc = pipe_ctx->stream->ctx->dc;
+	clk_mgr = dc->clk_mgr;
 
 	if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
 		return;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 39/87] drm/amd/display: fix DMCU hang when going into Modern Standby
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (37 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 38/87] drm/amd/display: Disable Audio on reinitialize hardware sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 40/87] drm/amd/display: Do not fill Null packet in the blank period sunpeng.li-5C7GfCeVMHo
                     ` (47 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Anthony Koo, Eric Yang, Zi Yu Liao

From: Zi Yu Liao <ziyu.liao@amd.com>

[why]
When the system is going into suspend, set_backlight gets called
after the eDP got blanked. Since smooth brightness is enabled,
the driver will make a call into the DMCU to ramp the brightness.
The DMCU would try to enable ABM to do so. But since the display is
blanked, this ends up causing ABM1_ACE_DBUF_REG_UPDATE_PENDING to
get stuck at 1, which results in a dead lock in the DMCU firmware.

[how]
Disable brightness ramping when the eDP display is blanked.

Signed-off-by: Zi Yu Liao <ziyu.liao@amd.com>
Reviewed-by: Eric Yang <eric.yang2@amd.com>
Acked-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

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 4b82b86f1e6a..5d6cf6bdccf7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2350,7 +2350,7 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
 			if (core_dc->current_state->res_ctx.pipe_ctx[i].stream) {
 				if (core_dc->current_state->res_ctx.
 						pipe_ctx[i].stream->link
-						== link)
+						== link) {
 					/* DMCU -1 for all controller id values,
 					 * therefore +1 here
 					 */
@@ -2358,6 +2358,13 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
 						core_dc->current_state->
 						res_ctx.pipe_ctx[i].stream_res.tg->inst +
 						1;
+
+					/* Disable brightness ramping when the display is blanked
+					 * as it can hang the DMCU
+					 */
+					if (core_dc->current_state->res_ctx.pipe_ctx[i].plane_state == NULL)
+						frame_ramp = 0;
+				}
 			}
 		}
 		abm->funcs->set_backlight_level_pwm(
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 40/87] drm/amd/display: Do not fill Null packet in the blank period
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (38 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 39/87] drm/amd/display: fix DMCU hang when going into Modern Standby sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 41/87] drm/amd/display: Remove unnecessary NULL check in set_preferred_link_settings sunpeng.li-5C7GfCeVMHo
                     ` (46 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

From: Charlene Liu <charlene.liu@amd.com>

[Description]
Do not fill Null packet in the blank period for new packet gen
This is based on HW IP team recommended default setting change.

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c | 3 ++-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
index 64adb9fb300c..a098287d71ae 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
@@ -511,11 +511,12 @@ void enc1_stream_encoder_hdmi_set_stream_attribute(
 	enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
 
 	/* setup HDMI engine */
-	REG_UPDATE_5(HDMI_CONTROL,
+	REG_UPDATE_6(HDMI_CONTROL,
 		HDMI_PACKET_GEN_VERSION, 1,
 		HDMI_KEEPOUT_MODE, 1,
 		HDMI_DEEP_COLOR_ENABLE, 0,
 		HDMI_DATA_SCRAMBLE_EN, 0,
+		HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1,
 		HDMI_CLOCK_CHANNEL_RATE, 0);
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
index 075e49c1283a..ab0ead3c3f46 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -189,6 +189,7 @@ struct dcn10_stream_enc_registers {
 	SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE, mask_sh),\
 	SE_SF(DIG0_HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, mask_sh),\
 	SE_SF(DIG0_HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN, mask_sh),\
+	SE_SF(DIG0_HDMI_CONTROL, HDMI_NO_EXTRA_NULL_PACKET_FILLED, mask_sh),\
 	SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT, mask_sh),\
 	SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND, mask_sh),\
 	SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND, mask_sh),\
@@ -374,6 +375,7 @@ struct dcn10_stream_enc_registers {
 	type HDMI_GC_SEND;\
 	type HDMI_NULL_SEND;\
 	type HDMI_DATA_SCRAMBLE_EN;\
+	type HDMI_NO_EXTRA_NULL_PACKET_FILLED;\
 	type HDMI_AUDIO_INFO_SEND;\
 	type AFMT_AUDIO_INFO_UPDATE;\
 	type HDMI_AUDIO_INFO_LINE;\
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 41/87] drm/amd/display: Remove unnecessary NULL check in set_preferred_link_settings
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (39 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 40/87] drm/amd/display: Do not fill Null packet in the blank period sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 42/87] drm/amd/display: use encoder's engine id to find matched free audio device sunpeng.li-5C7GfCeVMHo
                     ` (45 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Harry Wentland, Nicholas Kazlauskas

From: Harry Wentland <harry.wentland@amd.com>

[Why]
link_stream is never NULL here as we've dereferenced it a couple lines before
and have done so for a couple months now.

[How]
- Drop the NULL check.
- Initialize where we know link_stream is non-NULL

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 ++++-----
 1 file changed, 4 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 5d6cf6bdccf7..8803f6cc5414 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3021,8 +3021,10 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe->stream && pipe->stream->link) {
-			if (pipe->stream->link == link)
+			if (pipe->stream->link == link) {
+				link_stream = pipe->stream;
 				break;
+			}
 		}
 	}
 
@@ -3030,14 +3032,11 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
 	if (i == MAX_PIPES)
 		return;
 
-	link_stream = link->dc->current_state->res_ctx.pipe_ctx[i].stream;
-
 	/* Cannot retrain link if backend is off */
 	if (link_stream->dpms_off)
 		return;
 
-	if (link_stream)
-		decide_link_settings(link_stream, &store_settings);
+	decide_link_settings(link_stream, &store_settings);
 
 	if ((store_settings.lane_count != LANE_COUNT_UNKNOWN) &&
 		(store_settings.link_rate != LINK_RATE_UNKNOWN))
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 42/87] drm/amd/display: use encoder's engine id to find matched free audio device
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (40 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 41/87] drm/amd/display: Remove unnecessary NULL check in set_preferred_link_settings sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 43/87] drm/amd/display: fix not calling ppsmu to trigger PME sunpeng.li-5C7GfCeVMHo
                     ` (44 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Charlene Liu, Tai Man

From: Tai Man <taiman.wong@amd.com>

[Why]
On some platforms, the encoder id 3 is not populated. So the encoders
are not stored in right order as index (id: 0, 1, 2, 4, 5) at pool. This
would cause encoders id 4 & id 5 to fail when finding corresponding
audio device, defaulting to the first available audio device. As result,
we cannot stream audio into two DP ports with encoders id 4 & id 5.

[How]
It need to create enough audio device objects (0 - 5) to perform matching.
Then use encoder engine id to find matched audio device.

Signed-off-by: Tai Man Wong <taiman.wong@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 5b85139fb3ce..5e7b8b2dd178 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -265,7 +265,7 @@ bool resource_construct(
 		 * PORT_CONNECTIVITY == 1 (as instructed by HW team).
 		 */
 		update_num_audio(&straps, &num_audio, &pool->audio_support);
-		for (i = 0; i < pool->pipe_count && i < num_audio; i++) {
+		for (i = 0; i < caps->num_audio; i++) {
 			struct audio *aud = create_funcs->create_audio(ctx, i);
 
 			if (aud == NULL) {
@@ -1676,6 +1676,12 @@ static struct audio *find_first_free_audio(
 			return pool->audios[i];
 		}
 	}
+
+    /* use engine id to find free audio */
+	if ((id < pool->audio_count) && (res_ctx->is_audio_acquired[id] == false)) {
+		return pool->audios[id];
+	}
+
 	/*not found the matching one, first come first serve*/
 	for (i = 0; i < pool->audio_count; i++) {
 		if (res_ctx->is_audio_acquired[i] == false) {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 43/87] drm/amd/display: fix not calling ppsmu to trigger PME
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (41 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 42/87] drm/amd/display: use encoder's engine id to find matched free audio device sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 44/87] drm/amd/display: Change min_h_sync_width from 8 to 4 sunpeng.li-5C7GfCeVMHo
                     ` (43 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Eric Yang, Su Sung Chung

From: Su Sung Chung <Su.Chung@amd.com>

[why]
dcn20_clk_mgr_construct was not initializing pp_smu, and PME call gets
filtered out by the null check

[how]
initialize pp_smu dcn20_clk_mgr_construct

Signed-off-by: Su Sung Chung <Su.Chung@amd.com>
Reviewed-by: Eric Yang <eric.yang2@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index e9a7a7af11df..4842c91771d8 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -346,6 +346,8 @@ void dcn20_clk_mgr_construct(
 
 	clk_mgr->base.dprefclk_khz = 700000; // 700 MHz planned if VCO is 3.85 GHz, will be retrieved
 
+	clk_mgr->pp_smu = pp_smu;
+
 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
 		dcn2_funcs.update_clocks = dcn2_update_clocks_fpga;
 		clk_mgr->dentist_vco_freq_khz = 3850000;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 44/87] drm/amd/display: Change min_h_sync_width from 8 to 4
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (42 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 43/87] drm/amd/display: fix not calling ppsmu to trigger PME sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 45/87] drm/amd/display: Remove second initialization of pp_smu sunpeng.li-5C7GfCeVMHo
                     ` (42 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Joshua Aberback, Aric Cyr, Fatemeh Darbehani

From: Fatemeh Darbehani <fatemeh.darbehani@amd.com>

[Why]
Some display's hsync width is lower than the minimum dcn20 is set
to support right now. This will cause optc1_validate_timing to fail which
eventually will result in wrong set mode. This was set to 8 as per
HW team's request for no valid reason.

[How]
Changing min_h_sync_width to 4 will let us validate timing for
preffered mode and light up the headset. This change was made
to Vega 10 before for a similar issue.

Signed-off-by: Fatemeh Darbehani <fatemeh.darbehani@amd.com>
Reviewed-by: Joshua Aberback <Joshua.Aberback@amd.com>
Acked-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
index 26a66ccf6e72..1ae973962d53 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
@@ -535,7 +535,7 @@ void dcn20_timing_generator_init(struct optc *optc1)
 	optc1->min_h_blank = 32;
 	optc1->min_v_blank = 3;
 	optc1->min_v_blank_interlace = 5;
-	optc1->min_h_sync_width = 8;
+	optc1->min_h_sync_width = 4;//	Minimum HSYNC = 8 pixels asked By HW in the first place for no actual reason. Oculus Rift S will not light up with 8 as it's hsyncWidth is 6. Changing it to 4 to fix that issue.
 	optc1->min_v_sync_width = 1;
 	optc1->comb_opp_id = 0xf;
 }
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 45/87] drm/amd/display: Remove second initialization of pp_smu
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (43 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 44/87] drm/amd/display: Change min_h_sync_width from 8 to 4 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 46/87] drm/amd/display: 3.2.40 sunpeng.li-5C7GfCeVMHo
                     ` (41 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jaehyun Chung, Alvin Lee

From: Alvin Lee <alvin.lee2@amd.com>

[why]
We initialize pp_smu twice

[how]
Remove second initialization of pp_smu

Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Reviewed-by: Jaehyun Chung <Jaehyun.Chung@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 4842c91771d8..e9a7a7af11df 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -346,8 +346,6 @@ void dcn20_clk_mgr_construct(
 
 	clk_mgr->base.dprefclk_khz = 700000; // 700 MHz planned if VCO is 3.85 GHz, will be retrieved
 
-	clk_mgr->pp_smu = pp_smu;
-
 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
 		dcn2_funcs.update_clocks = dcn2_update_clocks_fpga;
 		clk_mgr->dentist_vco_freq_khz = 3850000;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 46/87] drm/amd/display: 3.2.40
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (44 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 45/87] drm/amd/display: Remove second initialization of pp_smu sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 47/87] drm/amd/display: Wait for flip to complete sunpeng.li-5C7GfCeVMHo
                     ` (40 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 0aad22b1ef36..14664bed8c84 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.39"
+#define DC_VER "3.2.40"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 47/87] drm/amd/display: Wait for flip to complete
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (45 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 46/87] drm/amd/display: 3.2.40 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 48/87] drm/amd/display: Implement generic MUX registers sunpeng.li-5C7GfCeVMHo
                     ` (39 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jaehyun Chung, Alvin Lee

From: Alvin Lee <alvin.lee2@amd.com>

[why]
In pipe split issue occurs when we program immediate flip while vsync flip is pending

[how]
Don't program immediate flip until flip is no longer pending

Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Reviewed-by: Jaehyun Chung <Jaehyun.Chung@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index a918f2770c38..9c0a788fbb18 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1283,6 +1283,17 @@ void dcn20_pipe_control_lock(
 	if (pipe->plane_state != NULL)
 		flip_immediate = pipe->plane_state->flip_immediate;
 
+	if (flip_immediate && lock) {
+		while (pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp))	{
+			udelay(1);
+		}
+
+		if (pipe->bottom_pipe != NULL)
+			while (pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp))	{
+				udelay(1);
+			}
+	}
+
 	/* In flip immediate and pipe splitting case, we need to use GSL
 	 * for synchronization. Only do setup on locking and on flip type change.
 	 */
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 48/87] drm/amd/display: Implement generic MUX registers
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (46 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 47/87] drm/amd/display: Wait for flip to complete sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 49/87] drm/amd/display: Use helper for determining HDMI signal sunpeng.li-5C7GfCeVMHo
                     ` (38 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Joshua Aberback, Murton Liu, Aric Cyr

From: Murton Liu <murton.liu@amd.com>

[Why]
Logic & structures for generic regs does not exist in DC currently.

[How]
Implement register masks/shifts and relevant functions for generic mux,
similar to existing HPD and DDC objects.

Signed-off-by: Murton Liu <murton.liu@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Joshua Aberback <Joshua.Aberback@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/gpio/Makefile  |   2 +-
 .../display/dc/gpio/dcn20/hw_factory_dcn20.c  |  41 +++++-
 .../dc/gpio/diagnostics/hw_factory_diag.c     |   1 +
 .../drm/amd/display/dc/gpio/generic_regs.h    |  66 +++++++++
 .../gpu/drm/amd/display/dc/gpio/hw_factory.h  |   3 +
 .../gpu/drm/amd/display/dc/gpio/hw_generic.c  | 132 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/gpio/hw_generic.h  |  46 ++++++
 7 files changed, 288 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h

diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile
index c3d92878875d..113affea49bf 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile
@@ -24,7 +24,7 @@
 # It provides the control and status of HW GPIO pins.
 
 GPIO = gpio_base.o gpio_service.o hw_factory.o \
-       hw_gpio.o hw_hpd.o hw_ddc.o hw_translate.o
+       hw_gpio.o hw_hpd.o hw_ddc.o hw_generic.o hw_translate.o
 
 AMD_DAL_GPIO = $(addprefix $(AMDDALPATH)/dc/gpio/,$(GPIO))
 
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
index abd76d855375..afb7c0f111bf 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
@@ -31,6 +31,7 @@
 #include "../hw_gpio.h"
 #include "../hw_ddc.h"
 #include "../hw_hpd.h"
+#include "../hw_generic.h"
 
 #include "hw_factory_dcn20.h"
 
@@ -138,6 +139,32 @@ static const struct ddc_sh_mask ddc_mask[] = {
 	DDC_MASK_SH_LIST_DCN2(_MASK, 6)
 };
 
+#include "../generic_regs.h"
+
+/* set field name */
+#define SF_GENERIC(reg_name, field_name, post_fix)\
+	.field_name = reg_name ## __ ## field_name ## post_fix
+
+#define generic_regs(id) \
+{\
+	GENERIC_REG_LIST(id)\
+}
+
+static const struct generic_registers generic_regs[] = {
+	generic_regs(A),
+	generic_regs(B),
+};
+
+static const struct generic_sh_mask generic_shift[] = {
+	GENERIC_MASK_SH_LIST(__SHIFT, A),
+	GENERIC_MASK_SH_LIST(__SHIFT, B),
+};
+
+static const struct generic_sh_mask generic_mask[] = {
+	GENERIC_MASK_SH_LIST(_MASK, A),
+	GENERIC_MASK_SH_LIST(_MASK, B),
+};
+
 static void define_ddc_registers(
 		struct hw_gpio_pin *pin,
 		uint32_t en)
@@ -173,17 +200,27 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en)
 	hpd->base.regs = &hpd_regs[en].gpio;
 }
 
+static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en)
+{
+	struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin);
+
+	generic->regs = &generic_regs[en];
+	generic->shifts = &generic_shift[en];
+	generic->masks = &generic_mask[en];
+	generic->base.regs = &generic_regs[en].gpio;
+}
 
 /* fucntion table */
 static const struct hw_factory_funcs funcs = {
 	.create_ddc_data = dal_hw_ddc_create,
 	.create_ddc_clock = dal_hw_ddc_create,
-	.create_generic = NULL,
+	.create_generic = dal_hw_generic_create,
 	.create_hpd = dal_hw_hpd_create,
 	.create_sync = NULL,
 	.create_gsl = NULL,
 	.define_hpd_registers = define_hpd_registers,
-	.define_ddc_registers = define_ddc_registers
+	.define_ddc_registers = define_ddc_registers,
+	.define_generic_registers = define_generic_registers,
 };
 /*
  * dal_hw_factory_dcn10_init
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c
index 26695b963c58..f15288c3986e 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c
@@ -38,6 +38,7 @@
 #include "../hw_gpio.h"
 #include "../hw_ddc.h"
 #include "../hw_hpd.h"
+#include "../hw_generic.h"
 
 /* function table */
 static const struct hw_factory_funcs funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h b/drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h
new file mode 100644
index 000000000000..8c05295c05c2
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012-16 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 DRIVERS_GPU_DRM_AMD_DC_DEV_DC_GPIO_GENERIC_REGS_H_
+#define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_GPIO_GENERIC_REGS_H_
+
+#include "gpio_regs.h"
+
+#define GENERIC_GPIO_REG_LIST_ENTRY(type, cd, id) \
+	.type ## _reg =  REG(DC_GPIO_GENERIC_## type),\
+	.type ## _mask =  DC_GPIO_GENERIC_ ## type ## __DC_GPIO_GENERIC ## id ## _ ## type ## _MASK,\
+	.type ## _shift = DC_GPIO_GENERIC_ ## type ## __DC_GPIO_GENERIC ## id ## _ ## type ## __SHIFT
+
+#define GENERIC_GPIO_REG_LIST(id) \
+	{\
+	GENERIC_GPIO_REG_LIST_ENTRY(MASK, cd, id),\
+	GENERIC_GPIO_REG_LIST_ENTRY(A, cd, id),\
+	GENERIC_GPIO_REG_LIST_ENTRY(EN, cd, id),\
+	GENERIC_GPIO_REG_LIST_ENTRY(Y, cd, id)\
+	}
+
+#define GENERIC_REG_LIST(id) \
+	GENERIC_GPIO_REG_LIST(id), \
+	.mux = REG(DC_GENERIC ## id),\
+
+#define GENERIC_MASK_SH_LIST(mask_sh, cd) \
+	{(DC_GENERIC ## cd ##__GENERIC ## cd ##_EN## mask_sh),\
+	(DC_GENERIC ## cd ##__GENERIC ## cd ##_SEL## mask_sh)}
+
+struct generic_registers {
+	struct gpio_registers gpio;
+	uint32_t mux;
+};
+
+struct generic_sh_mask {
+	/* enable */
+	uint32_t GENERIC_EN;
+	/* select */
+	uint32_t GENERIC_SEL;
+
+};
+
+
+#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_GPIO_GENERIC_REGS_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h
index 6e4dd3521935..7017c9337348 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h
@@ -63,6 +63,9 @@ struct hw_factory {
 		void (*define_ddc_registers)(
 				struct hw_gpio_pin *pin,
 				uint32_t en);
+		void (*define_generic_registers)(
+				struct hw_gpio_pin *pin,
+				uint32_t en);
 	} *funcs;
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c
new file mode 100644
index 000000000000..ea0a1fc8cf23
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012-15 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 "dm_services.h"
+
+#include "include/gpio_types.h"
+#include "hw_gpio.h"
+#include "hw_generic.h"
+
+#include "reg_helper.h"
+#include "generic_regs.h"
+
+#undef FN
+#define FN(reg_name, field_name) \
+	generic->shifts->field_name, generic->masks->field_name
+
+#define CTX \
+	generic->base.base.ctx
+#define REG(reg)\
+	(generic->regs->reg)
+
+static void dal_hw_generic_construct(
+	struct hw_generic *pin,
+	enum gpio_id id,
+	uint32_t en,
+	struct dc_context *ctx)
+{
+	dal_hw_gpio_construct(&pin->base, id, en, ctx);
+}
+
+static void dal_hw_generic_destruct(
+	struct hw_generic *pin)
+{
+	dal_hw_gpio_destruct(&pin->base);
+}
+
+static void destroy(
+	struct hw_gpio_pin **ptr)
+{
+	struct hw_generic *generic = HW_GENERIC_FROM_BASE(*ptr);
+
+	dal_hw_generic_destruct(generic);
+
+	kfree(generic);
+
+	*ptr = NULL;
+}
+
+static enum gpio_result set_config(
+	struct hw_gpio_pin *ptr,
+	const struct gpio_config_data *config_data)
+{
+	struct hw_generic *generic = HW_GENERIC_FROM_BASE(ptr);
+
+	if (!config_data)
+		return GPIO_RESULT_INVALID_DATA;
+
+	REG_UPDATE_2(mux,
+		GENERIC_EN, config_data->config.generic_mux.enable_output_from_mux,
+		GENERIC_SEL, config_data->config.generic_mux.mux_select);
+
+	return GPIO_RESULT_OK;
+}
+
+static const struct hw_gpio_pin_funcs funcs = {
+	.destroy = destroy,
+	.open = dal_hw_gpio_open,
+	.get_value = dal_hw_gpio_get_value,
+	.set_value = dal_hw_gpio_set_value,
+	.set_config = set_config,
+	.change_mode = dal_hw_gpio_change_mode,
+	.close = dal_hw_gpio_close,
+};
+
+static void construct(
+	struct hw_generic *generic,
+	enum gpio_id id,
+	uint32_t en,
+	struct dc_context *ctx)
+{
+	dal_hw_generic_construct(generic, id, en, ctx);
+	generic->base.base.funcs = &funcs;
+}
+
+struct hw_gpio_pin *dal_hw_generic_create(
+	struct dc_context *ctx,
+	enum gpio_id id,
+	uint32_t en)
+{
+	struct hw_generic *generic;
+
+	if (id != GPIO_ID_GENERIC) {
+		ASSERT_CRITICAL(false);
+		return NULL;
+	}
+
+	if ((en < GPIO_GENERIC_MIN) || (en > GPIO_GENERIC_MAX)) {
+		ASSERT_CRITICAL(false);
+		return NULL;
+	}
+
+	generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL);
+	if (!generic) {
+		ASSERT_CRITICAL(false);
+		return NULL;
+	}
+
+	construct(generic, id, en, ctx);
+	return &generic->base.base;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h
new file mode 100644
index 000000000000..3ea1c13e3ea6
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012-15 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 __DAL_HW_generic_H__
+#define __DAL_HW_generic_H__
+
+#include "generic_regs.h"
+
+struct hw_generic {
+	struct hw_gpio base;
+	const struct generic_registers *regs;
+	const struct generic_sh_mask *shifts;
+	const struct generic_sh_mask *masks;
+};
+
+#define HW_GENERIC_FROM_BASE(hw_gpio) \
+	container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_generic, base)
+
+struct hw_gpio_pin *dal_hw_generic_create(
+	struct dc_context *ctx,
+	enum gpio_id id,
+	uint32_t en);
+
+#endif
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 49/87] drm/amd/display: Use helper for determining HDMI signal
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (47 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 48/87] drm/amd/display: Implement generic MUX registers sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 50/87] drm/amd/display: Set FEC_READY always before link training sunpeng.li-5C7GfCeVMHo
                     ` (37 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Eric Bernstein

From: Eric Bernstein <eric.bernstein@amd.com>

Use helper to determine if HDMI signal when processing avmute.

Signed-off-by: Eric Bernstein <eric.bernstein@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 8803f6cc5414..19483fbf321b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2858,7 +2858,7 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
 {
 	struct dc  *core_dc = pipe_ctx->stream->ctx->dc;
 
-	if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A)
+	if (!dc_is_hdmi_signal(pipe_ctx->stream->signal))
 		return;
 
 	core_dc->hwss.set_avmute(pipe_ctx, enable);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 50/87] drm/amd/display: Set FEC_READY always before link training
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (48 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 49/87] drm/amd/display: Use helper for determining HDMI signal sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 51/87] drm/amd/display: put back front end initialization sequence sunpeng.li-5C7GfCeVMHo
                     ` (36 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Abdoulaye Berthe, Anthony Koo, Nikola Cornij

From: Nikola Cornij <nikola.cornij@amd.com>

[why]
Right now we FEC_READY is set only before the final link training,
i.e. at mode set time. This means FEC_READY won't be set when doing
link training as a response to HPD. It also fails UCD400 FEC test in
DP compliance.

[how]
Move FEC_READY setup to link training.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Abdoulaye Berthe <Abdoulaye.Berthe@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c  | 14 +++++---------
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c   | 18 +++++++++++++++---
 2 files changed, 20 insertions(+), 12 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 19483fbf321b..1422e74a5ffc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1521,15 +1521,6 @@ static enum dc_status enable_link_dp(
 	if (link_settings.link_rate == LINK_RATE_LOW)
 			skip_video_pattern = false;
 
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-	if (link->preferred_training_settings.fec_enable != NULL)
-		fec_enable = *link->preferred_training_settings.fec_enable;
-	else
-		fec_enable = true;
-
-	dp_set_fec_ready(link, fec_enable);
-#endif
-
 	if (link->aux_access_disabled) {
 		dc_link_dp_perform_link_training_skip_aux(link, &link_settings);
 
@@ -1547,6 +1538,11 @@ static enum dc_status enable_link_dp(
 		status = DC_FAIL_DP_LINK_TRAINING;
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	if (link->preferred_training_settings.fec_enable != NULL)
+		fec_enable = *link->preferred_training_settings.fec_enable;
+	else
+		fec_enable = true;
+
 	dp_set_fec_enable(link, fec_enable);
 #endif
 	return status;
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 4442e7b1e5b5..5c8e3318239c 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
@@ -1179,14 +1179,26 @@ enum link_training_result dc_link_dp_perform_link_training(
 	bool skip_video_pattern)
 {
 	enum link_training_result status = LINK_TRAINING_SUCCESS;
-
 	struct link_training_settings lt_settings;
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	bool fec_enable;
+#endif
 
 	initialize_training_settings(link, link_setting, &lt_settings);
 
 	/* 1. set link rate, lane count and spread. */
 	dpcd_set_link_settings(link, &lt_settings);
 
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+	if (link->preferred_training_settings.fec_enable != NULL)
+		fec_enable = *link->preferred_training_settings.fec_enable;
+	else
+		fec_enable = true;
+
+	dp_set_fec_ready(link, fec_enable);
+#endif
+
+
 	/* 2. perform link training (set link training done
 	 *  to false is done as well)
 	 */
@@ -3153,7 +3165,7 @@ void dp_set_fec_ready(struct dc_link *link, bool ready)
 
 	if (link_enc->funcs->fec_set_ready &&
 			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
-		if (link->fec_state == dc_link_fec_not_ready && ready) {
+		if (ready) {
 			fec_config = 1;
 			if (core_link_write_dpcd(link,
 					DP_FEC_CONFIGURATION,
@@ -3164,7 +3176,7 @@ void dp_set_fec_ready(struct dc_link *link, bool ready)
 			} else {
 				dm_error("dpcd write failed to set fec_ready");
 			}
-		} else if (link->fec_state == dc_link_fec_ready && !ready) {
+		} else if (link->fec_state == dc_link_fec_ready) {
 			fec_config = 0;
 			core_link_write_dpcd(link,
 					DP_FEC_CONFIGURATION,
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 51/87] drm/amd/display: put back front end initialization sequence
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (49 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 50/87] drm/amd/display: Set FEC_READY always before link training sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 52/87] drm/amd/display: Optimize gamma calculations sunpeng.li-5C7GfCeVMHo
                     ` (35 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Tony Cheng, Anthony Koo, Eric Yang

From: Eric Yang <Eric.Yang2@amd.com>

[Why]
Seamless boot optimization removed proper front end power off sequence.
In driver disable enable case, this causes driver to power gate hubp
and dpp while there is still memory fetching going on, this can cause
invalid memory requests to be generated which will hang data fabric.

[How]
Put back proper front end power off sequence

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Acked-by: Tony Cheng <Tony.Cheng@amd.com>
---
 .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

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 9f08bfb7f238..40a8198ce934 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
@@ -1194,16 +1194,7 @@ static void dcn10_init_hw(struct dc *dc)
 	 * everything down.
 	 */
 	if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
-		for (i = 0; i < dc->res_pool->pipe_count; i++) {
-			struct hubp *hubp = dc->res_pool->hubps[i];
-			struct dpp *dpp = dc->res_pool->dpps[i];
-
-			hubp->funcs->hubp_init(hubp);
-			dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
-			plane_atomic_power_down(dc, dpp, hubp);
-		}
-
-		apply_DEGVIDCN10_253_wa(dc);
+		dc->hwss.init_pipes(dc, dc->current_state);
 	}
 
 	for (i = 0; i < dc->res_pool->audio_count; i++) {
@@ -1374,10 +1365,6 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
 	return result;
 }
 
-
-
-
-
 static bool
 dcn10_set_output_transfer_func(struct pipe_ctx *pipe_ctx,
 			       const struct dc_stream_state *stream)
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 52/87] drm/amd/display: Optimize gamma calculations
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (50 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 51/87] drm/amd/display: put back front end initialization sequence sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 53/87] drm/amd/display: Clear FEC_READY shadow register if DPCD write fails sunpeng.li-5C7GfCeVMHo
                     ` (34 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Aric Cyr, Krunoslav Kovac, Anthony Koo

From: Krunoslav Kovac <Krunoslav.Kovac@amd.com>

[Why&How]

1. Stack usage is pretty high as fixed31_32 struct is 8 bytes and we
have functions with >30 vars on the stack.

2. Optimize gamma calculation by reducing number of calls to
dc_fixpt_pow Our X points are divided into 32 regions wth 16 pts each.
Each region is 2x the previous, meaning x[i] = 2*x[i-16] for i>=16.
Using (2x)^gamma = 2^gamma * x^gamma, we can recursively compute powers
of gamma, we just need first 16 pts to start it up. dc_fixpt_pow() is
expensive, it computes x^y by doing exp(y*logx) Exp is done by Taylor
series approximation, and log by Newton-like approximation that also
uses exp internally. In short, it's significantly heavier than
run-of-the-mill addition/subtraction/multiply.

Signed-off-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   1 -
 .../amd/display/modules/color/color_gamma.c   | 163 +++++++++++-------
 .../amd/display/modules/color/color_gamma.h   |   9 +
 3 files changed, 111 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 22db5682aa6c..e9a6225f4720 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -482,7 +482,6 @@ struct dc_gamma {
 	 * is_logical_identity indicates the given gamma ramp regardless of type is identity.
 	 */
 	bool is_identity;
-	bool is_logical_identity;
 };
 
 /* Used by both ipp amd opp functions*/
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index 3f413fb9f2ce..294fe4f0cb67 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -37,6 +37,33 @@ static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2];
 static struct fixed31_32 pq_table[MAX_HW_POINTS + 2];
 static struct fixed31_32 de_pq_table[MAX_HW_POINTS + 2];
 
+// these are helpers for calculations to reduce stack usage
+// do not depend on these being preserved across calls
+static struct fixed31_32 scratch_1;
+static struct fixed31_32 scratch_2;
+static struct translate_from_linear_space_args scratch_gamma_args;
+
+/* Helper to optimize gamma calculation, only use in translate_from_linear, in
+ * particular the dc_fixpt_pow function which is very expensive
+ * The idea is that our regions for X points are exponential and currently they all use
+ * the same number of points (NUM_PTS_IN_REGION) and in each region every point
+ * is exactly 2x the one at the same index in the previous region. In other words
+ * X[i] = 2 * X[i-NUM_PTS_IN_REGION] for i>=16
+ * The other fact is that (2x)^gamma = 2^gamma * x^gamma
+ * So we compute and save x^gamma for the first 16 regions, and for every next region
+ * just multiply with 2^gamma which can be computed once, and save the result so we
+ * recursively compute all the values.
+ */
+static struct fixed31_32 pow_buffer[NUM_PTS_IN_REGION];
+static struct fixed31_32 gamma_of_2; // 2^gamma
+int pow_buffer_ptr = -1;
+
+static const int32_t gamma_numerator01[] = { 31308,	180000,	0};
+static const int32_t gamma_numerator02[] = { 12920,	4500,	0};
+static const int32_t gamma_numerator03[] = { 55,	99,	0};
+static const int32_t gamma_numerator04[] = { 55,	99,	0};
+static const int32_t gamma_numerator05[] = { 2400,	2200, 2200};
+
 static bool pq_initialized; /* = false; */
 static bool de_pq_initialized; /* = false; */
 
@@ -248,11 +275,7 @@ enum gamma_type_index {
 
 static void build_coefficients(struct gamma_coefficients *coefficients, enum gamma_type_index type)
 {
-	static const int32_t numerator01[] = { 31308,	180000,	0};
-	static const int32_t numerator02[] = { 12920,	4500,	0};
-	static const int32_t numerator03[] = { 55,		99,		0};
-	static const int32_t numerator04[] = { 55,		99,		0};
-	static const int32_t numerator05[] = { 2400,	2200, 2200};
+
 
 	uint32_t i = 0;
 	uint32_t index = 0;
@@ -264,69 +287,74 @@ static void build_coefficients(struct gamma_coefficients *coefficients, enum gam
 
 	do {
 		coefficients->a0[i] = dc_fixpt_from_fraction(
-			numerator01[index], 10000000);
+			gamma_numerator01[index], 10000000);
 		coefficients->a1[i] = dc_fixpt_from_fraction(
-			numerator02[index], 1000);
+			gamma_numerator02[index], 1000);
 		coefficients->a2[i] = dc_fixpt_from_fraction(
-			numerator03[index], 1000);
+			gamma_numerator03[index], 1000);
 		coefficients->a3[i] = dc_fixpt_from_fraction(
-			numerator04[index], 1000);
+			gamma_numerator04[index], 1000);
 		coefficients->user_gamma[i] = dc_fixpt_from_fraction(
-			numerator05[index], 1000);
+			gamma_numerator05[index], 1000);
 
 		++i;
 	} while (i != ARRAY_SIZE(coefficients->a0));
 }
 
 static struct fixed31_32 translate_from_linear_space(
-	struct fixed31_32 arg,
-	struct fixed31_32 a0,
-	struct fixed31_32 a1,
-	struct fixed31_32 a2,
-	struct fixed31_32 a3,
-	struct fixed31_32 gamma)
+		struct translate_from_linear_space_args *args)
 {
 	const struct fixed31_32 one = dc_fixpt_from_int(1);
 
-	if (dc_fixpt_lt(one, arg))
+	if (dc_fixpt_le(one, args->arg))
 		return one;
 
-	if (dc_fixpt_le(arg, dc_fixpt_neg(a0)))
-		return dc_fixpt_sub(
-			a2,
-			dc_fixpt_mul(
-				dc_fixpt_add(
-					one,
-					a3),
-				dc_fixpt_pow(
-					dc_fixpt_neg(arg),
-					dc_fixpt_recip(gamma))));
-	else if (dc_fixpt_le(a0, arg))
-		return dc_fixpt_sub(
-			dc_fixpt_mul(
-				dc_fixpt_add(
-					one,
-					a3),
-				dc_fixpt_pow(
-					arg,
-					dc_fixpt_recip(gamma))),
-			a2);
+	if (dc_fixpt_le(args->arg, dc_fixpt_neg(args->a0))) {
+		scratch_1 = dc_fixpt_add(one, args->a3);
+		scratch_2 = dc_fixpt_pow(
+				dc_fixpt_neg(args->arg),
+				dc_fixpt_recip(args->gamma));
+		scratch_1 = dc_fixpt_mul(scratch_1, scratch_2);
+		scratch_1 = dc_fixpt_sub(args->a2, scratch_1);
+
+		return scratch_1;
+	} else if (dc_fixpt_le(args->a0, args->arg)) {
+		if (pow_buffer_ptr == 0) {
+			gamma_of_2 = dc_fixpt_pow(dc_fixpt_from_int(2),
+					dc_fixpt_recip(args->gamma));
+		}
+		scratch_1 = dc_fixpt_add(one, args->a3);
+		if (pow_buffer_ptr < 16)
+			scratch_2 = dc_fixpt_pow(args->arg,
+					dc_fixpt_recip(args->gamma));
+		else
+			scratch_2 = dc_fixpt_mul(gamma_of_2,
+					pow_buffer[pow_buffer_ptr%16]);
+
+		pow_buffer[pow_buffer_ptr%16] = scratch_2;
+		pow_buffer_ptr++;
+
+		scratch_1 = dc_fixpt_mul(scratch_1, scratch_2);
+		scratch_1 = dc_fixpt_sub(scratch_1, args->a2);
+
+		return scratch_1;
+	}
 	else
-		return dc_fixpt_mul(
-			arg,
-			a1);
+		return dc_fixpt_mul(args->arg, args->a1);
 }
 
 static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg)
 {
 	struct fixed31_32 gamma = dc_fixpt_from_fraction(22, 10);
 
-	return translate_from_linear_space(arg,
-			dc_fixpt_zero,
-			dc_fixpt_zero,
-			dc_fixpt_zero,
-			dc_fixpt_zero,
-			gamma);
+	scratch_gamma_args.arg = arg;
+	scratch_gamma_args.a0 = dc_fixpt_zero;
+	scratch_gamma_args.a1 = dc_fixpt_zero;
+	scratch_gamma_args.a2 = dc_fixpt_zero;
+	scratch_gamma_args.a3 = dc_fixpt_zero;
+	scratch_gamma_args.gamma = gamma;
+
+	return translate_from_linear_space(&scratch_gamma_args);
 }
 
 static struct fixed31_32 translate_to_linear_space(
@@ -362,18 +390,19 @@ static struct fixed31_32 translate_to_linear_space(
 	return linear;
 }
 
-static inline struct fixed31_32 translate_from_linear_space_ex(
+static struct fixed31_32 translate_from_linear_space_ex(
 	struct fixed31_32 arg,
 	struct gamma_coefficients *coeff,
 	uint32_t color_index)
 {
-	return translate_from_linear_space(
-		arg,
-		coeff->a0[color_index],
-		coeff->a1[color_index],
-		coeff->a2[color_index],
-		coeff->a3[color_index],
-		coeff->user_gamma[color_index]);
+	scratch_gamma_args.arg = arg;
+	scratch_gamma_args.a0 = coeff->a0[color_index];
+	scratch_gamma_args.a1 = coeff->a1[color_index];
+	scratch_gamma_args.a2 = coeff->a2[color_index];
+	scratch_gamma_args.a3 = coeff->a3[color_index];
+	scratch_gamma_args.gamma = coeff->user_gamma[color_index];
+
+	return translate_from_linear_space(&scratch_gamma_args);
 }
 
 
@@ -712,24 +741,32 @@ static void build_regamma(struct pwl_float_data_ex *rgb_regamma,
 {
 	uint32_t i;
 
-	struct gamma_coefficients coeff;
+	struct gamma_coefficients *coeff;
 	struct pwl_float_data_ex *rgb = rgb_regamma;
 	const struct hw_x_point *coord_x = coordinate_x;
 
-	build_coefficients(&coeff, type);
+	coeff = kvzalloc(sizeof(*coeff), GFP_KERNEL);
+	if (!coeff)
+		return;
 
-	i = 0;
+	build_coefficients(coeff, type);
 
-	while (i != hw_points_num + 1) {
+	memset(pow_buffer, 0, NUM_PTS_IN_REGION * sizeof(struct fixed31_32));
+	pow_buffer_ptr = 0; // see variable definition for more info
+	i = 0;
+	while (i <= hw_points_num) {
 		/*TODO use y vs r,g,b*/
 		rgb->r = translate_from_linear_space_ex(
-			coord_x->x, &coeff, 0);
+			coord_x->x, coeff, 0);
 		rgb->g = rgb->r;
 		rgb->b = rgb->r;
 		++coord_x;
 		++rgb;
 		++i;
 	}
+	pow_buffer_ptr = -1; // reset back to no optimize
+
+	kfree(coeff);
 }
 
 static void hermite_spline_eetf(struct fixed31_32 input_x,
@@ -859,6 +896,8 @@ static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma,
 	else
 		max_content = max_display;
 
+	if (!use_eetf)
+		pow_buffer_ptr = 0; // see var definition for more info
 	rgb += 32; // first 32 points have problems with fixed point, too small
 	coord_x += 32;
 	for (i = 32; i <= hw_points_num; i++) {
@@ -897,6 +936,7 @@ static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma,
 		++coord_x;
 		++rgb;
 	}
+	pow_buffer_ptr = -1;
 
 	return true;
 }
@@ -1569,14 +1609,15 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
 			output_tf->tf == TRANSFER_FUNCTION_SRGB) {
 		if (ramp == NULL)
 			return true;
-		if ((ramp->is_logical_identity) ||
+		if ((ramp->is_identity && ramp->type != GAMMA_CS_TFM_1D) ||
 				(!mapUserRamp && ramp->type == GAMMA_RGB_256))
 			return true;
 	}
 
 	output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
 
-	if (ramp && (mapUserRamp || ramp->type != GAMMA_RGB_256)) {
+	if (ramp && ramp->type != GAMMA_CS_TFM_1D &&
+			(mapUserRamp || ramp->type != GAMMA_RGB_256)) {
 		rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
 			    sizeof(*rgb_user),
 			    GFP_KERNEL);
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
index 369953fafadf..69cecd2ec251 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -82,6 +82,15 @@ struct freesync_hdr_tf_params {
 	unsigned int skip_tm; // skip tm
 };
 
+struct translate_from_linear_space_args {
+	struct fixed31_32 arg;
+	struct fixed31_32 a0;
+	struct fixed31_32 a1;
+	struct fixed31_32 a2;
+	struct fixed31_32 a3;
+	struct fixed31_32 gamma;
+};
+
 void setup_x_points_distribution(void);
 void precompute_pq(void);
 void precompute_de_pq(void);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 53/87] drm/amd/display: Clear FEC_READY shadow register if DPCD write fails
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (51 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 52/87] drm/amd/display: Optimize gamma calculations sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 54/87] drm/amd/display: Add debug option to disable timing sync sunpeng.li-5C7GfCeVMHo
                     ` (33 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Joshua Aberback, Chris Park, Nikola Cornij

From: Nikola Cornij <nikola.cornij@amd.com>

[why]
As a fail-safe, in case 'set FEC_READY' DPCD write fails, a HW shadow
register should be cleared and the internal FEC stat should be set to
'not ready'. This is to make sure HW settings will be consistent with
FEC_READY state on the RX.

Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Joshua Aberback <Joshua.Aberback@amd.com>
Acked-by: Chris Park <Chris.Park@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 ++
 1 file changed, 2 insertions(+)

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 5c8e3318239c..b512fecae061 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
@@ -3174,6 +3174,8 @@ void dp_set_fec_ready(struct dc_link *link, bool ready)
 				link_enc->funcs->fec_set_ready(link_enc, true);
 				link->fec_state = dc_link_fec_ready;
 			} else {
+				link->link_enc->funcs->fec_set_ready(link->link_enc, false);
+				link->fec_state = dc_link_fec_not_ready;
 				dm_error("dpcd write failed to set fec_ready");
 			}
 		} else if (link->fec_state == dc_link_fec_ready) {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 54/87] drm/amd/display: Add debug option to disable timing sync
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (52 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 53/87] drm/amd/display: Clear FEC_READY shadow register if DPCD write fails sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 55/87] drm/amd/display: Add MPC 3DLUT resource management sunpeng.li-5C7GfCeVMHo
                     ` (32 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Joshua Aberback, Jun Lei

From: Joshua Aberback <joshua.aberback@amd.com>

[Why]
We want a debug option to disable timing sync for testing.

[How]
New dc debug option that must be false to call program_timing_sync

Signed-off-by: Joshua Aberback <joshua.aberback@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +-
 drivers/gpu/drm/amd/display/dc/dc.h      | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 991e6d9f3628..d2948ffc3afe 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1060,7 +1060,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
 	if (result != DC_OK)
 		return result;
 
-	if (context->stream_count > 1) {
+	if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
 		enable_timing_multisync(dc, context);
 		program_timing_sync(dc, context);
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 14664bed8c84..786f61eb381d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -378,6 +378,7 @@ struct dc_debug_options {
 	 * watermarks are not affected.
 	 */
 	unsigned int force_min_dcfclk_mhz;
+	bool disable_timing_sync;
 };
 
 struct dc_debug_data {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 55/87] drm/amd/display: Add MPC 3DLUT resource management
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (53 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 54/87] drm/amd/display: Add debug option to disable timing sync sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 56/87] drm/amd/display: Add CM_BYPASS via debug option sunpeng.li-5C7GfCeVMHo
                     ` (31 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Vitaly Prosyak, Gary Kattan

From: Vitaly Prosyak <vitaly.prosyak@amd.com>

[Why & How]
Number of 3DLUT's in MPC are not equal to number of pipes.
Resource management is required.
Activate on FPGA entire tm solution  which includes
the following :hdr multiplier, shaper, 3dlut.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Gary Kattan <Gary.Kattan@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_surface.c |  3 +--
 drivers/gpu/drm/amd/display/dc/dc.h              | 16 +++++++++++++++-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c   |  4 ++--
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 394a87981614..9184f877f537 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -58,7 +58,6 @@ static void construct(struct dc_context *ctx, struct dc_plane_state *plane_state
 	plane_state->lut3d_func = dc_create_3dlut_func();
 	if (plane_state->lut3d_func != NULL) {
 		plane_state->lut3d_func->ctx = ctx;
-		plane_state->lut3d_func->initialized = false;
 	}
 	plane_state->blend_tf = dc_create_transfer_func();
 	if (plane_state->blend_tf != NULL) {
@@ -277,7 +276,7 @@ struct dc_3dlut *dc_create_3dlut_func(void)
 		goto alloc_fail;
 
 	kref_init(&lut->refcount);
-	lut->initialized = false;
+	lut->state.raw = 0;
 
 	return lut;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 786f61eb381d..421932ac3b26 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -616,12 +616,26 @@ struct dc_transfer_func {
 
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 
+union dc_3dlut_state {
+	struct {
+		uint32_t initialized:1;		/*if 3dlut is went through color module for initialization */
+		uint32_t rmu_idx_valid:1;	/*if mux settings are valid*/
+		uint32_t rmu_mux_num:3;		/*index of mux to use*/
+		uint32_t mpc_rmu0_mux:4;	/*select mpcc on mux, one of the following : mpcc0, mpcc1, mpcc2, mpcc3*/
+		uint32_t mpc_rmu1_mux:4;
+		uint32_t mpc_rmu2_mux:4;
+		uint32_t reserved:15;
+	} bits;
+	uint32_t raw;
+};
+
 
 struct dc_3dlut {
 	struct kref refcount;
 	struct tetrahedral_params lut_3d;
 	uint32_t hdr_multiplier;
-	bool initialized;
+	bool initialized; /*remove after diag fix*/
+	union dc_3dlut_state state;
 	struct dc_context *ctx;
 };
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 9c0a788fbb18..2aee663f1344 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -927,14 +927,14 @@ static bool dcn20_set_shaper_3dlut(
 
 	result = dpp_base->funcs->dpp_program_shaper_lut(dpp_base, shaper_lut);
 	if (plane_state->lut3d_func &&
-		plane_state->lut3d_func->initialized == true)
+		plane_state->lut3d_func->state.bits.initialized == 1)
 		result = dpp_base->funcs->dpp_program_3dlut(dpp_base,
 								&plane_state->lut3d_func->lut_3d);
 	else
 		result = dpp_base->funcs->dpp_program_3dlut(dpp_base, NULL);
 
 	if (plane_state->lut3d_func &&
-		plane_state->lut3d_func->initialized == true &&
+		plane_state->lut3d_func->state.bits.initialized == 1 &&
 		plane_state->lut3d_func->hdr_multiplier != 0)
 		dpp_base->funcs->dpp_set_hdr_multiplier(dpp_base,
 				plane_state->lut3d_func->hdr_multiplier);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 56/87] drm/amd/display: Add CM_BYPASS via debug option
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (54 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 55/87] drm/amd/display: Add MPC 3DLUT resource management sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 57/87] drm/amd/display: Add DIG_CLOCK_PATTERN register sunpeng.li-5C7GfCeVMHo
                     ` (30 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Qingqing Zhuo

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

[Why]
bypass CM block and MPC ogam for debug or triage use.

[How]
create a new flag cm_bypass_mode, which will set both CM_CONTROL
and MPCC_OGAM_MODE to bypass when set to 1.

Signed-off-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h                 |  3 +++
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c |  7 ++++++-
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c    | 11 +++++++++++
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h         |  1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h         |  1 +
 5 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 421932ac3b26..27900297bdcf 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -379,6 +379,9 @@ struct dc_debug_options {
 	 */
 	unsigned int force_min_dcfclk_mhz;
 	bool disable_timing_sync;
+#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
+	bool cm_in_bypass;
+#endif
 };
 
 struct dc_debug_data {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c
index e28b8e7bedf5..2d112c316424 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c
@@ -52,7 +52,12 @@ static void dpp2_enable_cm_block(
 {
 	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 
-	REG_UPDATE(CM_CONTROL, CM_BYPASS, 0);
+	unsigned int cm_bypass_mode = 0;
+	//Temp, put CM in bypass mode
+	if (dpp_base->ctx->dc->debug.cm_in_bypass)
+		cm_bypass_mode = 1;
+
+	REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
 }
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
index 240749e4cf83..f4d3008e5efa 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
@@ -368,6 +368,11 @@ void apply_DEDCN20_305_wa(
 {
 	struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
 
+	if (mpc->ctx->dc->debug.cm_in_bypass) {
+		REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0);
+		return;
+	}
+
 	if (mpc->ctx->dc->work_arounds.dedcn20_305_wa == false) {
 		/*hw fixed in new review*/
 		return;
@@ -390,10 +395,16 @@ void mpc2_set_output_gamma(
 	enum dc_lut_mode next_mode;
 	struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
 
+	if (mpc->ctx->dc->debug.cm_in_bypass) {
+		REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0);
+		return;
+	}
+
 	if (params == NULL) {
 		REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0);
 		return;
 	}
+
 	current_mode = mpc20_get_ogam_current(mpc, mpcc_id);
 	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 		next_mode = LUT_RAM_B;
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 60c671fcf186..9b69a06ab46f 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -42,6 +42,7 @@ struct dpp {
 
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 	struct pwl_params shaper_params;
+	bool cm_bypass_mode;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 45b94e319cd4..9f00289bda78 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -128,6 +128,7 @@ struct mpc {
 	struct mpcc mpcc_array[MAX_MPCC];
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 	struct pwl_params blender_params;
+	bool cm_bypass_mode;
 #endif
 };
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 57/87] drm/amd/display: Add DIG_CLOCK_PATTERN register
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (55 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 56/87] drm/amd/display: Add CM_BYPASS via debug option sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 58/87] drm/amd/display: Cache the use_pitch_c conditional sunpeng.li-5C7GfCeVMHo
                     ` (29 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Nevenko Stupar, Vitaly Prosyak

From: Nevenko Stupar <Nevenko.Stupar@amd.com>

Add this register for future use

Signed-off-by: Nevenko Stupar <Nevenko.Stupar@amd.com>
Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../drm/amd/display/dc/dcn10/dcn10_stream_encoder.h    | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
index ab0ead3c3f46..f585e7b620cc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
@@ -89,7 +89,8 @@
 	SRI(DP_VID_STREAM_CNTL, DP, id), \
 	SRI(DP_VID_TIMING, DP, id), \
 	SRI(DP_SEC_AUD_N, DP, id), \
-	SRI(DP_SEC_TIMESTAMP, DP, id)
+	SRI(DP_SEC_TIMESTAMP, DP, id), \
+	SRI(DIG_CLOCK_PATTERN, DIG, id)
 
 #define SE_DCN_REG_LIST(id)\
 	SE_COMMON_DCN_REG_LIST(id)
@@ -170,6 +171,7 @@ struct dcn10_stream_enc_registers {
 	uint32_t HDMI_METADATA_PACKET_CONTROL;
 	uint32_t DP_SEC_FRAMING4;
 #endif
+	uint32_t DIG_CLOCK_PATTERN;
 };
 
 
@@ -298,7 +300,8 @@ struct dcn10_stream_enc_registers {
 	SE_SF(DP0_DP_MSA_TIMING_PARAM4, DP_MSA_VHEIGHT, mask_sh),\
 	SE_SF(DIG0_HDMI_DB_CONTROL, HDMI_DB_DISABLE, mask_sh),\
 	SE_SF(DP0_DP_VID_TIMING, DP_VID_N_MUL, mask_sh),\
-	SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh)
+	SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh),\
+	SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh)
 
 #define SE_COMMON_MASK_SH_LIST_SOC(mask_sh)\
 	SE_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh)
@@ -460,7 +463,8 @@ struct dcn10_stream_enc_registers {
 	type HDMI_DB_DISABLE;\
 	type DP_VID_N_MUL;\
 	type DP_VID_M_DOUBLE_VALUE_EN;\
-	type DIG_SOURCE_SELECT
+	type DIG_SOURCE_SELECT;\
+	type DIG_CLOCK_PATTERN
 
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 #define SE_REG_FIELD_LIST_DCN2_0(type) \
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 58/87] drm/amd/display: Cache the use_pitch_c conditional
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (56 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 57/87] drm/amd/display: Add DIG_CLOCK_PATTERN register sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 59/87] drm/amd/display: Fixes for some MPO cases sunpeng.li-5C7GfCeVMHo
                     ` (28 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Ilya Bakoulin, Leo Li, Eric Bernstein

From: Ilya Bakoulin <Ilya.Bakoulin@amd.com>

For clarity, save the use_pitch_c logic to a bool

Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com>
Reviewed-by: Eric Bernstein <eric.bernstein@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index 02e8c0c6a233..a167f867cb72 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -402,11 +402,14 @@ void hubp2_program_size(
 {
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 	uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c;
+	bool use_pitch_c = false;
 
 	/* Program data and meta surface pitch (calculation from addrlib)
 	 * 444 or 420 luma
 	 */
-	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) {
+	use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
+		&& format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END;
+	if (use_pitch_c) {
 		ASSERT(plane_size->video.chroma_pitch != 0);
 		/* Chroma pitch zero can cause system hang! */
 
@@ -429,7 +432,8 @@ void hubp2_program_size(
 	REG_UPDATE_2(DCSURF_SURFACE_PITCH,
 			PITCH, pitch, META_PITCH, meta_pitch);
 
-	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
+	use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN;
+	if (use_pitch_c)
 		REG_UPDATE_2(DCSURF_SURFACE_PITCH_C,
 			PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c);
 }
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 59/87] drm/amd/display: Fixes for some MPO cases
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (57 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 58/87] drm/amd/display: Cache the use_pitch_c conditional sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 60/87] drm/amd/display: 3.2.41 sunpeng.li-5C7GfCeVMHo
                     ` (27 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Ilya Bakoulin, Leo Li, Dmytro Laktyushkin

From: Ilya Bakoulin <Ilya.Bakoulin@amd.com>

[Why]
Alpha could be improperly applied (only affecting half the
frame) for some source pixel formats.

[How]
Change how alpha is enabled in MPC/DPP LB and change the
bottom plane blend mode in MPC.

Signed-off-by: Ilya Bakoulin <Ilya.Bakoulin@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c   | 2 +-
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index 0bca011ed7c9..4f7a10390c57 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -211,7 +211,7 @@ struct mpcc *mpc1_insert_plane(
 	} else {
 		new_mpcc->mpcc_bot = NULL;
 		REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
-		REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_PASSTHROUGH);
+		REG_UPDATE(MPCC_CONTROL[mpcc_id], MPCC_MODE, MPCC_BLEND_MODE_TOP_LAYER_ONLY);
 	}
 	REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
 	REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 2aee663f1344..531ad4468457 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1838,7 +1838,7 @@ static void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
 {
 	struct hubp *hubp = pipe_ctx->plane_res.hubp;
 	struct mpcc_blnd_cfg blnd_cfg = { {0} };
-	bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
+	bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha;
 	int mpcc_id;
 	struct mpcc *new_mpcc;
 	struct mpc *mpc = dc->res_pool->mpc;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 60/87] drm/amd/display: 3.2.41
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (58 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 59/87] drm/amd/display: Fixes for some MPO cases sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 61/87] drm/amd/display: Hook up calls to do stereo mux and dig programming to stereo control interface sunpeng.li-5C7GfCeVMHo
                     ` (26 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 27900297bdcf..abc039b836d4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.40"
+#define DC_VER "3.2.41"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 61/87] drm/amd/display: Hook up calls to do stereo mux and dig programming to stereo control interface
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (59 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 60/87] drm/amd/display: 3.2.41 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 62/87] drm/amd/display: allocate 4 ddc engines for RV2 sunpeng.li-5C7GfCeVMHo
                     ` (25 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Murton Liu, Aric Cyr

From: Murton Liu <murton.liu@amd.com>

[Why]
Implementation of stereo mux register is complete, but unused. Need to
call functions to write relevant configs.

[How]
Add function to write stereo config for enable/disable case and call in
stereo control interface.

Signed-off-by: Murton Liu <murton.liu@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 47 ++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  3 +
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  7 ++
 .../display/dc/gpio/dcn10/hw_factory_dcn10.c  | 42 ++++++++++-
 .../drm/amd/display/dc/gpio/gpio_service.c    | 72 +++++++++++++++++++
 .../display/include/gpio_service_interface.h  | 18 ++++-
 6 files changed, 186 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index d2948ffc3afe..b57e4550e73f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1234,6 +1234,53 @@ void dc_release_state(struct dc_state *context)
 	kref_put(&context->refcount, dc_state_free);
 }
 
+bool dc_set_generic_gpio_for_stereo(bool enable,
+		struct gpio_service *gpio_service)
+{
+	enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR;
+	struct gpio_pin_info pin_info;
+	struct gpio *generic;
+	struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config),
+			   GFP_KERNEL);
+
+	pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0);
+
+	if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) {
+		kfree(config);
+		return false;
+	} else {
+		generic = dal_gpio_service_create_generic_mux(
+			gpio_service,
+			pin_info.offset,
+			pin_info.mask);
+	}
+
+	if (!generic) {
+		kfree(config);
+		return false;
+	}
+
+	gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT);
+
+	config->enable_output_from_mux = enable;
+	config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC;
+
+	if (gpio_result == GPIO_RESULT_OK)
+		gpio_result = dal_mux_setup_config(generic, config);
+
+	if (gpio_result == GPIO_RESULT_OK) {
+		dal_gpio_close(generic);
+		dal_gpio_destroy_generic_mux(&generic);
+		kfree(config);
+		return true;
+	} else {
+		dal_gpio_close(generic);
+		dal_gpio_destroy_generic_mux(&generic);
+		kfree(config);
+		return false;
+	}
+}
+
 static bool is_surface_in_context(
 		const struct dc_state *context,
 		const struct dc_plane_state *plane_state)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index abc039b836d4..b314fd2869dd 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -852,6 +852,9 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla
 
 void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info);
 
+bool dc_set_generic_gpio_for_stereo(bool enable,
+		struct gpio_service *gpio_service);
+
 /*
  * fast_validate: we return after determining if we can support the new state,
  * but before we populate the programming info
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 40a8198ce934..c22fc1568184 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
@@ -2691,6 +2691,13 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
 
 	dcn10_config_stereo_parameters(stream, &flags);
 
+	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
+		if (!dc_set_generic_gpio_for_stereo(true, dc->ctx->gpio_service))
+			dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
+	} else {
+		dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
+	}
+
 	pipe_ctx->stream_res.opp->funcs->opp_program_stereo(
 		pipe_ctx->stream_res.opp,
 		flags.PROGRAM_STEREO == 1 ? true:false,
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
index 32aa47a04a0d..5711f30cf848 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
@@ -31,6 +31,7 @@
 #include "../hw_gpio.h"
 #include "../hw_ddc.h"
 #include "../hw_hpd.h"
+#include "../hw_generic.h"
 
 #include "hw_factory_dcn10.h"
 
@@ -121,6 +122,42 @@ static const struct ddc_sh_mask ddc_mask = {
 		DDC_MASK_SH_LIST(_MASK)
 };
 
+#include "../generic_regs.h"
+
+/* set field name */
+#define SF_GENERIC(reg_name, field_name, post_fix)\
+	.field_name = reg_name ## __ ## field_name ## post_fix
+
+#define generic_regs(id) \
+{\
+	GENERIC_REG_LIST(id)\
+}
+
+static const struct generic_registers generic_regs[] = {
+	generic_regs(A),
+	generic_regs(B),
+};
+
+static const struct generic_sh_mask generic_shift[] = {
+	GENERIC_MASK_SH_LIST(__SHIFT, A),
+	GENERIC_MASK_SH_LIST(__SHIFT, B),
+};
+
+static const struct generic_sh_mask generic_mask[] = {
+	GENERIC_MASK_SH_LIST(_MASK, A),
+	GENERIC_MASK_SH_LIST(_MASK, B),
+};
+
+static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en)
+{
+	struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin);
+
+	generic->regs = &generic_regs[en];
+	generic->shifts = &generic_shift[en];
+	generic->masks = &generic_mask[en];
+	generic->base.regs = &generic_regs[en].gpio;
+}
+
 static void define_ddc_registers(
 		struct hw_gpio_pin *pin,
 		uint32_t en)
@@ -161,12 +198,13 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en)
 static const struct hw_factory_funcs funcs = {
 	.create_ddc_data = dal_hw_ddc_create,
 	.create_ddc_clock = dal_hw_ddc_create,
-	.create_generic = NULL,
+	.create_generic = dal_hw_generic_create,
 	.create_hpd = dal_hw_hpd_create,
 	.create_sync = NULL,
 	.create_gsl = NULL,
 	.define_hpd_registers = define_hpd_registers,
-	.define_ddc_registers = define_ddc_registers
+	.define_ddc_registers = define_ddc_registers,
+	.define_generic_registers = define_generic_registers
 };
 /*
  * dal_hw_factory_dcn10_init
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
index 3c63a3c04dbb..937478bac796 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
@@ -139,6 +139,62 @@ struct gpio *dal_gpio_service_create_irq(
 	return dal_gpio_create_irq(service, id, en);
 }
 
+struct gpio *dal_gpio_service_create_generic_mux(
+	struct gpio_service *service,
+	uint32_t offset,
+	uint32_t mask)
+{
+	enum gpio_id id;
+	uint32_t en;
+	struct gpio *generic;
+
+	if (mask == 1)
+		en = GPIO_GENERIC_A;
+	else if (mask == 0x00000100L)
+		en = GPIO_GENERIC_B;
+	else
+		return NULL;
+
+	id = GPIO_ID_GENERIC;
+
+	generic = dal_gpio_create(
+		service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
+
+	return generic;
+}
+
+void dal_gpio_destroy_generic_mux(
+	struct gpio **mux)
+{
+	if (!mux || !*mux) {
+		ASSERT_CRITICAL(false);
+		return;
+	}
+
+	dal_gpio_close(*mux);
+	dal_gpio_destroy(mux);
+	kfree(*mux);
+
+	*mux = NULL;
+}
+
+struct gpio_pin_info dal_gpio_get_generic_pin_info(
+	struct gpio_service *service,
+	enum gpio_id id,
+	uint32_t en)
+{
+	struct gpio_pin_info pin;
+
+	if (service->translate.funcs->id_to_offset) {
+		service->translate.funcs->id_to_offset(id, en, &pin);
+	} else {
+		pin.mask = 0xFFFFFFFF;
+		pin.offset = 0xFFFFFFFF;
+	}
+
+	return pin;
+}
+
 void dal_gpio_service_destroy(
 	struct gpio_service **ptr)
 {
@@ -163,6 +219,21 @@ void dal_gpio_service_destroy(
 	*ptr = NULL;
 }
 
+enum gpio_result dal_mux_setup_config(
+	struct gpio *mux,
+	struct gpio_generic_mux_config *config)
+{
+	struct gpio_config_data config_data;
+
+	if (!config)
+		return GPIO_RESULT_INVALID_DATA;
+
+	config_data.config.generic_mux = *config;
+	config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX;
+
+	return dal_gpio_set_config(mux, &config_data);
+}
+
 /*
  * @brief
  * Private API.
@@ -253,6 +324,7 @@ enum gpio_result dal_gpio_service_open(
 	case GPIO_ID_GENERIC:
 		pin = service->factory.funcs->create_generic(
 			service->ctx, id, en);
+		service->factory.funcs->define_generic_registers(pin, en);
 	break;
 	case GPIO_ID_HPD:
 		pin = service->factory.funcs->create_hpd(
diff --git a/drivers/gpu/drm/amd/display/include/gpio_service_interface.h b/drivers/gpu/drm/amd/display/include/gpio_service_interface.h
index f40259bade40..9c55d247227e 100644
--- a/drivers/gpu/drm/amd/display/include/gpio_service_interface.h
+++ b/drivers/gpu/drm/amd/display/include/gpio_service_interface.h
@@ -51,13 +51,29 @@ struct gpio *dal_gpio_service_create_irq(
 	uint32_t offset,
 	uint32_t mask);
 
+struct gpio *dal_gpio_service_create_generic_mux(
+	struct gpio_service *service,
+	uint32_t offset,
+	uint32_t mask);
+
+void dal_gpio_destroy_generic_mux(
+	struct gpio **mux);
+
+enum gpio_result dal_mux_setup_config(
+	struct gpio *mux,
+	struct gpio_generic_mux_config *config);
+
+struct gpio_pin_info dal_gpio_get_generic_pin_info(
+	struct gpio_service *service,
+	enum gpio_id id,
+	uint32_t en);
+
 struct ddc *dal_gpio_create_ddc(
 	struct gpio_service *service,
 	uint32_t offset,
 	uint32_t mask,
 	struct gpio_ddc_hw_info *info);
 
-
 void dal_gpio_destroy_ddc(
 	struct ddc **ddc);
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 62/87] drm/amd/display: allocate 4 ddc engines for RV2
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (60 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 61/87] drm/amd/display: Hook up calls to do stereo mux and dig programming to stereo control interface sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 63/87] drm/amd/display: add set and get clock for testing purposes sunpeng.li-5C7GfCeVMHo
                     ` (24 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr, Derek Lai

From: Derek Lai <Derek.Lai@amd.com>

[Why]
Driver will create 0, 1, and 2 ddc engines for RV2,
but some platforms used 0, 1, and 3.

[How]
Still allocate 4 ddc engines for RV2.

Signed-off-by: Derek Lai <Derek.Lai@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 29fd3cb9422b..2a01645c4bfd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -506,7 +506,7 @@ static const struct resource_caps rv2_res_cap = {
 		.num_audio = 3,
 		.num_stream_encoder = 3,
 		.num_pll = 3,
-		.num_ddc = 3,
+		.num_ddc = 4,
 };
 
 static const struct dc_plane_cap plane_cap = {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 63/87] drm/amd/display: add set and get clock for testing purposes
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (61 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 62/87] drm/amd/display: allocate 4 ddc engines for RV2 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 64/87] drm/amd/display: Change offset_to_id to reflect what id_to_offset returns sunpeng.li-5C7GfCeVMHo
                     ` (23 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

From: Charlene Liu <charlene.liu@amd.com>

add dc_set_clock
add dc_get_clock

this is for testing and diagnostics to get/set DPPCLK and DISPCLK.

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  | 23 +++++++-
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h  |  5 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 11 ++++
 drivers/gpu/drm/amd/display/dc/dc.h           |  5 ++
 drivers/gpu/drm/amd/display/dc/dc_types.h     | 13 +++++
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 53 ++++++++++++++++++-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |  5 ++
 .../gpu/drm/amd/display/dc/inc/core_status.h  |  3 ++
 .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h   |  7 +++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  9 ++++
 10 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index e9a7a7af11df..9a873e2b3736 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -316,11 +316,32 @@ void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base)
 	}
 }
 
+void dcn2_get_clock(struct clk_mgr *clk_mgr,
+		struct dc_state *context,
+			enum dc_clock_type clock_type,
+			struct dc_clock_config *clock_cfg)
+{
+
+	if (clock_type == DC_CLOCK_TYPE_DISPCLK) {
+		clock_cfg->max_clock_khz = context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz;
+		clock_cfg->min_clock_khz = DCN_MINIMUM_DISPCLK_Khz;
+		clock_cfg->current_clock_khz = clk_mgr->clks.dispclk_khz;
+		clock_cfg->bw_requirequired_clock_khz = context->bw_ctx.bw.dcn.clk.bw_dispclk_khz;
+	}
+	if (clock_type == DC_CLOCK_TYPE_DPPCLK) {
+		clock_cfg->max_clock_khz = context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz;
+		clock_cfg->min_clock_khz = DCN_MINIMUM_DPPCLK_Khz;
+		clock_cfg->current_clock_khz = clk_mgr->clks.dppclk_khz;
+		clock_cfg->bw_requirequired_clock_khz = context->bw_ctx.bw.dcn.clk.bw_dppclk_khz;
+	}
+}
+
 static struct clk_mgr_funcs dcn2_funcs = {
 	.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
 	.update_clocks = dcn2_update_clocks,
 	.init_clocks = dcn2_init_clocks,
-	.enable_pme_wa = dcn2_enable_pme_wa
+	.enable_pme_wa = dcn2_enable_pme_wa,
+	.get_clock = dcn2_get_clock,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
index 5661a5a89847..ac31a9787305 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.h
@@ -45,4 +45,9 @@ void dcn20_clk_mgr_construct(struct dc_context *ctx,
 
 uint32_t dentist_get_did_from_divider(int divider);
 
+void dcn2_get_clock(struct clk_mgr *clk_mgr,
+		struct dc_state *context,
+			enum dc_clock_type clock_type,
+			struct dc_clock_config *clock_cfg);
+
 #endif //__DCN20_CLK_MGR_H__
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index b57e4550e73f..b2004b3056af 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2429,3 +2429,14 @@ void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx
 	info->fClock					= (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz;
 	info->phyClock					= (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz;
 }
+enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping)
+{
+	if (dc->hwss.set_clock)
+		return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping);
+	return DC_ERROR_UNEXPECTED;
+}
+void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg)
+{
+	if (dc->hwss.get_clock)
+		dc->hwss.get_clock(dc, clock_type, clock_cfg);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index b314fd2869dd..a5b5afd48a7b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -252,7 +252,10 @@ enum wm_report_mode {
 struct dc_clocks {
 	int dispclk_khz;
 	int max_supported_dppclk_khz;
+	int max_supported_dispclk_khz;
 	int dppclk_khz;
+	int bw_dppclk_khz; /*a copy of dppclk_khz*/
+	int bw_dispclk_khz;
 	int dcfclk_khz;
 	int socclk_khz;
 	int dcfclk_deep_sleep_khz;
@@ -1041,6 +1044,8 @@ unsigned int dc_get_target_backlight_pwm(struct dc *dc);
 
 bool dc_is_dmcu_initialized(struct dc *dc);
 
+enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping);
+void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg);
 #if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT)
 /*******************************************************************************
  * DSC Interfaces
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index ce6d73d21cca..b273735b6a3e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -726,6 +726,19 @@ struct AsicStateEx {
 	unsigned int phyClock;
 };
 
+
+enum dc_clock_type {
+	DC_CLOCK_TYPE_DISPCLK = 0,
+	DC_CLOCK_TYPE_DPPCLK        = 1,
+};
+
+struct dc_clock_config {
+	uint32_t max_clock_khz;
+	uint32_t min_clock_khz;
+	uint32_t bw_requirequired_clock_khz;
+	uint32_t current_clock_khz;/*current clock in use*/
+};
+
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
 /* DSC DPCD capabilities */
 union dsc_slice_caps1 {
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 c22fc1568184..58d118a3ee8e 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
@@ -3068,6 +3068,56 @@ static void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
 				sdp_message_size);
 	}
 }
+static enum dc_status dcn10_set_clock(struct dc *dc,
+			enum dc_clock_type clock_type,
+			uint32_t clk_khz,
+			uint32_t stepping)
+{
+	struct dc_state *context = dc->current_state;
+	struct dc_clock_config clock_cfg = {0};
+	struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk;
+
+	if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+				dc->clk_mgr->funcs->get_clock(dc->clk_mgr,
+						context, clock_type, &clock_cfg);
+
+	if (!dc->clk_mgr->funcs->get_clock)
+		return DC_FAIL_UNSUPPORTED_1;
+
+	if (clk_khz > clock_cfg.max_clock_khz)
+		return DC_FAIL_CLK_EXCEED_MAX;
+
+	if (clk_khz < clock_cfg.min_clock_khz)
+		return DC_FAIL_CLK_BELOW_MIN;
+
+	if (clk_khz < clock_cfg.bw_requirequired_clock_khz)
+		return DC_FAIL_CLK_BELOW_CFG_REQUIRED;
+
+	/*update internal request clock for update clock use*/
+	if (clock_type == DC_CLOCK_TYPE_DISPCLK)
+		current_clocks->dispclk_khz = clk_khz;
+	else if (clock_type == DC_CLOCK_TYPE_DPPCLK)
+		current_clocks->dppclk_khz = clk_khz;
+	else
+		return DC_ERROR_UNEXPECTED;
+
+	if (dc->clk_mgr && dc->clk_mgr->funcs->update_clocks)
+				dc->clk_mgr->funcs->update_clocks(dc->clk_mgr,
+				context, true);
+	return DC_OK;
+
+}
+
+static void dcn10_get_clock(struct dc *dc,
+			enum dc_clock_type clock_type,
+			struct dc_clock_config *clock_cfg)
+{
+	struct dc_state *context = dc->current_state;
+
+	if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock)
+				dc->clk_mgr->funcs->get_clock(dc->clk_mgr, context, clock_type, clock_cfg);
+
+}
 
 static const struct hw_sequencer_funcs dcn10_funcs = {
 	.program_gamut_remap = program_gamut_remap,
@@ -3122,7 +3172,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
 	.enable_stream_gating = NULL,
 	.setup_periodic_interrupt = dcn10_setup_periodic_interrupt,
 	.setup_vupdate_interrupt = dcn10_setup_vupdate_interrupt,
-	.did_underflow_occur = dcn10_did_underflow_occur
+	.set_clock = dcn10_set_clock,
+	.get_clock = dcn10_get_clock,
 };
 
 
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 022d0f38723b..158743b165e8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2396,6 +2396,11 @@ void dcn20_calculate_dlg_params(
 		context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest;
 		pipe_idx++;
 	}
+	/*save a original dppclock copy*/
+	context->bw_ctx.bw.dcn.clk.bw_dppclk_khz = context->bw_ctx.bw.dcn.clk.dppclk_khz;
+	context->bw_ctx.bw.dcn.clk.bw_dispclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz;
+	context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dppclk_mhz*1000;
+	context->bw_ctx.bw.dcn.clk.max_supported_dispclk_khz = context->bw_ctx.dml.soc.clock_limits[vlevel].dispclk_mhz*1000;
 
 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
 		bool cstate_en = context->bw_ctx.dml.vba.PrefetchMode[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != 2;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
index 0a094d7c9380..fd39e2abe2ed 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
@@ -48,6 +48,9 @@ enum dc_status {
 	DC_NO_DSC_RESOURCE = 17,
 #endif
 	DC_FAIL_UNSUPPORTED_1 = 18,
+	DC_FAIL_CLK_EXCEED_MAX = 21,
+	DC_FAIL_CLK_BELOW_MIN = 22, /*THIS IS MIN PER IP*/
+	DC_FAIL_CLK_BELOW_CFG_REQUIRED = 23, /*THIS IS hard_min in PPLIB*/
 
 	DC_ERROR_UNEXPECTED = -1
 };
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
index 36ebd5bc7863..938bdc5c21a1 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
@@ -28,6 +28,9 @@
 
 #include "dc.h"
 
+#define DCN_MINIMUM_DISPCLK_Khz 100000
+#define DCN_MINIMUM_DPPCLK_Khz 100000
+
 /* Public interfaces */
 
 struct clk_states {
@@ -51,6 +54,10 @@ struct clk_mgr_funcs {
 	void (*init_clocks)(struct clk_mgr *clk_mgr);
 
 	void (*enable_pme_wa) (struct clk_mgr *clk_mgr);
+	void (*get_clock)(struct clk_mgr *clk_mgr,
+			struct dc_state *context,
+			enum dc_clock_type clock_type,
+			struct dc_clock_config *clock_cfg);
 };
 
 struct clk_mgr {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 4d56d48a3179..36be08adae05 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -294,6 +294,15 @@ struct hw_sequencer_funcs {
 	void (*disable_writeback)(struct dc *dc,
 			unsigned int dwb_pipe_inst);
 #endif
+	enum dc_status (*set_clock)(struct dc *dc,
+			enum dc_clock_type clock_type,
+			uint32_t clk_khz,
+			uint32_t stepping);
+
+	void (*get_clock)(struct dc *dc,
+			enum dc_clock_type clock_type,
+			struct dc_clock_config *clock_cfg);
+
 };
 
 void color_space_to_black_color(
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 64/87] drm/amd/display: Change offset_to_id to reflect what id_to_offset returns
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (62 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 63/87] drm/amd/display: add set and get clock for testing purposes sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 65/87] drm/amd/display: init res_pool dccg_ref, dchub_ref with xtalin_freq sunpeng.li-5C7GfCeVMHo
                     ` (22 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Murton Liu, Aric Cyr

From: Murton Liu <murton.liu@amd.com>

id_to_offset does not point to the same reg offset that offset_to_id checks for,
causing unintended asserts

Signed-off-by: Murton Liu <murton.liu@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c |  2 +-
 drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c     | 10 +++-------
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c
index b393cc13298a..915e896e0e91 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c
@@ -71,7 +71,7 @@ static bool offset_to_id(
 {
 	switch (offset) {
 	/* GENERIC */
-	case REG(DC_GENERICA):
+	case REG(DC_GPIO_GENERIC_A):
 		*id = GPIO_ID_GENERIC;
 		switch (mask) {
 		case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
index 937478bac796..80f938e68285 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
@@ -148,14 +148,10 @@ struct gpio *dal_gpio_service_create_generic_mux(
 	uint32_t en;
 	struct gpio *generic;
 
-	if (mask == 1)
-		en = GPIO_GENERIC_A;
-	else if (mask == 0x00000100L)
-		en = GPIO_GENERIC_B;
-	else
+	if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
+		ASSERT_CRITICAL(false);
 		return NULL;
-
-	id = GPIO_ID_GENERIC;
+	}
 
 	generic = dal_gpio_create(
 		service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 65/87] drm/amd/display: init res_pool dccg_ref, dchub_ref with xtalin_freq
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (63 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 64/87] drm/amd/display: Change offset_to_id to reflect what id_to_offset returns sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 66/87] drm/amd/display: add a option to force the clock at every mode change sunpeng.li-5C7GfCeVMHo
                     ` (21 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, hersen wu

From: hersen wu <hersenxs.wu@amd.com>

[WHY] dc sw clock implementation of navi10 and raven are not exact the
same. dcccg, dchub reference clock initialization is done after dc calls
vbios dispcontroller_init table. for raven family, before
dispcontroller_init is called by dc, the ref clk values are referred
by sw clock implementation and program asic register using wrong
values. this causes dchub pstate error. This need provide valid ref
clk values. for navi10, since dispcontroller_init is not called,
dchubbub_global_timer_enable = 0, hubbub2_get_dchub_ref_freq will
hit aeert. this need remove hubbub2_get_dchub_ref_freq from this
location and move to dcn20_init_hw.

[HOW] for all asic, initialize dccg, dchub ref clk with data from
vbios firmware table by default. for raven asic family, use these data
from vbios, for asic which support sw dccg component, like navi10,
read ref clk by sw dccg functions and update the ref clk.

Signed-off-by: hersen wu <hersenxs.wu@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 42 +++++++------------
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 25 +++++++++++
 2 files changed, 41 insertions(+), 26 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 5e7b8b2dd178..b567b2159f1a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -172,32 +172,22 @@ struct resource_pool *dc_create_resource_pool(struct dc  *dc,
 	if (res_pool != NULL) {
 		struct dc_firmware_info fw_info = { { 0 } };
 
-		if (dc->ctx->dc_bios->funcs->get_firmware_info(
-				dc->ctx->dc_bios, &fw_info) == BP_RESULT_OK) {
-				res_pool->ref_clocks.xtalin_clock_inKhz = fw_info.pll_info.crystal_frequency;
-
-				if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
-					// On FPGA these dividers are currently not configured by GDB
-					res_pool->ref_clocks.dccg_ref_clock_inKhz = res_pool->ref_clocks.xtalin_clock_inKhz;
-					res_pool->ref_clocks.dchub_ref_clock_inKhz = res_pool->ref_clocks.xtalin_clock_inKhz;
-				} else if (res_pool->dccg && res_pool->hubbub) {
-					// If DCCG reference frequency cannot be determined (usually means not set to xtalin) then this is a critical error
-					// as this value must be known for DCHUB programming
-					(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
-							fw_info.pll_info.crystal_frequency,
-							&res_pool->ref_clocks.dccg_ref_clock_inKhz);
-
-					// Similarly, if DCHUB reference frequency cannot be determined, then it is also a critical error
-					(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
-							res_pool->ref_clocks.dccg_ref_clock_inKhz,
-							&res_pool->ref_clocks.dchub_ref_clock_inKhz);
-				} else {
-					// Not all ASICs have DCCG sw component
-					res_pool->ref_clocks.dccg_ref_clock_inKhz = res_pool->ref_clocks.xtalin_clock_inKhz;
-					res_pool->ref_clocks.dchub_ref_clock_inKhz = res_pool->ref_clocks.xtalin_clock_inKhz;
-				}
-			} else
-				ASSERT_CRITICAL(false);
+		if (dc->ctx->dc_bios->funcs->get_firmware_info(dc->ctx->dc_bios,
+				&fw_info) == BP_RESULT_OK) {
+			res_pool->ref_clocks.xtalin_clock_inKhz =
+				fw_info.pll_info.crystal_frequency;
+			/* initialize with firmware data first, no all
+			 * ASIC have DCCG SW component. FPGA or
+			 * simulation need initialization of
+			 * dccg_ref_clock_inKhz, dchub_ref_clock_inKhz
+			 * with xtalin_clock_inKhz
+			 */
+			res_pool->ref_clocks.dccg_ref_clock_inKhz =
+				res_pool->ref_clocks.xtalin_clock_inKhz;
+			res_pool->ref_clocks.dchub_ref_clock_inKhz =
+				res_pool->ref_clocks.xtalin_clock_inKhz;
+		} else
+			ASSERT_CRITICAL(false);
 	}
 
 	return res_pool;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 531ad4468457..566cd4cdfef4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -562,6 +562,7 @@ static void dcn20_init_hw(struct dc *dc)
 	struct dc_bios *dcb = dc->ctx->dc_bios;
 	struct resource_pool *res_pool = dc->res_pool;
 	struct dc_state  *context = dc->current_state;
+	struct dc_firmware_info fw_info = { { 0 } };
 
 	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
 		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
@@ -585,6 +586,30 @@ static void dcn20_init_hw(struct dc *dc)
 	} else {
 		if (!dcb->funcs->is_accelerated_mode(dcb)) {
 			bios_golden_init(dc);
+			if (dc->ctx->dc_bios->funcs->get_firmware_info(
+					dc->ctx->dc_bios, &fw_info) == BP_RESULT_OK) {
+				res_pool->ref_clocks.xtalin_clock_inKhz = fw_info.pll_info.crystal_frequency;
+
+				if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+					if (res_pool->dccg && res_pool->hubbub) {
+
+						(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
+								fw_info.pll_info.crystal_frequency,
+								&res_pool->ref_clocks.dccg_ref_clock_inKhz);
+
+						(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,
+								res_pool->ref_clocks.dccg_ref_clock_inKhz,
+								&res_pool->ref_clocks.dchub_ref_clock_inKhz);
+					} else {
+						// Not all ASICs have DCCG sw component
+						res_pool->ref_clocks.dccg_ref_clock_inKhz =
+								res_pool->ref_clocks.xtalin_clock_inKhz;
+						res_pool->ref_clocks.dchub_ref_clock_inKhz =
+								res_pool->ref_clocks.xtalin_clock_inKhz;
+					}
+				}
+			} else
+				ASSERT_CRITICAL(false);
 			disable_vga(dc->hwseq);
 		}
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 66/87] drm/amd/display: add a option to force the clock at every mode change.
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (64 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 65/87] drm/amd/display: init res_pool dccg_ref, dchub_ref with xtalin_freq sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 67/87] drm/amd/display: use min disp and dpp clk debug option for dcn2 sunpeng.li-5C7GfCeVMHo
                     ` (20 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

From: Charlene Liu <charlene.liu@amd.com>

[Description]
This is for HW negative stress testing use.
force reset the dispclk and dppclk even the same clock already set in HW.

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 9 ++++++++-
 drivers/gpu/drm/amd/display/dc/dc.h                      | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 9a873e2b3736..3cff4f0518d3 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -151,7 +151,14 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 	bool enter_display_off = false;
 	bool dpp_clock_lowered = false;
 	struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
+	bool force_reset = false;
 
+	if (clk_mgr_base->clks.dispclk_khz == 0 ||
+		dc->debug.force_clock_mode & 0x1) {
+		//this is from resume or boot up, if forced_clock cfg option used, we bypass program dispclk and DPPCLK, but need set them for S3.
+		force_reset = true;
+		//force_clock_mode 0x1:  force reset the clock even it is the same clock as long as it is in Passive level.
+	}
 	display_count = clk_mgr_helper_get_active_display_cnt(dc, context);
 	if (dc->res_pool->pp_smu)
 		pp_smu = &dc->res_pool->pp_smu->nv_funcs;
@@ -223,7 +230,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 
 		update_dispclk = true;
 	}
-	if (dc->config.forced_clocks == false) {
+	if (dc->config.forced_clocks == false || (force_reset && safe_to_lower)) {
 		if (dpp_clock_lowered) {
 			// if clock is being lowered, increase DTO before lowering refclk
 			dcn20_update_clocks_update_dpp_dto(clk_mgr, context);
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index a5b5afd48a7b..584fabf5a9a1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -385,6 +385,7 @@ struct dc_debug_options {
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 	bool cm_in_bypass;
 #endif
+	int force_clock_mode;/*every mode change.*/
 };
 
 struct dc_debug_data {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 67/87] drm/amd/display: use min disp and dpp clk debug option for dcn2
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (65 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 66/87] drm/amd/display: add a option to force the clock at every mode change sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 68/87] drm/amd/display: add pipe CRC sources without disabling dithering sunpeng.li-5C7GfCeVMHo
                     ` (19 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Dmytro Laktyushkin, Tony Cheng

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

This allows to set a minimum display and dpp clock on dcn2+ HW
by adjusting clocks used for dml calculations.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc.h                   | 1 +
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 584fabf5a9a1..489f6240f2ed 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -344,6 +344,7 @@ struct dc_debug_options {
 	bool disable_pplib_wm_range;
 	enum wm_report_mode pplib_wm_report_mode;
 	unsigned int min_disp_clk_khz;
+	unsigned int min_dpp_clk_khz;
 	int sr_exit_time_dpm0_ns;
 	int sr_enter_plus_exit_time_dpm0_ns;
 	int sr_exit_time_ns;
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 158743b165e8..5571b8bfc942 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2168,10 +2168,6 @@ bool dcn20_fast_validate_bw(
 		}
 		if (force_split && context->bw_ctx.dml.vba.NoOfDPP[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] == 1)
 			context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] /= 2;
-		if (dc->config.forced_clocks == true) {
-			context->bw_ctx.dml.vba.RequiredDPPCLK[vlevel][context->bw_ctx.dml.vba.maxMpcComb][pipe_idx] =
-					context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
-		}
 		if (!pipe->top_pipe && !pipe->plane_state && context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx]) {
 			hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, dc->res_pool, pipe);
 			ASSERT(hsplit_pipe);
@@ -2291,6 +2287,10 @@ void dcn20_calculate_wm(
 				pipes[pipe_cnt].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
 				pipes[pipe_cnt].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
 			}
+			if (dc->debug.min_disp_clk_khz > pipes[pipe_cnt].clks_cfg.dispclk_mhz * 1000)
+				pipes[pipe_cnt].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
+			if (dc->debug.min_dpp_clk_khz > pipes[pipe_cnt].clks_cfg.dppclk_mhz * 1000)
+				pipes[pipe_cnt].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
 
 			pipe_cnt++;
 		}
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 68/87] drm/amd/display: add pipe CRC sources without disabling dithering.
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (66 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 67/87] drm/amd/display: use min disp and dpp clk debug option for dcn2 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 69/87] drm/amd/display: Implement DAL3 GPU Integer Scaling sunpeng.li-5C7GfCeVMHo
                     ` (18 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Hanghong Ma, Dingchen Zhang

From: Dingchen Zhang <dingchen.zhang@amd.com>

[Why]
need to verify the impact of spatial dithering on 8bpc bypass mode.

[How]
added CRC sources and configure dihter option from dc stream.

Signed-off-by: Dingchen Zhang <dingchen.zhang@amd.com>
Reviewed-by: Hanghong Ma <Hanghong.Ma@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 58 ++++++++++++++-----
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h |  6 +-
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index 7436c2e5a0a9..b01256a4692e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -32,7 +32,9 @@
 static const char *const pipe_crc_sources[] = {
 	"none",
 	"crtc",
+	"crtc dither",
 	"dprx",
+	"dprx dither",
 	"auto",
 };
 
@@ -44,10 +46,33 @@ static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
 		return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC;
 	if (!strcmp(source, "dprx"))
 		return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX;
+	if (!strcmp(source, "crtc dither"))
+		return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER;
+	if (!strcmp(source, "dprx dither"))
+		return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER;
 
 	return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID;
 }
 
+static bool dm_is_crc_source_crtc(enum amdgpu_dm_pipe_crc_source src)
+{
+	return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER);
+}
+
+static bool dm_is_crc_source_dprx(enum amdgpu_dm_pipe_crc_source src)
+{
+	return (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER);
+}
+
+static bool dm_need_crc_dither(enum amdgpu_dm_pipe_crc_source src)
+{
+	return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_NONE);
+}
+
 const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc,
 						  size_t *count)
 {
@@ -101,14 +126,18 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 	 * USER REQ SRC | CURRENT SRC | BEHAVIOR
 	 * -----------------------------
 	 * None         | None        | Do nothing
-	 * None         | CRTC        | Disable CRTC CRC
-	 * None         | DPRX        | Disable DPRX CRC, need 'aux'
-	 * CRTC         | XXXX        | Enable CRTC CRC, configure DC strm
-	 * DPRX         | XXXX        | Enable DPRX CRC, need 'aux'
+	 * None         | CRTC        | Disable CRTC CRC, set default to dither
+	 * None         | DPRX        | Disable DPRX CRC, need 'aux', set default to dither
+	 * None         | CRTC DITHER | Disable CRTC CRC
+	 * None         | DPRX DITHER | Disable DPRX CRC, need 'aux'
+	 * CRTC         | XXXX        | Enable CRTC CRC, no dither
+	 * DPRX         | XXXX        | Enable DPRX CRC, need 'aux', no dither
+	 * CRTC DITHER  | XXXX        | Enable CRTC CRC, set dither
+	 * DPRX DITHER  | XXXX        | Enable DPRX CRC, need 'aux', set dither
 	 */
-	if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX ||
+	if (dm_is_crc_source_dprx(source) ||
 		(source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE &&
-		 crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX)) {
+		 dm_is_crc_source_dprx(crtc_state->crc_src))) {
 		aconn = stream_state->link->priv;
 
 		if (!aconn) {
@@ -124,7 +153,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 			mutex_unlock(&adev->dm.dc_lock);
 			return -EINVAL;
 		}
-	} else if (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) {
+	} else if (dm_is_crc_source_crtc(source)) {
 		if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
 					     enable, enable)) {
 			mutex_unlock(&adev->dm.dc_lock);
@@ -132,10 +161,11 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 		}
 	}
 
-	/* When enabling CRC, we should also disable dithering. */
-	dc_stream_set_dither_option(stream_state,
-				    enable ? DITHER_OPTION_TRUN8
-					   : DITHER_OPTION_DEFAULT);
+	/* configure dithering */
+	if (!dm_need_crc_dither(source))
+		dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8);
+	else if (!dm_need_crc_dither(crtc_state->crc_src))
+		dc_stream_set_dither_option(stream_state, DITHER_OPTION_DEFAULT);
 
 	mutex_unlock(&adev->dm.dc_lock);
 
@@ -146,7 +176,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 	enabled = amdgpu_dm_is_valid_crc_source(crtc_state->crc_src);
 	if (!enabled && enable) {
 		drm_crtc_vblank_get(crtc);
-		if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) {
+		if (dm_is_crc_source_dprx(source)) {
 			if (drm_dp_start_crc(aux, crtc)) {
 				DRM_DEBUG_DRIVER("dp start crc failed\n");
 				return -EINVAL;
@@ -154,7 +184,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 		}
 	} else if (enabled && !enable) {
 		drm_crtc_vblank_put(crtc);
-		if (crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) {
+		if (dm_is_crc_source_dprx(source)) {
 			if (drm_dp_stop_crc(aux)) {
 				DRM_DEBUG_DRIVER("dp stop crc failed\n");
 				return -EINVAL;
@@ -203,7 +233,7 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
 		return;
 	}
 
-	if (crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) {
+	if (dm_is_crc_source_crtc(crtc_state->crc_src)) {
 		if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
 				       &crcs[0], &crcs[1], &crcs[2]))
 			return;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
index b63a9011f511..14de7301c28d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
@@ -29,15 +29,17 @@
 enum amdgpu_dm_pipe_crc_source {
 	AMDGPU_DM_PIPE_CRC_SOURCE_NONE = 0,
 	AMDGPU_DM_PIPE_CRC_SOURCE_CRTC,
+	AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER,
 	AMDGPU_DM_PIPE_CRC_SOURCE_DPRX,
+	AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER,
 	AMDGPU_DM_PIPE_CRC_SOURCE_MAX,
 	AMDGPU_DM_PIPE_CRC_SOURCE_INVALID = -1,
 };
 
 static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source source)
 {
-	return (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) ||
-		   (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX);
+	return (source > AMDGPU_DM_PIPE_CRC_SOURCE_NONE) &&
+	       (source < AMDGPU_DM_PIPE_CRC_SOURCE_MAX);
 }
 
 /* amdgpu_dm_crc.c */
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 69/87] drm/amd/display: Implement DAL3 GPU Integer Scaling
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (67 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 68/87] drm/amd/display: add pipe CRC sources without disabling dithering sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 70/87] drm/amd/display: add dcc programming for dual plane sunpeng.li-5C7GfCeVMHo
                     ` (17 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Aric Cyr, Reza Amini, Tony Cheng

From: Reza Amini <Reza.Amini@amd.com>

[WHY]
Users want to not have filtering when scaling by integer
multiples to native timing.

[HOW]
If timing is a multiple integer of view, we set number of taps
to 1 (effectivly closest neighbour).

Signed-off-by: Reza Amini <Reza.Amini@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Acked-by: Tony Cheng <Tony.Cheng@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c    | 16 ++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h     |  1 +
 2 files changed, 17 insertions(+)

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 b567b2159f1a..31a49c59c278 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -937,7 +937,14 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx)
 	data->inits.v_c_bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
 
 }
+static bool are_rect_integer_multiples(struct rect src, struct rect dest)
+{
+	if (dest.width  >= src.width  && dest.width  % src.width  == 0 &&
+		dest.height >= src.height && dest.height % src.height == 0)
+		return true;
 
+	return false;
+}
 bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 {
 	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
@@ -980,6 +987,15 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 	if (pipe_ctx->plane_res.dpp != NULL)
 		res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
 				pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+	if (res &&
+	    plane_state->scaling_quality.integer_scaling &&
+	    are_rect_integer_multiples(pipe_ctx->plane_res.scl_data.viewport,
+				       pipe_ctx->plane_res.scl_data.recout)) {
+		pipe_ctx->plane_res.scl_data.taps.v_taps = 1;
+		pipe_ctx->plane_res.scl_data.taps.h_taps = 1;
+	}
+
 	if (!res) {
 		/* Try 24 bpp linebuffer */
 		pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_24BPP;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index e9a6225f4720..28a2cd2d2a49 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -614,6 +614,7 @@ struct scaling_taps {
 	uint32_t h_taps;
 	uint32_t v_taps_c;
 	uint32_t h_taps_c;
+	bool integer_scaling;
 };
 
 enum dc_timing_standard {
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 70/87] drm/amd/display: add dcc programming for dual plane
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (68 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 69/87] drm/amd/display: Implement DAL3 GPU Integer Scaling sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 71/87] drm/amd/display: populate last calculated bb state with max clocks sunpeng.li-5C7GfCeVMHo
                     ` (16 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Dmytro Laktyushkin

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

Add dual plane dcc programming support for
surfaces.

Removes unions from plane size and dcc params as they
serve no practical purpose only making our code
more convoluted. This results in easy dual plane
dcc and surface size programming.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 +++++++--------
 .../gpu/drm/amd/display/dc/calcs/dce_calcs.c  |  2 +-
 .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c  |  2 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 10 ++--
 .../gpu/drm/amd/display/dc/core/dc_debug.c    | 40 +++++++-------
 drivers/gpu/drm/amd/display/dc/dc.h           |  4 +-
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  | 54 +++++++++----------
 .../drm/amd/display/dc/dce/dce_mem_input.c    | 10 ++--
 .../display/dc/dce110/dce110_mem_input_v.c    | 42 +++++++--------
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 20 +++----
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h |  4 +-
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  4 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 20 +++----
 .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h |  4 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 12 ++---
 drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h  |  2 +-
 .../gpu/drm/amd/display/dc/inc/hw/mem_input.h |  2 +-
 17 files changed, 136 insertions(+), 138 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 96b32c203561..492258937d50 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2743,7 +2743,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 			  const struct amdgpu_framebuffer *afb,
 			  const enum surface_pixel_format format,
 			  const enum dc_rotation_angle rotation,
-			  const union plane_size *plane_size,
+			  const struct plane_size *plane_size,
 			  const union dc_tiling_info *tiling_info,
 			  const uint64_t info,
 			  struct dc_plane_dcc_param *dcc,
@@ -2769,8 +2769,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 		return -EINVAL;
 
 	input.format = format;
-	input.surface_size.width = plane_size->grph.surface_size.width;
-	input.surface_size.height = plane_size->grph.surface_size.height;
+	input.surface_size.width = plane_size->surface_size.width;
+	input.surface_size.height = plane_size->surface_size.height;
 	input.swizzle_mode = tiling_info->gfx9.swizzle;
 
 	if (rotation == ROTATION_ANGLE_0 || rotation == ROTATION_ANGLE_180)
@@ -2788,9 +2788,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 		return -EINVAL;
 
 	dcc->enable = 1;
-	dcc->grph.meta_pitch =
+	dcc->meta_pitch =
 		AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
-	dcc->grph.independent_64b_blks = i64b;
+	dcc->independent_64b_blks = i64b;
 
 	dcc_address = get_dcc_address(afb->address, info);
 	address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
@@ -2806,7 +2806,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 			     const enum dc_rotation_angle rotation,
 			     const uint64_t tiling_flags,
 			     union dc_tiling_info *tiling_info,
-			     union plane_size *plane_size,
+			     struct plane_size *plane_size,
 			     struct dc_plane_dcc_param *dcc,
 			     struct dc_plane_address *address)
 {
@@ -2819,11 +2819,11 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 	memset(address, 0, sizeof(*address));
 
 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
-		plane_size->grph.surface_size.x = 0;
-		plane_size->grph.surface_size.y = 0;
-		plane_size->grph.surface_size.width = fb->width;
-		plane_size->grph.surface_size.height = fb->height;
-		plane_size->grph.surface_pitch =
+		plane_size->surface_size.x = 0;
+		plane_size->surface_size.y = 0;
+		plane_size->surface_size.width = fb->width;
+		plane_size->surface_size.height = fb->height;
+		plane_size->surface_pitch =
 			fb->pitches[0] / fb->format->cpp[0];
 
 		address->type = PLN_ADDR_TYPE_GRAPHICS;
@@ -2832,20 +2832,20 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 	} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
 		uint64_t chroma_addr = afb->address + fb->offsets[1];
 
-		plane_size->video.luma_size.x = 0;
-		plane_size->video.luma_size.y = 0;
-		plane_size->video.luma_size.width = fb->width;
-		plane_size->video.luma_size.height = fb->height;
-		plane_size->video.luma_pitch =
+		plane_size->surface_size.x = 0;
+		plane_size->surface_size.y = 0;
+		plane_size->surface_size.width = fb->width;
+		plane_size->surface_size.height = fb->height;
+		plane_size->surface_pitch =
 			fb->pitches[0] / fb->format->cpp[0];
 
-		plane_size->video.chroma_size.x = 0;
-		plane_size->video.chroma_size.y = 0;
+		plane_size->chroma_size.x = 0;
+		plane_size->chroma_size.y = 0;
 		/* TODO: set these based on surface format */
-		plane_size->video.chroma_size.width = fb->width / 2;
-		plane_size->video.chroma_size.height = fb->height / 2;
+		plane_size->chroma_size.width = fb->width / 2;
+		plane_size->chroma_size.height = fb->height / 2;
 
-		plane_size->video.chroma_pitch =
+		plane_size->chroma_pitch =
 			fb->pitches[1] / fb->format->cpp[1];
 
 		address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
index f3aa7b53d2aa..fdab16ea0a2e 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
@@ -2850,7 +2850,7 @@ static void populate_initial_data(
 			data->src_height[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.viewport.height);
 			data->src_width[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.viewport.width);
 			data->pitch_in_pixels[num_displays * 2 + j] = bw_int_to_fixed(
-					pipe[i].bottom_pipe->plane_state->plane_size.grph.surface_pitch);
+					pipe[i].bottom_pipe->plane_state->plane_size.surface_pitch);
 			data->h_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.taps.h_taps);
 			data->v_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.taps.v_taps);
 			data->h_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
index 38365dd911a3..061c6e3a3088 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -329,7 +329,7 @@ static void pipe_ctx_to_e2e_pipe_params (
 			dcc_support_pixel_format(pipe->plane_state->format, &bpe) ? 1 : 0;
 	}
 	input->src.dcc_rate            = 1;
-	input->src.meta_pitch          = pipe->plane_state->dcc.grph.meta_pitch;
+	input->src.meta_pitch          = pipe->plane_state->dcc.meta_pitch;
 	input->src.source_scan         = dm_horz;
 	input->src.sw_mode             = pipe->plane_state->tiling_info.gfx9.swizzle;
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index b2004b3056af..63d0f1386f4e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1347,8 +1347,8 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
 	}
 
 	if (u->plane_info->dcc.enable != u->surface->dcc.enable
-			|| u->plane_info->dcc.grph.independent_64b_blks != u->surface->dcc.grph.independent_64b_blks
-			|| u->plane_info->dcc.grph.meta_pitch != u->surface->dcc.grph.meta_pitch) {
+			|| u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks
+			|| u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) {
 		update_flags->bits.dcc_change = 1;
 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
 	}
@@ -1362,9 +1362,9 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
 		elevate_update_type(&update_type, UPDATE_TYPE_FULL);
 	}
 
-	if (u->plane_info->plane_size.grph.surface_pitch != u->surface->plane_size.grph.surface_pitch
-			|| u->plane_info->plane_size.video.luma_pitch != u->surface->plane_size.video.luma_pitch
-			|| u->plane_info->plane_size.video.chroma_pitch != u->surface->plane_size.video.chroma_pitch) {
+	if (u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
+			|| u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch
+			|| u->plane_info->plane_size.chroma_pitch != u->surface->plane_size.chroma_pitch) {
 		update_flags->bits.plane_size_change = 1;
 		elevate_update_type(&update_type, UPDATE_TYPE_MED);
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
index 5903e7822f98..b9227d5de3a3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
@@ -115,16 +115,16 @@ void pre_surface_trace(
 				plane_state->clip_rect.height);
 
 		SURFACE_TRACE(
-				"plane_state->plane_size.grph.surface_size.x = %d;\n"
-				"plane_state->plane_size.grph.surface_size.y = %d;\n"
-				"plane_state->plane_size.grph.surface_size.width = %d;\n"
-				"plane_state->plane_size.grph.surface_size.height = %d;\n"
-				"plane_state->plane_size.grph.surface_pitch = %d;\n",
-				plane_state->plane_size.grph.surface_size.x,
-				plane_state->plane_size.grph.surface_size.y,
-				plane_state->plane_size.grph.surface_size.width,
-				plane_state->plane_size.grph.surface_size.height,
-				plane_state->plane_size.grph.surface_pitch);
+				"plane_state->plane_size.surface_size.x = %d;\n"
+				"plane_state->plane_size.surface_size.y = %d;\n"
+				"plane_state->plane_size.surface_size.width = %d;\n"
+				"plane_state->plane_size.surface_size.height = %d;\n"
+				"plane_state->plane_size.surface_pitch = %d;\n",
+				plane_state->plane_size.surface_size.x,
+				plane_state->plane_size.surface_size.y,
+				plane_state->plane_size.surface_size.width,
+				plane_state->plane_size.surface_size.height,
+				plane_state->plane_size.surface_pitch);
 
 
 		SURFACE_TRACE(
@@ -202,20 +202,20 @@ void update_surface_trace(
 			SURFACE_TRACE(
 					"plane_info->color_space = %d;\n"
 					"plane_info->format = %d;\n"
-					"plane_info->plane_size.grph.surface_pitch = %d;\n"
-					"plane_info->plane_size.grph.surface_size.height = %d;\n"
-					"plane_info->plane_size.grph.surface_size.width = %d;\n"
-					"plane_info->plane_size.grph.surface_size.x = %d;\n"
-					"plane_info->plane_size.grph.surface_size.y = %d;\n"
+					"plane_info->plane_size.surface_pitch = %d;\n"
+					"plane_info->plane_size.surface_size.height = %d;\n"
+					"plane_info->plane_size.surface_size.width = %d;\n"
+					"plane_info->plane_size.surface_size.x = %d;\n"
+					"plane_info->plane_size.surface_size.y = %d;\n"
 					"plane_info->rotation = %d;\n"
 					"plane_info->stereo_format = %d;\n",
 					update->plane_info->color_space,
 					update->plane_info->format,
-					update->plane_info->plane_size.grph.surface_pitch,
-					update->plane_info->plane_size.grph.surface_size.height,
-					update->plane_info->plane_size.grph.surface_size.width,
-					update->plane_info->plane_size.grph.surface_size.x,
-					update->plane_info->plane_size.grph.surface_size.y,
+					update->plane_info->plane_size.surface_pitch,
+					update->plane_info->plane_size.surface_size.height,
+					update->plane_info->plane_size.surface_size.width,
+					update->plane_info->plane_size.surface_size.x,
+					update->plane_info->plane_size.surface_size.y,
 					update->plane_info->rotation,
 					update->plane_info->stereo_format);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 489f6240f2ed..c28fca5c0a3b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -705,7 +705,7 @@ struct dc_plane_state {
 	struct rect dst_rect;
 	struct rect clip_rect;
 
-	union plane_size plane_size;
+	struct plane_size plane_size;
 	union dc_tiling_info tiling_info;
 
 	struct dc_plane_dcc_param dcc;
@@ -754,7 +754,7 @@ struct dc_plane_state {
 };
 
 struct dc_plane_info {
-	union plane_size plane_size;
+	struct plane_size plane_size;
 	union dc_tiling_info tiling_info;
 	struct dc_plane_dcc_param dcc;
 	enum surface_pixel_format format;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 28a2cd2d2a49..929c4eadc1dc 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -115,42 +115,40 @@ struct rect {
 	int height;
 };
 
-union plane_size {
-	/* Grph or Video will be selected
-	 * based on format above:
-	 * Use Video structure if
-	 * format >= DalPixelFormat_VideoBegin
-	 * else use Grph structure
+struct plane_size {
+	/* Graphic surface pitch in pixels.
+	 * In LINEAR_GENERAL mode, pitch
+	 * is 32 pixel aligned.
 	 */
-	struct {
-		struct rect surface_size;
-		/* Graphic surface pitch in pixels.
-		 * In LINEAR_GENERAL mode, pitch
-		 * is 32 pixel aligned.
-		 */
-		int surface_pitch;
-	} grph;
+	int surface_pitch;
+	int chroma_pitch;
+	struct rect surface_size;
+	struct rect chroma_size;
 
-	struct {
-		struct rect luma_size;
-		/* Graphic surface pitch in pixels.
-		 * In LINEAR_GENERAL mode, pitch is
-		 * 32 pixel aligned.
-		 */
-		int luma_pitch;
+	union {
+		struct {
+			struct rect surface_size;
+			int surface_pitch;
+		} grph;
 
-		struct rect chroma_size;
-		/* Graphic surface pitch in pixels.
-		 * In LINEAR_GENERAL mode, pitch is
-		 * 32 pixel aligned.
-		 */
-		int chroma_pitch;
-	} video;
+		struct {
+			struct rect luma_size;
+			int luma_pitch;
+			struct rect chroma_size;
+			int chroma_pitch;
+		} video;
+	};
 };
 
 struct dc_plane_dcc_param {
 	bool enable;
 
+	int meta_pitch;
+	bool independent_64b_blks;
+
+	int meta_pitch_c;
+	bool independent_64b_blks_c;
+
 	union {
 		struct {
 			int meta_pitch;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
index a24a2bda8656..1488ffddf4e3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
@@ -391,10 +391,10 @@ static void program_tiling(
 static void program_size_and_rotation(
 	struct dce_mem_input *dce_mi,
 	enum dc_rotation_angle rotation,
-	const union plane_size *plane_size)
+	const struct plane_size *plane_size)
 {
-	const struct rect *in_rect = &plane_size->grph.surface_size;
-	struct rect hw_rect = plane_size->grph.surface_size;
+	const struct rect *in_rect = &plane_size->surface_size;
+	struct rect hw_rect = plane_size->surface_size;
 	const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = {
 			[ROTATION_ANGLE_0] = 0,
 			[ROTATION_ANGLE_90] = 1,
@@ -423,7 +423,7 @@ static void program_size_and_rotation(
 			GRPH_Y_END, hw_rect.height);
 
 	REG_SET(GRPH_PITCH, 0,
-			GRPH_PITCH, plane_size->grph.surface_pitch);
+			GRPH_PITCH, plane_size->surface_pitch);
 
 	REG_SET(HW_ROTATION, 0,
 			GRPH_ROTATION_ANGLE, rotation_angles[rotation]);
@@ -505,7 +505,7 @@ static void dce_mi_program_surface_config(
 	struct mem_input *mi,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
-	union plane_size *plane_size,
+	struct plane_size *plane_size,
 	enum dc_rotation_angle rotation,
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
index 9b9fc3d96c07..d54172d88f5f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c
@@ -229,26 +229,26 @@ static void program_tiling(
 static void program_size_and_rotation(
 	struct dce_mem_input *mem_input110,
 	enum dc_rotation_angle rotation,
-	const union plane_size *plane_size)
+	const struct plane_size *plane_size)
 {
 	uint32_t value = 0;
-	union plane_size local_size = *plane_size;
+	struct plane_size local_size = *plane_size;
 
 	if (rotation == ROTATION_ANGLE_90 ||
 		rotation == ROTATION_ANGLE_270) {
 
-		swap(local_size.video.luma_size.x,
-		     local_size.video.luma_size.y);
-		swap(local_size.video.luma_size.width,
-		     local_size.video.luma_size.height);
-		swap(local_size.video.chroma_size.x,
-		     local_size.video.chroma_size.y);
-		swap(local_size.video.chroma_size.width,
-		     local_size.video.chroma_size.height);
+		swap(local_size.surface_size.x,
+		     local_size.surface_size.y);
+		swap(local_size.surface_size.width,
+		     local_size.surface_size.height);
+		swap(local_size.chroma_size.x,
+		     local_size.chroma_size.y);
+		swap(local_size.chroma_size.width,
+		     local_size.chroma_size.height);
 	}
 
 	value = 0;
-	set_reg_field_value(value, local_size.video.luma_pitch,
+	set_reg_field_value(value, local_size.surface_pitch,
 			UNP_GRPH_PITCH_L, GRPH_PITCH_L);
 
 	dm_write_reg(
@@ -257,7 +257,7 @@ static void program_size_and_rotation(
 		value);
 
 	value = 0;
-	set_reg_field_value(value, local_size.video.chroma_pitch,
+	set_reg_field_value(value, local_size.chroma_pitch,
 			UNP_GRPH_PITCH_C, GRPH_PITCH_C);
 	dm_write_reg(
 		mem_input110->base.ctx,
@@ -297,8 +297,8 @@ static void program_size_and_rotation(
 		value);
 
 	value = 0;
-	set_reg_field_value(value, local_size.video.luma_size.x +
-			local_size.video.luma_size.width,
+	set_reg_field_value(value, local_size.surface_size.x +
+			local_size.surface_size.width,
 			UNP_GRPH_X_END_L, GRPH_X_END_L);
 	dm_write_reg(
 		mem_input110->base.ctx,
@@ -306,8 +306,8 @@ static void program_size_and_rotation(
 		value);
 
 	value = 0;
-	set_reg_field_value(value, local_size.video.chroma_size.x +
-			local_size.video.chroma_size.width,
+	set_reg_field_value(value, local_size.chroma_size.x +
+			local_size.chroma_size.width,
 			UNP_GRPH_X_END_C, GRPH_X_END_C);
 	dm_write_reg(
 		mem_input110->base.ctx,
@@ -315,8 +315,8 @@ static void program_size_and_rotation(
 		value);
 
 	value = 0;
-	set_reg_field_value(value, local_size.video.luma_size.y +
-			local_size.video.luma_size.height,
+	set_reg_field_value(value, local_size.surface_size.y +
+			local_size.surface_size.height,
 			UNP_GRPH_Y_END_L, GRPH_Y_END_L);
 	dm_write_reg(
 		mem_input110->base.ctx,
@@ -324,8 +324,8 @@ static void program_size_and_rotation(
 		value);
 
 	value = 0;
-	set_reg_field_value(value, local_size.video.chroma_size.y +
-			local_size.video.chroma_size.height,
+	set_reg_field_value(value, local_size.chroma_size.y +
+			local_size.chroma_size.height,
 			UNP_GRPH_Y_END_C, GRPH_Y_END_C);
 	dm_write_reg(
 		mem_input110->base.ctx,
@@ -637,7 +637,7 @@ void dce_mem_input_v_program_surface_config(
 	struct mem_input *mem_input,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
-	union plane_size *plane_size,
+	struct plane_size *plane_size,
 	enum dc_rotation_angle rotation,
 	struct dc_plane_dcc_param *dcc,
 	bool horizotal_mirror)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index a16128814d62..03f5aa10c4c4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -163,7 +163,7 @@ void hubp1_program_tiling(
 void hubp1_program_size(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
-	const union plane_size *plane_size,
+	const struct plane_size *plane_size,
 	struct dc_plane_dcc_param *dcc)
 {
 	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
@@ -173,16 +173,16 @@ void hubp1_program_size(
 	 * 444 or 420 luma
 	 */
 	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) {
-		ASSERT(plane_size->video.chroma_pitch != 0);
+		ASSERT(plane_size->chroma_pitch != 0);
 		/* Chroma pitch zero can cause system hang! */
 
-		pitch = plane_size->video.luma_pitch - 1;
-		meta_pitch = dcc->video.meta_pitch_l - 1;
-		pitch_c = plane_size->video.chroma_pitch - 1;
-		meta_pitch_c = dcc->video.meta_pitch_c - 1;
+		pitch = plane_size->surface_pitch - 1;
+		meta_pitch = dcc->meta_pitch - 1;
+		pitch_c = plane_size->chroma_pitch - 1;
+		meta_pitch_c = dcc->meta_pitch_c - 1;
 	} else {
-		pitch = plane_size->grph.surface_pitch - 1;
-		meta_pitch = dcc->grph.meta_pitch - 1;
+		pitch = plane_size->surface_pitch - 1;
+		meta_pitch = dcc->meta_pitch - 1;
 		pitch_c = 0;
 		meta_pitch_c = 0;
 	}
@@ -526,13 +526,13 @@ void hubp1_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
-	union plane_size *plane_size,
+	struct plane_size *plane_size,
 	enum dc_rotation_angle rotation,
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror,
 	unsigned int compat_level)
 {
-	hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
+	hubp1_dcc_control(hubp, dcc->enable, dcc->independent_64b_blks);
 	hubp1_program_tiling(hubp, tiling_info, format);
 	hubp1_program_size(hubp, format, plane_size, dcc);
 	hubp1_program_rotation(hubp, rotation, horizontal_mirror);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 8f4bcdc74116..344e446e337d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -685,7 +685,7 @@ void hubp1_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
-	union plane_size *plane_size,
+	struct plane_size *plane_size,
 	enum dc_rotation_angle rotation,
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror,
@@ -707,7 +707,7 @@ void hubp1_program_pixel_format(
 void hubp1_program_size(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
-	const union plane_size *plane_size,
+	const struct plane_size *plane_size,
 	struct dc_plane_dcc_param *dcc);
 
 void hubp1_program_rotation(
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 58d118a3ee8e..96aae19c3d6c 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
@@ -2131,7 +2131,7 @@ void update_dchubp_dpp(
 	struct hubp *hubp = pipe_ctx->plane_res.hubp;
 	struct dpp *dpp = pipe_ctx->plane_res.dpp;
 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
-	union plane_size size = plane_state->plane_size;
+	struct plane_size size = plane_state->plane_size;
 	unsigned int compat_level = 0;
 
 	/* depends on DML calculation, DPP clock value may change dynamically */
@@ -2177,7 +2177,7 @@ void update_dchubp_dpp(
 			&pipe_ctx->ttu_regs);
 	}
 
-	size.grph.surface_size = pipe_ctx->plane_res.scl_data.viewport;
+	size.surface_size = pipe_ctx->plane_res.scl_data.viewport;
 
 	if (plane_state->update_flags.bits.full_update ||
 		plane_state->update_flags.bits.bpp_change)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index a167f867cb72..487de87b03eb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -397,7 +397,7 @@ static void hubp2_program_tiling(
 void hubp2_program_size(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
-	const union plane_size *plane_size,
+	const struct plane_size *plane_size,
 	struct dc_plane_dcc_param *dcc)
 {
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
@@ -410,16 +410,16 @@ void hubp2_program_size(
 	use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
 		&& format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END;
 	if (use_pitch_c) {
-		ASSERT(plane_size->video.chroma_pitch != 0);
+		ASSERT(plane_size->chroma_pitch != 0);
 		/* Chroma pitch zero can cause system hang! */
 
-		pitch = plane_size->video.luma_pitch - 1;
-		meta_pitch = dcc->video.meta_pitch_l - 1;
-		pitch_c = plane_size->video.chroma_pitch - 1;
-		meta_pitch_c = dcc->video.meta_pitch_c - 1;
+		pitch = plane_size->surface_pitch - 1;
+		meta_pitch = dcc->meta_pitch - 1;
+		pitch_c = plane_size->chroma_pitch - 1;
+		meta_pitch_c = dcc->meta_pitch_c - 1;
 	} else {
-		pitch = plane_size->grph.surface_pitch - 1;
-		meta_pitch = dcc->grph.meta_pitch - 1;
+		pitch = plane_size->surface_pitch - 1;
+		meta_pitch = dcc->meta_pitch - 1;
 		pitch_c = 0;
 		meta_pitch_c = 0;
 	}
@@ -592,7 +592,7 @@ void hubp2_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
-	union plane_size *plane_size,
+	struct plane_size *plane_size,
 	enum dc_rotation_angle rotation,
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror,
@@ -600,7 +600,7 @@ void hubp2_program_surface_config(
 {
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 
-	hubp2_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
+	hubp2_dcc_control(hubp, dcc->enable, dcc->independent_64b_blks);
 	hubp2_program_tiling(hubp2, tiling_info, format);
 	hubp2_program_size(hubp, format, plane_size, dcc);
 	hubp2_program_rotation(hubp, rotation, horizontal_mirror);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
index c8418235e154..1c53af4811e8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
@@ -273,7 +273,7 @@ void hubp2_dcc_control(struct hubp *hubp, bool enable,
 void hubp2_program_size(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
-	const union plane_size *plane_size,
+	const struct plane_size *plane_size,
 	struct dc_plane_dcc_param *dcc);
 
 void hubp2_program_rotation(
@@ -289,7 +289,7 @@ void hubp2_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
-	union plane_size *plane_size,
+	struct plane_size *plane_size,
 	enum dc_rotation_angle rotation,
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror,
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 5571b8bfc942..296bc7e4c4a2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -1820,13 +1820,13 @@ int dcn20_populate_dml_pipes_from_context(
 			pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
 			pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
 			if (pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
-				pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.video.luma_pitch;
-				pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.video.chroma_pitch;
-				pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.video.meta_pitch_l;
-				pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.video.meta_pitch_c;
+				pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
+				pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
+				pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
+				pipes[pipe_cnt].pipe.src.meta_pitch_c = pln->dcc.meta_pitch_c;
 			} else {
-				pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.grph.surface_pitch;
-				pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.grph.meta_pitch;
+				pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
+				pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch;
 			}
 			pipes[pipe_cnt].pipe.src.dcc = pln->dcc.enable;
 			pipes[pipe_cnt].pipe.dest.recout_width = scl->recout.width;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index 51bff8717cc9..61cd4f8752c3 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -103,7 +103,7 @@ struct hubp_funcs {
 		struct hubp *hubp,
 		enum surface_pixel_format format,
 		union dc_tiling_info *tiling_info,
-		union plane_size *plane_size,
+		struct plane_size *plane_size,
 		enum dc_rotation_angle rotation,
 		struct dc_plane_dcc_param *dcc,
 		bool horizontal_mirror,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
index da89c2edb07c..7193acfcd779 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
@@ -149,7 +149,7 @@ struct mem_input_funcs {
 		struct mem_input *mem_input,
 		enum surface_pixel_format format,
 		union dc_tiling_info *tiling_info,
-		union plane_size *plane_size,
+		struct plane_size *plane_size,
 		enum dc_rotation_angle rotation,
 		struct dc_plane_dcc_param *dcc,
 		bool horizontal_mirror);
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 71/87] drm/amd/display: populate last calculated bb state with max clocks
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (69 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 70/87] drm/amd/display: add dcc programming for dual plane sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 72/87] drm/amd/display: Fix dc_create failure handling and 666 color depths sunpeng.li-5C7GfCeVMHo
                     ` (15 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr, Jun Lei

From: Jun Lei <Jun.Lei@amd.com>

[why]
update_bounding_box calculates intermediate bb states based on clock relationship
however, the last state doesn't need to maintain a minimum relationship, but should
actually contain maximum of every clock.  otherwise maximum clocks are not usable

[how]
once the calculated bb is built, override the last state with max values

Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 ++++
 1 file changed, 4 insertions(+)

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 296bc7e4c4a2..193270ba60e6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2746,6 +2746,10 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_
 		num_calculated_states++;
 	}
 
+	calculated_states[num_calculated_states - 1].socclk_mhz = max_clocks->socClockInKhz / 1000;
+	calculated_states[num_calculated_states - 1].fabricclk_mhz = max_clocks->socClockInKhz / 1000;
+	calculated_states[num_calculated_states - 1].dcfclk_mhz = max_clocks->dcfClockInKhz / 1000;
+
 	memcpy(bb->clock_limits, calculated_states, sizeof(bb->clock_limits));
 	bb->num_states = num_calculated_states;
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 72/87] drm/amd/display: Fix dc_create failure handling and 666 color depths
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (70 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 71/87] drm/amd/display: populate last calculated bb state with max clocks sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 73/87] drm/amd/display: Only enable audio if speaker allocation exists sunpeng.li-5C7GfCeVMHo
                     ` (14 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Julian Parkin

From: Julian Parkin <julian.parkin@amd.com>

[Why]
It is possible (but very unlikely) that constructing dc fails
before current_state is created.

We support 666 color depth in some scenarios, but this
isn't handled in get_norm_pix_clk. It uses exactly the
same pixel clock as the 888 case.

[How]
Check for non null current_state before destructing.

Add case for 666 color depth to get_norm_pix_clk to
avoid assertion.

Signed-off-by: Julian Parkin <julian.parkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c          | 6 ++++--
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 63d0f1386f4e..c445de4d272e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -500,8 +500,10 @@ void dc_stream_set_static_screen_events(struct dc *dc,
 
 static void destruct(struct dc *dc)
 {
-	dc_release_state(dc->current_state);
-	dc->current_state = NULL;
+	if (dc->current_state) {
+		dc_release_state(dc->current_state);
+		dc->current_state = NULL;
+	}
 
 	destroy_links(dc);
 
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 31a49c59c278..c5a740821c0e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1852,6 +1852,7 @@ static int get_norm_pix_clk(const struct dc_crtc_timing *timing)
 		pix_clk /= 2;
 	if (timing->pixel_encoding != PIXEL_ENCODING_YCBCR422) {
 		switch (timing->display_color_depth) {
+		case COLOR_DEPTH_666:
 		case COLOR_DEPTH_888:
 			normalized_pix_clk = pix_clk;
 			break;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 73/87] drm/amd/display: Only enable audio if speaker allocation exists
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (71 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 72/87] drm/amd/display: Fix dc_create failure handling and 666 color depths sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 74/87] drm/amd/display: Clean up dynamic metadata logic sunpeng.li-5C7GfCeVMHo
                     ` (13 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Jun Lei, Alvin Lee

From: Alvin Lee <alvin.lee2@amd.com>

[Why]

In dm_helpers_parse_edid_caps, there is a corner case where no speakers
can be allocated even though the audio mode count is greater than 0.
Enabling audio when no speaker allocations exists can cause issues in
the video stream.

[How]

Add a check to not enable audio unless one or more speaker allocations
exist (since doing this can cause issues in the video stream).

Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index c5a740821c0e..43bb4c933da7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1999,7 +1999,7 @@ enum dc_status resource_map_pool_resources(
 	/* TODO: Add check if ASIC support and EDID audio */
 	if (!stream->converter_disable_audio &&
 	    dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
-	    stream->audio_info.mode_count) {
+	    stream->audio_info.mode_count && stream->audio_info.flags.all) {
 		pipe_ctx->stream_res.audio = find_first_free_audio(
 		&context->res_ctx, pool, pipe_ctx->stream_res.stream_enc->id);
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 74/87] drm/amd/display: Clean up dynamic metadata logic
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (72 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 73/87] drm/amd/display: Only enable audio if speaker allocation exists sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 75/87] drm/amd/display: Set enabled to false at start of audio disable sunpeng.li-5C7GfCeVMHo
                     ` (12 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Charlene Liu, Julian Parkin

From: Julian Parkin <julian.parkin@amd.com>

 [Why]
Code to enable DCN20 dynamic metadata feature is duplicated in two places
and was added to DCE110 enable stream.

[How]
Create DCN20 specific enable stream function for clarity, and add a hardware
sequencer function to program dynamic metadata to avoid the duplicate
code.

Signed-off-by: Julian Parkin <julian.parkin@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_stream.c   | 27 +++----
 .../display/dc/dce110/dce110_hw_sequencer.c   | 24 +-----
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 74 +++++++++++++++++++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  1 +
 4 files changed, 86 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 35d697dd5808..41032c4c5bdf 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -563,6 +563,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
 
 	return ret;
 }
+
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 bool dc_stream_dmdata_status_done(struct dc *dc, struct dc_stream_state *stream)
 {
@@ -594,6 +595,14 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
 	struct hubp *hubp;
 	int i;
 
+	/* Dynamic metadata is only supported on HDMI or DP */
+	if (!dc_is_hdmi_signal(stream->signal) && !dc_is_dp_signal(stream->signal))
+		return false;
+
+	/* Check hardware support */
+	if (!dc->hwss.program_dmdata_engine)
+		return false;
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream == stream)
@@ -609,23 +618,7 @@ bool dc_stream_set_dynamic_metadata(struct dc *dc,
 
 	pipe_ctx->stream->dmdata_address = attr->address;
 
-	if (pipe_ctx->stream_res.stream_enc &&
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL) {
-		if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-			/* if using dynamic meta, don't set up generic infopackets */
-			pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					true, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-		} else
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					false, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-	}
+	dc->hwss.program_dmdata_engine(pipe_ctx);
 
 	if (hubp->funcs->dmdata_set_attributes != NULL &&
 			pipe_ctx->stream->dmdata_address.quad_part != 0) {
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index fedbc6d0c40d..b8ef57a24228 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -664,29 +664,7 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
 						    pipe_ctx->stream_res.stream_enc->id, true);
 
-	/* update AVI info frame (HDMI, DP)*/
-	/* TODO: FPGA may change to hwss.update_info_frame */
-
-#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
-	if (pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata != NULL &&
-			pipe_ctx->plane_res.hubp != NULL) {
-		if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
-			/* if using dynamic meta, don't set up generic infopackets */
-			pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					true, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-		} else
-			pipe_ctx->stream_res.stream_enc->funcs->set_dynamic_metadata(
-					pipe_ctx->stream_res.stream_enc,
-					false, pipe_ctx->plane_res.hubp->inst,
-					dc_is_dp_signal(pipe_ctx->stream->signal) ?
-							dmdata_dp : dmdata_hdmi);
-	}
-#endif
-	dce110_update_info_frame(pipe_ctx);
+	link->dc->hwss.update_info_frame(pipe_ctx);
 
 	/* enable early control to avoid corruption on DP monitor*/
 	active_total_with_borders =
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 566cd4cdfef4..76ce622e1421 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2056,6 +2056,78 @@ static void dcn20_set_flip_control_gsl(
 
 }
 
+static void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
+{
+	enum dc_lane_count lane_count =
+		pipe_ctx->stream->link->cur_link_settings.lane_count;
+
+	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+	struct dc_link *link = pipe_ctx->stream->link;
+
+	uint32_t active_total_with_borders;
+	uint32_t early_control = 0;
+	struct timing_generator *tg = pipe_ctx->stream_res.tg;
+
+	/* For MST, there are multiply stream go to only one link.
+	 * connect DIG back_end to front_end while enable_stream and
+	 * disconnect them during disable_stream
+	 * BY this, it is logic clean to separate stream and link
+	 */
+	link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
+						    pipe_ctx->stream_res.stream_enc->id, true);
+
+	if (link->dc->hwss.program_dmdata_engine)
+		link->dc->hwss.program_dmdata_engine(pipe_ctx);
+
+	link->dc->hwss.update_info_frame(pipe_ctx);
+
+	/* enable early control to avoid corruption on DP monitor*/
+	active_total_with_borders =
+			timing->h_addressable
+				+ timing->h_border_left
+				+ timing->h_border_right;
+
+	if (lane_count != 0)
+		early_control = active_total_with_borders % lane_count;
+
+	if (early_control == 0)
+		early_control = lane_count;
+
+	tg->funcs->set_early_control(tg, early_control);
+
+	/* enable audio only within mode set */
+	if (pipe_ctx->stream_res.audio != NULL) {
+		if (dc_is_dp_signal(pipe_ctx->stream->signal))
+			pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
+	}
+}
+
+static void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
+{
+	struct dc_stream_state    *stream     = pipe_ctx->stream;
+	struct hubp               *hubp       = pipe_ctx->plane_res.hubp;
+	bool                       enable     = false;
+	struct stream_encoder     *stream_enc = pipe_ctx->stream_res.stream_enc;
+	enum dynamic_metadata_mode mode       = dc_is_dp_signal(stream->signal)
+							? dmdata_dp
+							: dmdata_hdmi;
+
+	/* if using dynamic meta, don't set up generic infopackets */
+	if (pipe_ctx->stream->dmdata_address.quad_part != 0) {
+		pipe_ctx->stream_res.encoder_info_frame.hdrsmd.valid = false;
+		enable = true;
+	}
+
+	if (!hubp)
+		return;
+
+	if (!stream_enc || !stream_enc->funcs->set_dynamic_metadata)
+		return;
+
+	stream_enc->funcs->set_dynamic_metadata(stream_enc, enable,
+						hubp->inst, mode);
+}
+
 void dcn20_hw_sequencer_construct(struct dc *dc)
 {
 	dcn10_hw_sequencer_construct(dc);
@@ -2080,6 +2152,8 @@ void dcn20_hw_sequencer_construct(struct dc *dc)
 	dc->hwss.update_odm = dcn20_update_odm;
 	dc->hwss.blank_pixel_data = dcn20_blank_pixel_data;
 	dc->hwss.dmdata_status_done = dcn20_dmdata_status_done;
+	dc->hwss.program_dmdata_engine = dcn20_program_dmdata_engine;
+	dc->hwss.enable_stream = dcn20_enable_stream;
 	dc->hwss.disable_stream = dcn20_disable_stream;
 	dc->hwss.init_sys_ctx = dcn20_init_sys_ctx;
 	dc->hwss.init_vm_ctx = dcn20_init_vm_ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 36be08adae05..28645e10f854 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -231,6 +231,7 @@ struct hw_sequencer_funcs {
 	bool (*update_bandwidth)(
 			struct dc *dc,
 			struct dc_state *context);
+	void (*program_dmdata_engine)(struct pipe_ctx *pipe_ctx);
 	bool (*dmdata_status_done)(struct pipe_ctx *pipe_ctx);
 #endif
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 75/87] drm/amd/display: Set enabled to false at start of audio disable
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (73 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 74/87] drm/amd/display: Clean up dynamic metadata logic sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 76/87] drm/amd/display: drop ASSERT() if eDP panel is not connected sunpeng.li-5C7GfCeVMHo
                     ` (11 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Zhan Liu, Nicholas Kazlauskas

From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

[Why]
In an effort to stop redundant calls to dce110_disable_audio_stream
the audio->enabled flag was added to the audio resource struct. While
this state probably shouldn't have been tracked on the audio struct
itself it still works fine for some sequences.

However, it does not work for cases where we're freeing the audio
resource (such as hotplugs) or when dynamic audio is enabled.

In these cases the pipe_ctx->stream_res.audio = NULL before we can
set audio->enabled = false. The next time we acquire the audio resource
such as on hotplug the audio will not be enabled for the stream since
DC thinks it's still enabled.

Audio state tracking should cover this sequence.

[How]
Set audio->enabled = false at the start as long as we have
pipe_ctx->stream_res.audio.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Zhan Liu <Zhan.Liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index b8ef57a24228..46dfab749679 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -996,6 +996,8 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option)
 	pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
 			pipe_ctx->stream_res.stream_enc, true);
 	if (pipe_ctx->stream_res.audio) {
+		pipe_ctx->stream_res.audio->enabled = false;
+
 		if (dc->res_pool->pp_smu)
 			pp_smu = dc->res_pool->pp_smu;
 
@@ -1026,8 +1028,6 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx, int option)
 		/* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
 		 * stream->stream_engine_id);
 		 */
-		if (pipe_ctx->stream_res.audio)
-			pipe_ctx->stream_res.audio->enabled = false;
 	}
 }
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 76/87] drm/amd/display: drop ASSERT() if eDP panel is not connected
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (74 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 75/87] drm/amd/display: Set enabled to false at start of audio disable sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 77/87] drm/amd/display: 3.2.42 sunpeng.li-5C7GfCeVMHo
                     ` (10 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Zhan Liu, Nicholas Kazlauskas

From: Zhan Liu <zhan.liu@amd.com>

[Why]
For boards that support eDP but do not have a physical eDP
display connected an ASSERT will be thrown. This is not a
critical failure and shouldn't be treated as such.

[How]
Drop the assertion.

Signed-off-by: Zhan Liu <zhan.liu@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 --
 1 file changed, 2 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 1422e74a5ffc..467016ddfbe8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -552,8 +552,6 @@ static void read_edp_current_link_settings_on_detect(struct dc_link *link)
 		msleep(8);
 	}
 
-	ASSERT(status == DC_OK);
-
 	// Read DPCD 00100h to find if standard link rates are set
 	core_link_read_dpcd(link, DP_LINK_BW_SET,
 			&link_bw_set, sizeof(link_bw_set));
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 77/87] drm/amd/display: 3.2.42
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (75 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 76/87] drm/amd/display: drop ASSERT() if eDP panel is not connected sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 78/87] drm/amd/display: Increase size of audios array sunpeng.li-5C7GfCeVMHo
                     ` (9 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Aric Cyr

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

Signed-off-by: Aric Cyr <aric.cyr@amd.com>
Acked-by: Leo Li <sunpeng.li@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 c28fca5c0a3b..b12eee93c253 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.41"
+#define DC_VER "3.2.42"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 78/87] drm/amd/display: Increase size of audios array
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (76 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 77/87] drm/amd/display: 3.2.42 sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 79/87] drm/amd/display: do not read link setting if edp not connected sunpeng.li-5C7GfCeVMHo
                     ` (8 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Joshua Aberback, Tai Man

From: Tai Man <taiman.wong@amd.com>

[Why]
The audios array defined in "struct resource_pool" is only 6 (MAX_PIPES)
but the max number of audio devices (num_audio) is 7. In some projects,
it will run out of audios array.

[How]
Incraese the audios array size to 7.

Signed-off-by: Tai Man Wong <taiman.wong@amd.com>
Reviewed-by: Joshua Aberback <Joshua.Aberback@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/inc/core_types.h   | 2 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index c89393c19232..a148ffde8b12 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -212,7 +212,7 @@ struct resource_pool {
 	struct clock_source *clock_sources[MAX_CLOCK_SOURCES];
 	unsigned int clk_src_count;
 
-	struct audio *audios[MAX_PIPES];
+	struct audio *audios[MAX_AUDIOS];
 	unsigned int audio_count;
 	struct audio_support audio_support;
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index 8759ec03aede..f82365e2d03c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -34,6 +34,7 @@
  * Data types shared between different Virtual HW blocks
  ******************************************************************************/
 
+#define MAX_AUDIOS 7
 #define MAX_PIPES 6
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 #define MAX_DWB_PIPES	1
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 79/87] drm/amd/display: do not read link setting if edp not connected
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (77 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 78/87] drm/amd/display: Increase size of audios array sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 80/87] drm/amd/display: fix mpcc assert condition sunpeng.li-5C7GfCeVMHo
                     ` (7 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Yongqiang Sun, Eric Yang

From: Eric Yang <Eric.Yang2@amd.com>

[Why]
Previously assume eDP sink present if connector present. Do not
need to enforce this restriction. Fix issue where driver attempt
to read link setting even though no edp connected.

{How]
Only read link setting after reading connection status.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c | 8 +-------
 1 file changed, 1 insertion(+), 7 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 467016ddfbe8..9166e41248d8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -720,13 +720,6 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 		return false;
 	}
 
-	if (link->connector_signal == SIGNAL_TYPE_EDP) {
-		/* On detect, we want to make sure current link settings are
-		 * up to date, especially if link was powered on by GOP.
-		 */
-		read_edp_current_link_settings_on_detect(link);
-	}
-
 	prev_sink = link->local_sink;
 	if (prev_sink != NULL) {
 		dc_sink_retain(prev_sink);
@@ -768,6 +761,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 		}
 
 		case SIGNAL_TYPE_EDP: {
+			read_edp_current_link_settings_on_detect(link);
 			detect_edp_sink_caps(link);
 			sink_caps.transaction_type =
 				DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 80/87] drm/amd/display: fix mpcc assert condition
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (78 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 79/87] drm/amd/display: do not read link setting if edp not connected sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 81/87] drm/amd/display: support "dummy pstate" sunpeng.li-5C7GfCeVMHo
                     ` (6 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Yongqiang Sun, Eric Yang

From: Eric Yang <Eric.Yang2@amd.com>

[Why]
In DCN2x asic, the MPCC status register definition changed, and
our logic for assert is incorrect. disabled is valid state,
where we should see idle and not busy, where as in not
disabled state, we should see not idle.

[How]
Change assert condition to be more sensible.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c  | 23 +++++++++----------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
index f4d3008e5efa..67f0128f0b38 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
@@ -446,23 +446,22 @@ void mpc2_assert_mpcc_idle_before_connect(struct mpc *mpc, int mpcc_id)
 {
 	struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
 	unsigned int top_sel, mpc_busy, mpc_idle, mpc_disabled;
-	REG_GET(MPCC_STATUS[mpcc_id], MPCC_DISABLED, &mpc_disabled);
-
-	if (mpc_disabled) {
-		ASSERT(0);
-		return;
-	}
 
 	REG_GET(MPCC_TOP_SEL[mpcc_id],
 			MPCC_TOP_SEL, &top_sel);
 
-	if (top_sel == 0xf) {
-		REG_GET_2(MPCC_STATUS[mpcc_id],
-				MPCC_BUSY, &mpc_busy,
-				MPCC_IDLE, &mpc_idle);
+	REG_GET_3(MPCC_STATUS[mpcc_id],
+			MPCC_BUSY, &mpc_busy,
+			MPCC_IDLE, &mpc_idle,
+			MPCC_DISABLED, &mpc_disabled);
 
-		ASSERT(mpc_busy == 0);
-		ASSERT(mpc_idle == 1);
+	if (top_sel == 0xf) {
+		ASSERT(!mpc_busy);
+		ASSERT(mpc_idle);
+		ASSERT(mpc_disabled);
+	} else {
+		ASSERT(!mpc_disabled);
+		ASSERT(!mpc_idle);
 	}
 }
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 81/87] drm/amd/display: support "dummy pstate"
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (79 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 80/87] drm/amd/display: fix mpcc assert condition sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 82/87] drm/amd/display: Add SMU version field to clk_mgr_internal sunpeng.li-5C7GfCeVMHo
                     ` (5 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Dmytro Laktyushkin, Leo Li, Jun Lei

From: Jun Lei <Jun.Lei@amd.com>

[why]
Existing support in DC for pstate only accounts for a single latency.  This is sufficient when the
variance of latency is small, or that pstate support isn't necessary for correct ASIC functionality.

Newer ASICs violate both existing assumptions.  PState support is mandatory of correct ASIC
functionality, but not all latencies have to be supported.  Existing code supports a "full p state" which
allows memory clock to change, but is hard for DCN to support (as it requires very large buffers).
New code will now fall back to a "dummy p state" support when "full p state" cannot be support.
This easy p state support should always be allowed.

[how]
Define a new latency in socBB.  Add fallback logic to support it.  Note DML is also updated to ensure
that fallback will always work.

Change-Id: I068e34cae8fa2f7cd31b530a68822c479525048c
Signed-off-by: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c  |    2 +
 drivers/gpu/drm/amd/display/dc/dc.h           |    7 +
 .../drm/amd/display/dc/dcn20/dcn20_hubbub.c   |   11 +
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   10 +-
 .../drm/amd/display/dc/dcn20/dcn20_resource.c |   59 +-
 drivers/gpu/drm/amd/display/dc/dml/Makefile   |    3 +
 .../dc/dml/dcn20/display_mode_vba_20v2.c      | 5109 +++++++++++++++++
 .../dc/dml/dcn20/display_mode_vba_20v2.h      |   32 +
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c   | 1701 ++++++
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.h   |   74 +
 .../drm/amd/display/dc/dml/display_mode_lib.c |   12 +
 .../drm/amd/display/dc/dml/display_mode_lib.h |    1 +
 .../amd/display/dc/dml/display_mode_structs.h |    1 +
 .../drm/amd/display/dc/dml/display_mode_vba.c |    8 +-
 14 files changed, 7022 insertions(+), 8 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.h
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
 create mode 100644 drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
index 3cff4f0518d3..7ff0396956b3 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -201,6 +201,7 @@ void dcn2_update_clocks(struct clk_mgr *clk_mgr_base,
 	}
 
 	if (should_update_pstate_support(safe_to_lower, new_clocks->p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
+		clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
 		clk_mgr_base->clks.p_state_change_support = new_clocks->p_state_change_support;
 		if (pp_smu && pp_smu->set_pstate_handshake_support)
 			pp_smu->set_pstate_handshake_support(&pp_smu->pp_smu, clk_mgr_base->clks.p_state_change_support);
@@ -308,6 +309,7 @@ void dcn2_init_clocks(struct clk_mgr *clk_mgr)
 	memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
 	// Assumption is that boot state always supports pstate
 	clk_mgr->clks.p_state_change_support = true;
+	clk_mgr->clks.prev_p_state_change_support = true;
 }
 
 void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index b12eee93c253..6da0a6fe2973 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -121,6 +121,7 @@ struct dc_caps {
 struct dc_bug_wa {
 	bool no_connect_phy_config;
 	bool dedcn20_305_wa;
+	struct display_mode_lib alternate_dml;
 };
 #endif
 
@@ -263,6 +264,12 @@ struct dc_clocks {
 	int phyclk_khz;
 	int dramclk_khz;
 	bool p_state_change_support;
+
+	/*
+	 * Elements below are not compared for the purposes of
+	 * optimization required
+	 */
+	bool prev_p_state_change_support;
 };
 
 struct dc_bw_validation_profile {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
index 6e2dbd03f9bf..31d6e79ba2b8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -26,6 +26,7 @@
 
 #include "dcn20_hubbub.h"
 #include "reg_helper.h"
+#include "clk_mgr.h"
 
 #define REG(reg)\
 	hubbub1->regs->reg
@@ -553,6 +554,16 @@ static void hubbub2_program_watermarks(
 	 */
 	hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
 	hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
+
+	/*
+	 * There's a special case when going from p-state support to p-state unsupported
+	 * here we are going to LOWER watermarks to go to dummy p-state only, but this has
+	 * to be done prepare_bandwidth, not optimize
+	 */
+	if (hubbub1->base.ctx->dc->clk_mgr->clks.prev_p_state_change_support == true &&
+		hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == false)
+		safe_to_lower = true;
+
 	hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
 
 	REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 76ce622e1421..b61774d2e8b2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1443,16 +1443,16 @@ void dcn20_prepare_bandwidth(
 {
 	struct hubbub *hubbub = dc->res_pool->hubbub;
 
+	dc->clk_mgr->funcs->update_clocks(
+			dc->clk_mgr,
+			context,
+			false);
+
 	/* program dchubbub watermarks */
 	hubbub->funcs->program_watermarks(hubbub,
 					&context->bw_ctx.bw.dcn.watermarks,
 					dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
 					false);
-
-	dc->clk_mgr->funcs->update_clocks(
-			dc->clk_mgr,
-			context,
-			false);
 }
 
 void dcn20_optimize_bandwidth(
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 193270ba60e6..2cf788a3704e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2425,7 +2425,7 @@ void dcn20_calculate_dlg_params(
 	}
 }
 
-bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *context,
 		bool fast_validate)
 {
 	bool out = false;
@@ -2477,6 +2477,62 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
 	return out;
 }
 
+
+bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
+		bool fast_validate)
+{
+	bool voltage_supported = false;
+	bool full_pstate_supported = false;
+	bool dummy_pstate_supported = false;
+	double p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
+
+	if (fast_validate)
+		return dcn20_validate_bandwidth_internal(dc, context, true);
+
+
+	// Best case, we support full UCLK switch latency
+	voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
+	full_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+
+	if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
+		(voltage_supported && full_pstate_supported)) {
+		context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
+		goto restore_dml_state;
+	}
+
+	// Fallback #1: Try to only support G6 temperature read latency
+	context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
+
+	voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
+	dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+
+	if (voltage_supported && dummy_pstate_supported) {
+		context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
+		goto restore_dml_state;
+	}
+
+	// Fallback #2: Retry with "new" DCN20 to support G6 temperature read latency
+	memcpy (&context->bw_ctx.dml, &dc->work_arounds.alternate_dml, sizeof (struct display_mode_lib));
+	context->bw_ctx.dml.soc.dram_clock_change_latency_us = context->bw_ctx.dml.soc.dummy_pstate_latency_us;
+
+	voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false);
+	dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+
+	if (voltage_supported && dummy_pstate_supported) {
+		context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
+		goto restore_dml_state;
+	}
+
+	// ERROR: fallback #2 is supposed to always work.
+	ASSERT(false);
+
+restore_dml_state:
+	memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib));
+	context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
+
+	return voltage_supported;
+}
+
 struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
 		struct dc_state *state,
 		const struct resource_pool *pool,
@@ -3073,6 +3129,7 @@ static bool construct(
 	}
 
 	dml_init_instance(&dc->dml, &dcn2_0_soc, &dcn2_0_ip, DML_PROJECT_NAVI10);
+	dml_init_instance(&dc->work_arounds.alternate_dml, &dcn2_0_soc, &dcn2_0_ip, DML_PROJECT_NAVI10v2);
 
 	if (!dc->debug.disable_pplib_wm_range) {
 		struct pp_smu_wm_range_sets ranges = {0};
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index 0bb7a20675c4..1735fc1e2eb1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -38,6 +38,8 @@ ifdef CONFIG_DRM_AMD_DC_DCN2_0
 CFLAGS_display_mode_vba.o := $(dml_ccflags)
 CFLAGS_display_mode_vba_20.o := $(dml_ccflags)
 CFLAGS_display_rq_dlg_calc_20.o := $(dml_ccflags)
+CFLAGS_display_mode_vba_20v2.o := $(dml_ccflags)
+CFLAGS_display_rq_dlg_calc_20v2.o := $(dml_ccflags)
 endif
 ifdef CONFIG_DRM_AMD_DCN3AG
 CFLAGS_display_mode_vba_3ag.o := $(dml_ccflags)
@@ -51,6 +53,7 @@ DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
 
 ifdef CONFIG_DRM_AMD_DC_DCN2_0
 DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
+DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
 endif
 
 AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
new file mode 100644
index 000000000000..22455db54980
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
@@ -0,0 +1,5109 @@
+/*
+ * Copyright 2018 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 "../display_mode_lib.h"
+#include "display_mode_vba_20v2.h"
+#include "../dml_inline_defs.h"
+
+/*
+ * NOTE:
+ *   This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
+#define BPP_INVALID 0
+#define BPP_BLENDED_PIPE 0xffffffff
+
+static double adjust_ReturnBW(
+		struct display_mode_lib *mode_lib,
+		double ReturnBW,
+		bool DCCEnabledAnyPlane,
+		double ReturnBandwidthToDCN);
+static unsigned int dscceComputeDelay(
+		unsigned int bpc,
+		double bpp,
+		unsigned int sliceWidth,
+		unsigned int numSlices,
+		enum output_format_class pixelFormat);
+static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
+static bool CalculateDelayAfterScaler(
+		struct display_mode_lib *mode_lib,
+		double ReturnBW,
+		double ReadBandwidthPlaneLuma,
+		double ReadBandwidthPlaneChroma,
+		double TotalDataReadBandwidth,
+		double DisplayPipeLineDeliveryTimeLuma,
+		double DisplayPipeLineDeliveryTimeChroma,
+		double DPPCLK,
+		double DISPCLK,
+		double PixelClock,
+		unsigned int DSCDelay,
+		unsigned int DPPPerPlane,
+		bool ScalerEnabled,
+		unsigned int NumberOfCursors,
+		double DPPCLKDelaySubtotal,
+		double DPPCLKDelaySCL,
+		double DPPCLKDelaySCLLBOnly,
+		double DPPCLKDelayCNVCFormater,
+		double DPPCLKDelayCNVCCursor,
+		double DISPCLKDelaySubtotal,
+		unsigned int ScalerRecoutWidth,
+		enum output_format_class OutputFormat,
+		unsigned int HTotal,
+		unsigned int SwathWidthSingleDPPY,
+		double BytePerPixelDETY,
+		double BytePerPixelDETC,
+		unsigned int SwathHeightY,
+		unsigned int SwathHeightC,
+		bool Interlace,
+		bool ProgressiveToInterlaceUnitInOPP,
+		double *DSTXAfterScaler,
+		double *DSTYAfterScaler
+		);
+// Super monster function with some 45 argument
+static bool CalculatePrefetchSchedule(
+		struct display_mode_lib *mode_lib,
+		double DPPCLK,
+		double DISPCLK,
+		double PixelClock,
+		double DCFCLKDeepSleep,
+		unsigned int DPPPerPlane,
+		unsigned int NumberOfCursors,
+		unsigned int VBlank,
+		unsigned int HTotal,
+		unsigned int MaxInterDCNTileRepeaters,
+		unsigned int VStartup,
+		unsigned int PageTableLevels,
+		bool GPUVMEnable,
+		bool DynamicMetadataEnable,
+		unsigned int DynamicMetadataLinesBeforeActiveRequired,
+		unsigned int DynamicMetadataTransmittedBytes,
+		bool DCCEnable,
+		double UrgentLatencyPixelDataOnly,
+		double UrgentExtraLatency,
+		double TCalc,
+		unsigned int PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		double PrefetchSourceLinesY,
+		unsigned int SwathWidthY,
+		double BytePerPixelDETY,
+		double VInitPreFillY,
+		unsigned int MaxNumSwathY,
+		double PrefetchSourceLinesC,
+		double BytePerPixelDETC,
+		double VInitPreFillC,
+		unsigned int MaxNumSwathC,
+		unsigned int SwathHeightY,
+		unsigned int SwathHeightC,
+		double TWait,
+		bool XFCEnabled,
+		double XFCRemoteSurfaceFlipDelay,
+		bool InterlaceEnable,
+		bool ProgressiveToInterlaceUnitInOPP,
+		double DSTXAfterScaler,
+		double DSTYAfterScaler,
+		double *DestinationLinesForPrefetch,
+		double *PrefetchBandwidth,
+		double *DestinationLinesToRequestVMInVBlank,
+		double *DestinationLinesToRequestRowInVBlank,
+		double *VRatioPrefetchY,
+		double *VRatioPrefetchC,
+		double *RequiredPrefetchPixDataBW,
+		double *Tno_bw,
+		unsigned int *VUpdateOffsetPix,
+		double *VUpdateWidthPix,
+		double *VReadyOffsetPix);
+static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
+static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
+static double CalculatePrefetchSourceLines(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double vtaps,
+		bool Interlace,
+		bool ProgressiveToInterlaceUnitInOPP,
+		unsigned int SwathHeight,
+		unsigned int ViewportYStart,
+		double *VInitPreFill,
+		unsigned int *MaxNumSwath);
+static unsigned int CalculateVMAndRowBytes(
+		struct display_mode_lib *mode_lib,
+		bool DCCEnable,
+		unsigned int BlockHeight256Bytes,
+		unsigned int BlockWidth256Bytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int SurfaceTiling,
+		unsigned int BytePerPixel,
+		enum scan_direction_class ScanDirection,
+		unsigned int ViewportWidth,
+		unsigned int ViewportHeight,
+		unsigned int SwathWidthY,
+		bool GPUVMEnable,
+		unsigned int VMMPageSize,
+		unsigned int PTEBufferSizeInRequestsLuma,
+		unsigned int PDEProcessingBufIn64KBReqs,
+		unsigned int Pitch,
+		unsigned int DCCMetaPitch,
+		unsigned int *MacroTileWidth,
+		unsigned int *MetaRowByte,
+		unsigned int *PixelPTEBytesPerRow,
+		bool *PTEBufferSizeNotExceeded,
+		unsigned int *dpte_row_height,
+		unsigned int *meta_row_height);
+static double CalculateTWait(
+		unsigned int PrefetchMode,
+		double DRAMClockChangeLatency,
+		double UrgentLatencyPixelDataOnly,
+		double SREnterPlusExitTime);
+static double CalculateRemoteSurfaceFlipDelay(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double SwathWidth,
+		double Bpp,
+		double LineTime,
+		double XFCTSlvVupdateOffset,
+		double XFCTSlvVupdateWidth,
+		double XFCTSlvVreadyOffset,
+		double XFCXBUFLatencyTolerance,
+		double XFCFillBWOverhead,
+		double XFCSlvChunkSize,
+		double XFCBusTransportTime,
+		double TCalc,
+		double TWait,
+		double *SrcActiveDrainRate,
+		double *TInitXFill,
+		double *TslvChk);
+static void CalculateActiveRowBandwidth(
+		bool GPUVMEnable,
+		enum source_format_class SourcePixelFormat,
+		double VRatio,
+		bool DCCEnable,
+		double LineTime,
+		unsigned int MetaRowByteLuma,
+		unsigned int MetaRowByteChroma,
+		unsigned int meta_row_height_luma,
+		unsigned int meta_row_height_chroma,
+		unsigned int PixelPTEBytesPerRowLuma,
+		unsigned int PixelPTEBytesPerRowChroma,
+		unsigned int dpte_row_height_luma,
+		unsigned int dpte_row_height_chroma,
+		double *meta_row_bw,
+		double *dpte_row_bw,
+		double *qual_row_bw);
+static void CalculateFlipSchedule(
+		struct display_mode_lib *mode_lib,
+		double UrgentExtraLatency,
+		double UrgentLatencyPixelDataOnly,
+		unsigned int GPUVMMaxPageTableLevels,
+		bool GPUVMEnable,
+		double BandwidthAvailableForImmediateFlip,
+		unsigned int TotImmediateFlipBytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int ImmediateFlipBytes,
+		double LineTime,
+		double VRatio,
+		double Tno_bw,
+		double PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		bool DCCEnable,
+		unsigned int dpte_row_height,
+		unsigned int meta_row_height,
+		double qual_row_bw,
+		double *DestinationLinesToRequestVMInImmediateFlip,
+		double *DestinationLinesToRequestRowInImmediateFlip,
+		double *final_flip_bw,
+		bool *ImmediateFlipSupportedForPipe);
+static double CalculateWriteBackDelay(
+		enum source_format_class WritebackPixelFormat,
+		double WritebackHRatio,
+		double WritebackVRatio,
+		unsigned int WritebackLumaHTaps,
+		unsigned int WritebackLumaVTaps,
+		unsigned int WritebackChromaHTaps,
+		unsigned int WritebackChromaVTaps,
+		unsigned int WritebackDestinationWidth);
+
+static void dml20v2_DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
+static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+		struct display_mode_lib *mode_lib);
+
+void dml20v2_recalculate(struct display_mode_lib *mode_lib)
+{
+	ModeSupportAndSystemConfiguration(mode_lib);
+	mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
+		mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels * mode_lib->vba.DRAMChannelWidth,
+		mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000.0;
+	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
+	dml20v2_DisplayPipeConfiguration(mode_lib);
+	dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
+}
+
+static double adjust_ReturnBW(
+		struct display_mode_lib *mode_lib,
+		double ReturnBW,
+		bool DCCEnabledAnyPlane,
+		double ReturnBandwidthToDCN)
+{
+	double CriticalCompression;
+
+	if (DCCEnabledAnyPlane
+			&& ReturnBandwidthToDCN
+					> mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
+		ReturnBW =
+				dml_min(
+						ReturnBW,
+						ReturnBandwidthToDCN * 4
+								* (1.0
+										- mode_lib->vba.UrgentLatencyPixelDataOnly
+												/ ((mode_lib->vba.ROBBufferSizeInKByte
+														- mode_lib->vba.PixelChunkSizeInKByte)
+														* 1024
+														/ ReturnBandwidthToDCN
+														- mode_lib->vba.DCFCLK
+																* mode_lib->vba.ReturnBusWidth
+																/ 4)
+										+ mode_lib->vba.UrgentLatencyPixelDataOnly));
+
+	CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
+			* mode_lib->vba.UrgentLatencyPixelDataOnly
+			/ (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatencyPixelDataOnly
+					+ (mode_lib->vba.ROBBufferSizeInKByte
+							- mode_lib->vba.PixelChunkSizeInKByte)
+							* 1024);
+
+	if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
+		ReturnBW =
+				dml_min(
+						ReturnBW,
+						4.0 * ReturnBandwidthToDCN
+								* (mode_lib->vba.ROBBufferSizeInKByte
+										- mode_lib->vba.PixelChunkSizeInKByte)
+								* 1024
+								* mode_lib->vba.ReturnBusWidth
+								* mode_lib->vba.DCFCLK
+								* mode_lib->vba.UrgentLatencyPixelDataOnly
+								/ dml_pow(
+										(ReturnBandwidthToDCN
+												* mode_lib->vba.UrgentLatencyPixelDataOnly
+												+ (mode_lib->vba.ROBBufferSizeInKByte
+														- mode_lib->vba.PixelChunkSizeInKByte)
+														* 1024),
+										2));
+
+	return ReturnBW;
+}
+
+static unsigned int dscceComputeDelay(
+		unsigned int bpc,
+		double bpp,
+		unsigned int sliceWidth,
+		unsigned int numSlices,
+		enum output_format_class pixelFormat)
+{
+	// valid bpc         = source bits per component in the set of {8, 10, 12}
+	// valid bpp         = increments of 1/16 of a bit
+	//                    min = 6/7/8 in N420/N422/444, respectively
+	//                    max = such that compression is 1:1
+	//valid sliceWidth  = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
+	//valid numSlices   = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
+	//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
+
+	// fixed value
+	unsigned int rcModelSize = 8192;
+
+	// N422/N420 operate at 2 pixels per clock
+	unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
+			Delay, pixels;
+
+	if (pixelFormat == dm_n422 || pixelFormat == dm_420)
+		pixelsPerClock = 2;
+	// #all other modes operate at 1 pixel per clock
+	else
+		pixelsPerClock = 1;
+
+	//initial transmit delay as per PPS
+	initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
+
+	//compute ssm delay
+	if (bpc == 8)
+		D = 81;
+	else if (bpc == 10)
+		D = 89;
+	else
+		D = 113;
+
+	//divide by pixel per cycle to compute slice width as seen by DSC
+	w = sliceWidth / pixelsPerClock;
+
+	//422 mode has an additional cycle of delay
+	if (pixelFormat == dm_s422)
+		s = 1;
+	else
+		s = 0;
+
+	//main calculation for the dscce
+	ix = initalXmitDelay + 45;
+	wx = (w + 2) / 3;
+	p = 3 * wx - w;
+	l0 = ix / w;
+	a = ix + p * l0;
+	ax = (a + 2) / 3 + D + 6 + 1;
+	l = (ax + wx - 1) / wx;
+	if ((ix % w) == 0 && p != 0)
+		lstall = 1;
+	else
+		lstall = 0;
+	Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
+
+	//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
+	pixels = Delay * 3 * pixelsPerClock;
+	return pixels;
+}
+
+static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
+{
+	unsigned int Delay = 0;
+
+	if (pixelFormat == dm_420) {
+		//   sfr
+		Delay = Delay + 2;
+		//   dsccif
+		Delay = Delay + 0;
+		//   dscc - input deserializer
+		Delay = Delay + 3;
+		//   dscc gets pixels every other cycle
+		Delay = Delay + 2;
+		//   dscc - input cdc fifo
+		Delay = Delay + 12;
+		//   dscc gets pixels every other cycle
+		Delay = Delay + 13;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output cdc fifo
+		Delay = Delay + 7;
+		//   dscc gets pixels every other cycle
+		Delay = Delay + 3;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output serializer
+		Delay = Delay + 1;
+		//   sft
+		Delay = Delay + 1;
+	} else if (pixelFormat == dm_n422) {
+		//   sfr
+		Delay = Delay + 2;
+		//   dsccif
+		Delay = Delay + 1;
+		//   dscc - input deserializer
+		Delay = Delay + 5;
+		//  dscc - input cdc fifo
+		Delay = Delay + 25;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output cdc fifo
+		Delay = Delay + 10;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output serializer
+		Delay = Delay + 1;
+		//   sft
+		Delay = Delay + 1;
+	} else {
+		//   sfr
+		Delay = Delay + 2;
+		//   dsccif
+		Delay = Delay + 0;
+		//   dscc - input deserializer
+		Delay = Delay + 3;
+		//   dscc - input cdc fifo
+		Delay = Delay + 12;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output cdc fifo
+		Delay = Delay + 7;
+		//   dscc - output serializer
+		Delay = Delay + 1;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   sft
+		Delay = Delay + 1;
+	}
+
+	return Delay;
+}
+
+static bool CalculateDelayAfterScaler(
+		struct display_mode_lib *mode_lib,
+		double ReturnBW,
+		double ReadBandwidthPlaneLuma,
+		double ReadBandwidthPlaneChroma,
+		double TotalDataReadBandwidth,
+		double DisplayPipeLineDeliveryTimeLuma,
+		double DisplayPipeLineDeliveryTimeChroma,
+		double DPPCLK,
+		double DISPCLK,
+		double PixelClock,
+		unsigned int DSCDelay,
+		unsigned int DPPPerPlane,
+		bool ScalerEnabled,
+		unsigned int NumberOfCursors,
+		double DPPCLKDelaySubtotal,
+		double DPPCLKDelaySCL,
+		double DPPCLKDelaySCLLBOnly,
+		double DPPCLKDelayCNVCFormater,
+		double DPPCLKDelayCNVCCursor,
+		double DISPCLKDelaySubtotal,
+		unsigned int ScalerRecoutWidth,
+		enum output_format_class OutputFormat,
+		unsigned int HTotal,
+		unsigned int SwathWidthSingleDPPY,
+		double BytePerPixelDETY,
+		double BytePerPixelDETC,
+		unsigned int SwathHeightY,
+		unsigned int SwathHeightC,
+		bool Interlace,
+		bool ProgressiveToInterlaceUnitInOPP,
+		double *DSTXAfterScaler,
+		double *DSTYAfterScaler
+		)
+{
+	unsigned int DPPCycles, DISPCLKCycles;
+	double DataFabricLineDeliveryTimeLuma;
+	double DataFabricLineDeliveryTimeChroma;
+	double DSTTotalPixelsAfterScaler;
+
+	DataFabricLineDeliveryTimeLuma = SwathWidthSingleDPPY * SwathHeightY * dml_ceil(BytePerPixelDETY, 1) / (mode_lib->vba.ReturnBW * ReadBandwidthPlaneLuma / TotalDataReadBandwidth);
+	mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, DataFabricLineDeliveryTimeLuma - DisplayPipeLineDeliveryTimeLuma);
+
+	if (BytePerPixelDETC != 0) {
+		DataFabricLineDeliveryTimeChroma = SwathWidthSingleDPPY / 2 * SwathHeightC * dml_ceil(BytePerPixelDETC, 2) / (mode_lib->vba.ReturnBW * ReadBandwidthPlaneChroma / TotalDataReadBandwidth);
+		mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(mode_lib->vba.LastPixelOfLineExtraWatermark, DataFabricLineDeliveryTimeChroma - DisplayPipeLineDeliveryTimeChroma);
+	}
+
+	if (ScalerEnabled)
+		DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
+	else
+		DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
+
+	DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
+
+	DISPCLKCycles = DISPCLKDelaySubtotal;
+
+	if (DPPCLK == 0.0 || DISPCLK == 0.0)
+		return true;
+
+	*DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
+			+ DSCDelay;
+
+	if (DPPPerPlane > 1)
+		*DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
+
+	if (OutputFormat == dm_420 || (Interlace && ProgressiveToInterlaceUnitInOPP))
+		*DSTYAfterScaler = 1;
+	else
+		*DSTYAfterScaler = 0;
+
+	DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
+	*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
+	*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
+
+	return true;
+}
+
+static bool CalculatePrefetchSchedule(
+		struct display_mode_lib *mode_lib,
+		double DPPCLK,
+		double DISPCLK,
+		double PixelClock,
+		double DCFCLKDeepSleep,
+		unsigned int DPPPerPlane,
+		unsigned int NumberOfCursors,
+		unsigned int VBlank,
+		unsigned int HTotal,
+		unsigned int MaxInterDCNTileRepeaters,
+		unsigned int VStartup,
+		unsigned int PageTableLevels,
+		bool GPUVMEnable,
+		bool DynamicMetadataEnable,
+		unsigned int DynamicMetadataLinesBeforeActiveRequired,
+		unsigned int DynamicMetadataTransmittedBytes,
+		bool DCCEnable,
+		double UrgentLatencyPixelDataOnly,
+		double UrgentExtraLatency,
+		double TCalc,
+		unsigned int PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		double PrefetchSourceLinesY,
+		unsigned int SwathWidthY,
+		double BytePerPixelDETY,
+		double VInitPreFillY,
+		unsigned int MaxNumSwathY,
+		double PrefetchSourceLinesC,
+		double BytePerPixelDETC,
+		double VInitPreFillC,
+		unsigned int MaxNumSwathC,
+		unsigned int SwathHeightY,
+		unsigned int SwathHeightC,
+		double TWait,
+		bool XFCEnabled,
+		double XFCRemoteSurfaceFlipDelay,
+		bool InterlaceEnable,
+		bool ProgressiveToInterlaceUnitInOPP,
+		double DSTXAfterScaler,
+		double DSTYAfterScaler,
+		double *DestinationLinesForPrefetch,
+		double *PrefetchBandwidth,
+		double *DestinationLinesToRequestVMInVBlank,
+		double *DestinationLinesToRequestRowInVBlank,
+		double *VRatioPrefetchY,
+		double *VRatioPrefetchC,
+		double *RequiredPrefetchPixDataBW,
+		double *Tno_bw,
+		unsigned int *VUpdateOffsetPix,
+		double *VUpdateWidthPix,
+		double *VReadyOffsetPix)
+{
+	bool MyError = false;
+	double TotalRepeaterDelayTime;
+	double Tdm, LineTime, Tsetup;
+	double dst_y_prefetch_equ;
+	double Tsw_oto;
+	double prefetch_bw_oto;
+	double Tvm_oto;
+	double Tr0_oto;
+	double Tpre_oto;
+	double dst_y_prefetch_oto;
+	double TimeForFetchingMetaPTE = 0;
+	double TimeForFetchingRowInVBlank = 0;
+	double LinesToRequestPrefetchPixelData = 0;
+
+	*VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
+	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
+	*VUpdateWidthPix = (14.0 / DCFCLKDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
+			* PixelClock;
+
+	*VReadyOffsetPix = dml_max(
+			150.0 / DPPCLK,
+			TotalRepeaterDelayTime + 20.0 / DCFCLKDeepSleep + 10.0 / DPPCLK)
+			* PixelClock;
+
+	Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
+
+	LineTime = (double) HTotal / PixelClock;
+
+	if (DynamicMetadataEnable) {
+		double Tdmbf, Tdmec, Tdmsks;
+
+		Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
+		Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
+		Tdmec = LineTime;
+		if (DynamicMetadataLinesBeforeActiveRequired == 0)
+			Tdmsks = VBlank * LineTime / 2.0;
+		else
+			Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
+		if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
+			Tdmsks = Tdmsks / 2;
+		if (VStartup * LineTime
+				< Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
+			MyError = true;
+		}
+	} else
+		Tdm = 0;
+
+	if (GPUVMEnable) {
+		if (PageTableLevels == 4)
+			*Tno_bw = UrgentExtraLatency + UrgentLatencyPixelDataOnly;
+		else if (PageTableLevels == 3)
+			*Tno_bw = UrgentExtraLatency;
+		else
+			*Tno_bw = 0;
+	} else if (DCCEnable)
+		*Tno_bw = LineTime;
+	else
+		*Tno_bw = LineTime / 4;
+
+	dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
+			- (Tsetup + Tdm) / LineTime
+			- (DSTYAfterScaler + DSTXAfterScaler / HTotal);
+
+	Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
+
+	prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
+			+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+			+ PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
+			/ Tsw_oto;
+
+	if (GPUVMEnable == true) {
+		Tvm_oto =
+				dml_max(
+						*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
+						dml_max(
+								UrgentExtraLatency
+										+ UrgentLatencyPixelDataOnly
+												* (PageTableLevels
+														- 1),
+								LineTime / 4.0));
+	} else
+		Tvm_oto = LineTime / 4.0;
+
+	if ((GPUVMEnable == true || DCCEnable == true)) {
+		Tr0_oto = dml_max(
+				(MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
+				dml_max(UrgentLatencyPixelDataOnly, dml_max(LineTime - Tvm_oto, LineTime / 4)));
+	} else
+		Tr0_oto = LineTime - Tvm_oto;
+
+	Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
+
+	dst_y_prefetch_oto = Tpre_oto / LineTime;
+
+	if (dst_y_prefetch_oto < dst_y_prefetch_equ)
+		*DestinationLinesForPrefetch = dst_y_prefetch_oto;
+	else
+		*DestinationLinesForPrefetch = dst_y_prefetch_equ;
+
+	*DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
+			/ 4;
+
+	dml_print("DML: VStartup: %d\n", VStartup);
+	dml_print("DML: TCalc: %f\n", TCalc);
+	dml_print("DML: TWait: %f\n", TWait);
+	dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
+	dml_print("DML: LineTime: %f\n", LineTime);
+	dml_print("DML: Tsetup: %f\n", Tsetup);
+	dml_print("DML: Tdm: %f\n", Tdm);
+	dml_print("DML: DSTYAfterScaler: %f\n", DSTYAfterScaler);
+	dml_print("DML: DSTXAfterScaler: %f\n", DSTXAfterScaler);
+	dml_print("DML: HTotal: %d\n", HTotal);
+
+	*PrefetchBandwidth = 0;
+	*DestinationLinesToRequestVMInVBlank = 0;
+	*DestinationLinesToRequestRowInVBlank = 0;
+	*VRatioPrefetchY = 0;
+	*VRatioPrefetchC = 0;
+	*RequiredPrefetchPixDataBW = 0;
+	if (*DestinationLinesForPrefetch > 1) {
+		*PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
+				+ 2 * PixelPTEBytesPerRow
+				+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+				+ PrefetchSourceLinesC * SwathWidthY / 2
+						* dml_ceil(BytePerPixelDETC, 2))
+				/ (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
+		if (GPUVMEnable) {
+			TimeForFetchingMetaPTE =
+					dml_max(
+							*Tno_bw
+									+ (double) PDEAndMetaPTEBytesFrame
+											/ *PrefetchBandwidth,
+							dml_max(
+									UrgentExtraLatency
+											+ UrgentLatencyPixelDataOnly
+													* (PageTableLevels
+															- 1),
+									LineTime / 4));
+		} else {
+			if (NumberOfCursors > 0 || XFCEnabled)
+				TimeForFetchingMetaPTE = LineTime / 4;
+			else
+				TimeForFetchingMetaPTE = 0.0;
+		}
+
+		if ((GPUVMEnable == true || DCCEnable == true)) {
+			TimeForFetchingRowInVBlank =
+					dml_max(
+							(MetaRowByte + PixelPTEBytesPerRow)
+									/ *PrefetchBandwidth,
+							dml_max(
+									UrgentLatencyPixelDataOnly,
+									dml_max(
+											LineTime
+													- TimeForFetchingMetaPTE,
+											LineTime
+													/ 4.0)));
+		} else {
+			if (NumberOfCursors > 0 || XFCEnabled)
+				TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
+			else
+				TimeForFetchingRowInVBlank = 0.0;
+		}
+
+		*DestinationLinesToRequestVMInVBlank = dml_floor(
+				4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
+				1) / 4.0;
+
+		*DestinationLinesToRequestRowInVBlank = dml_floor(
+				4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
+				1) / 4.0;
+
+		LinesToRequestPrefetchPixelData =
+				*DestinationLinesForPrefetch
+						- ((NumberOfCursors > 0 || GPUVMEnable
+								|| DCCEnable) ?
+								(*DestinationLinesToRequestVMInVBlank
+										+ *DestinationLinesToRequestRowInVBlank) :
+								0.0);
+
+		if (LinesToRequestPrefetchPixelData > 0) {
+
+			*VRatioPrefetchY = (double) PrefetchSourceLinesY
+					/ LinesToRequestPrefetchPixelData;
+			*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
+			if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
+				if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
+					*VRatioPrefetchY =
+							dml_max(
+									(double) PrefetchSourceLinesY
+											/ LinesToRequestPrefetchPixelData,
+									(double) MaxNumSwathY
+											* SwathHeightY
+											/ (LinesToRequestPrefetchPixelData
+													- (VInitPreFillY
+															- 3.0)
+															/ 2.0));
+					*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
+				} else {
+					MyError = true;
+					*VRatioPrefetchY = 0;
+				}
+			}
+
+			*VRatioPrefetchC = (double) PrefetchSourceLinesC
+					/ LinesToRequestPrefetchPixelData;
+			*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
+
+			if ((SwathHeightC > 4)) {
+				if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
+					*VRatioPrefetchC =
+							dml_max(
+									*VRatioPrefetchC,
+									(double) MaxNumSwathC
+											* SwathHeightC
+											/ (LinesToRequestPrefetchPixelData
+													- (VInitPreFillC
+															- 3.0)
+															/ 2.0));
+					*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
+				} else {
+					MyError = true;
+					*VRatioPrefetchC = 0;
+				}
+			}
+
+			*RequiredPrefetchPixDataBW =
+					DPPPerPlane
+							* ((double) PrefetchSourceLinesY
+									/ LinesToRequestPrefetchPixelData
+									* dml_ceil(
+											BytePerPixelDETY,
+											1)
+									+ (double) PrefetchSourceLinesC
+											/ LinesToRequestPrefetchPixelData
+											* dml_ceil(
+													BytePerPixelDETC,
+													2)
+											/ 2)
+							* SwathWidthY / LineTime;
+		} else {
+			MyError = true;
+			*VRatioPrefetchY = 0;
+			*VRatioPrefetchC = 0;
+			*RequiredPrefetchPixDataBW = 0;
+		}
+
+	} else {
+		MyError = true;
+	}
+
+	if (MyError) {
+		*PrefetchBandwidth = 0;
+		TimeForFetchingMetaPTE = 0;
+		TimeForFetchingRowInVBlank = 0;
+		*DestinationLinesToRequestVMInVBlank = 0;
+		*DestinationLinesToRequestRowInVBlank = 0;
+		*DestinationLinesForPrefetch = 0;
+		LinesToRequestPrefetchPixelData = 0;
+		*VRatioPrefetchY = 0;
+		*VRatioPrefetchC = 0;
+		*RequiredPrefetchPixDataBW = 0;
+	}
+
+	return MyError;
+}
+
+static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
+{
+	return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
+}
+
+static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
+{
+	return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
+}
+
+static double CalculatePrefetchSourceLines(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double vtaps,
+		bool Interlace,
+		bool ProgressiveToInterlaceUnitInOPP,
+		unsigned int SwathHeight,
+		unsigned int ViewportYStart,
+		double *VInitPreFill,
+		unsigned int *MaxNumSwath)
+{
+	unsigned int MaxPartialSwath;
+
+	if (ProgressiveToInterlaceUnitInOPP)
+		*VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
+	else
+		*VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
+
+	if (!mode_lib->vba.IgnoreViewportPositioning) {
+
+		*MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
+
+		if (*VInitPreFill > 1.0)
+			MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
+		else
+			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
+					% SwathHeight;
+		MaxPartialSwath = dml_max(1U, MaxPartialSwath);
+
+	} else {
+
+		if (ViewportYStart != 0)
+			dml_print(
+					"WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
+
+		*MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
+
+		if (*VInitPreFill > 1.0)
+			MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
+		else
+			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
+					% SwathHeight;
+	}
+
+	return *MaxNumSwath * SwathHeight + MaxPartialSwath;
+}
+
+static unsigned int CalculateVMAndRowBytes(
+		struct display_mode_lib *mode_lib,
+		bool DCCEnable,
+		unsigned int BlockHeight256Bytes,
+		unsigned int BlockWidth256Bytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int SurfaceTiling,
+		unsigned int BytePerPixel,
+		enum scan_direction_class ScanDirection,
+		unsigned int ViewportWidth,
+		unsigned int ViewportHeight,
+		unsigned int SwathWidth,
+		bool GPUVMEnable,
+		unsigned int VMMPageSize,
+		unsigned int PTEBufferSizeInRequestsLuma,
+		unsigned int PDEProcessingBufIn64KBReqs,
+		unsigned int Pitch,
+		unsigned int DCCMetaPitch,
+		unsigned int *MacroTileWidth,
+		unsigned int *MetaRowByte,
+		unsigned int *PixelPTEBytesPerRow,
+		bool *PTEBufferSizeNotExceeded,
+		unsigned int *dpte_row_height,
+		unsigned int *meta_row_height)
+{
+	unsigned int MetaRequestHeight;
+	unsigned int MetaRequestWidth;
+	unsigned int MetaSurfWidth;
+	unsigned int MetaSurfHeight;
+	unsigned int MPDEBytesFrame;
+	unsigned int MetaPTEBytesFrame;
+	unsigned int DCCMetaSurfaceBytes;
+
+	unsigned int MacroTileSizeBytes;
+	unsigned int MacroTileHeight;
+	unsigned int DPDE0BytesFrame;
+	unsigned int ExtraDPDEBytesFrame;
+	unsigned int PDEAndMetaPTEBytesFrame;
+
+	if (DCCEnable == true) {
+		MetaRequestHeight = 8 * BlockHeight256Bytes;
+		MetaRequestWidth = 8 * BlockWidth256Bytes;
+		if (ScanDirection == dm_horz) {
+			*meta_row_height = MetaRequestHeight;
+			MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
+					+ MetaRequestWidth;
+			*MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
+		} else {
+			*meta_row_height = MetaRequestWidth;
+			MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
+					+ MetaRequestHeight;
+			*MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
+		}
+		if (ScanDirection == dm_horz) {
+			DCCMetaSurfaceBytes = DCCMetaPitch
+					* (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
+							+ 64 * BlockHeight256Bytes) * BytePerPixel
+					/ 256;
+		} else {
+			DCCMetaSurfaceBytes = DCCMetaPitch
+					* (dml_ceil(
+							(double) ViewportHeight - 1,
+							64 * BlockHeight256Bytes)
+							+ 64 * BlockHeight256Bytes) * BytePerPixel
+					/ 256;
+		}
+		if (GPUVMEnable == true) {
+			MetaPTEBytesFrame = (dml_ceil(
+					(double) (DCCMetaSurfaceBytes - VMMPageSize)
+							/ (8 * VMMPageSize),
+					1) + 1) * 64;
+			MPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 1);
+		} else {
+			MetaPTEBytesFrame = 0;
+			MPDEBytesFrame = 0;
+		}
+	} else {
+		MetaPTEBytesFrame = 0;
+		MPDEBytesFrame = 0;
+		*MetaRowByte = 0;
+	}
+
+	if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) {
+		MacroTileSizeBytes = 256;
+		MacroTileHeight = BlockHeight256Bytes;
+	} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
+			|| SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
+		MacroTileSizeBytes = 4096;
+		MacroTileHeight = 4 * BlockHeight256Bytes;
+	} else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
+			|| SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
+			|| SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
+			|| SurfaceTiling == dm_sw_64kb_r_x) {
+		MacroTileSizeBytes = 65536;
+		MacroTileHeight = 16 * BlockHeight256Bytes;
+	} else {
+		MacroTileSizeBytes = 262144;
+		MacroTileHeight = 32 * BlockHeight256Bytes;
+	}
+	*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
+
+	if (GPUVMEnable == true && mode_lib->vba.GPUVMMaxPageTableLevels > 1) {
+		if (ScanDirection == dm_horz) {
+			DPDE0BytesFrame =
+					64
+							* (dml_ceil(
+									((Pitch
+											* (dml_ceil(
+													ViewportHeight
+															- 1,
+													MacroTileHeight)
+													+ MacroTileHeight)
+											* BytePerPixel)
+											- MacroTileSizeBytes)
+											/ (8
+													* 2097152),
+									1) + 1);
+		} else {
+			DPDE0BytesFrame =
+					64
+							* (dml_ceil(
+									((Pitch
+											* (dml_ceil(
+													(double) SwathWidth
+															- 1,
+													MacroTileHeight)
+													+ MacroTileHeight)
+											* BytePerPixel)
+											- MacroTileSizeBytes)
+											/ (8
+													* 2097152),
+									1) + 1);
+		}
+		ExtraDPDEBytesFrame = 128 * (mode_lib->vba.GPUVMMaxPageTableLevels - 2);
+	} else {
+		DPDE0BytesFrame = 0;
+		ExtraDPDEBytesFrame = 0;
+	}
+
+	PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
+			+ ExtraDPDEBytesFrame;
+
+	if (GPUVMEnable == true) {
+		unsigned int PTERequestSize;
+		unsigned int PixelPTEReqHeight;
+		unsigned int PixelPTEReqWidth;
+		double FractionOfPTEReturnDrop;
+		unsigned int EffectivePDEProcessingBufIn64KBReqs;
+
+		if (SurfaceTiling == dm_sw_linear) {
+			PixelPTEReqHeight = 1;
+			PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
+			PTERequestSize = 64;
+			FractionOfPTEReturnDrop = 0;
+		} else if (MacroTileSizeBytes == 4096) {
+			PixelPTEReqHeight = MacroTileHeight;
+			PixelPTEReqWidth = 8 * *MacroTileWidth;
+			PTERequestSize = 64;
+			if (ScanDirection == dm_horz)
+				FractionOfPTEReturnDrop = 0;
+			else
+				FractionOfPTEReturnDrop = 7 / 8;
+		} else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
+			PixelPTEReqHeight = 16 * BlockHeight256Bytes;
+			PixelPTEReqWidth = 16 * BlockWidth256Bytes;
+			PTERequestSize = 128;
+			FractionOfPTEReturnDrop = 0;
+		} else {
+			PixelPTEReqHeight = MacroTileHeight;
+			PixelPTEReqWidth = 8 * *MacroTileWidth;
+			PTERequestSize = 64;
+			FractionOfPTEReturnDrop = 0;
+		}
+
+		if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
+			EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
+		else
+			EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
+
+		if (SurfaceTiling == dm_sw_linear) {
+			*dpte_row_height =
+					dml_min(
+							128,
+							1
+									<< (unsigned int) dml_floor(
+											dml_log2(
+													dml_min(
+															(double) PTEBufferSizeInRequestsLuma
+																	* PixelPTEReqWidth,
+															EffectivePDEProcessingBufIn64KBReqs
+																	* 65536.0
+																	/ BytePerPixel)
+															/ Pitch),
+											1));
+			*PixelPTEBytesPerRow = PTERequestSize
+					* (dml_ceil(
+							(double) (Pitch * *dpte_row_height - 1)
+									/ PixelPTEReqWidth,
+							1) + 1);
+		} else if (ScanDirection == dm_horz) {
+			*dpte_row_height = PixelPTEReqHeight;
+			*PixelPTEBytesPerRow = PTERequestSize
+					* (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
+							+ 1);
+		} else {
+			*dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
+			*PixelPTEBytesPerRow = PTERequestSize
+					* (dml_ceil(
+							((double) SwathWidth - 1)
+									/ PixelPTEReqHeight,
+							1) + 1);
+		}
+		if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
+				<= 64 * PTEBufferSizeInRequestsLuma) {
+			*PTEBufferSizeNotExceeded = true;
+		} else {
+			*PTEBufferSizeNotExceeded = false;
+		}
+	} else {
+		*PixelPTEBytesPerRow = 0;
+		*PTEBufferSizeNotExceeded = true;
+	}
+
+	return PDEAndMetaPTEBytesFrame;
+}
+
+static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+		struct display_mode_lib *mode_lib)
+{
+	unsigned int j, k;
+
+	mode_lib->vba.WritebackDISPCLK = 0.0;
+	mode_lib->vba.DISPCLKWithRamping = 0;
+	mode_lib->vba.DISPCLKWithoutRamping = 0;
+	mode_lib->vba.GlobalDPPCLK = 0.0;
+
+	// dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
+	//
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.WritebackEnable[k]) {
+			mode_lib->vba.WritebackDISPCLK =
+					dml_max(
+							mode_lib->vba.WritebackDISPCLK,
+							CalculateWriteBackDISPCLK(
+									mode_lib->vba.WritebackPixelFormat[k],
+									mode_lib->vba.PixelClock[k],
+									mode_lib->vba.WritebackHRatio[k],
+									mode_lib->vba.WritebackVRatio[k],
+									mode_lib->vba.WritebackLumaHTaps[k],
+									mode_lib->vba.WritebackLumaVTaps[k],
+									mode_lib->vba.WritebackChromaHTaps[k],
+									mode_lib->vba.WritebackChromaVTaps[k],
+									mode_lib->vba.WritebackDestinationWidth[k],
+									mode_lib->vba.HTotal[k],
+									mode_lib->vba.WritebackChromaLineBufferWidth));
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.HRatio[k] > 1) {
+			mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput
+							* mode_lib->vba.HRatio[k]
+							/ dml_ceil(
+									mode_lib->vba.htaps[k]
+											/ 6.0,
+									1));
+		} else {
+			mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput);
+		}
+
+		mode_lib->vba.DPPCLKUsingSingleDPPLuma =
+				mode_lib->vba.PixelClock[k]
+						* dml_max(
+								mode_lib->vba.vtaps[k] / 6.0
+										* dml_min(
+												1.0,
+												mode_lib->vba.HRatio[k]),
+								dml_max(
+										mode_lib->vba.HRatio[k]
+												* mode_lib->vba.VRatio[k]
+												/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
+										1.0));
+
+		if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
+				&& mode_lib->vba.DPPCLKUsingSingleDPPLuma
+						< 2 * mode_lib->vba.PixelClock[k]) {
+			mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
+		}
+
+		if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+			mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
+			mode_lib->vba.DPPCLKUsingSingleDPP[k] =
+					mode_lib->vba.DPPCLKUsingSingleDPPLuma;
+		} else {
+			if (mode_lib->vba.HRatio[k] > 1) {
+				mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
+						dml_min(
+								mode_lib->vba.MaxDCHUBToPSCLThroughput,
+								mode_lib->vba.MaxPSCLToLBThroughput
+										* mode_lib->vba.HRatio[k]
+										/ 2
+										/ dml_ceil(
+												mode_lib->vba.HTAPsChroma[k]
+														/ 6.0,
+												1.0));
+			} else {
+				mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
+						mode_lib->vba.MaxDCHUBToPSCLThroughput,
+						mode_lib->vba.MaxPSCLToLBThroughput);
+			}
+			mode_lib->vba.DPPCLKUsingSingleDPPChroma =
+					mode_lib->vba.PixelClock[k]
+							* dml_max(
+									mode_lib->vba.VTAPsChroma[k]
+											/ 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]
+															/ 2),
+									dml_max(
+											mode_lib->vba.HRatio[k]
+													* mode_lib->vba.VRatio[k]
+													/ 4
+													/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
+											1.0));
+
+			if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
+					&& mode_lib->vba.DPPCLKUsingSingleDPPChroma
+							< 2 * mode_lib->vba.PixelClock[k]) {
+				mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
+						* mode_lib->vba.PixelClock[k];
+			}
+
+			mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
+					mode_lib->vba.DPPCLKUsingSingleDPPLuma,
+					mode_lib->vba.DPPCLKUsingSingleDPPChroma);
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.BlendingAndTiming[k] != k)
+			continue;
+		if (mode_lib->vba.ODMCombineEnabled[k]) {
+			mode_lib->vba.DISPCLKWithRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithRamping,
+							mode_lib->vba.PixelClock[k] / 2
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100)
+									* (1
+											+ mode_lib->vba.DISPCLKRampingMargin
+													/ 100));
+			mode_lib->vba.DISPCLKWithoutRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithoutRamping,
+							mode_lib->vba.PixelClock[k] / 2
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100));
+		} else if (!mode_lib->vba.ODMCombineEnabled[k]) {
+			mode_lib->vba.DISPCLKWithRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithRamping,
+							mode_lib->vba.PixelClock[k]
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100)
+									* (1
+											+ mode_lib->vba.DISPCLKRampingMargin
+													/ 100));
+			mode_lib->vba.DISPCLKWithoutRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithoutRamping,
+							mode_lib->vba.PixelClock[k]
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100));
+		}
+	}
+
+	mode_lib->vba.DISPCLKWithRamping = dml_max(
+			mode_lib->vba.DISPCLKWithRamping,
+			mode_lib->vba.WritebackDISPCLK);
+	mode_lib->vba.DISPCLKWithoutRamping = dml_max(
+			mode_lib->vba.DISPCLKWithoutRamping,
+			mode_lib->vba.WritebackDISPCLK);
+
+	ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
+	mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
+			mode_lib->vba.DISPCLKWithRamping,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
+			mode_lib->vba.DISPCLKWithoutRamping,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
+			mode_lib->vba.soc.clock_limits[mode_lib->vba.soc.num_states].dispclk_mhz,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
+			> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
+		mode_lib->vba.DISPCLK_calculated =
+				mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
+	} else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
+			> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
+		mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
+	} else {
+		mode_lib->vba.DISPCLK_calculated =
+				mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
+	}
+	DTRACE("   dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.DPPPerPlane[k] == 0) {
+			mode_lib->vba.DPPCLK_calculated[k] = 0;
+		} else {
+			mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
+					/ mode_lib->vba.DPPPerPlane[k]
+					* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
+		}
+		mode_lib->vba.GlobalDPPCLK = dml_max(
+				mode_lib->vba.GlobalDPPCLK,
+				mode_lib->vba.DPPCLK_calculated[k]);
+	}
+	mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
+			mode_lib->vba.GlobalDPPCLK,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
+				* dml_ceil(
+						mode_lib->vba.DPPCLK_calculated[k] * 255
+								/ mode_lib->vba.GlobalDPPCLK,
+						1);
+		DTRACE("   dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
+	}
+
+	// Urgent Watermark
+	mode_lib->vba.DCCEnabledAnyPlane = false;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		if (mode_lib->vba.DCCEnable[k])
+			mode_lib->vba.DCCEnabledAnyPlane = true;
+
+	mode_lib->vba.ReturnBandwidthToDCN = dml_min(
+			mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
+			mode_lib->vba.FabricAndDRAMBandwidth * 1000)
+			* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
+
+	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
+	mode_lib->vba.ReturnBW = adjust_ReturnBW(
+			mode_lib,
+			mode_lib->vba.ReturnBW,
+			mode_lib->vba.DCCEnabledAnyPlane,
+			mode_lib->vba.ReturnBandwidthToDCN);
+
+	// Let's do this calculation again??
+	mode_lib->vba.ReturnBandwidthToDCN = dml_min(
+			mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
+			mode_lib->vba.FabricAndDRAMBandwidth * 1000);
+	mode_lib->vba.ReturnBW = adjust_ReturnBW(
+			mode_lib,
+			mode_lib->vba.ReturnBW,
+			mode_lib->vba.DCCEnabledAnyPlane,
+			mode_lib->vba.ReturnBandwidthToDCN);
+
+	DTRACE("   dcfclk_mhz         = %f", mode_lib->vba.DCFCLK);
+	DTRACE("   return_bw_to_dcn   = %f", mode_lib->vba.ReturnBandwidthToDCN);
+	DTRACE("   return_bus_bw      = %f", mode_lib->vba.ReturnBW);
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		bool MainPlaneDoesODMCombine = false;
+
+		if (mode_lib->vba.SourceScan[k] == dm_horz)
+			mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
+		else
+			mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
+
+		if (mode_lib->vba.ODMCombineEnabled[k] == true)
+			MainPlaneDoesODMCombine = true;
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+			if (mode_lib->vba.BlendingAndTiming[k] == j
+					&& mode_lib->vba.ODMCombineEnabled[j] == true)
+				MainPlaneDoesODMCombine = true;
+
+		if (MainPlaneDoesODMCombine == true)
+			mode_lib->vba.SwathWidthY[k] = dml_min(
+					(double) mode_lib->vba.SwathWidthSingleDPPY[k],
+					dml_round(
+							mode_lib->vba.HActive[k] / 2.0
+									* mode_lib->vba.HRatio[k]));
+		else {
+			if (mode_lib->vba.DPPPerPlane[k] == 0) {
+				mode_lib->vba.SwathWidthY[k] = 0;
+			} else {
+				mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+						/ mode_lib->vba.DPPPerPlane[k];
+			}
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+			mode_lib->vba.BytePerPixelDETY[k] = 8;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+			mode_lib->vba.BytePerPixelDETY[k] = 4;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+			mode_lib->vba.BytePerPixelDETY[k] = 2;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
+			mode_lib->vba.BytePerPixelDETY[k] = 1;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+			mode_lib->vba.BytePerPixelDETY[k] = 1;
+			mode_lib->vba.BytePerPixelDETC[k] = 2;
+		} else { // dm_420_10
+			mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
+			mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
+		}
+	}
+
+	mode_lib->vba.TotalDataReadBandwidth = 0.0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+				* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				* mode_lib->vba.VRatio[k];
+		mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+				/ 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				* mode_lib->vba.VRatio[k] / 2;
+		DTRACE(
+				"   read_bw[%i] = %fBps",
+				k,
+				mode_lib->vba.ReadBandwidthPlaneLuma[k]
+						+ mode_lib->vba.ReadBandwidthPlaneChroma[k]);
+		mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
+				+ mode_lib->vba.ReadBandwidthPlaneChroma[k];
+	}
+
+	mode_lib->vba.TotalDCCActiveDPP = 0;
+	mode_lib->vba.TotalActiveDPP = 0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
+				+ mode_lib->vba.DPPPerPlane[k];
+		if (mode_lib->vba.DCCEnable[k])
+			mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
+					+ mode_lib->vba.DPPPerPlane[k];
+	}
+
+	mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
+			(mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
+					+ mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly
+							* mode_lib->vba.NumberOfChannels
+							/ mode_lib->vba.ReturnBW;
+
+	mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
+
+	mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
+			+ (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
+					+ mode_lib->vba.TotalDCCActiveDPP
+							* mode_lib->vba.MetaChunkSize) * 1024.0
+					/ mode_lib->vba.ReturnBW;
+
+	if (mode_lib->vba.GPUVMEnable)
+		mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
+				* mode_lib->vba.PTEGroupSize / mode_lib->vba.ReturnBW;
+
+	mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatencyPixelDataOnly
+			+ mode_lib->vba.LastPixelOfLineExtraWatermark
+			+ mode_lib->vba.UrgentExtraLatency;
+
+	DTRACE("   urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
+	DTRACE("   wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
+
+	mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly;
+
+	mode_lib->vba.TotalActiveWriteback = 0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.WritebackEnable[k])
+			mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + mode_lib->vba.ActiveWritebacksPerPlane[k];
+	}
+
+	if (mode_lib->vba.TotalActiveWriteback <= 1)
+		mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
+	else
+		mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
+				+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
+						/ mode_lib->vba.SOCCLK;
+
+	DTRACE("   wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
+
+	// NB P-State/DRAM Clock Change Watermark
+	mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
+			+ mode_lib->vba.UrgentWatermark;
+
+	DTRACE("   wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
+
+	DTRACE("   calculating wb pstate watermark");
+	DTRACE("      total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
+	DTRACE("      socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
+
+	if (mode_lib->vba.TotalActiveWriteback <= 1)
+		mode_lib->vba.WritebackDRAMClockChangeWatermark =
+				mode_lib->vba.DRAMClockChangeLatency
+						+ mode_lib->vba.WritebackLatency;
+	else
+		mode_lib->vba.WritebackDRAMClockChangeWatermark =
+				mode_lib->vba.DRAMClockChangeLatency
+						+ mode_lib->vba.WritebackLatency
+						+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
+								/ mode_lib->vba.SOCCLK;
+
+	DTRACE("   wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
+
+	// Stutter Efficiency
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
+				/ mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
+		mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
+				mode_lib->vba.LinesInDETY[k],
+				mode_lib->vba.SwathHeightY[k]);
+		mode_lib->vba.FullDETBufferingTimeY[k] =
+				mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
+						* (mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k])
+						/ mode_lib->vba.VRatio[k];
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k]
+					/ mode_lib->vba.BytePerPixelDETC[k]
+					/ (mode_lib->vba.SwathWidthY[k] / 2);
+			mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(
+					mode_lib->vba.LinesInDETC[k],
+					mode_lib->vba.SwathHeightC[k]);
+			mode_lib->vba.FullDETBufferingTimeC[k] =
+					mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
+							* (mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k])
+							/ (mode_lib->vba.VRatio[k] / 2);
+		} else {
+			mode_lib->vba.LinesInDETC[k] = 0;
+			mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
+			mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
+		}
+	}
+
+	mode_lib->vba.MinFullDETBufferingTime = 999999.0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.FullDETBufferingTimeY[k]
+				< mode_lib->vba.MinFullDETBufferingTime) {
+			mode_lib->vba.MinFullDETBufferingTime =
+					mode_lib->vba.FullDETBufferingTimeY[k];
+			mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
+					(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k];
+		}
+		if (mode_lib->vba.FullDETBufferingTimeC[k]
+				< mode_lib->vba.MinFullDETBufferingTime) {
+			mode_lib->vba.MinFullDETBufferingTime =
+					mode_lib->vba.FullDETBufferingTimeC[k];
+			mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
+					(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k];
+		}
+	}
+
+	mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.DCCEnable[k]) {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ mode_lib->vba.DCCRate[k]
+									/ 1000
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ mode_lib->vba.DCCRate[k]
+									/ 1000;
+		} else {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ 1000
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ 1000;
+		}
+		if (mode_lib->vba.DCCEnable[k]) {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ 1000 / 256
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ 1000 / 256;
+		}
+		if (mode_lib->vba.GPUVMEnable) {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ 1000 / 512
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ 1000 / 512;
+		}
+	}
+
+	mode_lib->vba.PartOfBurstThatFitsInROB =
+			dml_min(
+					mode_lib->vba.MinFullDETBufferingTime
+							* mode_lib->vba.TotalDataReadBandwidth,
+					mode_lib->vba.ROBBufferSizeInKByte * 1024
+							* mode_lib->vba.TotalDataReadBandwidth
+							/ (mode_lib->vba.AverageReadBandwidthGBytePerSecond
+									* 1000));
+	mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
+			* (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
+			/ mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
+			+ (mode_lib->vba.MinFullDETBufferingTime
+					* mode_lib->vba.TotalDataReadBandwidth
+					- mode_lib->vba.PartOfBurstThatFitsInROB)
+					/ (mode_lib->vba.DCFCLK * 64);
+	if (mode_lib->vba.TotalActiveWriteback == 0) {
+		mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
+				- (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
+						/ mode_lib->vba.MinFullDETBufferingTime) * 100;
+	} else {
+		mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
+	}
+
+	mode_lib->vba.SmallestVBlank = 999999;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
+			mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
+					- mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
+					/ mode_lib->vba.PixelClock[k];
+		} else {
+			mode_lib->vba.VBlankTime = 0;
+		}
+		mode_lib->vba.SmallestVBlank = dml_min(
+				mode_lib->vba.SmallestVBlank,
+				mode_lib->vba.VBlankTime);
+	}
+
+	mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
+			* (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
+					- mode_lib->vba.SmallestVBlank)
+			+ mode_lib->vba.SmallestVBlank)
+			/ mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
+
+	// dml_ml->vba.DCFCLK Deep Sleep
+	mode_lib->vba.DCFCLKDeepSleep = 8.0;
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			mode_lib->vba.DCFCLKDeepSleepPerPlane[k] =
+					dml_max(
+							1.1 * mode_lib->vba.SwathWidthY[k]
+									* dml_ceil(
+											mode_lib->vba.BytePerPixelDETY[k],
+											1) / 32
+									/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
+							1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
+									* dml_ceil(
+											mode_lib->vba.BytePerPixelDETC[k],
+											2) / 32
+									/ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
+		} else
+			mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = 1.1 * mode_lib->vba.SwathWidthY[k]
+					* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
+					/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
+		mode_lib->vba.DCFCLKDeepSleepPerPlane[k] = dml_max(
+				mode_lib->vba.DCFCLKDeepSleepPerPlane[k],
+				mode_lib->vba.PixelClock[k] / 16.0);
+		mode_lib->vba.DCFCLKDeepSleep = dml_max(
+				mode_lib->vba.DCFCLKDeepSleep,
+				mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
+
+		DTRACE(
+				"   dcfclk_deepsleep_per_plane[%i] = %fMHz",
+				k,
+				mode_lib->vba.DCFCLKDeepSleepPerPlane[k]);
+	}
+
+	DTRACE("   dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFCLKDeepSleep);
+
+	// Stutter Watermark
+	mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
+			+ mode_lib->vba.LastPixelOfLineExtraWatermark
+			+ mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFCLKDeepSleep;
+	mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
+			+ mode_lib->vba.LastPixelOfLineExtraWatermark
+			+ mode_lib->vba.UrgentExtraLatency;
+
+	DTRACE("   wm_cstate_exit       = %fus", mode_lib->vba.StutterExitWatermark);
+	DTRACE("   wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
+
+	// Urgent Latency Supported
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.EffectiveDETPlusLBLinesLuma =
+				dml_floor(
+						mode_lib->vba.LinesInDETY[k]
+								+ dml_min(
+										mode_lib->vba.LinesInDETY[k]
+												* mode_lib->vba.DPPCLK[k]
+												* mode_lib->vba.BytePerPixelDETY[k]
+												* mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+												/ (mode_lib->vba.ReturnBW
+														/ mode_lib->vba.DPPPerPlane[k]),
+										(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
+						mode_lib->vba.SwathHeightY[k]);
+
+		mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
+				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				/ mode_lib->vba.VRatio[k]
+				- mode_lib->vba.EffectiveDETPlusLBLinesLuma
+						* mode_lib->vba.SwathWidthY[k]
+						* mode_lib->vba.BytePerPixelDETY[k]
+						/ (mode_lib->vba.ReturnBW
+								/ mode_lib->vba.DPPPerPlane[k]);
+
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			mode_lib->vba.EffectiveDETPlusLBLinesChroma =
+					dml_floor(
+							mode_lib->vba.LinesInDETC[k]
+									+ dml_min(
+											mode_lib->vba.LinesInDETC[k]
+													* mode_lib->vba.DPPCLK[k]
+													* mode_lib->vba.BytePerPixelDETC[k]
+													* mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
+													/ (mode_lib->vba.ReturnBW
+															/ mode_lib->vba.DPPPerPlane[k]),
+											(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
+							mode_lib->vba.SwathHeightC[k]);
+			mode_lib->vba.UrgentLatencySupportUsChroma =
+					mode_lib->vba.EffectiveDETPlusLBLinesChroma
+							* (mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k])
+							/ (mode_lib->vba.VRatio[k] / 2)
+							- mode_lib->vba.EffectiveDETPlusLBLinesChroma
+									* (mode_lib->vba.SwathWidthY[k]
+											/ 2)
+									* mode_lib->vba.BytePerPixelDETC[k]
+									/ (mode_lib->vba.ReturnBW
+											/ mode_lib->vba.DPPPerPlane[k]);
+			mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
+					mode_lib->vba.UrgentLatencySupportUsLuma,
+					mode_lib->vba.UrgentLatencySupportUsChroma);
+		} else {
+			mode_lib->vba.UrgentLatencySupportUs[k] =
+					mode_lib->vba.UrgentLatencySupportUsLuma;
+		}
+	}
+
+	mode_lib->vba.MinUrgentLatencySupportUs = 999999;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
+				mode_lib->vba.MinUrgentLatencySupportUs,
+				mode_lib->vba.UrgentLatencySupportUs[k]);
+	}
+
+	// Non-Urgent Latency Tolerance
+	mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
+			- mode_lib->vba.UrgentWatermark;
+
+	// DSCCLK
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
+			mode_lib->vba.DSCCLK_calculated[k] = 0.0;
+		} else {
+			if (mode_lib->vba.OutputFormat[k] == dm_420
+					|| mode_lib->vba.OutputFormat[k] == dm_n422)
+				mode_lib->vba.DSCFormatFactor = 2;
+			else
+				mode_lib->vba.DSCFormatFactor = 1;
+			if (mode_lib->vba.ODMCombineEnabled[k])
+				mode_lib->vba.DSCCLK_calculated[k] =
+						mode_lib->vba.PixelClockBackEnd[k] / 6
+								/ mode_lib->vba.DSCFormatFactor
+								/ (1
+										- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100);
+			else
+				mode_lib->vba.DSCCLK_calculated[k] =
+						mode_lib->vba.PixelClockBackEnd[k] / 3
+								/ mode_lib->vba.DSCFormatFactor
+								/ (1
+										- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100);
+		}
+	}
+
+	// DSC Delay
+	// TODO
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		double bpp = mode_lib->vba.OutputBpp[k];
+		unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
+
+		if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
+			if (!mode_lib->vba.ODMCombineEnabled[k]) {
+				mode_lib->vba.DSCDelay[k] =
+						dscceComputeDelay(
+								mode_lib->vba.DSCInputBitPerComponent[k],
+								bpp,
+								dml_ceil(
+										(double) mode_lib->vba.HActive[k]
+												/ mode_lib->vba.NumberOfDSCSlices[k],
+										1),
+								slices,
+								mode_lib->vba.OutputFormat[k])
+								+ dscComputeDelay(
+										mode_lib->vba.OutputFormat[k]);
+			} else {
+				mode_lib->vba.DSCDelay[k] =
+						2
+								* (dscceComputeDelay(
+										mode_lib->vba.DSCInputBitPerComponent[k],
+										bpp,
+										dml_ceil(
+												(double) mode_lib->vba.HActive[k]
+														/ mode_lib->vba.NumberOfDSCSlices[k],
+												1),
+										slices / 2.0,
+										mode_lib->vba.OutputFormat[k])
+										+ dscComputeDelay(
+												mode_lib->vba.OutputFormat[k]));
+			}
+			mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k]
+					* mode_lib->vba.PixelClock[k]
+					/ mode_lib->vba.PixelClockBackEnd[k];
+		} else {
+			mode_lib->vba.DSCDelay[k] = 0;
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes
+			if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
+					&& mode_lib->vba.DSCEnabled[j])
+				mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
+
+	// Prefetch
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		unsigned int PDEAndMetaPTEBytesFrameY;
+		unsigned int PixelPTEBytesPerRowY;
+		unsigned int MetaRowByteY;
+		unsigned int MetaRowByteC;
+		unsigned int PDEAndMetaPTEBytesFrameC;
+		unsigned int PixelPTEBytesPerRowC;
+
+		Calculate256BBlockSizes(
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.SurfaceTiling[k],
+				dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+				dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
+				&mode_lib->vba.BlockHeight256BytesY[k],
+				&mode_lib->vba.BlockHeight256BytesC[k],
+				&mode_lib->vba.BlockWidth256BytesY[k],
+				&mode_lib->vba.BlockWidth256BytesC[k]);
+		PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
+				mode_lib,
+				mode_lib->vba.DCCEnable[k],
+				mode_lib->vba.BlockHeight256BytesY[k],
+				mode_lib->vba.BlockWidth256BytesY[k],
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.SurfaceTiling[k],
+				dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+				mode_lib->vba.SourceScan[k],
+				mode_lib->vba.ViewportWidth[k],
+				mode_lib->vba.ViewportHeight[k],
+				mode_lib->vba.SwathWidthY[k],
+				mode_lib->vba.GPUVMEnable,
+				mode_lib->vba.VMMPageSize,
+				mode_lib->vba.PTEBufferSizeInRequestsLuma,
+				mode_lib->vba.PDEProcessingBufIn64KBReqs,
+				mode_lib->vba.PitchY[k],
+				mode_lib->vba.DCCMetaPitchY[k],
+				&mode_lib->vba.MacroTileWidthY[k],
+				&MetaRowByteY,
+				&PixelPTEBytesPerRowY,
+				&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel][0],
+				&mode_lib->vba.dpte_row_height[k],
+				&mode_lib->vba.meta_row_height[k]);
+		mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
+				mode_lib,
+				mode_lib->vba.VRatio[k],
+				mode_lib->vba.vtaps[k],
+				mode_lib->vba.Interlace[k],
+				mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+				mode_lib->vba.SwathHeightY[k],
+				mode_lib->vba.ViewportYStartY[k],
+				&mode_lib->vba.VInitPreFillY[k],
+				&mode_lib->vba.MaxNumSwathY[k]);
+
+		if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
+			PDEAndMetaPTEBytesFrameC =
+					CalculateVMAndRowBytes(
+							mode_lib,
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.BlockHeight256BytesC[k],
+							mode_lib->vba.BlockWidth256BytesC[k],
+							mode_lib->vba.SourcePixelFormat[k],
+							mode_lib->vba.SurfaceTiling[k],
+							dml_ceil(
+									mode_lib->vba.BytePerPixelDETC[k],
+									2),
+							mode_lib->vba.SourceScan[k],
+							mode_lib->vba.ViewportWidth[k] / 2,
+							mode_lib->vba.ViewportHeight[k] / 2,
+							mode_lib->vba.SwathWidthY[k] / 2,
+							mode_lib->vba.GPUVMEnable,
+							mode_lib->vba.VMMPageSize,
+							mode_lib->vba.PTEBufferSizeInRequestsLuma,
+							mode_lib->vba.PDEProcessingBufIn64KBReqs,
+							mode_lib->vba.PitchC[k],
+							0,
+							&mode_lib->vba.MacroTileWidthC[k],
+							&MetaRowByteC,
+							&PixelPTEBytesPerRowC,
+							&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel][0],
+							&mode_lib->vba.dpte_row_height_chroma[k],
+							&mode_lib->vba.meta_row_height_chroma[k]);
+			mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
+					mode_lib,
+					mode_lib->vba.VRatio[k] / 2,
+					mode_lib->vba.VTAPsChroma[k],
+					mode_lib->vba.Interlace[k],
+					mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+					mode_lib->vba.SwathHeightC[k],
+					mode_lib->vba.ViewportYStartC[k],
+					&mode_lib->vba.VInitPreFillC[k],
+					&mode_lib->vba.MaxNumSwathC[k]);
+		} else {
+			PixelPTEBytesPerRowC = 0;
+			PDEAndMetaPTEBytesFrameC = 0;
+			MetaRowByteC = 0;
+			mode_lib->vba.MaxNumSwathC[k] = 0;
+			mode_lib->vba.PrefetchSourceLinesC[k] = 0;
+		}
+
+		mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
+		mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
+				+ PDEAndMetaPTEBytesFrameC;
+		mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
+
+		CalculateActiveRowBandwidth(
+				mode_lib->vba.GPUVMEnable,
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.VRatio[k],
+				mode_lib->vba.DCCEnable[k],
+				mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+				MetaRowByteY,
+				MetaRowByteC,
+				mode_lib->vba.meta_row_height[k],
+				mode_lib->vba.meta_row_height_chroma[k],
+				PixelPTEBytesPerRowY,
+				PixelPTEBytesPerRowC,
+				mode_lib->vba.dpte_row_height[k],
+				mode_lib->vba.dpte_row_height_chroma[k],
+				&mode_lib->vba.meta_row_bw[k],
+				&mode_lib->vba.dpte_row_bw[k],
+				&mode_lib->vba.qual_row_bw[k]);
+	}
+
+	mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFCLKDeepSleep;
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.BlendingAndTiming[k] == k) {
+			if (mode_lib->vba.WritebackEnable[k] == true) {
+				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+						mode_lib->vba.WritebackLatency
+								+ CalculateWriteBackDelay(
+										mode_lib->vba.WritebackPixelFormat[k],
+										mode_lib->vba.WritebackHRatio[k],
+										mode_lib->vba.WritebackVRatio[k],
+										mode_lib->vba.WritebackLumaHTaps[k],
+										mode_lib->vba.WritebackLumaVTaps[k],
+										mode_lib->vba.WritebackChromaHTaps[k],
+										mode_lib->vba.WritebackChromaVTaps[k],
+										mode_lib->vba.WritebackDestinationWidth[k])
+										/ mode_lib->vba.DISPCLK;
+			} else
+				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
+			for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+				if (mode_lib->vba.BlendingAndTiming[j] == k
+						&& mode_lib->vba.WritebackEnable[j] == true) {
+					mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+							dml_max(
+									mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
+									mode_lib->vba.WritebackLatency
+											+ CalculateWriteBackDelay(
+													mode_lib->vba.WritebackPixelFormat[j],
+													mode_lib->vba.WritebackHRatio[j],
+													mode_lib->vba.WritebackVRatio[j],
+													mode_lib->vba.WritebackLumaHTaps[j],
+													mode_lib->vba.WritebackLumaVTaps[j],
+													mode_lib->vba.WritebackChromaHTaps[j],
+													mode_lib->vba.WritebackChromaVTaps[j],
+													mode_lib->vba.WritebackDestinationWidth[j])
+													/ mode_lib->vba.DISPCLK);
+				}
+			}
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+			if (mode_lib->vba.BlendingAndTiming[k] == j)
+				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+						mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
+
+	mode_lib->vba.VStartupLines = 13;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.MaxVStartupLines[k] =
+				mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
+						- dml_max(
+								1.0,
+								dml_ceil(
+										mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
+												/ (mode_lib->vba.HTotal[k]
+														/ mode_lib->vba.PixelClock[k]),
+										1));
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		mode_lib->vba.MaximumMaxVStartupLines = dml_max(
+				mode_lib->vba.MaximumMaxVStartupLines,
+				mode_lib->vba.MaxVStartupLines[k]);
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.cursor_bw[k] = 0.0;
+		for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
+			mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
+					* mode_lib->vba.CursorBPP[k][j] / 8.0
+					/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+					* mode_lib->vba.VRatio[k];
+	}
+
+	do {
+		double MaxTotalRDBandwidth = 0;
+		bool DestinationLineTimesForPrefetchLessThan2 = false;
+		bool VRatioPrefetchMoreThan4 = false;
+		bool prefetch_vm_bw_valid = true;
+		bool prefetch_row_bw_valid = true;
+		double TWait = CalculateTWait(
+				mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
+				mode_lib->vba.DRAMClockChangeLatency,
+				mode_lib->vba.UrgentLatencyPixelDataOnly,
+				mode_lib->vba.SREnterPlusExitTime);
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+			if (mode_lib->vba.XFCEnabled[k] == true) {
+				mode_lib->vba.XFCRemoteSurfaceFlipDelay =
+						CalculateRemoteSurfaceFlipDelay(
+								mode_lib,
+								mode_lib->vba.VRatio[k],
+								mode_lib->vba.SwathWidthY[k],
+								dml_ceil(
+										mode_lib->vba.BytePerPixelDETY[k],
+										1),
+								mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k],
+								mode_lib->vba.XFCTSlvVupdateOffset,
+								mode_lib->vba.XFCTSlvVupdateWidth,
+								mode_lib->vba.XFCTSlvVreadyOffset,
+								mode_lib->vba.XFCXBUFLatencyTolerance,
+								mode_lib->vba.XFCFillBWOverhead,
+								mode_lib->vba.XFCSlvChunkSize,
+								mode_lib->vba.XFCBusTransportTime,
+								mode_lib->vba.TCalc,
+								TWait,
+								&mode_lib->vba.SrcActiveDrainRate,
+								&mode_lib->vba.TInitXFill,
+								&mode_lib->vba.TslvChk);
+			} else {
+				mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
+			}
+
+			CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBW, mode_lib->vba.ReadBandwidthPlaneLuma[k], mode_lib->vba.ReadBandwidthPlaneChroma[k], mode_lib->vba.TotalDataReadBandwidth,
+					mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k],
+					mode_lib->vba.DPPCLK[k], mode_lib->vba.DISPCLK, mode_lib->vba.PixelClock[k], mode_lib->vba.DSCDelay[k], mode_lib->vba.DPPPerPlane[k], mode_lib->vba.ScalerEnabled[k], mode_lib->vba.NumberOfCursors[k],
+					mode_lib->vba.DPPCLKDelaySubtotal, mode_lib->vba.DPPCLKDelaySCL, mode_lib->vba.DPPCLKDelaySCLLBOnly, mode_lib->vba.DPPCLKDelayCNVCFormater, mode_lib->vba.DPPCLKDelayCNVCCursor, mode_lib->vba.DISPCLKDelaySubtotal,
+					mode_lib->vba.SwathWidthY[k] / mode_lib->vba.HRatio[k], mode_lib->vba.OutputFormat[k], mode_lib->vba.HTotal[k],
+					mode_lib->vba.SwathWidthSingleDPPY[k], mode_lib->vba.BytePerPixelDETY[k], mode_lib->vba.BytePerPixelDETC[k], mode_lib->vba.SwathHeightY[k], mode_lib->vba.SwathHeightC[k], mode_lib->vba.Interlace[k],
+					mode_lib->vba.ProgressiveToInterlaceUnitInOPP, &mode_lib->vba.DSTXAfterScaler[k], &mode_lib->vba.DSTYAfterScaler[k]);
+
+			mode_lib->vba.ErrorResult[k] =
+					CalculatePrefetchSchedule(
+							mode_lib,
+							mode_lib->vba.DPPCLK[k],
+							mode_lib->vba.DISPCLK,
+							mode_lib->vba.PixelClock[k],
+							mode_lib->vba.DCFCLKDeepSleep,
+							mode_lib->vba.DPPPerPlane[k],
+							mode_lib->vba.NumberOfCursors[k],
+							mode_lib->vba.VTotal[k]
+									- mode_lib->vba.VActive[k],
+							mode_lib->vba.HTotal[k],
+							mode_lib->vba.MaxInterDCNTileRepeaters,
+							dml_min(
+									mode_lib->vba.VStartupLines,
+									mode_lib->vba.MaxVStartupLines[k]),
+							mode_lib->vba.GPUVMMaxPageTableLevels,
+							mode_lib->vba.GPUVMEnable,
+							mode_lib->vba.DynamicMetadataEnable[k],
+							mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
+							mode_lib->vba.DynamicMetadataTransmittedBytes[k],
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.UrgentLatencyPixelDataOnly,
+							mode_lib->vba.UrgentExtraLatency,
+							mode_lib->vba.TCalc,
+							mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
+							mode_lib->vba.MetaRowByte[k],
+							mode_lib->vba.PixelPTEBytesPerRow[k],
+							mode_lib->vba.PrefetchSourceLinesY[k],
+							mode_lib->vba.SwathWidthY[k],
+							mode_lib->vba.BytePerPixelDETY[k],
+							mode_lib->vba.VInitPreFillY[k],
+							mode_lib->vba.MaxNumSwathY[k],
+							mode_lib->vba.PrefetchSourceLinesC[k],
+							mode_lib->vba.BytePerPixelDETC[k],
+							mode_lib->vba.VInitPreFillC[k],
+							mode_lib->vba.MaxNumSwathC[k],
+							mode_lib->vba.SwathHeightY[k],
+							mode_lib->vba.SwathHeightC[k],
+							TWait,
+							mode_lib->vba.XFCEnabled[k],
+							mode_lib->vba.XFCRemoteSurfaceFlipDelay,
+							mode_lib->vba.Interlace[k],
+							mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+							mode_lib->vba.DSTXAfterScaler[k],
+							mode_lib->vba.DSTYAfterScaler[k],
+							&mode_lib->vba.DestinationLinesForPrefetch[k],
+							&mode_lib->vba.PrefetchBandwidth[k],
+							&mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
+							&mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
+							&mode_lib->vba.VRatioPrefetchY[k],
+							&mode_lib->vba.VRatioPrefetchC[k],
+							&mode_lib->vba.RequiredPrefetchPixDataBWLuma[k],
+							&mode_lib->vba.Tno_bw[k],
+							&mode_lib->vba.VUpdateOffsetPix[k],
+							&mode_lib->vba.VUpdateWidthPix[k],
+							&mode_lib->vba.VReadyOffsetPix[k]);
+
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				mode_lib->vba.VStartup[k] = dml_min(
+						mode_lib->vba.VStartupLines,
+						mode_lib->vba.MaxVStartupLines[k]);
+				if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
+						!= 0) {
+					mode_lib->vba.VStartup[k] =
+							mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
+				}
+			} else {
+				mode_lib->vba.VStartup[k] =
+						dml_min(
+								mode_lib->vba.VStartupLines,
+								mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
+			}
+		}
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+
+			if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
+				mode_lib->vba.prefetch_vm_bw[k] = 0;
+			else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
+				mode_lib->vba.prefetch_vm_bw[k] =
+						(double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+								/ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+										* mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k]);
+			} else {
+				mode_lib->vba.prefetch_vm_bw[k] = 0;
+				prefetch_vm_bw_valid = false;
+			}
+			if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
+					== 0)
+				mode_lib->vba.prefetch_row_bw[k] = 0;
+			else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
+				mode_lib->vba.prefetch_row_bw[k] =
+						(double) (mode_lib->vba.MetaRowByte[k]
+								+ mode_lib->vba.PixelPTEBytesPerRow[k])
+								/ (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
+										* mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k]);
+			} else {
+				mode_lib->vba.prefetch_row_bw[k] = 0;
+				prefetch_row_bw_valid = false;
+			}
+
+			MaxTotalRDBandwidth =
+					MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
+							+ dml_max(
+									mode_lib->vba.prefetch_vm_bw[k],
+									dml_max(
+											mode_lib->vba.prefetch_row_bw[k],
+											dml_max(
+													mode_lib->vba.ReadBandwidthPlaneLuma[k]
+															+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
+													mode_lib->vba.RequiredPrefetchPixDataBWLuma[k])
+													+ mode_lib->vba.meta_row_bw[k]
+													+ mode_lib->vba.dpte_row_bw[k]));
+
+			if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
+				DestinationLineTimesForPrefetchLessThan2 = true;
+			if (mode_lib->vba.VRatioPrefetchY[k] > 4
+					|| mode_lib->vba.VRatioPrefetchC[k] > 4)
+				VRatioPrefetchMoreThan4 = true;
+		}
+
+		if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
+				&& prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
+				&& !DestinationLineTimesForPrefetchLessThan2)
+			mode_lib->vba.PrefetchModeSupported = true;
+		else {
+			mode_lib->vba.PrefetchModeSupported = false;
+			dml_print(
+					"DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
+		}
+
+		if (mode_lib->vba.PrefetchModeSupported == true) {
+			double final_flip_bw[DC__NUM_DPP__MAX];
+			unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
+			double total_dcn_read_bw_with_flip = 0;
+
+			mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				mode_lib->vba.BandwidthAvailableForImmediateFlip =
+						mode_lib->vba.BandwidthAvailableForImmediateFlip
+								- mode_lib->vba.cursor_bw[k]
+								- dml_max(
+										mode_lib->vba.ReadBandwidthPlaneLuma[k]
+												+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+												+ mode_lib->vba.qual_row_bw[k],
+										mode_lib->vba.PrefetchBandwidth[k]);
+			}
+
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				ImmediateFlipBytes[k] = 0;
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+					ImmediateFlipBytes[k] =
+							mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+									+ mode_lib->vba.MetaRowByte[k]
+									+ mode_lib->vba.PixelPTEBytesPerRow[k];
+				}
+			}
+			mode_lib->vba.TotImmediateFlipBytes = 0;
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+					mode_lib->vba.TotImmediateFlipBytes =
+							mode_lib->vba.TotImmediateFlipBytes
+									+ ImmediateFlipBytes[k];
+				}
+			}
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				CalculateFlipSchedule(
+						mode_lib,
+						mode_lib->vba.UrgentExtraLatency,
+						mode_lib->vba.UrgentLatencyPixelDataOnly,
+						mode_lib->vba.GPUVMMaxPageTableLevels,
+						mode_lib->vba.GPUVMEnable,
+						mode_lib->vba.BandwidthAvailableForImmediateFlip,
+						mode_lib->vba.TotImmediateFlipBytes,
+						mode_lib->vba.SourcePixelFormat[k],
+						ImmediateFlipBytes[k],
+						mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k],
+						mode_lib->vba.VRatio[k],
+						mode_lib->vba.Tno_bw[k],
+						mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
+						mode_lib->vba.MetaRowByte[k],
+						mode_lib->vba.PixelPTEBytesPerRow[k],
+						mode_lib->vba.DCCEnable[k],
+						mode_lib->vba.dpte_row_height[k],
+						mode_lib->vba.meta_row_height[k],
+						mode_lib->vba.qual_row_bw[k],
+						&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
+						&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
+						&final_flip_bw[k],
+						&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
+			}
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				total_dcn_read_bw_with_flip =
+						total_dcn_read_bw_with_flip
+								+ mode_lib->vba.cursor_bw[k]
+								+ dml_max(
+										mode_lib->vba.prefetch_vm_bw[k],
+										dml_max(
+												mode_lib->vba.prefetch_row_bw[k],
+												final_flip_bw[k]
+														+ dml_max(
+																mode_lib->vba.ReadBandwidthPlaneLuma[k]
+																		+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
+																mode_lib->vba.RequiredPrefetchPixDataBWLuma[k])));
+			}
+			mode_lib->vba.ImmediateFlipSupported = true;
+			if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
+				mode_lib->vba.ImmediateFlipSupported = false;
+			}
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
+					mode_lib->vba.ImmediateFlipSupported = false;
+				}
+			}
+		} else {
+			mode_lib->vba.ImmediateFlipSupported = false;
+		}
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+			if (mode_lib->vba.ErrorResult[k]) {
+				mode_lib->vba.PrefetchModeSupported = false;
+				dml_print(
+						"DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
+			}
+		}
+
+		mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
+	} while (!((mode_lib->vba.PrefetchModeSupported
+			&& (!mode_lib->vba.ImmediateFlipSupport
+					|| mode_lib->vba.ImmediateFlipSupported))
+			|| mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
+
+	//Display Pipeline Delivery Time in Prefetch
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
+			mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
+					mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
+							/ mode_lib->vba.HRatio[k]
+							/ mode_lib->vba.PixelClock[k];
+		} else {
+			mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
+					mode_lib->vba.SwathWidthY[k]
+							/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+							/ mode_lib->vba.DPPCLK[k];
+		}
+		if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
+			mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
+		} else {
+			if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
+				mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
+						mode_lib->vba.SwathWidthY[k]
+								* mode_lib->vba.DPPPerPlane[k]
+								/ mode_lib->vba.HRatio[k]
+								/ mode_lib->vba.PixelClock[k];
+			} else {
+				mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
+						mode_lib->vba.SwathWidthY[k]
+								/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+								/ mode_lib->vba.DPPCLK[k];
+			}
+		}
+	}
+
+	// Min TTUVBlank
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 0) {
+			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
+			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
+			mode_lib->vba.MinTTUVBlank[k] = dml_max(
+					mode_lib->vba.DRAMClockChangeWatermark,
+					dml_max(
+							mode_lib->vba.StutterEnterPlusExitWatermark,
+							mode_lib->vba.UrgentWatermark));
+		} else if (mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] == 1) {
+			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
+			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
+			mode_lib->vba.MinTTUVBlank[k] = dml_max(
+					mode_lib->vba.StutterEnterPlusExitWatermark,
+					mode_lib->vba.UrgentWatermark);
+		} else {
+			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
+			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
+			mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
+		}
+		if (!mode_lib->vba.DynamicMetadataEnable[k])
+			mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
+					+ mode_lib->vba.MinTTUVBlank[k];
+	}
+
+	// DCC Configuration
+	mode_lib->vba.ActiveDPPs = 0;
+	// NB P-State/DRAM Clock Change Support
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		double EffectiveLBLatencyHidingY;
+		double EffectiveLBLatencyHidingC;
+		double DPPOutputBufferLinesY;
+		double DPPOutputBufferLinesC;
+		double DPPOPPBufferingY;
+		double MaxDETBufferingTimeY;
+		double ActiveDRAMClockChangeLatencyMarginY;
+
+		mode_lib->vba.LBLatencyHidingSourceLinesY =
+				dml_min(
+						mode_lib->vba.MaxLineBufferLines,
+						(unsigned int) dml_floor(
+								(double) mode_lib->vba.LineBufferSize
+										/ mode_lib->vba.LBBitPerPixel[k]
+										/ (mode_lib->vba.SwathWidthY[k]
+												/ dml_max(
+														mode_lib->vba.HRatio[k],
+														1.0)),
+								1)) - (mode_lib->vba.vtaps[k] - 1);
+
+		mode_lib->vba.LBLatencyHidingSourceLinesC =
+				dml_min(
+						mode_lib->vba.MaxLineBufferLines,
+						(unsigned int) dml_floor(
+								(double) mode_lib->vba.LineBufferSize
+										/ mode_lib->vba.LBBitPerPixel[k]
+										/ (mode_lib->vba.SwathWidthY[k]
+												/ 2.0
+												/ dml_max(
+														mode_lib->vba.HRatio[k]
+																/ 2,
+														1.0)),
+								1))
+						- (mode_lib->vba.VTAPsChroma[k] - 1);
+
+		EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
+				/ mode_lib->vba.VRatio[k]
+				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+
+		EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
+				/ (mode_lib->vba.VRatio[k] / 2)
+				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+
+		if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
+					/ mode_lib->vba.SwathWidthY[k];
+		} else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesY = 0.5;
+		} else {
+			DPPOutputBufferLinesY = 1;
+		}
+
+		if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
+					/ (mode_lib->vba.SwathWidthY[k] / 2);
+		} else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesC = 0.5;
+		} else {
+			DPPOutputBufferLinesC = 1;
+		}
+
+		DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				* (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
+		MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
+				+ (mode_lib->vba.LinesInDETY[k]
+						- mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
+						/ mode_lib->vba.SwathHeightY[k]
+						* (mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k]);
+
+		ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
+				+ MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
+
+		if (mode_lib->vba.ActiveDPPs > 1) {
+			ActiveDRAMClockChangeLatencyMarginY =
+					ActiveDRAMClockChangeLatencyMarginY
+							- (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
+									* mode_lib->vba.SwathHeightY[k]
+									* (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]);
+		}
+
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
+					/ mode_lib->vba.PixelClock[k])
+					* (DPPOutputBufferLinesC
+							+ mode_lib->vba.OPPOutputBufferLines);
+			double MaxDETBufferingTimeC =
+					mode_lib->vba.FullDETBufferingTimeC[k]
+							+ (mode_lib->vba.LinesInDETC[k]
+									- mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
+									/ mode_lib->vba.SwathHeightC[k]
+									* (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]);
+			double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
+					+ EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
+					- mode_lib->vba.DRAMClockChangeWatermark;
+
+			if (mode_lib->vba.ActiveDPPs > 1) {
+				ActiveDRAMClockChangeLatencyMarginC =
+						ActiveDRAMClockChangeLatencyMarginC
+								- (1
+										- 1
+												/ (mode_lib->vba.ActiveDPPs
+														- 1))
+										* mode_lib->vba.SwathHeightC[k]
+										* (mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k]);
+			}
+			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
+					ActiveDRAMClockChangeLatencyMarginY,
+					ActiveDRAMClockChangeLatencyMarginC);
+		} else {
+			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
+					ActiveDRAMClockChangeLatencyMarginY;
+		}
+
+		if (mode_lib->vba.WritebackEnable[k]) {
+			double WritebackDRAMClockChangeLatencyMargin;
+
+			if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+				WritebackDRAMClockChangeLatencyMargin =
+						(double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
+								+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ (mode_lib->vba.WritebackDestinationWidth[k]
+										* mode_lib->vba.WritebackDestinationHeight[k]
+										/ (mode_lib->vba.WritebackSourceHeight[k]
+												* mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k])
+										* 4)
+								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
+			} else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+				WritebackDRAMClockChangeLatencyMargin =
+						dml_min(
+								(double) mode_lib->vba.WritebackInterfaceLumaBufferSize
+										* 8.0 / 10,
+								2.0
+										* mode_lib->vba.WritebackInterfaceChromaBufferSize
+										* 8 / 10)
+								/ (mode_lib->vba.WritebackDestinationWidth[k]
+										* mode_lib->vba.WritebackDestinationHeight[k]
+										/ (mode_lib->vba.WritebackSourceHeight[k]
+												* mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k]))
+								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
+			} else {
+				WritebackDRAMClockChangeLatencyMargin =
+						dml_min(
+								(double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
+								2.0
+										* mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ (mode_lib->vba.WritebackDestinationWidth[k]
+										* mode_lib->vba.WritebackDestinationHeight[k]
+										/ (mode_lib->vba.WritebackSourceHeight[k]
+												* mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k]))
+								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
+			}
+			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
+					mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
+					WritebackDRAMClockChangeLatencyMargin);
+		}
+	}
+
+	mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
+				< mode_lib->vba.MinActiveDRAMClockChangeMargin) {
+			mode_lib->vba.MinActiveDRAMClockChangeMargin =
+					mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
+		}
+	}
+
+	mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
+			mode_lib->vba.MinActiveDRAMClockChangeMargin
+					+ mode_lib->vba.DRAMClockChangeLatency;
+
+	if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
+		mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive;
+	} else {
+		if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
+			mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vblank;
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
+					mode_lib->vba.DRAMClockChangeSupport[0][0] =
+							dm_dram_clock_change_unsupported;
+				}
+			}
+		} else {
+			mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_unsupported;
+		}
+	}
+	for (k = 0; k <= mode_lib->vba.soc.num_states; k++)
+		for (j = 0; j < 2; j++)
+			mode_lib->vba.DRAMClockChangeSupport[k][j] = mode_lib->vba.DRAMClockChangeSupport[0][0];
+
+	//XFC Parameters:
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.XFCEnabled[k] == true) {
+			double TWait;
+
+			mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
+			mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
+			mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
+			TWait = CalculateTWait(
+					mode_lib->vba.PrefetchMode[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb],
+					mode_lib->vba.DRAMClockChangeLatency,
+					mode_lib->vba.UrgentLatencyPixelDataOnly,
+					mode_lib->vba.SREnterPlusExitTime);
+			mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
+					mode_lib,
+					mode_lib->vba.VRatio[k],
+					mode_lib->vba.SwathWidthY[k],
+					dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+					mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+					mode_lib->vba.XFCTSlvVupdateOffset,
+					mode_lib->vba.XFCTSlvVupdateWidth,
+					mode_lib->vba.XFCTSlvVreadyOffset,
+					mode_lib->vba.XFCXBUFLatencyTolerance,
+					mode_lib->vba.XFCFillBWOverhead,
+					mode_lib->vba.XFCSlvChunkSize,
+					mode_lib->vba.XFCBusTransportTime,
+					mode_lib->vba.TCalc,
+					TWait,
+					&mode_lib->vba.SrcActiveDrainRate,
+					&mode_lib->vba.TInitXFill,
+					&mode_lib->vba.TslvChk);
+			mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
+					dml_floor(
+							mode_lib->vba.XFCRemoteSurfaceFlipDelay
+									/ (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]),
+							1);
+			mode_lib->vba.XFCTransferDelay[k] =
+					dml_ceil(
+							mode_lib->vba.XFCBusTransportTime
+									/ (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]),
+							1);
+			mode_lib->vba.XFCPrechargeDelay[k] =
+					dml_ceil(
+							(mode_lib->vba.XFCBusTransportTime
+									+ mode_lib->vba.TInitXFill
+									+ mode_lib->vba.TslvChk)
+									/ (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]),
+							1);
+			mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
+					* mode_lib->vba.SrcActiveDrainRate;
+			mode_lib->vba.FinalFillMargin =
+					(mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+							+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]
+							* mode_lib->vba.SrcActiveDrainRate
+							+ mode_lib->vba.XFCFillConstant;
+			mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
+					* mode_lib->vba.SrcActiveDrainRate
+					+ mode_lib->vba.FinalFillMargin;
+			mode_lib->vba.RemainingFillLevel = dml_max(
+					0.0,
+					mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
+			mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
+					/ (mode_lib->vba.SrcActiveDrainRate
+							* mode_lib->vba.XFCFillBWOverhead / 100);
+			mode_lib->vba.XFCPrefetchMargin[k] =
+					mode_lib->vba.XFCRemoteSurfaceFlipDelay
+							+ mode_lib->vba.TFinalxFill
+							+ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+									+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
+									* mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k];
+		} else {
+			mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
+			mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
+			mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
+			mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
+			mode_lib->vba.XFCPrechargeDelay[k] = 0;
+			mode_lib->vba.XFCTransferDelay[k] = 0;
+			mode_lib->vba.XFCPrefetchMargin[k] = 0;
+		}
+	}
+	{
+		unsigned int VStartupMargin = 0;
+		bool FirstMainPlane = true;
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				unsigned int Margin = (mode_lib->vba.MaxVStartupLines[k] - mode_lib->vba.VStartup[k])
+						* mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k];
+
+				if (FirstMainPlane) {
+					VStartupMargin = Margin;
+					FirstMainPlane = false;
+				} else
+					VStartupMargin = dml_min(VStartupMargin, Margin);
+		}
+
+		if (mode_lib->vba.UseMaximumVStartup) {
+			if (mode_lib->vba.VTotal_Max[k] == mode_lib->vba.VTotal[k]) {
+				//only use max vstart if it is not drr or lateflip.
+				mode_lib->vba.VStartup[k] = mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]];
+			}
+		}
+	}
+}
+}
+
+static void dml20v2_DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
+{
+	double BytePerPixDETY;
+	double BytePerPixDETC;
+	double Read256BytesBlockHeightY;
+	double Read256BytesBlockHeightC;
+	double Read256BytesBlockWidthY;
+	double Read256BytesBlockWidthC;
+	double MaximumSwathHeightY;
+	double MaximumSwathHeightC;
+	double MinimumSwathHeightY;
+	double MinimumSwathHeightC;
+	double SwathWidth;
+	double SwathWidthGranularityY;
+	double SwathWidthGranularityC;
+	double RoundedUpMaxSwathSizeBytesY;
+	double RoundedUpMaxSwathSizeBytesC;
+	unsigned int j, k;
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		bool MainPlaneDoesODMCombine = false;
+
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+			BytePerPixDETY = 8;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+			BytePerPixDETY = 4;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+			BytePerPixDETY = 2;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
+			BytePerPixDETY = 1;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+			BytePerPixDETY = 1;
+			BytePerPixDETC = 2;
+		} else {
+			BytePerPixDETY = 4.0 / 3.0;
+			BytePerPixDETC = 8.0 / 3.0;
+		}
+
+		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				Read256BytesBlockHeightY = 1;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+				Read256BytesBlockHeightY = 4;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+					|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+				Read256BytesBlockHeightY = 8;
+			} else {
+				Read256BytesBlockHeightY = 16;
+			}
+			Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
+					/ Read256BytesBlockHeightY;
+			Read256BytesBlockHeightC = 0;
+			Read256BytesBlockWidthC = 0;
+		} else {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				Read256BytesBlockHeightY = 1;
+				Read256BytesBlockHeightC = 1;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+				Read256BytesBlockHeightY = 16;
+				Read256BytesBlockHeightC = 8;
+			} else {
+				Read256BytesBlockHeightY = 8;
+				Read256BytesBlockHeightC = 8;
+			}
+			Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
+					/ Read256BytesBlockHeightY;
+			Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
+					/ Read256BytesBlockHeightC;
+		}
+
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			MaximumSwathHeightY = Read256BytesBlockHeightY;
+			MaximumSwathHeightC = Read256BytesBlockHeightC;
+		} else {
+			MaximumSwathHeightY = Read256BytesBlockWidthY;
+			MaximumSwathHeightC = Read256BytesBlockWidthC;
+		}
+
+		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+					|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+							&& (mode_lib->vba.SurfaceTiling[k]
+									== dm_sw_4kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_4kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_t
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s_x)
+							&& mode_lib->vba.SourceScan[k] == dm_horz)) {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
+					&& mode_lib->vba.SourceScan[k] != dm_horz) {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+			} else {
+				MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
+			}
+			MinimumSwathHeightC = MaximumSwathHeightC;
+		} else {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+				MinimumSwathHeightC = MaximumSwathHeightC;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
+				MinimumSwathHeightC = MaximumSwathHeightC;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
+				MinimumSwathHeightY = MaximumSwathHeightY;
+			} else {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+				MinimumSwathHeightC = MaximumSwathHeightC;
+			}
+		}
+
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			SwathWidth = mode_lib->vba.ViewportWidth[k];
+		} else {
+			SwathWidth = mode_lib->vba.ViewportHeight[k];
+		}
+
+		if (mode_lib->vba.ODMCombineEnabled[k] == true) {
+			MainPlaneDoesODMCombine = true;
+		}
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+			if (mode_lib->vba.BlendingAndTiming[k] == j
+					&& mode_lib->vba.ODMCombineEnabled[j] == true) {
+				MainPlaneDoesODMCombine = true;
+			}
+		}
+
+		if (MainPlaneDoesODMCombine == true) {
+			SwathWidth = dml_min(
+					SwathWidth,
+					mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
+		} else {
+			if (mode_lib->vba.DPPPerPlane[k] == 0)
+				SwathWidth = 0;
+			else
+				SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
+		}
+
+		SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
+		RoundedUpMaxSwathSizeBytesY = (dml_ceil(
+				(double) (SwathWidth - 1),
+				SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
+				* MaximumSwathHeightY;
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+			RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
+					+ 256;
+		}
+		if (MaximumSwathHeightC > 0) {
+			SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
+					/ MaximumSwathHeightC;
+			RoundedUpMaxSwathSizeBytesC = (dml_ceil(
+					(double) (SwathWidth / 2.0 - 1),
+					SwathWidthGranularityC) + SwathWidthGranularityC)
+					* BytePerPixDETC * MaximumSwathHeightC;
+			if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+				RoundedUpMaxSwathSizeBytesC = dml_ceil(
+						RoundedUpMaxSwathSizeBytesC,
+						256) + 256;
+			}
+		} else
+			RoundedUpMaxSwathSizeBytesC = 0.0;
+
+		if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
+				<= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
+			mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
+			mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
+		} else {
+			mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
+			mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
+		}
+
+		if (mode_lib->vba.SwathHeightC[k] == 0) {
+			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
+			mode_lib->vba.DETBufferSizeC[k] = 0;
+		} else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
+			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 / 2;
+			mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 / 2;
+		} else {
+			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 * 2 / 3;
+			mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 / 3;
+		}
+	}
+}
+
+static double CalculateTWait(
+		unsigned int PrefetchMode,
+		double DRAMClockChangeLatency,
+		double UrgentLatencyPixelDataOnly,
+		double SREnterPlusExitTime)
+{
+	if (PrefetchMode == 0) {
+		return dml_max(
+				DRAMClockChangeLatency + UrgentLatencyPixelDataOnly,
+				dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly));
+	} else if (PrefetchMode == 1) {
+		return dml_max(SREnterPlusExitTime, UrgentLatencyPixelDataOnly);
+	} else {
+		return UrgentLatencyPixelDataOnly;
+	}
+}
+
+static double CalculateRemoteSurfaceFlipDelay(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double SwathWidth,
+		double Bpp,
+		double LineTime,
+		double XFCTSlvVupdateOffset,
+		double XFCTSlvVupdateWidth,
+		double XFCTSlvVreadyOffset,
+		double XFCXBUFLatencyTolerance,
+		double XFCFillBWOverhead,
+		double XFCSlvChunkSize,
+		double XFCBusTransportTime,
+		double TCalc,
+		double TWait,
+		double *SrcActiveDrainRate,
+		double *TInitXFill,
+		double *TslvChk)
+{
+	double TSlvSetup, AvgfillRate, result;
+
+	*SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
+	TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
+	*TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
+	AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
+	*TslvChk = XFCSlvChunkSize / AvgfillRate;
+	dml_print(
+			"DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
+			*SrcActiveDrainRate);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
+	result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
+	return result;
+}
+
+static double CalculateWriteBackDelay(
+		enum source_format_class WritebackPixelFormat,
+		double WritebackHRatio,
+		double WritebackVRatio,
+		unsigned int WritebackLumaHTaps,
+		unsigned int WritebackLumaVTaps,
+		unsigned int WritebackChromaHTaps,
+		unsigned int WritebackChromaVTaps,
+		unsigned int WritebackDestinationWidth)
+{
+	double CalculateWriteBackDelay =
+			dml_max(
+					dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
+					WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
+							* dml_ceil(
+									WritebackDestinationWidth
+											/ 4.0,
+									1)
+							+ dml_ceil(1.0 / WritebackVRatio, 1)
+									* (dml_ceil(
+											WritebackLumaVTaps
+													/ 4.0,
+											1) + 4));
+
+	if (WritebackPixelFormat != dm_444_32) {
+		CalculateWriteBackDelay =
+				dml_max(
+						CalculateWriteBackDelay,
+						dml_max(
+								dml_ceil(
+										WritebackChromaHTaps
+												/ 2.0,
+										1)
+										/ (2
+												* WritebackHRatio),
+								WritebackChromaVTaps
+										* dml_ceil(
+												1
+														/ (2
+																* WritebackVRatio),
+												1)
+										* dml_ceil(
+												WritebackDestinationWidth
+														/ 2.0
+														/ 2.0,
+												1)
+										+ dml_ceil(
+												1
+														/ (2
+																* WritebackVRatio),
+												1)
+												* (dml_ceil(
+														WritebackChromaVTaps
+																/ 4.0,
+														1)
+														+ 4)));
+	}
+	return CalculateWriteBackDelay;
+}
+
+static void CalculateActiveRowBandwidth(
+		bool GPUVMEnable,
+		enum source_format_class SourcePixelFormat,
+		double VRatio,
+		bool DCCEnable,
+		double LineTime,
+		unsigned int MetaRowByteLuma,
+		unsigned int MetaRowByteChroma,
+		unsigned int meta_row_height_luma,
+		unsigned int meta_row_height_chroma,
+		unsigned int PixelPTEBytesPerRowLuma,
+		unsigned int PixelPTEBytesPerRowChroma,
+		unsigned int dpte_row_height_luma,
+		unsigned int dpte_row_height_chroma,
+		double *meta_row_bw,
+		double *dpte_row_bw,
+		double *qual_row_bw)
+{
+	if (DCCEnable != true) {
+		*meta_row_bw = 0;
+	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
+				+ VRatio / 2 * MetaRowByteChroma
+						/ (meta_row_height_chroma * LineTime);
+	} else {
+		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
+	}
+
+	if (GPUVMEnable != true) {
+		*dpte_row_bw = 0;
+	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
+				+ VRatio / 2 * PixelPTEBytesPerRowChroma
+						/ (dpte_row_height_chroma * LineTime);
+	} else {
+		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
+	}
+
+	if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
+		*qual_row_bw = *meta_row_bw + *dpte_row_bw;
+	} else {
+		*qual_row_bw = 0;
+	}
+}
+
+static void CalculateFlipSchedule(
+		struct display_mode_lib *mode_lib,
+		double UrgentExtraLatency,
+		double UrgentLatencyPixelDataOnly,
+		unsigned int GPUVMMaxPageTableLevels,
+		bool GPUVMEnable,
+		double BandwidthAvailableForImmediateFlip,
+		unsigned int TotImmediateFlipBytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int ImmediateFlipBytes,
+		double LineTime,
+		double VRatio,
+		double Tno_bw,
+		double PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		bool DCCEnable,
+		unsigned int dpte_row_height,
+		unsigned int meta_row_height,
+		double qual_row_bw,
+		double *DestinationLinesToRequestVMInImmediateFlip,
+		double *DestinationLinesToRequestRowInImmediateFlip,
+		double *final_flip_bw,
+		bool *ImmediateFlipSupportedForPipe)
+{
+	double min_row_time = 0.0;
+
+	if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+		*DestinationLinesToRequestVMInImmediateFlip = 0.0;
+		*DestinationLinesToRequestRowInImmediateFlip = 0.0;
+		*final_flip_bw = qual_row_bw;
+		*ImmediateFlipSupportedForPipe = true;
+	} else {
+		double TimeForFetchingMetaPTEImmediateFlip;
+		double TimeForFetchingRowInVBlankImmediateFlip;
+
+		if (GPUVMEnable == true) {
+			mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
+					* ImmediateFlipBytes / TotImmediateFlipBytes;
+			TimeForFetchingMetaPTEImmediateFlip =
+					dml_max(
+							Tno_bw
+									+ PDEAndMetaPTEBytesFrame
+											/ mode_lib->vba.ImmediateFlipBW[0],
+							dml_max(
+									UrgentExtraLatency
+											+ UrgentLatencyPixelDataOnly
+													* (GPUVMMaxPageTableLevels
+															- 1),
+									LineTime / 4.0));
+		} else {
+			TimeForFetchingMetaPTEImmediateFlip = 0;
+		}
+
+		*DestinationLinesToRequestVMInImmediateFlip = dml_floor(
+				4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
+				1) / 4.0;
+
+		if ((GPUVMEnable == true || DCCEnable == true)) {
+			mode_lib->vba.ImmediateFlipBW[0] = BandwidthAvailableForImmediateFlip
+					* ImmediateFlipBytes / TotImmediateFlipBytes;
+			TimeForFetchingRowInVBlankImmediateFlip = dml_max(
+					(MetaRowByte + PixelPTEBytesPerRow)
+							/ mode_lib->vba.ImmediateFlipBW[0],
+					dml_max(UrgentLatencyPixelDataOnly, LineTime / 4.0));
+		} else {
+			TimeForFetchingRowInVBlankImmediateFlip = 0;
+		}
+
+		*DestinationLinesToRequestRowInImmediateFlip = dml_floor(
+				4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
+				1) / 4.0;
+
+		if (GPUVMEnable == true) {
+			*final_flip_bw =
+					dml_max(
+							PDEAndMetaPTEBytesFrame
+									/ (*DestinationLinesToRequestVMInImmediateFlip
+											* LineTime),
+							(MetaRowByte + PixelPTEBytesPerRow)
+									/ (TimeForFetchingRowInVBlankImmediateFlip
+											* LineTime));
+		} else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
+			*final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
+					/ (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
+		} else {
+			*final_flip_bw = 0;
+		}
+
+		if (GPUVMEnable && !DCCEnable)
+			min_row_time = dpte_row_height * LineTime / VRatio;
+		else if (!GPUVMEnable && DCCEnable)
+			min_row_time = meta_row_height * LineTime / VRatio;
+		else
+			min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
+					/ VRatio;
+
+		if (*DestinationLinesToRequestVMInImmediateFlip >= 8
+				|| *DestinationLinesToRequestRowInImmediateFlip >= 16
+				|| TimeForFetchingMetaPTEImmediateFlip
+						+ 2 * TimeForFetchingRowInVBlankImmediateFlip
+						> min_row_time)
+			*ImmediateFlipSupportedForPipe = false;
+		else
+			*ImmediateFlipSupportedForPipe = true;
+	}
+}
+
+static unsigned int TruncToValidBPP(
+		double DecimalBPP,
+		bool DSCEnabled,
+		enum output_encoder_class Output,
+		enum output_format_class Format,
+		unsigned int DSCInputBitPerComponent)
+{
+	if (Output == dm_hdmi) {
+		if (Format == dm_420) {
+			if (DecimalBPP >= 18)
+				return 18;
+			else if (DecimalBPP >= 15)
+				return 15;
+			else if (DecimalBPP >= 12)
+				return 12;
+			else
+				return BPP_INVALID;
+		} else if (Format == dm_444) {
+			if (DecimalBPP >= 36)
+				return 36;
+			else if (DecimalBPP >= 30)
+				return 30;
+			else if (DecimalBPP >= 24)
+				return 24;
+			else if (DecimalBPP >= 18)
+				return 18;
+			else
+				return BPP_INVALID;
+		} else {
+			if (DecimalBPP / 1.5 >= 24)
+				return 24;
+			else if (DecimalBPP / 1.5 >= 20)
+				return 20;
+			else if (DecimalBPP / 1.5 >= 16)
+				return 16;
+			else
+				return BPP_INVALID;
+		}
+	} else {
+		if (DSCEnabled) {
+			if (Format == dm_420) {
+				if (DecimalBPP < 6)
+					return BPP_INVALID;
+				else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
+					return 1.5 * DSCInputBitPerComponent - 1 / 16;
+				else
+					return dml_floor(16 * DecimalBPP, 1) / 16;
+			} else if (Format == dm_n422) {
+				if (DecimalBPP < 7)
+					return BPP_INVALID;
+				else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
+					return 2 * DSCInputBitPerComponent - 1 / 16;
+				else
+					return dml_floor(16 * DecimalBPP, 1) / 16;
+			} else {
+				if (DecimalBPP < 8)
+					return BPP_INVALID;
+				else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
+					return 3 * DSCInputBitPerComponent - 1 / 16;
+				else
+					return dml_floor(16 * DecimalBPP, 1) / 16;
+			}
+		} else if (Format == dm_420) {
+			if (DecimalBPP >= 18)
+				return 18;
+			else if (DecimalBPP >= 15)
+				return 15;
+			else if (DecimalBPP >= 12)
+				return 12;
+			else
+				return BPP_INVALID;
+		} else if (Format == dm_s422 || Format == dm_n422) {
+			if (DecimalBPP >= 24)
+				return 24;
+			else if (DecimalBPP >= 20)
+				return 20;
+			else if (DecimalBPP >= 16)
+				return 16;
+			else
+				return BPP_INVALID;
+		} else {
+			if (DecimalBPP >= 36)
+				return 36;
+			else if (DecimalBPP >= 30)
+				return 30;
+			else if (DecimalBPP >= 24)
+				return 24;
+			else if (DecimalBPP >= 18)
+				return 18;
+			else
+				return BPP_INVALID;
+		}
+	}
+}
+
+void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
+{
+	struct vba_vars_st *locals = &mode_lib->vba;
+
+	int i;
+	unsigned int j, k, m;
+
+	/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
+
+	/*Scale Ratio, taps Support Check*/
+
+	mode_lib->vba.ScaleRatioAndTapsSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.ScalerEnabled[k] == false
+				&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
+						|| mode_lib->vba.HRatio[k] != 1.0
+						|| mode_lib->vba.htaps[k] != 1.0
+						|| mode_lib->vba.VRatio[k] != 1.0
+						|| mode_lib->vba.vtaps[k] != 1.0)) {
+			mode_lib->vba.ScaleRatioAndTapsSupport = false;
+		} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
+				|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
+				|| (mode_lib->vba.htaps[k] > 1.0
+						&& (mode_lib->vba.htaps[k] % 2) == 1)
+				|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
+				|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
+				|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
+				|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
+				|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
+						&& (mode_lib->vba.HRatio[k] / 2.0
+								> mode_lib->vba.HTAPsChroma[k]
+								|| mode_lib->vba.VRatio[k] / 2.0
+										> mode_lib->vba.VTAPsChroma[k]))) {
+			mode_lib->vba.ScaleRatioAndTapsSupport = false;
+		}
+	}
+	/*Source Format, Pixel Format and Scan Support Check*/
+
+	mode_lib->vba.SourceFormatPixelAndScanSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+				&& mode_lib->vba.SourceScan[k] != dm_horz)
+				|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
+				|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
+						&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
+								|| mode_lib->vba.SourcePixelFormat[k]
+										== dm_420_8
+								|| mode_lib->vba.SourcePixelFormat[k]
+										== dm_420_10))
+				|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
+						|| mode_lib->vba.SurfaceTiling[k]
+								== dm_sw_gfx7_2d_thin_lvp)
+						&& !((mode_lib->vba.SourcePixelFormat[k]
+								== dm_444_64
+								|| mode_lib->vba.SourcePixelFormat[k]
+										== dm_444_32)
+								&& mode_lib->vba.SourceScan[k]
+										== dm_horz
+								&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
+										== true
+								&& mode_lib->vba.DCCEnable[k]
+										== false))
+						|| (mode_lib->vba.DCCEnable[k] == true
+								&& (mode_lib->vba.SurfaceTiling[k]
+										== dm_sw_linear
+										|| mode_lib->vba.SourcePixelFormat[k]
+												== dm_420_8
+										|| mode_lib->vba.SourcePixelFormat[k]
+												== dm_420_10)))) {
+			mode_lib->vba.SourceFormatPixelAndScanSupport = false;
+		}
+	}
+	/*Bandwidth Support Check*/
+
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+			locals->BytePerPixelInDETY[k] = 8.0;
+			locals->BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+			locals->BytePerPixelInDETY[k] = 4.0;
+			locals->BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
+			locals->BytePerPixelInDETY[k] = 2.0;
+			locals->BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
+			locals->BytePerPixelInDETY[k] = 1.0;
+			locals->BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+			locals->BytePerPixelInDETY[k] = 1.0;
+			locals->BytePerPixelInDETC[k] = 2.0;
+		} else {
+			locals->BytePerPixelInDETY[k] = 4.0 / 3;
+			locals->BytePerPixelInDETC[k] = 8.0 / 3;
+		}
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
+		} else {
+			locals->SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
+		}
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		locals->ReadBandwidthLuma[k] = locals->SwathWidthYSingleDPP[k] * dml_ceil(locals->BytePerPixelInDETY[k], 1.0)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
+		locals->ReadBandwidthChroma[k] = locals->SwathWidthYSingleDPP[k] / 2 * dml_ceil(locals->BytePerPixelInDETC[k], 2.0)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k] / 2.0;
+		locals->ReadBandwidth[k] = locals->ReadBandwidthLuma[k] + locals->ReadBandwidthChroma[k];
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true
+				&& mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+			locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+					* mode_lib->vba.WritebackDestinationHeight[k]
+					/ (mode_lib->vba.WritebackSourceHeight[k]
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]) * 4.0;
+		} else if (mode_lib->vba.WritebackEnable[k] == true
+				&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+			locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+					* mode_lib->vba.WritebackDestinationHeight[k]
+					/ (mode_lib->vba.WritebackSourceHeight[k]
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]) * 3.0;
+		} else if (mode_lib->vba.WritebackEnable[k] == true) {
+			locals->WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+					* mode_lib->vba.WritebackDestinationHeight[k]
+					/ (mode_lib->vba.WritebackSourceHeight[k]
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]) * 1.5;
+		} else {
+			locals->WriteBandwidth[k] = 0.0;
+		}
+	}
+	mode_lib->vba.DCCEnabledInAnyPlane = false;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.DCCEnable[k] == true) {
+			mode_lib->vba.DCCEnabledInAnyPlane = true;
+		}
+	}
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		locals->FabricAndDRAMBandwidthPerState[i] = dml_min(
+				mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+						* mode_lib->vba.DRAMChannelWidth,
+				mode_lib->vba.FabricClockPerState[i]
+						* mode_lib->vba.FabricDatapathToDCNDataReturn) / 1000;
+		locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth * locals->DCFCLKPerState[i],
+				locals->FabricAndDRAMBandwidthPerState[i] * 1000)
+				* locals->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
+
+		locals->ReturnBWPerState[i] = locals->ReturnBWToDCNPerState;
+
+		if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
+			locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
+					locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
+					((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
+					/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
+					* locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
+		}
+		locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
+				locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
+				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
+
+		if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
+			locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
+				4 * locals->ReturnBWToDCNPerState *
+				(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
+				* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
+				dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
+				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
+		}
+
+		locals->ReturnBWToDCNPerState = dml_min(locals->ReturnBusWidth *
+				locals->DCFCLKPerState[i], locals->FabricAndDRAMBandwidthPerState[i] * 1000);
+
+		if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
+			locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
+					locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
+					((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
+					/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
+					* locals->ReturnBusWidth / 4) + locals->UrgentLatency)));
+		}
+		locals->CriticalPoint = 2 * locals->ReturnBusWidth * locals->DCFCLKPerState[i] *
+				locals->UrgentLatency / (locals->ReturnBWToDCNPerState * locals->UrgentLatency
+				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
+
+		if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
+			locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
+				4 * locals->ReturnBWToDCNPerState *
+				(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
+				* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
+				dml_pow((locals->ReturnBWToDCNPerState * locals->UrgentLatency
+				+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024), 2));
+		}
+	}
+	/*Writeback Latency support check*/
+
+	mode_lib->vba.WritebackLatencySupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+				if (locals->WriteBandwidth[k]
+						> (mode_lib->vba.WritebackInterfaceLumaBufferSize
+								+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ mode_lib->vba.WritebackLatency) {
+					mode_lib->vba.WritebackLatencySupport = false;
+				}
+			} else {
+				if (locals->WriteBandwidth[k]
+						> 1.5
+								* dml_min(
+										mode_lib->vba.WritebackInterfaceLumaBufferSize,
+										2.0
+												* mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ mode_lib->vba.WritebackLatency) {
+					mode_lib->vba.WritebackLatencySupport = false;
+				}
+			}
+		}
+	}
+	/*Re-ordering Buffer Support Check*/
+
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
+				(mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
+				+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i];
+		if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i]
+				> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
+			locals->ROBSupport[i] = true;
+		} else {
+			locals->ROBSupport[i] = false;
+		}
+	}
+	/*Writeback Mode Support Check*/
+
+	mode_lib->vba.TotalNumberOfActiveWriteback = 0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			if (mode_lib->vba.ActiveWritebacksPerPlane[k] == 0)
+				mode_lib->vba.ActiveWritebacksPerPlane[k] = 1;
+			mode_lib->vba.TotalNumberOfActiveWriteback =
+					mode_lib->vba.TotalNumberOfActiveWriteback
+							+ mode_lib->vba.ActiveWritebacksPerPlane[k];
+		}
+	}
+	mode_lib->vba.WritebackModeSupport = true;
+	if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
+		mode_lib->vba.WritebackModeSupport = false;
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true
+				&& mode_lib->vba.Writeback10bpc420Supported != true
+				&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+			mode_lib->vba.WritebackModeSupport = false;
+		}
+	}
+	/*Writeback Scale Ratio and Taps Support Check*/
+
+	mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
+					&& (mode_lib->vba.WritebackHRatio[k] != 1.0
+							|| mode_lib->vba.WritebackVRatio[k] != 1.0)) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+			if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
+					|| mode_lib->vba.WritebackVRatio[k]
+							> mode_lib->vba.WritebackMaxVSCLRatio
+					|| mode_lib->vba.WritebackHRatio[k]
+							< mode_lib->vba.WritebackMinHSCLRatio
+					|| mode_lib->vba.WritebackVRatio[k]
+							< mode_lib->vba.WritebackMinVSCLRatio
+					|| mode_lib->vba.WritebackLumaHTaps[k]
+							> mode_lib->vba.WritebackMaxHSCLTaps
+					|| mode_lib->vba.WritebackLumaVTaps[k]
+							> mode_lib->vba.WritebackMaxVSCLTaps
+					|| mode_lib->vba.WritebackHRatio[k]
+							> mode_lib->vba.WritebackLumaHTaps[k]
+					|| mode_lib->vba.WritebackVRatio[k]
+							> mode_lib->vba.WritebackLumaVTaps[k]
+					|| (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
+							&& ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
+									== 1))
+					|| (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
+							&& (mode_lib->vba.WritebackChromaHTaps[k]
+									> mode_lib->vba.WritebackMaxHSCLTaps
+									|| mode_lib->vba.WritebackChromaVTaps[k]
+											> mode_lib->vba.WritebackMaxVSCLTaps
+									|| 2.0
+											* mode_lib->vba.WritebackHRatio[k]
+											> mode_lib->vba.WritebackChromaHTaps[k]
+									|| 2.0
+											* mode_lib->vba.WritebackVRatio[k]
+											> mode_lib->vba.WritebackChromaVTaps[k]
+									|| (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
+										&& ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+			if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
+				mode_lib->vba.WritebackLumaVExtra =
+						dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
+			} else {
+				mode_lib->vba.WritebackLumaVExtra = -1;
+			}
+			if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
+					&& mode_lib->vba.WritebackLumaVTaps[k]
+							> (mode_lib->vba.WritebackLineBufferLumaBufferSize
+									+ mode_lib->vba.WritebackLineBufferChromaBufferSize)
+									/ 3.0
+									/ mode_lib->vba.WritebackDestinationWidth[k]
+									- mode_lib->vba.WritebackLumaVExtra)
+					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
+							&& mode_lib->vba.WritebackLumaVTaps[k]
+									> mode_lib->vba.WritebackLineBufferLumaBufferSize
+											* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
+											- mode_lib->vba.WritebackLumaVExtra)
+					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
+							&& mode_lib->vba.WritebackLumaVTaps[k]
+									> mode_lib->vba.WritebackLineBufferLumaBufferSize
+											* 8.0 / 10.0
+											/ mode_lib->vba.WritebackDestinationWidth[k]
+											- mode_lib->vba.WritebackLumaVExtra)) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+			if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
+				mode_lib->vba.WritebackChromaVExtra = 0.0;
+			} else {
+				mode_lib->vba.WritebackChromaVExtra = -1;
+			}
+			if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
+					&& mode_lib->vba.WritebackChromaVTaps[k]
+							> mode_lib->vba.WritebackLineBufferChromaBufferSize
+									* 8.0 / 10.0 / mode_lib->vba.WritebackDestinationWidth[k]
+									- mode_lib->vba.WritebackChromaVExtra)
+					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
+							&& mode_lib->vba.WritebackChromaVTaps[k]
+									> mode_lib->vba.WritebackLineBufferChromaBufferSize
+											* 8.0 / 10.0
+											/ mode_lib->vba.WritebackDestinationWidth[k]
+											- mode_lib->vba.WritebackChromaVExtra)) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+		}
+	}
+	/*Maximum DISPCLK/DPPCLK Support check*/
+
+	mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			mode_lib->vba.WritebackRequiredDISPCLK =
+					dml_max(
+							mode_lib->vba.WritebackRequiredDISPCLK,
+							CalculateWriteBackDISPCLK(
+									mode_lib->vba.WritebackPixelFormat[k],
+									mode_lib->vba.PixelClock[k],
+									mode_lib->vba.WritebackHRatio[k],
+									mode_lib->vba.WritebackVRatio[k],
+									mode_lib->vba.WritebackLumaHTaps[k],
+									mode_lib->vba.WritebackLumaVTaps[k],
+									mode_lib->vba.WritebackChromaHTaps[k],
+									mode_lib->vba.WritebackChromaVTaps[k],
+									mode_lib->vba.WritebackDestinationWidth[k],
+									mode_lib->vba.HTotal[k],
+									mode_lib->vba.WritebackChromaLineBufferWidth));
+		}
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.HRatio[k] > 1.0) {
+			locals->PSCL_FACTOR[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput
+							* mode_lib->vba.HRatio[k]
+							/ dml_ceil(
+									mode_lib->vba.htaps[k]
+											/ 6.0,
+									1.0));
+		} else {
+			locals->PSCL_FACTOR[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput);
+		}
+		if (locals->BytePerPixelInDETC[k] == 0.0) {
+			locals->PSCL_FACTOR_CHROMA[k] = 0.0;
+			locals->MinDPPCLKUsingSingleDPP[k] =
+					mode_lib->vba.PixelClock[k]
+							* dml_max3(
+									mode_lib->vba.vtaps[k] / 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]),
+									mode_lib->vba.HRatio[k]
+											* mode_lib->vba.VRatio[k]
+											/ locals->PSCL_FACTOR[k],
+									1.0);
+			if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
+					&& locals->MinDPPCLKUsingSingleDPP[k]
+							< 2.0 * mode_lib->vba.PixelClock[k]) {
+				locals->MinDPPCLKUsingSingleDPP[k] = 2.0
+						* mode_lib->vba.PixelClock[k];
+			}
+		} else {
+			if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
+				locals->PSCL_FACTOR_CHROMA[k] =
+						dml_min(
+								mode_lib->vba.MaxDCHUBToPSCLThroughput,
+								mode_lib->vba.MaxPSCLToLBThroughput
+										* mode_lib->vba.HRatio[k]
+										/ 2.0
+										/ dml_ceil(
+												mode_lib->vba.HTAPsChroma[k]
+														/ 6.0,
+												1.0));
+			} else {
+				locals->PSCL_FACTOR_CHROMA[k] = dml_min(
+						mode_lib->vba.MaxDCHUBToPSCLThroughput,
+						mode_lib->vba.MaxPSCLToLBThroughput);
+			}
+			locals->MinDPPCLKUsingSingleDPP[k] =
+					mode_lib->vba.PixelClock[k]
+							* dml_max5(
+									mode_lib->vba.vtaps[k] / 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]),
+									mode_lib->vba.HRatio[k]
+											* mode_lib->vba.VRatio[k]
+											/ locals->PSCL_FACTOR[k],
+									mode_lib->vba.VTAPsChroma[k]
+											/ 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]
+															/ 2.0),
+									mode_lib->vba.HRatio[k]
+											* mode_lib->vba.VRatio[k]
+											/ 4.0
+											/ locals->PSCL_FACTOR_CHROMA[k],
+									1.0);
+			if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
+					|| mode_lib->vba.HTAPsChroma[k] > 6.0
+					|| mode_lib->vba.VTAPsChroma[k] > 6.0)
+					&& locals->MinDPPCLKUsingSingleDPP[k]
+							< 2.0 * mode_lib->vba.PixelClock[k]) {
+				locals->MinDPPCLKUsingSingleDPP[k] = 2.0
+						* mode_lib->vba.PixelClock[k];
+			}
+		}
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		Calculate256BBlockSizes(
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.SurfaceTiling[k],
+				dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
+				dml_ceil(locals->BytePerPixelInDETC[k], 2.0),
+				&locals->Read256BlockHeightY[k],
+				&locals->Read256BlockHeightC[k],
+				&locals->Read256BlockWidthY[k],
+				&locals->Read256BlockWidthC[k]);
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			locals->MaxSwathHeightY[k] = locals->Read256BlockHeightY[k];
+			locals->MaxSwathHeightC[k] = locals->Read256BlockHeightC[k];
+		} else {
+			locals->MaxSwathHeightY[k] = locals->Read256BlockWidthY[k];
+			locals->MaxSwathHeightC[k] = locals->Read256BlockWidthC[k];
+		}
+		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+					|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+							&& (mode_lib->vba.SurfaceTiling[k]
+									== dm_sw_4kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_4kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_t
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s_x)
+							&& mode_lib->vba.SourceScan[k] == dm_horz)) {
+				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
+			} else {
+				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
+						/ 2.0;
+			}
+			locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
+		} else {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
+				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k]
+						/ 2.0;
+				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k]
+						/ 2.0;
+				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
+			} else {
+				locals->MinSwathHeightY[k] = locals->MaxSwathHeightY[k];
+				locals->MinSwathHeightC[k] = locals->MaxSwathHeightC[k];
+			}
+		}
+		if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+			mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
+		} else {
+			mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
+		}
+		mode_lib->vba.MaximumSwathWidthInDETBuffer =
+				dml_min(
+						mode_lib->vba.MaximumSwathWidthSupport,
+						mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
+								/ (locals->BytePerPixelInDETY[k]
+										* locals->MinSwathHeightY[k]
+										+ locals->BytePerPixelInDETC[k]
+												/ 2.0
+												* locals->MinSwathHeightC[k]));
+		if (locals->BytePerPixelInDETC[k] == 0.0) {
+			mode_lib->vba.MaximumSwathWidthInLineBuffer =
+					mode_lib->vba.LineBufferSize
+							* dml_max(mode_lib->vba.HRatio[k], 1.0)
+							/ mode_lib->vba.LBBitPerPixel[k]
+							/ (mode_lib->vba.vtaps[k]
+									+ dml_max(
+											dml_ceil(
+													mode_lib->vba.VRatio[k],
+													1.0)
+													- 2,
+											0.0));
+		} else {
+			mode_lib->vba.MaximumSwathWidthInLineBuffer =
+					dml_min(
+							mode_lib->vba.LineBufferSize
+									* dml_max(
+											mode_lib->vba.HRatio[k],
+											1.0)
+									/ mode_lib->vba.LBBitPerPixel[k]
+									/ (mode_lib->vba.vtaps[k]
+											+ dml_max(
+													dml_ceil(
+															mode_lib->vba.VRatio[k],
+															1.0)
+															- 2,
+													0.0)),
+							2.0 * mode_lib->vba.LineBufferSize
+									* dml_max(
+											mode_lib->vba.HRatio[k]
+													/ 2.0,
+											1.0)
+									/ mode_lib->vba.LBBitPerPixel[k]
+									/ (mode_lib->vba.VTAPsChroma[k]
+											+ dml_max(
+													dml_ceil(
+															mode_lib->vba.VRatio[k]
+																	/ 2.0,
+															1.0)
+															- 2,
+													0.0)));
+		}
+		locals->MaximumSwathWidth[k] = dml_min(
+				mode_lib->vba.MaximumSwathWidthInDETBuffer,
+				mode_lib->vba.MaximumSwathWidthInLineBuffer);
+	}
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
+				mode_lib->vba.MaxDispclk[i],
+				mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+			mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
+				mode_lib->vba.MaxDppclk[i],
+				mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+			locals->RequiredDISPCLK[i][j] = 0.0;
+			locals->DISPCLK_DPPCLK_Support[i][j] = true;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
+						mode_lib->vba.PixelClock[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+								* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
+				if (mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine >= mode_lib->vba.MaxDispclk[i]
+						&& i == mode_lib->vba.soc.num_states)
+					mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine = mode_lib->vba.PixelClock[k]
+							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+
+				mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
+					* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
+				if (mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine >= mode_lib->vba.MaxDispclk[i]
+						&& i == mode_lib->vba.soc.num_states)
+					mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
+							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+				if (mode_lib->vba.ODMCapability == false || mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+					locals->ODMCombineEnablePerState[i][k] = false;
+					mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+				} else {
+					locals->ODMCombineEnablePerState[i][k] = true;
+					mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+				}
+				if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
+						&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
+						&& locals->ODMCombineEnablePerState[i][k] == false) {
+					locals->NoOfDPP[i][j][k] = 1;
+					locals->RequiredDPPCLK[i][j][k] =
+						locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+				} else {
+					locals->NoOfDPP[i][j][k] = 2;
+					locals->RequiredDPPCLK[i][j][k] =
+						locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
+				}
+				locals->RequiredDISPCLK[i][j] = dml_max(
+						locals->RequiredDISPCLK[i][j],
+						mode_lib->vba.PlaneRequiredDISPCLK);
+				if ((locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+						> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+						|| (mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+					locals->DISPCLK_DPPCLK_Support[i][j] = false;
+				}
+			}
+			locals->TotalNumberOfActiveDPP[i][j] = 0.0;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
+				locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
+			if (j == 1) {
+				while (locals->TotalNumberOfActiveDPP[i][j] < mode_lib->vba.MaxNumDPP
+						&& locals->TotalNumberOfActiveDPP[i][j] < 2 * mode_lib->vba.NumberOfActivePlanes) {
+					double BWOfNonSplitPlaneOfMaximumBandwidth;
+					unsigned int NumberOfNonSplitPlaneOfMaximumBandwidth;
+
+					BWOfNonSplitPlaneOfMaximumBandwidth = 0;
+					NumberOfNonSplitPlaneOfMaximumBandwidth = 0;
+					for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+						if (locals->ReadBandwidth[k] > BWOfNonSplitPlaneOfMaximumBandwidth && locals->NoOfDPP[i][j][k] == 1) {
+							BWOfNonSplitPlaneOfMaximumBandwidth = locals->ReadBandwidth[k];
+							NumberOfNonSplitPlaneOfMaximumBandwidth = k;
+						}
+					}
+					locals->NoOfDPP[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] = 2;
+					locals->RequiredDPPCLK[i][j][NumberOfNonSplitPlaneOfMaximumBandwidth] =
+						locals->MinDPPCLKUsingSingleDPP[NumberOfNonSplitPlaneOfMaximumBandwidth]
+							* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100) / 2;
+					locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + 1;
+				}
+			}
+			if (locals->TotalNumberOfActiveDPP[i][j] > mode_lib->vba.MaxNumDPP) {
+				locals->RequiredDISPCLK[i][j] = 0.0;
+				locals->DISPCLK_DPPCLK_Support[i][j] = true;
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					locals->ODMCombineEnablePerState[i][k] = false;
+					if (locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]) {
+						locals->NoOfDPP[i][j][k] = 1;
+						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
+							* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+					} else {
+						locals->NoOfDPP[i][j][k] = 2;
+						locals->RequiredDPPCLK[i][j][k] = locals->MinDPPCLKUsingSingleDPP[k]
+										* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) / 2.0;
+					}
+					if (i != mode_lib->vba.soc.num_states) {
+						mode_lib->vba.PlaneRequiredDISPCLK =
+								mode_lib->vba.PixelClock[k]
+										* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+										* (1.0 + mode_lib->vba.DISPCLKRampingMargin / 100.0);
+					} else {
+						mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PixelClock[k]
+							* (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
+					}
+					locals->RequiredDISPCLK[i][j] = dml_max(
+							locals->RequiredDISPCLK[i][j],
+							mode_lib->vba.PlaneRequiredDISPCLK);
+					if (locals->MinDPPCLKUsingSingleDPP[k] / locals->NoOfDPP[i][j][k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0)
+							> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
+							|| mode_lib->vba.PlaneRequiredDISPCLK > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)
+						locals->DISPCLK_DPPCLK_Support[i][j] = false;
+				}
+				locals->TotalNumberOfActiveDPP[i][j] = 0.0;
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++)
+					locals->TotalNumberOfActiveDPP[i][j] = locals->TotalNumberOfActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
+			}
+			locals->RequiredDISPCLK[i][j] = dml_max(
+					locals->RequiredDISPCLK[i][j],
+					mode_lib->vba.WritebackRequiredDISPCLK);
+			if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
+					< mode_lib->vba.WritebackRequiredDISPCLK) {
+				locals->DISPCLK_DPPCLK_Support[i][j] = false;
+			}
+		}
+	}
+	/*Viewport Size Check*/
+
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		locals->ViewportSizeSupport[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (locals->ODMCombineEnablePerState[i][k] == true) {
+				if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
+						> locals->MaximumSwathWidth[k]) {
+					locals->ViewportSizeSupport[i] = false;
+				}
+			} else {
+				if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
+					locals->ViewportSizeSupport[i] = false;
+				}
+			}
+		}
+	}
+	/*Total Available Pipes Support Check*/
+
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			if (locals->TotalNumberOfActiveDPP[i][j] <= mode_lib->vba.MaxNumDPP)
+				locals->TotalAvailablePipesSupport[i][j] = true;
+			else
+				locals->TotalAvailablePipesSupport[i][j] = false;
+		}
+	}
+	/*Total Available OTG Support Check*/
+
+	mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.BlendingAndTiming[k] == k) {
+			mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+					+ 1.0;
+		}
+	}
+	if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
+		mode_lib->vba.NumberOfOTGSupport = true;
+	} else {
+		mode_lib->vba.NumberOfOTGSupport = false;
+	}
+	/*Display IO and DSC Support Check*/
+
+	mode_lib->vba.NonsupportedDSCInputBPC = false;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
+				|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
+				|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
+			mode_lib->vba.NonsupportedDSCInputBPC = true;
+		}
+	}
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			locals->RequiresDSC[i][k] = 0;
+			locals->RequiresFEC[i][k] = 0;
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				if (mode_lib->vba.Output[k] == dm_hdmi) {
+					locals->RequiresDSC[i][k] = 0;
+					locals->RequiresFEC[i][k] = 0;
+					locals->OutputBppPerState[i][k] = TruncToValidBPP(
+							dml_min(600.0, mode_lib->vba.PHYCLKPerState[i]) / mode_lib->vba.PixelClockBackEnd[k] * 24,
+							false,
+							mode_lib->vba.Output[k],
+							mode_lib->vba.OutputFormat[k],
+							mode_lib->vba.DSCInputBitPerComponent[k]);
+				} else if (mode_lib->vba.Output[k] == dm_dp
+						|| mode_lib->vba.Output[k] == dm_edp) {
+					if (mode_lib->vba.Output[k] == dm_edp) {
+						mode_lib->vba.EffectiveFECOverhead = 0.0;
+					} else {
+						mode_lib->vba.EffectiveFECOverhead =
+								mode_lib->vba.FECOverhead;
+					}
+					if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
+						mode_lib->vba.Outbpp = TruncToValidBPP(
+								(1.0 - mode_lib->vba.Downspreading / 100.0) * 270.0
+								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
+								false,
+								mode_lib->vba.Output[k],
+								mode_lib->vba.OutputFormat[k],
+								mode_lib->vba.DSCInputBitPerComponent[k]);
+						mode_lib->vba.OutbppDSC = TruncToValidBPP(
+								(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 270.0
+								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
+								true,
+								mode_lib->vba.Output[k],
+								mode_lib->vba.OutputFormat[k],
+								mode_lib->vba.DSCInputBitPerComponent[k]);
+						if (mode_lib->vba.DSCEnabled[k] == true) {
+							locals->RequiresDSC[i][k] = true;
+							if (mode_lib->vba.Output[k] == dm_dp) {
+								locals->RequiresFEC[i][k] = true;
+							} else {
+								locals->RequiresFEC[i][k] = false;
+							}
+							mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
+						} else {
+							locals->RequiresDSC[i][k] = false;
+							locals->RequiresFEC[i][k] = false;
+						}
+						locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
+					}
+					if (mode_lib->vba.Outbpp == BPP_INVALID && mode_lib->vba.PHYCLKPerState[i] >= 540.0) {
+						mode_lib->vba.Outbpp = TruncToValidBPP(
+								(1.0 - mode_lib->vba.Downspreading / 100.0) * 540.0
+								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
+									false,
+									mode_lib->vba.Output[k],
+									mode_lib->vba.OutputFormat[k],
+									mode_lib->vba.DSCInputBitPerComponent[k]);
+						mode_lib->vba.OutbppDSC = TruncToValidBPP(
+								(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 540.0
+								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
+								true,
+								mode_lib->vba.Output[k],
+								mode_lib->vba.OutputFormat[k],
+								mode_lib->vba.DSCInputBitPerComponent[k]);
+						if (mode_lib->vba.DSCEnabled[k] == true) {
+							locals->RequiresDSC[i][k] = true;
+							if (mode_lib->vba.Output[k] == dm_dp) {
+								locals->RequiresFEC[i][k] = true;
+							} else {
+								locals->RequiresFEC[i][k] = false;
+							}
+							mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
+						} else {
+							locals->RequiresDSC[i][k] = false;
+							locals->RequiresFEC[i][k] = false;
+						}
+						locals->OutputBppPerState[i][k] = mode_lib->vba.Outbpp;
+					}
+					if (mode_lib->vba.Outbpp == BPP_INVALID
+							&& mode_lib->vba.PHYCLKPerState[i]
+									>= 810.0) {
+						mode_lib->vba.Outbpp = TruncToValidBPP(
+								(1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
+								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
+								false,
+								mode_lib->vba.Output[k],
+								mode_lib->vba.OutputFormat[k],
+								mode_lib->vba.DSCInputBitPerComponent[k]);
+						mode_lib->vba.OutbppDSC = TruncToValidBPP(
+								(1.0 - mode_lib->vba.Downspreading / 100.0) * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
+								* mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
+								true,
+								mode_lib->vba.Output[k],
+								mode_lib->vba.OutputFormat[k],
+								mode_lib->vba.DSCInputBitPerComponent[k]);
+						if (mode_lib->vba.DSCEnabled[k] == true || mode_lib->vba.Outbpp == BPP_INVALID) {
+							locals->RequiresDSC[i][k] = true;
+							if (mode_lib->vba.Output[k] == dm_dp) {
+								locals->RequiresFEC[i][k] = true;
+							} else {
+								locals->RequiresFEC[i][k] = false;
+							}
+							mode_lib->vba.Outbpp = mode_lib->vba.OutbppDSC;
+						} else {
+							locals->RequiresDSC[i][k] = false;
+							locals->RequiresFEC[i][k] = false;
+						}
+						locals->OutputBppPerState[i][k] =
+								mode_lib->vba.Outbpp;
+					}
+				}
+			} else {
+				locals->OutputBppPerState[i][k] = BPP_BLENDED_PIPE;
+			}
+		}
+	}
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		locals->DIOSupport[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (locals->OutputBppPerState[i][k] == BPP_INVALID
+					|| (mode_lib->vba.OutputFormat[k] == dm_420
+							&& mode_lib->vba.Interlace[k] == true
+							&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true)) {
+				locals->DIOSupport[i] = false;
+			}
+		}
+	}
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			locals->DSCCLKRequiredMoreThanSupported[i] = false;
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				if ((mode_lib->vba.Output[k] == dm_dp
+						|| mode_lib->vba.Output[k] == dm_edp)) {
+					if (mode_lib->vba.OutputFormat[k] == dm_420
+							|| mode_lib->vba.OutputFormat[k]
+									== dm_n422) {
+						mode_lib->vba.DSCFormatFactor = 2;
+					} else {
+						mode_lib->vba.DSCFormatFactor = 1;
+					}
+					if (locals->RequiresDSC[i][k] == true) {
+						if (locals->ODMCombineEnablePerState[i][k]
+								== true) {
+							if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
+									> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
+								locals->DSCCLKRequiredMoreThanSupported[i] =
+										true;
+							}
+						} else {
+							if (mode_lib->vba.PixelClockBackEnd[k] / 3.0 / mode_lib->vba.DSCFormatFactor
+									> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
+								locals->DSCCLKRequiredMoreThanSupported[i] =
+										true;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		locals->NotEnoughDSCUnits[i] = false;
+		mode_lib->vba.TotalDSCUnitsRequired = 0.0;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (locals->RequiresDSC[i][k] == true) {
+				if (locals->ODMCombineEnablePerState[i][k] == true) {
+					mode_lib->vba.TotalDSCUnitsRequired =
+							mode_lib->vba.TotalDSCUnitsRequired + 2.0;
+				} else {
+					mode_lib->vba.TotalDSCUnitsRequired =
+							mode_lib->vba.TotalDSCUnitsRequired + 1.0;
+				}
+			}
+		}
+		if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
+			locals->NotEnoughDSCUnits[i] = true;
+		}
+	}
+	/*DSC Delay per state*/
+
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.BlendingAndTiming[k] != k) {
+				mode_lib->vba.slices = 0;
+			} else if (locals->RequiresDSC[i][k] == 0
+					|| locals->RequiresDSC[i][k] == false) {
+				mode_lib->vba.slices = 0;
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
+				mode_lib->vba.slices = dml_ceil(
+						mode_lib->vba.PixelClockBackEnd[k] / 400.0,
+						4.0);
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
+				mode_lib->vba.slices = 8.0;
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
+				mode_lib->vba.slices = 4.0;
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
+				mode_lib->vba.slices = 2.0;
+			} else {
+				mode_lib->vba.slices = 1.0;
+			}
+			if (locals->OutputBppPerState[i][k] == BPP_BLENDED_PIPE
+					|| locals->OutputBppPerState[i][k] == BPP_INVALID) {
+				mode_lib->vba.bpp = 0.0;
+			} else {
+				mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
+			}
+			if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
+				if (locals->ODMCombineEnablePerState[i][k] == false) {
+					locals->DSCDelayPerState[i][k] =
+							dscceComputeDelay(
+									mode_lib->vba.DSCInputBitPerComponent[k],
+									mode_lib->vba.bpp,
+									dml_ceil(
+											mode_lib->vba.HActive[k]
+													/ mode_lib->vba.slices,
+											1.0),
+									mode_lib->vba.slices,
+									mode_lib->vba.OutputFormat[k])
+									+ dscComputeDelay(
+											mode_lib->vba.OutputFormat[k]);
+				} else {
+					locals->DSCDelayPerState[i][k] =
+							2.0 * (dscceComputeDelay(
+											mode_lib->vba.DSCInputBitPerComponent[k],
+											mode_lib->vba.bpp,
+											dml_ceil(mode_lib->vba.HActive[k] / mode_lib->vba.slices, 1.0),
+											mode_lib->vba.slices / 2,
+											mode_lib->vba.OutputFormat[k])
+									+ dscComputeDelay(mode_lib->vba.OutputFormat[k]));
+				}
+				locals->DSCDelayPerState[i][k] =
+						locals->DSCDelayPerState[i][k] * mode_lib->vba.PixelClock[k] / mode_lib->vba.PixelClockBackEnd[k];
+			} else {
+				locals->DSCDelayPerState[i][k] = 0.0;
+			}
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
+				for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+					if (mode_lib->vba.BlendingAndTiming[k] == m && locals->RequiresDSC[i][m] == true)
+						locals->DSCDelayPerState[i][k] = locals->DSCDelayPerState[i][m];
+				}
+			}
+		}
+	}
+
+	//Prefetch Check
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				if (locals->ODMCombineEnablePerState[i][k] == true)
+					locals->SwathWidthYPerState[i][j][k] = dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
+				else
+					locals->SwathWidthYPerState[i][j][k] = locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
+				locals->SwathWidthGranularityY = 256  / dml_ceil(locals->BytePerPixelInDETY[k], 1) / locals->MaxSwathHeightY[k];
+				locals->RoundedUpMaxSwathSizeBytesY = (dml_ceil(locals->SwathWidthYPerState[i][j][k] - 1, locals->SwathWidthGranularityY)
+						+ locals->SwathWidthGranularityY) * locals->BytePerPixelInDETY[k] * locals->MaxSwathHeightY[k];
+				if (locals->SourcePixelFormat[k] == dm_420_10) {
+					locals->RoundedUpMaxSwathSizeBytesY = dml_ceil(locals->RoundedUpMaxSwathSizeBytesY, 256) + 256;
+				}
+				if (locals->MaxSwathHeightC[k] > 0) {
+					locals->SwathWidthGranularityC = 256 / dml_ceil(locals->BytePerPixelInDETC[k], 2) / locals->MaxSwathHeightC[k];
+
+					locals->RoundedUpMaxSwathSizeBytesC = (dml_ceil(locals->SwathWidthYPerState[i][j][k] / 2 - 1, locals->SwathWidthGranularityC)
+					+ locals->SwathWidthGranularityC) * locals->BytePerPixelInDETC[k] * locals->MaxSwathHeightC[k];
+				}
+				if (locals->SourcePixelFormat[k] == dm_420_10) {
+					locals->RoundedUpMaxSwathSizeBytesC = dml_ceil(locals->RoundedUpMaxSwathSizeBytesC, 256)  + 256;
+				} else {
+					locals->RoundedUpMaxSwathSizeBytesC = 0;
+				}
+
+				if (locals->RoundedUpMaxSwathSizeBytesY + locals->RoundedUpMaxSwathSizeBytesC <= locals->DETBufferSizeInKByte * 1024 / 2) {
+					locals->SwathHeightYPerState[i][j][k] = locals->MaxSwathHeightY[k];
+					locals->SwathHeightCPerState[i][j][k] = locals->MaxSwathHeightC[k];
+				} else {
+					locals->SwathHeightYPerState[i][j][k] = locals->MinSwathHeightY[k];
+					locals->SwathHeightCPerState[i][j][k] = locals->MinSwathHeightC[k];
+				}
+
+				if (locals->BytePerPixelInDETC[k] == 0) {
+					locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
+					locals->LinesInDETChroma = 0;
+				} else if (locals->SwathHeightYPerState[i][j][k] <= locals->SwathHeightCPerState[i][j][k]) {
+					locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 / 2 / locals->BytePerPixelInDETY[k] /
+							locals->SwathWidthYPerState[i][j][k];
+					locals->LinesInDETChroma = locals->DETBufferSizeInKByte * 1024 / 2 / locals->BytePerPixelInDETC[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
+				} else {
+					locals->LinesInDETLuma = locals->DETBufferSizeInKByte * 1024 * 2 / 3 / locals->BytePerPixelInDETY[k] / locals->SwathWidthYPerState[i][j][k];
+					locals->LinesInDETChroma = locals->DETBufferSizeInKByte * 1024 / 3 / locals->BytePerPixelInDETY[k] / (locals->SwathWidthYPerState[i][j][k] / 2);
+				}
+
+				locals->EffectiveLBLatencyHidingSourceLinesLuma = dml_min(locals->MaxLineBufferLines,
+					dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k] / (locals->SwathWidthYPerState[i][j][k]
+					/ dml_max(locals->HRatio[k], 1)), 1)) - (locals->vtaps[k] - 1);
+
+				locals->EffectiveLBLatencyHidingSourceLinesChroma =  dml_min(locals->MaxLineBufferLines,
+						dml_floor(locals->LineBufferSize / locals->LBBitPerPixel[k]
+						/ (locals->SwathWidthYPerState[i][j][k] / 2
+						/ dml_max(locals->HRatio[k] / 2, 1)), 1)) - (locals->VTAPsChroma[k] - 1);
+
+				locals->EffectiveDETLBLinesLuma = dml_floor(locals->LinesInDETLuma +  dml_min(
+						locals->LinesInDETLuma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETY[k] *
+						locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i],
+						locals->EffectiveLBLatencyHidingSourceLinesLuma),
+						locals->SwathHeightYPerState[i][j][k]);
+
+				locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min(
+						locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] *
+						locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i],
+						locals->EffectiveLBLatencyHidingSourceLinesChroma),
+						locals->SwathHeightCPerState[i][j][k]);
+
+				if (locals->BytePerPixelInDETC[k] == 0) {
+					locals->UrgentLatencySupportUsPerState[i][j][k] = locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
+							/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
+								dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]);
+				} else {
+					locals->UrgentLatencySupportUsPerState[i][j][k] = dml_min(
+						locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
+						/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
+						dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]),
+							locals->EffectiveDETLBLinesChroma * (locals->HTotal[k] / locals->PixelClock[k]) / (locals->VRatio[k] / 2) -
+							locals->EffectiveDETLBLinesChroma * locals->SwathWidthYPerState[i][j][k] / 2 *
+							dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]));
+				}
+			}
+		}
+	}
+
+	for (i = 0; i <= locals->soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			locals->UrgentLatencySupport[i][j] = true;
+			for (k = 0; k < locals->NumberOfActivePlanes; k++) {
+				if (locals->UrgentLatencySupportUsPerState[i][j][k] < locals->UrgentLatency)
+					locals->UrgentLatencySupport[i][j] = false;
+			}
+		}
+	}
+
+
+	/*Prefetch Check*/
+	for (i = 0; i <= locals->soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			locals->TotalNumberOfDCCActiveDPP[i][j] = 0;
+			for (k = 0; k < locals->NumberOfActivePlanes; k++) {
+				if (locals->DCCEnable[k] == true) {
+					locals->TotalNumberOfDCCActiveDPP[i][j] =
+						locals->TotalNumberOfDCCActiveDPP[i][j] + locals->NoOfDPP[i][j][k];
+				}
+			}
+		}
+	}
+
+	CalculateMinAndMaxPrefetchMode(locals->AllowDRAMSelfRefreshOrDRAMClockChangeInVblank, &locals->MinPrefetchMode, &locals->MaxPrefetchMode);
+
+	locals->MaxTotalVActiveRDBandwidth = 0;
+	for (k = 0; k < locals->NumberOfActivePlanes; k++) {
+		locals->MaxTotalVActiveRDBandwidth = locals->MaxTotalVActiveRDBandwidth + locals->ReadBandwidth[k];
+	}
+
+	for (i = 0; i <= locals->soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			for (k = 0; k < locals->NumberOfActivePlanes; k++) {
+				locals->NoOfDPPThisState[k] = locals->NoOfDPP[i][j][k];
+				locals->RequiredDPPCLKThisState[k] = locals->RequiredDPPCLK[i][j][k];
+				locals->SwathHeightYThisState[k] = locals->SwathHeightYPerState[i][j][k];
+				locals->SwathHeightCThisState[k] = locals->SwathHeightCPerState[i][j][k];
+				locals->SwathWidthYThisState[k] = locals->SwathWidthYPerState[i][j][k];
+				mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
+						mode_lib->vba.ProjectedDCFCLKDeepSleep,
+						mode_lib->vba.PixelClock[k] / 16.0);
+				if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+					if (mode_lib->vba.VRatio[k] <= 1.0) {
+						mode_lib->vba.ProjectedDCFCLKDeepSleep =
+								dml_max(
+										mode_lib->vba.ProjectedDCFCLKDeepSleep,
+										1.1
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETY[k],
+														1.0)
+												/ 64.0
+												* mode_lib->vba.HRatio[k]
+												* mode_lib->vba.PixelClock[k]
+												/ mode_lib->vba.NoOfDPP[i][j][k]);
+					} else {
+						mode_lib->vba.ProjectedDCFCLKDeepSleep =
+								dml_max(
+										mode_lib->vba.ProjectedDCFCLKDeepSleep,
+										1.1
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETY[k],
+														1.0)
+												/ 64.0
+												* mode_lib->vba.PSCL_FACTOR[k]
+												* mode_lib->vba.RequiredDPPCLK[i][j][k]);
+					}
+				} else {
+					if (mode_lib->vba.VRatio[k] <= 1.0) {
+						mode_lib->vba.ProjectedDCFCLKDeepSleep =
+								dml_max(
+										mode_lib->vba.ProjectedDCFCLKDeepSleep,
+										1.1
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETY[k],
+														1.0)
+												/ 32.0
+												* mode_lib->vba.HRatio[k]
+												* mode_lib->vba.PixelClock[k]
+												/ mode_lib->vba.NoOfDPP[i][j][k]);
+					} else {
+						mode_lib->vba.ProjectedDCFCLKDeepSleep =
+								dml_max(
+										mode_lib->vba.ProjectedDCFCLKDeepSleep,
+										1.1
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETY[k],
+														1.0)
+												/ 32.0
+												* mode_lib->vba.PSCL_FACTOR[k]
+												* mode_lib->vba.RequiredDPPCLK[i][j][k]);
+					}
+					if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
+						mode_lib->vba.ProjectedDCFCLKDeepSleep =
+								dml_max(
+										mode_lib->vba.ProjectedDCFCLKDeepSleep,
+										1.1
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETC[k],
+														2.0)
+												/ 32.0
+												* mode_lib->vba.HRatio[k]
+												/ 2.0
+												* mode_lib->vba.PixelClock[k]
+												/ mode_lib->vba.NoOfDPP[i][j][k]);
+					} else {
+						mode_lib->vba.ProjectedDCFCLKDeepSleep =
+								dml_max(
+										mode_lib->vba.ProjectedDCFCLKDeepSleep,
+										1.1
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETC[k],
+														2.0)
+												/ 32.0
+												* mode_lib->vba.PSCL_FACTOR_CHROMA[k]
+												* mode_lib->vba.RequiredDPPCLK[i][j][k]);
+					}
+				}
+			}
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
+						mode_lib,
+						mode_lib->vba.DCCEnable[k],
+						mode_lib->vba.Read256BlockHeightY[k],
+						mode_lib->vba.Read256BlockWidthY[k],
+						mode_lib->vba.SourcePixelFormat[k],
+						mode_lib->vba.SurfaceTiling[k],
+						dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
+						mode_lib->vba.SourceScan[k],
+						mode_lib->vba.ViewportWidth[k],
+						mode_lib->vba.ViewportHeight[k],
+						mode_lib->vba.SwathWidthYPerState[i][j][k],
+						mode_lib->vba.GPUVMEnable,
+						mode_lib->vba.VMMPageSize,
+						mode_lib->vba.PTEBufferSizeInRequestsLuma,
+						mode_lib->vba.PDEProcessingBufIn64KBReqs,
+						mode_lib->vba.PitchY[k],
+						mode_lib->vba.DCCMetaPitchY[k],
+						&mode_lib->vba.MacroTileWidthY[k],
+						&mode_lib->vba.MetaRowBytesY,
+						&mode_lib->vba.DPTEBytesPerRowY,
+						&mode_lib->vba.PTEBufferSizeNotExceededY[i][j][k],
+						&mode_lib->vba.dpte_row_height[k],
+						&mode_lib->vba.meta_row_height[k]);
+				mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
+						mode_lib,
+						mode_lib->vba.VRatio[k],
+						mode_lib->vba.vtaps[k],
+						mode_lib->vba.Interlace[k],
+						mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+						mode_lib->vba.SwathHeightYPerState[i][j][k],
+						mode_lib->vba.ViewportYStartY[k],
+						&mode_lib->vba.PrefillY[k],
+						&mode_lib->vba.MaxNumSwY[k]);
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
+					mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
+							mode_lib,
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.Read256BlockHeightY[k],
+							mode_lib->vba.Read256BlockWidthY[k],
+							mode_lib->vba.SourcePixelFormat[k],
+							mode_lib->vba.SurfaceTiling[k],
+							dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
+							mode_lib->vba.SourceScan[k],
+							mode_lib->vba.ViewportWidth[k] / 2.0,
+							mode_lib->vba.ViewportHeight[k] / 2.0,
+							mode_lib->vba.SwathWidthYPerState[i][j][k] / 2.0,
+							mode_lib->vba.GPUVMEnable,
+							mode_lib->vba.VMMPageSize,
+							mode_lib->vba.PTEBufferSizeInRequestsLuma,
+							mode_lib->vba.PDEProcessingBufIn64KBReqs,
+							mode_lib->vba.PitchC[k],
+							0.0,
+							&mode_lib->vba.MacroTileWidthC[k],
+							&mode_lib->vba.MetaRowBytesC,
+							&mode_lib->vba.DPTEBytesPerRowC,
+							&mode_lib->vba.PTEBufferSizeNotExceededC[i][j][k],
+							&mode_lib->vba.dpte_row_height_chroma[k],
+							&mode_lib->vba.meta_row_height_chroma[k]);
+					mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
+							mode_lib,
+							mode_lib->vba.VRatio[k] / 2.0,
+							mode_lib->vba.VTAPsChroma[k],
+							mode_lib->vba.Interlace[k],
+							mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+							mode_lib->vba.SwathHeightCPerState[i][j][k],
+							mode_lib->vba.ViewportYStartC[k],
+							&mode_lib->vba.PrefillC[k],
+							&mode_lib->vba.MaxNumSwC[k]);
+				} else {
+					mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
+					mode_lib->vba.MetaRowBytesC = 0.0;
+					mode_lib->vba.DPTEBytesPerRowC = 0.0;
+					locals->PrefetchLinesC[k] = 0.0;
+					locals->PTEBufferSizeNotExceededC[i][j][k] = true;
+					locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
+				}
+				locals->PDEAndMetaPTEBytesPerFrame[k] =
+						mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
+				locals->MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
+				locals->DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
+
+				CalculateActiveRowBandwidth(
+						mode_lib->vba.GPUVMEnable,
+						mode_lib->vba.SourcePixelFormat[k],
+						mode_lib->vba.VRatio[k],
+						mode_lib->vba.DCCEnable[k],
+						mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+						mode_lib->vba.MetaRowBytesY,
+						mode_lib->vba.MetaRowBytesC,
+						mode_lib->vba.meta_row_height[k],
+						mode_lib->vba.meta_row_height_chroma[k],
+						mode_lib->vba.DPTEBytesPerRowY,
+						mode_lib->vba.DPTEBytesPerRowC,
+						mode_lib->vba.dpte_row_height[k],
+						mode_lib->vba.dpte_row_height_chroma[k],
+						&mode_lib->vba.meta_row_bw[k],
+						&mode_lib->vba.dpte_row_bw[k],
+						&mode_lib->vba.qual_row_bw[k]);
+			}
+			mode_lib->vba.ExtraLatency =
+					mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
+							+ (mode_lib->vba.TotalNumberOfActiveDPP[i][j]
+									* mode_lib->vba.PixelChunkSizeInKByte
+									+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i][j]
+											* mode_lib->vba.MetaChunkSize)
+									* 1024.0
+									/ mode_lib->vba.ReturnBWPerState[i];
+			if (mode_lib->vba.GPUVMEnable == true) {
+				mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
+						+ mode_lib->vba.TotalNumberOfActiveDPP[i][j]
+								* mode_lib->vba.PTEGroupSize
+								/ mode_lib->vba.ReturnBWPerState[i];
+			}
+			mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
+
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				if (mode_lib->vba.BlendingAndTiming[k] == k) {
+					if (mode_lib->vba.WritebackEnable[k] == true) {
+						locals->WritebackDelay[i][k] = mode_lib->vba.WritebackLatency
+								+ CalculateWriteBackDelay(
+										mode_lib->vba.WritebackPixelFormat[k],
+										mode_lib->vba.WritebackHRatio[k],
+										mode_lib->vba.WritebackVRatio[k],
+										mode_lib->vba.WritebackLumaHTaps[k],
+										mode_lib->vba.WritebackLumaVTaps[k],
+										mode_lib->vba.WritebackChromaHTaps[k],
+										mode_lib->vba.WritebackChromaVTaps[k],
+										mode_lib->vba.WritebackDestinationWidth[k]) / locals->RequiredDISPCLK[i][j];
+					} else {
+						locals->WritebackDelay[i][k] = 0.0;
+					}
+					for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
+						if (mode_lib->vba.BlendingAndTiming[m] == k
+								&& mode_lib->vba.WritebackEnable[m]
+										== true) {
+							locals->WritebackDelay[i][k] = dml_max(locals->WritebackDelay[i][k],
+											mode_lib->vba.WritebackLatency + CalculateWriteBackDelay(
+													mode_lib->vba.WritebackPixelFormat[m],
+													mode_lib->vba.WritebackHRatio[m],
+													mode_lib->vba.WritebackVRatio[m],
+													mode_lib->vba.WritebackLumaHTaps[m],
+													mode_lib->vba.WritebackLumaVTaps[m],
+													mode_lib->vba.WritebackChromaHTaps[m],
+													mode_lib->vba.WritebackChromaVTaps[m],
+													mode_lib->vba.WritebackDestinationWidth[m]) / locals->RequiredDISPCLK[i][j]);
+						}
+					}
+				}
+			}
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				for (m = 0; m <= mode_lib->vba.NumberOfActivePlanes - 1; m++) {
+					if (mode_lib->vba.BlendingAndTiming[k] == m) {
+						locals->WritebackDelay[i][k] = locals->WritebackDelay[i][m];
+					}
+				}
+			}
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				for (m = 0; m < locals->NumberOfCursors[k]; m++)
+					locals->cursor_bw[k] = locals->NumberOfCursors[k] * locals->CursorWidth[k][m] * locals->CursorBPP[k][m]
+						/ 8 / (locals->HTotal[k] / locals->PixelClock[k]) * locals->VRatio[k];
+			}
+
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				locals->MaximumVStartup[k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
+					- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
+			}
+
+			mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
+			do {
+				mode_lib->vba.PrefetchMode[i][j] = mode_lib->vba.NextPrefetchMode;
+				mode_lib->vba.NextPrefetchMode = mode_lib->vba.NextPrefetchMode + 1;
+
+				mode_lib->vba.TWait = CalculateTWait(
+						mode_lib->vba.PrefetchMode[i][j],
+						mode_lib->vba.DRAMClockChangeLatency,
+						mode_lib->vba.UrgentLatency,
+						mode_lib->vba.SREnterPlusExitTime);
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+
+					if (mode_lib->vba.XFCEnabled[k] == true) {
+						mode_lib->vba.XFCRemoteSurfaceFlipDelay =
+								CalculateRemoteSurfaceFlipDelay(
+										mode_lib,
+										mode_lib->vba.VRatio[k],
+										locals->SwathWidthYPerState[i][j][k],
+										dml_ceil(locals->BytePerPixelInDETY[k], 1.0),
+										mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+										mode_lib->vba.XFCTSlvVupdateOffset,
+										mode_lib->vba.XFCTSlvVupdateWidth,
+										mode_lib->vba.XFCTSlvVreadyOffset,
+										mode_lib->vba.XFCXBUFLatencyTolerance,
+										mode_lib->vba.XFCFillBWOverhead,
+										mode_lib->vba.XFCSlvChunkSize,
+										mode_lib->vba.XFCBusTransportTime,
+										mode_lib->vba.TimeCalc,
+										mode_lib->vba.TWait,
+										&mode_lib->vba.SrcActiveDrainRate,
+										&mode_lib->vba.TInitXFill,
+										&mode_lib->vba.TslvChk);
+					} else {
+						mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
+					}
+
+					CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBWPerState[i], mode_lib->vba.ReadBandwidthLuma[k], mode_lib->vba.ReadBandwidthChroma[k], mode_lib->vba.MaxTotalVActiveRDBandwidth,
+						mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k],
+						mode_lib->vba.RequiredDPPCLK[i][j][k], mode_lib->vba.RequiredDISPCLK[i][j], mode_lib->vba.PixelClock[k], mode_lib->vba.DSCDelayPerState[i][k], mode_lib->vba.NoOfDPP[i][j][k], mode_lib->vba.ScalerEnabled[k], mode_lib->vba.NumberOfCursors[k],
+						mode_lib->vba.DPPCLKDelaySubtotal, mode_lib->vba.DPPCLKDelaySCL, mode_lib->vba.DPPCLKDelaySCLLBOnly, mode_lib->vba.DPPCLKDelayCNVCFormater, mode_lib->vba.DPPCLKDelayCNVCCursor, mode_lib->vba.DISPCLKDelaySubtotal,
+						mode_lib->vba.SwathWidthYPerState[i][j][k] / mode_lib->vba.HRatio[k], mode_lib->vba.OutputFormat[k], mode_lib->vba.HTotal[k],
+						mode_lib->vba.SwathWidthYSingleDPP[k], mode_lib->vba.BytePerPixelInDETY[k], mode_lib->vba.BytePerPixelInDETC[k], mode_lib->vba.SwathHeightYThisState[k], mode_lib->vba.SwathHeightCThisState[k], mode_lib->vba.Interlace[k], mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+						&mode_lib->vba.DSTXAfterScaler[k], &mode_lib->vba.DSTYAfterScaler[k]);
+
+					mode_lib->vba.IsErrorResult[i][j][k] =
+							CalculatePrefetchSchedule(
+									mode_lib,
+									mode_lib->vba.RequiredDPPCLK[i][j][k],
+									mode_lib->vba.RequiredDISPCLK[i][j],
+									mode_lib->vba.PixelClock[k],
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									mode_lib->vba.NoOfDPP[i][j][k],
+									mode_lib->vba.NumberOfCursors[k],
+									mode_lib->vba.VTotal[k]
+											- mode_lib->vba.VActive[k],
+									mode_lib->vba.HTotal[k],
+									mode_lib->vba.MaxInterDCNTileRepeaters,
+									mode_lib->vba.MaximumVStartup[k],
+									mode_lib->vba.GPUVMMaxPageTableLevels,
+									mode_lib->vba.GPUVMEnable,
+									mode_lib->vba.DynamicMetadataEnable[k],
+									mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
+									mode_lib->vba.DynamicMetadataTransmittedBytes[k],
+									mode_lib->vba.DCCEnable[k],
+									mode_lib->vba.UrgentLatencyPixelDataOnly,
+									mode_lib->vba.ExtraLatency,
+									mode_lib->vba.TimeCalc,
+									mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
+									mode_lib->vba.MetaRowBytes[k],
+									mode_lib->vba.DPTEBytesPerRow[k],
+									mode_lib->vba.PrefetchLinesY[k],
+									mode_lib->vba.SwathWidthYPerState[i][j][k],
+									mode_lib->vba.BytePerPixelInDETY[k],
+									mode_lib->vba.PrefillY[k],
+									mode_lib->vba.MaxNumSwY[k],
+									mode_lib->vba.PrefetchLinesC[k],
+									mode_lib->vba.BytePerPixelInDETC[k],
+									mode_lib->vba.PrefillC[k],
+									mode_lib->vba.MaxNumSwC[k],
+									mode_lib->vba.SwathHeightYPerState[i][j][k],
+									mode_lib->vba.SwathHeightCPerState[i][j][k],
+									mode_lib->vba.TWait,
+									mode_lib->vba.XFCEnabled[k],
+									mode_lib->vba.XFCRemoteSurfaceFlipDelay,
+									mode_lib->vba.Interlace[k],
+									mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+									mode_lib->vba.DSTXAfterScaler[k],
+									mode_lib->vba.DSTYAfterScaler[k],
+									&mode_lib->vba.LineTimesForPrefetch[k],
+									&mode_lib->vba.PrefetchBW[k],
+									&mode_lib->vba.LinesForMetaPTE[k],
+									&mode_lib->vba.LinesForMetaAndDPTERow[k],
+									&mode_lib->vba.VRatioPreY[i][j][k],
+									&mode_lib->vba.VRatioPreC[i][j][k],
+									&mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k],
+									&mode_lib->vba.Tno_bw[k],
+									&mode_lib->vba.VUpdateOffsetPix[k],
+									&mode_lib->vba.VUpdateWidthPix[k],
+									&mode_lib->vba.VReadyOffsetPix[k]);
+				}
+				mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0;
+				mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
+				locals->prefetch_vm_bw_valid = true;
+				locals->prefetch_row_bw_valid = true;
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					if (locals->PDEAndMetaPTEBytesPerFrame[k] == 0)
+						locals->prefetch_vm_bw[k] = 0;
+					else if (locals->LinesForMetaPTE[k] > 0)
+						locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[k]
+							/ (locals->LinesForMetaPTE[k] * locals->HTotal[k] / locals->PixelClock[k]);
+					else {
+						locals->prefetch_vm_bw[k] = 0;
+						locals->prefetch_vm_bw_valid = false;
+					}
+					if (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k] == 0)
+						locals->prefetch_row_bw[k] = 0;
+					else if (locals->LinesForMetaAndDPTERow[k] > 0)
+						locals->prefetch_row_bw[k] = (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k])
+							/ (locals->LinesForMetaAndDPTERow[k] * locals->HTotal[k] / locals->PixelClock[k]);
+					else {
+						locals->prefetch_row_bw[k] = 0;
+						locals->prefetch_row_bw_valid = false;
+					}
+
+					mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = mode_lib->vba.MaximumReadBandwidthWithPrefetch
+							+ mode_lib->vba.cursor_bw[k] + mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k];
+					mode_lib->vba.MaximumReadBandwidthWithPrefetch =
+							mode_lib->vba.MaximumReadBandwidthWithPrefetch
+									+ mode_lib->vba.cursor_bw[k]
+									+ dml_max3(
+											mode_lib->vba.prefetch_vm_bw[k],
+											mode_lib->vba.prefetch_row_bw[k],
+											dml_max(mode_lib->vba.ReadBandwidth[k],
+											mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k])
+											+ mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k]);
+				}
+				locals->BandwidthWithoutPrefetchSupported[i] = true;
+				if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i]) {
+					locals->BandwidthWithoutPrefetchSupported[i] = false;
+				}
+
+				locals->PrefetchSupported[i][j] = true;
+				if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i]) {
+					locals->PrefetchSupported[i][j] = false;
+				}
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					if (locals->LineTimesForPrefetch[k] < 2.0
+							|| locals->LinesForMetaPTE[k] >= 8.0
+							|| locals->LinesForMetaAndDPTERow[k] >= 16.0
+							|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
+						locals->PrefetchSupported[i][j] = false;
+					}
+				}
+				locals->VRatioInPrefetchSupported[i][j] = true;
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					if (locals->VRatioPreY[i][j][k] > 4.0
+							|| locals->VRatioPreC[i][j][k] > 4.0
+							|| mode_lib->vba.IsErrorResult[i][j][k] == true) {
+						locals->VRatioInPrefetchSupported[i][j] = false;
+					}
+				}
+			} while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true)
+					&& mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode);
+
+			if (mode_lib->vba.PrefetchSupported[i][j] == true
+					&& mode_lib->vba.VRatioInPrefetchSupported[i][j] == true) {
+				mode_lib->vba.BandwidthAvailableForImmediateFlip =
+						mode_lib->vba.ReturnBWPerState[i];
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					mode_lib->vba.BandwidthAvailableForImmediateFlip =
+							mode_lib->vba.BandwidthAvailableForImmediateFlip
+									- mode_lib->vba.cursor_bw[k]
+									- dml_max(
+											mode_lib->vba.ReadBandwidth[k] + mode_lib->vba.qual_row_bw[k],
+											mode_lib->vba.PrefetchBW[k]);
+				}
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
+					if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+							&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+						mode_lib->vba.ImmediateFlipBytes[k] =
+								mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
+										+ mode_lib->vba.MetaRowBytes[k]
+										+ mode_lib->vba.DPTEBytesPerRow[k];
+					}
+				}
+				mode_lib->vba.TotImmediateFlipBytes = 0.0;
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+							&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+						mode_lib->vba.TotImmediateFlipBytes =
+								mode_lib->vba.TotImmediateFlipBytes
+										+ mode_lib->vba.ImmediateFlipBytes[k];
+					}
+				}
+
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					CalculateFlipSchedule(
+							mode_lib,
+							mode_lib->vba.ExtraLatency,
+							mode_lib->vba.UrgentLatencyPixelDataOnly,
+							mode_lib->vba.GPUVMMaxPageTableLevels,
+							mode_lib->vba.GPUVMEnable,
+							mode_lib->vba.BandwidthAvailableForImmediateFlip,
+							mode_lib->vba.TotImmediateFlipBytes,
+							mode_lib->vba.SourcePixelFormat[k],
+							mode_lib->vba.ImmediateFlipBytes[k],
+							mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k],
+							mode_lib->vba.VRatio[k],
+							mode_lib->vba.Tno_bw[k],
+							mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
+							mode_lib->vba.MetaRowBytes[k],
+							mode_lib->vba.DPTEBytesPerRow[k],
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.dpte_row_height[k],
+							mode_lib->vba.meta_row_height[k],
+							mode_lib->vba.qual_row_bw[k],
+							&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
+							&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
+							&mode_lib->vba.final_flip_bw[k],
+							&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
+				}
+				mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					mode_lib->vba.total_dcn_read_bw_with_flip =
+							mode_lib->vba.total_dcn_read_bw_with_flip
+									+ mode_lib->vba.cursor_bw[k]
+									+ dml_max3(
+											mode_lib->vba.prefetch_vm_bw[k],
+											mode_lib->vba.prefetch_row_bw[k],
+											mode_lib->vba.final_flip_bw[k]
+													+ dml_max(
+															mode_lib->vba.ReadBandwidth[k],
+															mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k]));
+				}
+				mode_lib->vba.ImmediateFlipSupportedForState[i][j] = true;
+				if (mode_lib->vba.total_dcn_read_bw_with_flip
+						> mode_lib->vba.ReturnBWPerState[i]) {
+					mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
+				}
+				for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+					if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
+						mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
+					}
+				}
+			} else {
+				mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
+			}
+		}
+	}
+
+	/*Vertical Active BW support*/
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i] = dml_min(mode_lib->vba.ReturnBusWidth *
+				mode_lib->vba.DCFCLKPerState[i], mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000) *
+				mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100;
+		if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i])
+			mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = true;
+		else
+			mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = false;
+	}
+
+	/*PTE Buffer Size Check*/
+
+	for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
+		for (j = 0; j < 2; j++) {
+			locals->PTEBufferSizeNotExceeded[i][j] = true;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				if (locals->PTEBufferSizeNotExceededY[i][j][k] == false
+						|| locals->PTEBufferSizeNotExceededC[i][j][k] == false) {
+					locals->PTEBufferSizeNotExceeded[i][j] = false;
+				}
+			}
+		}
+	}
+	/*Cursor Support Check*/
+	mode_lib->vba.CursorSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		for (j = 0; j < 2; j++) {
+			if (mode_lib->vba.CursorWidth[k][j] > 0.0) {
+				if (dml_floor(
+						dml_floor(
+								mode_lib->vba.CursorBufferSize
+										- mode_lib->vba.CursorChunkSize,
+								mode_lib->vba.CursorChunkSize) * 1024.0
+								/ (mode_lib->vba.CursorWidth[k][j]
+										* mode_lib->vba.CursorBPP[k][j]
+										/ 8.0),
+						1.0)
+						* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+						/ mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatencyPixelDataOnly
+						|| (mode_lib->vba.CursorBPP[k][j] == 64.0
+								&& mode_lib->vba.Cursor64BppSupport == false)) {
+					mode_lib->vba.CursorSupport = false;
+				}
+			}
+		}
+	}
+	/*Valid Pitch Check*/
+
+	mode_lib->vba.PitchSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		locals->AlignedYPitch[k] = dml_ceil(
+				dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
+				locals->MacroTileWidthY[k]);
+		if (locals->AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
+			mode_lib->vba.PitchSupport = false;
+		}
+		if (mode_lib->vba.DCCEnable[k] == true) {
+			locals->AlignedDCCMetaPitch[k] = dml_ceil(
+					dml_max(
+							mode_lib->vba.DCCMetaPitchY[k],
+							mode_lib->vba.ViewportWidth[k]),
+					64.0 * locals->Read256BlockWidthY[k]);
+		} else {
+			locals->AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
+		}
+		if (locals->AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
+			mode_lib->vba.PitchSupport = false;
+		}
+		if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
+			locals->AlignedCPitch[k] = dml_ceil(
+					dml_max(
+							mode_lib->vba.PitchC[k],
+							mode_lib->vba.ViewportWidth[k] / 2.0),
+					locals->MacroTileWidthC[k]);
+		} else {
+			locals->AlignedCPitch[k] = mode_lib->vba.PitchC[k];
+		}
+		if (locals->AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
+			mode_lib->vba.PitchSupport = false;
+		}
+	}
+	/*Mode Support, Voltage State and SOC Configuration*/
+
+	for (i = mode_lib->vba.soc.num_states; i >= 0; i--) {
+		for (j = 0; j < 2; j++) {
+			enum dm_validation_status status = DML_VALIDATION_OK;
+
+			if (mode_lib->vba.ScaleRatioAndTapsSupport != true) {
+				status = DML_FAIL_SCALE_RATIO_TAP;
+			} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
+				status = DML_FAIL_SOURCE_PIXEL_FORMAT;
+			} else if (locals->ViewportSizeSupport[i] != true) {
+				status = DML_FAIL_VIEWPORT_SIZE;
+			} else if (locals->DIOSupport[i] != true) {
+				status = DML_FAIL_DIO_SUPPORT;
+			} else if (locals->NotEnoughDSCUnits[i] != false) {
+				status = DML_FAIL_NOT_ENOUGH_DSC;
+			} else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) {
+				status = DML_FAIL_DSC_CLK_REQUIRED;
+			} else if (locals->UrgentLatencySupport[i][j] != true) {
+				status = DML_FAIL_URGENT_LATENCY;
+			} else if (locals->ROBSupport[i] != true) {
+				status = DML_FAIL_REORDERING_BUFFER;
+			} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
+				status = DML_FAIL_DISPCLK_DPPCLK;
+			} else if (locals->TotalAvailablePipesSupport[i][j] != true) {
+				status = DML_FAIL_TOTAL_AVAILABLE_PIPES;
+			} else if (mode_lib->vba.NumberOfOTGSupport != true) {
+				status = DML_FAIL_NUM_OTG;
+			} else if (mode_lib->vba.WritebackModeSupport != true) {
+				status = DML_FAIL_WRITEBACK_MODE;
+			} else if (mode_lib->vba.WritebackLatencySupport != true) {
+				status = DML_FAIL_WRITEBACK_LATENCY;
+			} else if (mode_lib->vba.WritebackScaleRatioAndTapsSupport != true) {
+				status = DML_FAIL_WRITEBACK_SCALE_RATIO_TAP;
+			} else if (mode_lib->vba.CursorSupport != true) {
+				status = DML_FAIL_CURSOR_SUPPORT;
+			} else if (mode_lib->vba.PitchSupport != true) {
+				status = DML_FAIL_PITCH_SUPPORT;
+			} else if (locals->PrefetchSupported[i][j] != true) {
+				status = DML_FAIL_PREFETCH_SUPPORT;
+			} else if (locals->TotalVerticalActiveBandwidthSupport[i] != true) {
+				status = DML_FAIL_TOTAL_V_ACTIVE_BW;
+			} else if (locals->VRatioInPrefetchSupported[i][j] != true) {
+				status = DML_FAIL_V_RATIO_PREFETCH;
+			} else if (locals->PTEBufferSizeNotExceeded[i][j] != true) {
+				status = DML_FAIL_PTE_BUFFER_SIZE;
+			} else if (mode_lib->vba.NonsupportedDSCInputBPC != false) {
+				status = DML_FAIL_DSC_INPUT_BPC;
+			}
+
+			if (status == DML_VALIDATION_OK) {
+				locals->ModeSupport[i][j] = true;
+			} else {
+				locals->ModeSupport[i][j] = false;
+			}
+			locals->ValidationStatus[i] = status;
+		}
+	}
+	{
+		unsigned int MaximumMPCCombine = 0;
+		mode_lib->vba.VoltageLevel = mode_lib->vba.soc.num_states + 1;
+		for (i = mode_lib->vba.VoltageOverrideLevel; i <= mode_lib->vba.soc.num_states; i++) {
+			if (locals->ModeSupport[i][0] == true || locals->ModeSupport[i][1] == true) {
+				mode_lib->vba.VoltageLevel = i;
+				if (locals->ModeSupport[i][1] == true && (locals->ModeSupport[i][0] == false
+						|| mode_lib->vba.WhenToDoMPCCombine == dm_mpc_always_when_possible)) {
+					MaximumMPCCombine = 1;
+				} else {
+					MaximumMPCCombine = 0;
+				}
+				break;
+			}
+		}
+		mode_lib->vba.ImmediateFlipSupport =
+			locals->ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.DPPPerPlane[k] = locals->NoOfDPP[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
+			locals->DPPCLK[k] = locals->RequiredDPPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine][k];
+		}
+		mode_lib->vba.DISPCLK = locals->RequiredDISPCLK[mode_lib->vba.VoltageLevel][MaximumMPCCombine];
+		mode_lib->vba.maxMpcComb = MaximumMPCCombine;
+	}
+	mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.FabricAndDRAMBandwidth = locals->FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.BlendingAndTiming[k] == k) {
+			mode_lib->vba.ODMCombineEnabled[k] =
+					locals->ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
+		} else {
+			mode_lib->vba.ODMCombineEnabled[k] = 0;
+		}
+		mode_lib->vba.DSCEnabled[k] =
+				locals->RequiresDSC[mode_lib->vba.VoltageLevel][k];
+		mode_lib->vba.OutputBpp[k] =
+				locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
+	}
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.h
new file mode 100644
index 000000000000..a989d3ca1e99
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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 _DCN20V2_DISPLAY_MODE_VBA_H_
+#define _DCN20V2_DISPLAY_MODE_VBA_H_
+
+void dml20v2_recalculate(struct display_mode_lib *mode_lib);
+void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
new file mode 100644
index 000000000000..ed8bf5f723c9
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -0,0 +1,1701 @@
+/*
+ * Copyright 2018 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 "../display_mode_lib.h"
+#include "../display_mode_vba.h"
+#include "display_rq_dlg_calc_20v2.h"
+
+// Function: dml20v2_rq_dlg_get_rq_params
+//  Calculate requestor related parameters that register definition agnostic
+//  (i.e. this layer does try to separate real values from register definition)
+// Input:
+//  pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+// Output:
+//  rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
+//
+static void dml20v2_rq_dlg_get_rq_params(
+		struct display_mode_lib *mode_lib,
+		display_rq_params_st * rq_param,
+		const display_pipe_source_params_st pipe_src_param);
+
+// Function: dml20v2_rq_dlg_get_dlg_params
+//  Calculate deadline related parameters
+//
+static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
+		display_dlg_regs_st *disp_dlg_regs,
+		display_ttu_regs_st *disp_ttu_regs,
+		const display_rq_dlg_params_st rq_dlg_param,
+		const display_dlg_sys_params_st dlg_sys_param,
+		const bool cstate_en,
+		const bool pstate_en);
+/*
+ * NOTE:
+ *   This file is gcc-parseable HW gospel, coming straight from HW engineers.
+ *
+ * It doesn't adhere to Linux kernel style and sometimes will do things in odd
+ * ways. Unless there is something clearly wrong with it the code should
+ * remain as-is as it provides us with a guarantee from HW that it is correct.
+ */
+
+static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+		double *refcyc_per_req_delivery_pre_cur,
+		double *refcyc_per_req_delivery_cur,
+		double refclk_freq_in_mhz,
+		double ref_freq_to_pix_freq,
+		double hscale_pixel_rate_l,
+		double hscl_ratio,
+		double vratio_pre_l,
+		double vratio_l,
+		unsigned int cur_width,
+		enum cursor_bpp cur_bpp);
+
+#include "../dml_inline_defs.h"
+
+static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
+{
+	unsigned int ret_val = 0;
+
+	if (source_format == dm_444_16) {
+		if (!is_chroma)
+			ret_val = 2;
+	} else if (source_format == dm_444_32) {
+		if (!is_chroma)
+			ret_val = 4;
+	} else if (source_format == dm_444_64) {
+		if (!is_chroma)
+			ret_val = 8;
+	} else if (source_format == dm_420_8) {
+		if (is_chroma)
+			ret_val = 2;
+		else
+			ret_val = 1;
+	} else if (source_format == dm_420_10) {
+		if (is_chroma)
+			ret_val = 4;
+		else
+			ret_val = 2;
+	} else if (source_format == dm_444_8) {
+		ret_val = 1;
+	}
+	return ret_val;
+}
+
+static bool is_dual_plane(enum source_format_class source_format)
+{
+	bool ret_val = 0;
+
+	if ((source_format == dm_420_8) || (source_format == dm_420_10))
+		ret_val = 1;
+
+	return ret_val;
+}
+
+static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib,
+		double refclk_freq_in_mhz,
+		double pclk_freq_in_mhz,
+		bool odm_combine,
+		unsigned int recout_width,
+		unsigned int hactive,
+		double vratio,
+		double hscale_pixel_rate,
+		unsigned int delivery_width,
+		unsigned int req_per_swath_ub)
+{
+	double refcyc_per_delivery = 0.0;
+
+	if (vratio <= 1.0) {
+		if (odm_combine)
+			refcyc_per_delivery = (double) refclk_freq_in_mhz
+					* dml_min((double) recout_width, (double) hactive / 2.0)
+					/ pclk_freq_in_mhz / (double) req_per_swath_ub;
+		else
+			refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
+					/ pclk_freq_in_mhz / (double) req_per_swath_ub;
+	} else {
+		refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
+				/ (double) hscale_pixel_rate / (double) req_per_swath_ub;
+	}
+
+	dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: pclk_freq_in_mhz   = %3.2f\n", __func__, pclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: recout_width       = %d\n", __func__, recout_width);
+	dml_print("DML_DLG: %s: vratio             = %3.2f\n", __func__, vratio);
+	dml_print("DML_DLG: %s: req_per_swath_ub   = %d\n", __func__, req_per_swath_ub);
+	dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery);
+
+	return refcyc_per_delivery;
+
+}
+
+static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
+{
+	if (tile_size == dm_256k_tile)
+		return (256 * 1024);
+	else if (tile_size == dm_64k_tile)
+		return (64 * 1024);
+	else
+		return (4 * 1024);
+}
+
+static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib,
+		display_data_rq_regs_st *rq_regs,
+		const display_data_rq_sizing_params_st rq_sizing)
+{
+	dml_print("DML_DLG: %s: rq_sizing param\n", __func__);
+	print__data_rq_sizing_params_st(mode_lib, rq_sizing);
+
+	rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
+
+	if (rq_sizing.min_chunk_bytes == 0)
+		rq_regs->min_chunk_size = 0;
+	else
+		rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1;
+
+	rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10;
+	if (rq_sizing.min_meta_chunk_bytes == 0)
+		rq_regs->min_meta_chunk_size = 0;
+	else
+		rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1;
+
+	rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6;
+	rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
+}
+
+static void extract_rq_regs(struct display_mode_lib *mode_lib,
+		display_rq_regs_st *rq_regs,
+		const display_rq_params_st rq_param)
+{
+	unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
+	unsigned int detile_buf_plane1_addr = 0;
+
+	extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
+
+	rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height),
+			1) - 3;
+
+	if (rq_param.yuv420) {
+		extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
+		rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height),
+				1) - 3;
+	}
+
+	rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
+	rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
+
+	// FIXME: take the max between luma, chroma chunk size?
+	// okay for now, as we are setting chunk_bytes to 8kb anyways
+	if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb
+		rq_regs->drq_expansion_mode = 0;
+	} else {
+		rq_regs->drq_expansion_mode = 2;
+	}
+	rq_regs->prq_expansion_mode = 1;
+	rq_regs->mrq_expansion_mode = 1;
+	rq_regs->crq_expansion_mode = 1;
+
+	if (rq_param.yuv420) {
+		if ((double) rq_param.misc.rq_l.stored_swath_bytes
+				/ (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
+			detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma
+		} else {
+			detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
+					256,
+					0) / 64.0; // 2/3 to chroma
+		}
+	}
+	rq_regs->plane1_base_address = detile_buf_plane1_addr;
+}
+
+static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+		display_rq_params_st *rq_param,
+		const display_pipe_source_params_st pipe_src_param)
+{
+	unsigned int total_swath_bytes = 0;
+	unsigned int swath_bytes_l = 0;
+	unsigned int swath_bytes_c = 0;
+	unsigned int full_swath_bytes_packed_l = 0;
+	unsigned int full_swath_bytes_packed_c = 0;
+	bool req128_l = 0;
+	bool req128_c = 0;
+	bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
+	bool surf_vert = (pipe_src_param.source_scan == dm_vert);
+	unsigned int log2_swath_height_l = 0;
+	unsigned int log2_swath_height_c = 0;
+	unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
+
+	full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes;
+	full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
+
+	if (rq_param->yuv420_10bpc) {
+		full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
+				256,
+				1) + 256;
+		full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
+				256,
+				1) + 256;
+	}
+
+	if (rq_param->yuv420) {
+		total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
+
+		if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request
+			req128_l = 0;
+			req128_c = 0;
+			swath_bytes_l = full_swath_bytes_packed_l;
+			swath_bytes_c = full_swath_bytes_packed_c;
+		} else { //128b request (for luma only for yuv420 8bpc)
+			req128_l = 1;
+			req128_c = 0;
+			swath_bytes_l = full_swath_bytes_packed_l / 2;
+			swath_bytes_c = full_swath_bytes_packed_c;
+		}
+		// Note: assumption, the config that pass in will fit into
+		//       the detiled buffer.
+	} else {
+		total_swath_bytes = 2 * full_swath_bytes_packed_l;
+
+		if (total_swath_bytes <= detile_buf_size_in_bytes)
+			req128_l = 0;
+		else
+			req128_l = 1;
+
+		swath_bytes_l = total_swath_bytes;
+		swath_bytes_c = 0;
+	}
+	rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l;
+	rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c;
+
+	if (surf_linear) {
+		log2_swath_height_l = 0;
+		log2_swath_height_c = 0;
+	} else if (!surf_vert) {
+		log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+		log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+	} else {
+		log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+		log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
+	}
+	rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+	rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+	dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l);
+	dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c);
+	dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n",
+			__func__,
+			full_swath_bytes_packed_l);
+	dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n",
+			__func__,
+			full_swath_bytes_packed_c);
+}
+
+static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
+		display_data_rq_dlg_params_st *rq_dlg_param,
+		display_data_rq_misc_params_st *rq_misc_param,
+		display_data_rq_sizing_params_st *rq_sizing_param,
+		unsigned int vp_width,
+		unsigned int vp_height,
+		unsigned int data_pitch,
+		unsigned int meta_pitch,
+		unsigned int source_format,
+		unsigned int tiling,
+		unsigned int macro_tile_size,
+		unsigned int source_scan,
+		unsigned int is_chroma)
+{
+	bool surf_linear = (tiling == dm_sw_linear);
+	bool surf_vert = (source_scan == dm_vert);
+
+	unsigned int bytes_per_element;
+	unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format),
+			false);
+	unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format),
+			true);
+
+	unsigned int blk256_width = 0;
+	unsigned int blk256_height = 0;
+
+	unsigned int blk256_width_y = 0;
+	unsigned int blk256_height_y = 0;
+	unsigned int blk256_width_c = 0;
+	unsigned int blk256_height_c = 0;
+	unsigned int log2_bytes_per_element;
+	unsigned int log2_blk256_width;
+	unsigned int log2_blk256_height;
+	unsigned int blk_bytes;
+	unsigned int log2_blk_bytes;
+	unsigned int log2_blk_height;
+	unsigned int log2_blk_width;
+	unsigned int log2_meta_req_bytes;
+	unsigned int log2_meta_req_height;
+	unsigned int log2_meta_req_width;
+	unsigned int meta_req_width;
+	unsigned int meta_req_height;
+	unsigned int log2_meta_row_height;
+	unsigned int meta_row_width_ub;
+	unsigned int log2_meta_chunk_bytes;
+	unsigned int log2_meta_chunk_height;
+
+	//full sized meta chunk width in unit of data elements
+	unsigned int log2_meta_chunk_width;
+	unsigned int log2_min_meta_chunk_bytes;
+	unsigned int min_meta_chunk_width;
+	unsigned int meta_chunk_width;
+	unsigned int meta_chunk_per_row_int;
+	unsigned int meta_row_remainder;
+	unsigned int meta_chunk_threshold;
+	unsigned int meta_blk_bytes;
+	unsigned int meta_blk_height;
+	unsigned int meta_blk_width;
+	unsigned int meta_surface_bytes;
+	unsigned int vmpg_bytes;
+	unsigned int meta_pte_req_per_frame_ub;
+	unsigned int meta_pte_bytes_per_frame_ub;
+	const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+	const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma;
+	const unsigned int pde_proc_buffer_size_64k_reqs =
+			mode_lib->ip.pde_proc_buffer_size_64k_reqs;
+
+	unsigned int log2_vmpg_height = 0;
+	unsigned int log2_vmpg_width = 0;
+	unsigned int log2_dpte_req_height_ptes = 0;
+	unsigned int log2_dpte_req_height = 0;
+	unsigned int log2_dpte_req_width = 0;
+	unsigned int log2_dpte_row_height_linear = 0;
+	unsigned int log2_dpte_row_height = 0;
+	unsigned int log2_dpte_group_width = 0;
+	unsigned int dpte_row_width_ub = 0;
+	unsigned int dpte_req_height = 0;
+	unsigned int dpte_req_width = 0;
+	unsigned int dpte_group_width = 0;
+	unsigned int log2_dpte_group_bytes = 0;
+	unsigned int log2_dpte_group_length = 0;
+	unsigned int pde_buf_entries;
+	bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10);
+
+	Calculate256BBlockSizes((enum source_format_class)(source_format),
+			(enum dm_swizzle_mode)(tiling),
+			bytes_per_element_y,
+			bytes_per_element_c,
+			&blk256_height_y,
+			&blk256_height_c,
+			&blk256_width_y,
+			&blk256_width_c);
+
+	if (!is_chroma) {
+		blk256_width = blk256_width_y;
+		blk256_height = blk256_height_y;
+		bytes_per_element = bytes_per_element_y;
+	} else {
+		blk256_width = blk256_width_c;
+		blk256_height = blk256_height_c;
+		bytes_per_element = bytes_per_element_c;
+	}
+
+	log2_bytes_per_element = dml_log2(bytes_per_element);
+
+	dml_print("DML_DLG: %s: surf_linear        = %d\n", __func__, surf_linear);
+	dml_print("DML_DLG: %s: surf_vert          = %d\n", __func__, surf_vert);
+	dml_print("DML_DLG: %s: blk256_width       = %d\n", __func__, blk256_width);
+	dml_print("DML_DLG: %s: blk256_height      = %d\n", __func__, blk256_height);
+
+	log2_blk256_width = dml_log2((double) blk256_width);
+	log2_blk256_height = dml_log2((double) blk256_height);
+	blk_bytes = surf_linear ?
+			256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
+	log2_blk_bytes = dml_log2((double) blk_bytes);
+	log2_blk_height = 0;
+	log2_blk_width = 0;
+
+	// remember log rule
+	// "+" in log is multiply
+	// "-" in log is divide
+	// "/2" is like square root
+	// blk is vertical biased
+	if (tiling != dm_sw_linear)
+		log2_blk_height = log2_blk256_height
+				+ dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
+	else
+		log2_blk_height = 0;  // blk height of 1
+
+	log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
+
+	if (!surf_vert) {
+		rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1)
+				+ blk256_width;
+		rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
+	} else {
+		rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_height - 1, blk256_height, 1)
+				+ blk256_height;
+		rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
+	}
+
+	if (!surf_vert)
+		rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height
+				* bytes_per_element;
+	else
+		rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width
+				* bytes_per_element;
+
+	rq_misc_param->blk256_height = blk256_height;
+	rq_misc_param->blk256_width = blk256_width;
+
+	// -------
+	// meta
+	// -------
+	log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
+
+	// each 64b meta request for dcn is 8x8 meta elements and
+	// a meta element covers one 256b block of the the data surface.
+	log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
+	log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
+			- log2_meta_req_height;
+	meta_req_width = 1 << log2_meta_req_width;
+	meta_req_height = 1 << log2_meta_req_height;
+	log2_meta_row_height = 0;
+	meta_row_width_ub = 0;
+
+	// the dimensions of a meta row are meta_row_width x meta_row_height in elements.
+	// calculate upper bound of the meta_row_width
+	if (!surf_vert) {
+		log2_meta_row_height = log2_meta_req_height;
+		meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1)
+				+ meta_req_width;
+		rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width;
+	} else {
+		log2_meta_row_height = log2_meta_req_width;
+		meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1)
+				+ meta_req_height;
+		rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height;
+	}
+	rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
+
+	rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
+
+	log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
+	log2_meta_chunk_height = log2_meta_row_height;
+
+	//full sized meta chunk width in unit of data elements
+	log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element
+			- log2_meta_chunk_height;
+	log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
+	min_meta_chunk_width = 1
+			<< (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element
+					- log2_meta_chunk_height);
+	meta_chunk_width = 1 << log2_meta_chunk_width;
+	meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width);
+	meta_row_remainder = meta_row_width_ub % meta_chunk_width;
+	meta_chunk_threshold = 0;
+	meta_blk_bytes = 4096;
+	meta_blk_height = blk256_height * 64;
+	meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height;
+	meta_surface_bytes = meta_pitch
+			* (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height)
+			* bytes_per_element / 256;
+	vmpg_bytes = mode_lib->soc.vmm_page_size_bytes;
+	meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes,
+			8 * vmpg_bytes,
+			1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
+	meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request
+	rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
+
+	dml_print("DML_DLG: %s: meta_blk_height             = %d\n", __func__, meta_blk_height);
+	dml_print("DML_DLG: %s: meta_blk_width              = %d\n", __func__, meta_blk_width);
+	dml_print("DML_DLG: %s: meta_surface_bytes          = %d\n", __func__, meta_surface_bytes);
+	dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub   = %d\n",
+			__func__,
+			meta_pte_req_per_frame_ub);
+	dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n",
+			__func__,
+			meta_pte_bytes_per_frame_ub);
+
+	if (!surf_vert)
+		meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
+	else
+		meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height;
+
+	if (meta_row_remainder <= meta_chunk_threshold)
+		rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
+	else
+		rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
+
+	// ------
+	// dpte
+	// ------
+	if (surf_linear) {
+		log2_vmpg_height = 0;   // one line high
+	} else {
+		log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
+	}
+	log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
+
+	// only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4.
+	if (surf_linear) { //one 64B PTE request returns 8 PTEs
+		log2_dpte_req_height_ptes = 0;
+		log2_dpte_req_width = log2_vmpg_width + 3;
+		log2_dpte_req_height = 0;
+	} else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size
+		//one 64B req gives 8x1 PTEs for 4KB tile
+		log2_dpte_req_height_ptes = 0;
+		log2_dpte_req_width = log2_blk_width + 3;
+		log2_dpte_req_height = log2_blk_height + 0;
+	} else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB
+		//two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB
+		log2_dpte_req_height_ptes = 4;
+		log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width
+		log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height
+	} else { //64KB page size and must 64KB tile block
+		 //one 64B req gives 8x1 PTEs for 64KB tile
+		log2_dpte_req_height_ptes = 0;
+		log2_dpte_req_width = log2_blk_width + 3;
+		log2_dpte_req_height = log2_blk_height + 0;
+	}
+
+	// The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
+	// log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
+	// That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
+	//log2_dpte_req_height    = log2_vmpg_height + log2_dpte_req_height_ptes;
+	//log2_dpte_req_width     = log2_vmpg_width + log2_dpte_req_width_ptes;
+	dpte_req_height = 1 << log2_dpte_req_height;
+	dpte_req_width = 1 << log2_dpte_req_width;
+
+	// calculate pitch dpte row buffer can hold
+	// round the result down to a power of two.
+	pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs;
+	if (surf_linear) {
+		unsigned int dpte_row_height;
+
+		log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries
+										/ bytes_per_element,
+								dpte_buf_in_pte_reqs
+										* dpte_req_width)
+								/ data_pitch),
+				1);
+
+		ASSERT(log2_dpte_row_height_linear >= 3);
+
+		if (log2_dpte_row_height_linear > 7)
+			log2_dpte_row_height_linear = 7;
+
+		log2_dpte_row_height = log2_dpte_row_height_linear;
+		// For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
+		// the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
+		dpte_row_height = 1 << log2_dpte_row_height;
+		dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1,
+				dpte_req_width,
+				1) + dpte_req_width;
+		rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
+	} else {
+		// the upper bound of the dpte_row_width without dependency on viewport position follows.
+		// for tiled mode, row height is the same as req height and row store up to vp size upper bound
+		if (!surf_vert) {
+			log2_dpte_row_height = log2_dpte_req_height;
+			dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1)
+					+ dpte_req_width;
+			rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
+		} else {
+			log2_dpte_row_height =
+					(log2_blk_width < log2_dpte_req_width) ?
+							log2_blk_width : log2_dpte_req_width;
+			dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1)
+					+ dpte_req_height;
+			rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
+		}
+	}
+	if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB
+		rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request
+	else
+		rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request
+
+	rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
+
+	// the dpte_group_bytes is reduced for the specific case of vertical
+	// access of a tile surface that has dpte request of 8x1 ptes.
+	if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group
+		rq_sizing_param->dpte_group_bytes = 512;
+	else
+		//full size
+		rq_sizing_param->dpte_group_bytes = 2048;
+
+	//since pte request size is 64byte, the number of data pte requests per full sized group is as follows.
+	log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
+	log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests
+
+	// full sized data pte group width in elements
+	if (!surf_vert)
+		log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
+	else
+		log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
+
+	//But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B
+	if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB
+		log2_dpte_group_width = log2_dpte_group_width - 1;
+
+	dpte_group_width = 1 << log2_dpte_group_width;
+
+	// since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
+	// the upper bound for the dpte groups per row is as follows.
+	rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width,
+			1);
+}
+
+static void get_surf_rq_param(struct display_mode_lib *mode_lib,
+		display_data_rq_sizing_params_st *rq_sizing_param,
+		display_data_rq_dlg_params_st *rq_dlg_param,
+		display_data_rq_misc_params_st *rq_misc_param,
+		const display_pipe_source_params_st pipe_src_param,
+		bool is_chroma)
+{
+	bool mode_422 = 0;
+	unsigned int vp_width = 0;
+	unsigned int vp_height = 0;
+	unsigned int data_pitch = 0;
+	unsigned int meta_pitch = 0;
+	unsigned int ppe = mode_422 ? 2 : 1;
+
+	// FIXME check if ppe apply for both luma and chroma in 422 case
+	if (is_chroma) {
+		vp_width = pipe_src_param.viewport_width_c / ppe;
+		vp_height = pipe_src_param.viewport_height_c;
+		data_pitch = pipe_src_param.data_pitch_c;
+		meta_pitch = pipe_src_param.meta_pitch_c;
+	} else {
+		vp_width = pipe_src_param.viewport_width / ppe;
+		vp_height = pipe_src_param.viewport_height;
+		data_pitch = pipe_src_param.data_pitch;
+		meta_pitch = pipe_src_param.meta_pitch;
+	}
+
+	rq_sizing_param->chunk_bytes = 8192;
+
+	if (rq_sizing_param->chunk_bytes == 64 * 1024)
+		rq_sizing_param->min_chunk_bytes = 0;
+	else
+		rq_sizing_param->min_chunk_bytes = 1024;
+
+	rq_sizing_param->meta_chunk_bytes = 2048;
+	rq_sizing_param->min_meta_chunk_bytes = 256;
+
+	rq_sizing_param->mpte_group_bytes = 2048;
+
+	get_meta_and_pte_attr(mode_lib,
+			rq_dlg_param,
+			rq_misc_param,
+			rq_sizing_param,
+			vp_width,
+			vp_height,
+			data_pitch,
+			meta_pitch,
+			pipe_src_param.source_format,
+			pipe_src_param.sw_mode,
+			pipe_src_param.macro_tile_size,
+			pipe_src_param.source_scan,
+			is_chroma);
+}
+
+static void dml20v2_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
+		display_rq_params_st *rq_param,
+		const display_pipe_source_params_st pipe_src_param)
+{
+	// get param for luma surface
+	rq_param->yuv420 = pipe_src_param.source_format == dm_420_8
+			|| pipe_src_param.source_format == dm_420_10;
+	rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10;
+
+	get_surf_rq_param(mode_lib,
+			&(rq_param->sizing.rq_l),
+			&(rq_param->dlg.rq_l),
+			&(rq_param->misc.rq_l),
+			pipe_src_param,
+			0);
+
+	if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) {
+		// get param for chroma surface
+		get_surf_rq_param(mode_lib,
+				&(rq_param->sizing.rq_c),
+				&(rq_param->dlg.rq_c),
+				&(rq_param->misc.rq_c),
+				pipe_src_param,
+				1);
+	}
+
+	// calculate how to split the det buffer space between luma and chroma
+	handle_det_buf_split(mode_lib, rq_param, pipe_src_param);
+	print__rq_params_st(mode_lib, *rq_param);
+}
+
+void dml20v2_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
+		display_rq_regs_st *rq_regs,
+		const display_pipe_params_st pipe_param)
+{
+	display_rq_params_st rq_param = {0};
+
+	memset(rq_regs, 0, sizeof(*rq_regs));
+	dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src);
+	extract_rq_regs(mode_lib, rq_regs, rq_param);
+
+	print__rq_regs_st(mode_lib, *rq_regs);
+}
+
+// Note: currently taken in as is.
+// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
+static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
+		display_dlg_regs_st *disp_dlg_regs,
+		display_ttu_regs_st *disp_ttu_regs,
+		const display_rq_dlg_params_st rq_dlg_param,
+		const display_dlg_sys_params_st dlg_sys_param,
+		const bool cstate_en,
+		const bool pstate_en)
+{
+	const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
+	const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
+	const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout;
+	const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
+	const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth;
+	const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps;
+
+	// -------------------------
+	// Section 1.15.2.1: OTG dependent Params
+	// -------------------------
+	// Timing
+	unsigned int htotal = dst->htotal;
+//    unsigned int hblank_start = dst.hblank_start; // TODO: Remove
+	unsigned int hblank_end = dst->hblank_end;
+	unsigned int vblank_start = dst->vblank_start;
+	unsigned int vblank_end = dst->vblank_end;
+	unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
+
+	double dppclk_freq_in_mhz = clks->dppclk_mhz;
+	double dispclk_freq_in_mhz = clks->dispclk_mhz;
+	double refclk_freq_in_mhz = clks->refclk_mhz;
+	double pclk_freq_in_mhz = dst->pixel_rate_mhz;
+	bool interlaced = dst->interlaced;
+
+	double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
+
+	double min_dcfclk_mhz;
+	double t_calc_us;
+	double min_ttu_vblank;
+
+	double min_dst_y_ttu_vblank;
+	unsigned int dlg_vblank_start;
+	bool dual_plane;
+	bool mode_422;
+	unsigned int access_dir;
+	unsigned int vp_height_l;
+	unsigned int vp_width_l;
+	unsigned int vp_height_c;
+	unsigned int vp_width_c;
+
+	// Scaling
+	unsigned int htaps_l;
+	unsigned int htaps_c;
+	double hratio_l;
+	double hratio_c;
+	double vratio_l;
+	double vratio_c;
+	bool scl_enable;
+
+	double line_time_in_us;
+	//    double vinit_l;
+	//    double vinit_c;
+	//    double vinit_bot_l;
+	//    double vinit_bot_c;
+
+	//    unsigned int swath_height_l;
+	unsigned int swath_width_ub_l;
+	//    unsigned int dpte_bytes_per_row_ub_l;
+	unsigned int dpte_groups_per_row_ub_l;
+	//    unsigned int meta_pte_bytes_per_frame_ub_l;
+	//    unsigned int meta_bytes_per_row_ub_l;
+
+	//    unsigned int swath_height_c;
+	unsigned int swath_width_ub_c;
+	//   unsigned int dpte_bytes_per_row_ub_c;
+	unsigned int dpte_groups_per_row_ub_c;
+
+	unsigned int meta_chunks_per_row_ub_l;
+	unsigned int meta_chunks_per_row_ub_c;
+	unsigned int vupdate_offset;
+	unsigned int vupdate_width;
+	unsigned int vready_offset;
+
+	unsigned int dppclk_delay_subtotal;
+	unsigned int dispclk_delay_subtotal;
+	unsigned int pixel_rate_delay_subtotal;
+
+	unsigned int vstartup_start;
+	unsigned int dst_x_after_scaler;
+	unsigned int dst_y_after_scaler;
+	double line_wait;
+	double dst_y_prefetch;
+	double dst_y_per_vm_vblank;
+	double dst_y_per_row_vblank;
+	double dst_y_per_vm_flip;
+	double dst_y_per_row_flip;
+	double min_dst_y_per_vm_vblank;
+	double min_dst_y_per_row_vblank;
+	double lsw;
+	double vratio_pre_l;
+	double vratio_pre_c;
+	unsigned int req_per_swath_ub_l;
+	unsigned int req_per_swath_ub_c;
+	unsigned int meta_row_height_l;
+	unsigned int meta_row_height_c;
+	unsigned int swath_width_pixels_ub_l;
+	unsigned int swath_width_pixels_ub_c;
+	unsigned int scaler_rec_in_width_l;
+	unsigned int scaler_rec_in_width_c;
+	unsigned int dpte_row_height_l;
+	unsigned int dpte_row_height_c;
+	double hscale_pixel_rate_l;
+	double hscale_pixel_rate_c;
+	double min_hratio_fact_l;
+	double min_hratio_fact_c;
+	double refcyc_per_line_delivery_pre_l;
+	double refcyc_per_line_delivery_pre_c;
+	double refcyc_per_line_delivery_l;
+	double refcyc_per_line_delivery_c;
+
+	double refcyc_per_req_delivery_pre_l;
+	double refcyc_per_req_delivery_pre_c;
+	double refcyc_per_req_delivery_l;
+	double refcyc_per_req_delivery_c;
+
+	unsigned int full_recout_width;
+	double xfc_transfer_delay;
+	double xfc_precharge_delay;
+	double xfc_remote_surface_flip_latency;
+	double xfc_dst_y_delta_drq_limit;
+	double xfc_prefetch_margin;
+	double refcyc_per_req_delivery_pre_cur0;
+	double refcyc_per_req_delivery_cur0;
+	double refcyc_per_req_delivery_pre_cur1;
+	double refcyc_per_req_delivery_cur1;
+
+	memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
+	memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
+
+	dml_print("DML_DLG: %s:  cstate_en = %d\n", __func__, cstate_en);
+	dml_print("DML_DLG: %s:  pstate_en = %d\n", __func__, pstate_en);
+
+	dml_print("DML_DLG: %s: dppclk_freq_in_mhz     = %3.2f\n", __func__, dppclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: dispclk_freq_in_mhz    = %3.2f\n", __func__, dispclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: refclk_freq_in_mhz     = %3.2f\n", __func__, refclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: pclk_freq_in_mhz       = %3.2f\n", __func__, pclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: interlaced             = %d\n", __func__, interlaced);
+	ASSERT(ref_freq_to_pix_freq < 4.0);
+
+	disp_dlg_regs->ref_freq_to_pix_freq =
+			(unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
+	disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal
+			* dml_pow(2, 8));
+	disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits
+	disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end
+			* (double) ref_freq_to_pix_freq);
+	ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13));
+
+	min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
+	t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes);
+	min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+	min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal;
+	dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
+
+	disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start
+			+ min_dst_y_ttu_vblank) * dml_pow(2, 2));
+	ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18));
+
+	dml_print("DML_DLG: %s: min_dcfclk_mhz                         = %3.2f\n",
+			__func__,
+			min_dcfclk_mhz);
+	dml_print("DML_DLG: %s: min_ttu_vblank                         = %3.2f\n",
+			__func__,
+			min_ttu_vblank);
+	dml_print("DML_DLG: %s: min_dst_y_ttu_vblank                   = %3.2f\n",
+			__func__,
+			min_dst_y_ttu_vblank);
+	dml_print("DML_DLG: %s: t_calc_us                              = %3.2f\n",
+			__func__,
+			t_calc_us);
+	dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start    = 0x%0x\n",
+			__func__,
+			disp_dlg_regs->min_dst_y_next_start);
+	dml_print("DML_DLG: %s: ref_freq_to_pix_freq                   = %3.2f\n",
+			__func__,
+			ref_freq_to_pix_freq);
+
+	// -------------------------
+	// Section 1.15.2.2: Prefetch, Active and TTU
+	// -------------------------
+	// Prefetch Calc
+	// Source
+//             dcc_en              = src.dcc;
+	dual_plane = is_dual_plane((enum source_format_class)(src->source_format));
+	mode_422 = 0; // FIXME
+	access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
+//      bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0);
+//      bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1);
+	vp_height_l = src->viewport_height;
+	vp_width_l = src->viewport_width;
+	vp_height_c = src->viewport_height_c;
+	vp_width_c = src->viewport_width_c;
+
+	// Scaling
+	htaps_l = taps->htaps;
+	htaps_c = taps->htaps_c;
+	hratio_l = scl->hscl_ratio;
+	hratio_c = scl->hscl_ratio_c;
+	vratio_l = scl->vscl_ratio;
+	vratio_c = scl->vscl_ratio_c;
+	scl_enable = scl->scl_enable;
+
+	line_time_in_us = (htotal / pclk_freq_in_mhz);
+//     vinit_l         = scl.vinit;
+//     vinit_c         = scl.vinit_c;
+//     vinit_bot_l     = scl.vinit_bot;
+//     vinit_bot_c     = scl.vinit_bot_c;
+
+//    unsigned int swath_height_l                 = rq_dlg_param.rq_l.swath_height;
+	swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
+//    unsigned int dpte_bytes_per_row_ub_l        = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
+	dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
+//    unsigned int meta_pte_bytes_per_frame_ub_l  = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
+//    unsigned int meta_bytes_per_row_ub_l        = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
+
+//    unsigned int swath_height_c                 = rq_dlg_param.rq_c.swath_height;
+	swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
+	//   dpte_bytes_per_row_ub_c        = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
+	dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
+
+	meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
+	meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub;
+	vupdate_offset = dst->vupdate_offset;
+	vupdate_width = dst->vupdate_width;
+	vready_offset = dst->vready_offset;
+
+	dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
+	dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
+
+	if (scl_enable)
+		dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl;
+	else
+		dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only;
+
+	dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter
+			+ src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor;
+
+	if (dout->dsc_enable) {
+		double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+		dispclk_delay_subtotal += dsc_delay;
+	}
+
+	pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
+			+ dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
+
+	vstartup_start = dst->vstartup_start;
+	if (interlaced) {
+		if (vstartup_start / 2.0
+				- (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
+				<= vblank_end / 2.0)
+			disp_dlg_regs->vready_after_vcount0 = 1;
+		else
+			disp_dlg_regs->vready_after_vcount0 = 0;
+	} else {
+		if (vstartup_start
+				- (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
+				<= vblank_end)
+			disp_dlg_regs->vready_after_vcount0 = 1;
+		else
+			disp_dlg_regs->vready_after_vcount0 = 0;
+	}
+
+	// TODO: Where is this coming from?
+	if (interlaced)
+		vstartup_start = vstartup_start / 2;
+
+	// TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp?
+	if (vstartup_start >= min_vblank) {
+		dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n",
+				__func__,
+				vblank_start,
+				vblank_end);
+		dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
+				__func__,
+				vstartup_start,
+				min_vblank);
+		min_vblank = vstartup_start + 1;
+		dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
+				__func__,
+				vstartup_start,
+				min_vblank);
+	}
+
+	dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+	dml_print("DML_DLG: %s: htotal                                 = %d\n", __func__, htotal);
+	dml_print("DML_DLG: %s: pixel_rate_delay_subtotal              = %d\n",
+			__func__,
+			pixel_rate_delay_subtotal);
+	dml_print("DML_DLG: %s: dst_x_after_scaler                     = %d\n",
+			__func__,
+			dst_x_after_scaler);
+	dml_print("DML_DLG: %s: dst_y_after_scaler                     = %d\n",
+			__func__,
+			dst_y_after_scaler);
+
+	// Lwait
+	line_wait = mode_lib->soc.urgent_latency_us;
+	if (cstate_en)
+		line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
+	if (pstate_en)
+		line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us
+						+ mode_lib->soc.urgent_latency_us,
+				line_wait);
+	line_wait = line_wait / line_time_in_us;
+
+	dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
+
+	dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+	min_dst_y_per_vm_vblank = 8.0;
+	min_dst_y_per_row_vblank = 16.0;
+
+	// magic!
+	if (htotal <= 75) {
+		min_vblank = 300;
+		min_dst_y_per_vm_vblank = 100.0;
+		min_dst_y_per_row_vblank = 100.0;
+	}
+
+	dml_print("DML_DLG: %s: dst_y_per_vm_vblank    = %3.2f\n", __func__, dst_y_per_vm_vblank);
+	dml_print("DML_DLG: %s: dst_y_per_row_vblank   = %3.2f\n", __func__, dst_y_per_row_vblank);
+
+	ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
+	ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
+
+	ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
+	lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
+
+	dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw);
+
+	vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+	dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l);
+	dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c);
+
+	// Active
+	req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
+	req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
+	meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
+	meta_row_height_c = rq_dlg_param.rq_c.meta_row_height;
+	swath_width_pixels_ub_l = 0;
+	swath_width_pixels_ub_c = 0;
+	scaler_rec_in_width_l = 0;
+	scaler_rec_in_width_c = 0;
+	dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
+	dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
+
+	if (mode_422) {
+		swath_width_pixels_ub_l = swath_width_ub_l * 2;  // *2 for 2 pixel per element
+		swath_width_pixels_ub_c = swath_width_ub_c * 2;
+	} else {
+		swath_width_pixels_ub_l = swath_width_ub_l * 1;
+		swath_width_pixels_ub_c = swath_width_ub_c * 1;
+	}
+
+	hscale_pixel_rate_l = 0.;
+	hscale_pixel_rate_c = 0.;
+	min_hratio_fact_l = 1.0;
+	min_hratio_fact_c = 1.0;
+
+	if (htaps_l <= 1)
+		min_hratio_fact_l = 2.0;
+	else if (htaps_l <= 6) {
+		if ((hratio_l * 2.0) > 4.0)
+			min_hratio_fact_l = 4.0;
+		else
+			min_hratio_fact_l = hratio_l * 2.0;
+	} else {
+		if (hratio_l > 4.0)
+			min_hratio_fact_l = 4.0;
+		else
+			min_hratio_fact_l = hratio_l;
+	}
+
+	hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
+
+	if (htaps_c <= 1)
+		min_hratio_fact_c = 2.0;
+	else if (htaps_c <= 6) {
+		if ((hratio_c * 2.0) > 4.0)
+			min_hratio_fact_c = 4.0;
+		else
+			min_hratio_fact_c = hratio_c * 2.0;
+	} else {
+		if (hratio_c > 4.0)
+			min_hratio_fact_c = 4.0;
+		else
+			min_hratio_fact_c = hratio_c;
+	}
+
+	hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
+
+	refcyc_per_line_delivery_pre_l = 0.;
+	refcyc_per_line_delivery_pre_c = 0.;
+	refcyc_per_line_delivery_l = 0.;
+	refcyc_per_line_delivery_c = 0.;
+
+	refcyc_per_req_delivery_pre_l = 0.;
+	refcyc_per_req_delivery_pre_c = 0.;
+	refcyc_per_req_delivery_l = 0.;
+	refcyc_per_req_delivery_c = 0.;
+
+	full_recout_width = 0;
+	// In ODM
+	if (src->is_hsplit) {
+		// This "hack"  is only allowed (and valid) for MPC combine. In ODM
+		// combine, you MUST specify the full_recout_width...according to Oswin
+		if (dst->full_recout_width == 0 && !dst->odm_combine) {
+			dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n",
+					__func__);
+			full_recout_width = dst->recout_width * 2; // assume half split for dcn1
+		} else
+			full_recout_width = dst->full_recout_width;
+	} else
+		full_recout_width = dst->recout_width;
+
+	// As of DCN2, mpc_combine and odm_combine are mutually exclusive
+	refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
+			refclk_freq_in_mhz,
+			pclk_freq_in_mhz,
+			dst->odm_combine,
+			full_recout_width,
+			dst->hactive,
+			vratio_pre_l,
+			hscale_pixel_rate_l,
+			swath_width_pixels_ub_l,
+			1); // per line
+
+	refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib,
+			refclk_freq_in_mhz,
+			pclk_freq_in_mhz,
+			dst->odm_combine,
+			full_recout_width,
+			dst->hactive,
+			vratio_l,
+			hscale_pixel_rate_l,
+			swath_width_pixels_ub_l,
+			1); // per line
+
+	dml_print("DML_DLG: %s: full_recout_width              = %d\n",
+			__func__,
+			full_recout_width);
+	dml_print("DML_DLG: %s: hscale_pixel_rate_l            = %3.2f\n",
+			__func__,
+			hscale_pixel_rate_l);
+	dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n",
+			__func__,
+			refcyc_per_line_delivery_pre_l);
+	dml_print("DML_DLG: %s: refcyc_per_line_delivery_l     = %3.2f\n",
+			__func__,
+			refcyc_per_line_delivery_l);
+
+	if (dual_plane) {
+		refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
+				refclk_freq_in_mhz,
+				pclk_freq_in_mhz,
+				dst->odm_combine,
+				full_recout_width,
+				dst->hactive,
+				vratio_pre_c,
+				hscale_pixel_rate_c,
+				swath_width_pixels_ub_c,
+				1); // per line
+
+		refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib,
+				refclk_freq_in_mhz,
+				pclk_freq_in_mhz,
+				dst->odm_combine,
+				full_recout_width,
+				dst->hactive,
+				vratio_c,
+				hscale_pixel_rate_c,
+				swath_width_pixels_ub_c,
+				1);  // per line
+
+		dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n",
+				__func__,
+				refcyc_per_line_delivery_pre_c);
+		dml_print("DML_DLG: %s: refcyc_per_line_delivery_c     = %3.2f\n",
+				__func__,
+				refcyc_per_line_delivery_c);
+	}
+
+	// TTU - Luma / Chroma
+	if (access_dir) {  // vertical access
+		scaler_rec_in_width_l = vp_height_l;
+		scaler_rec_in_width_c = vp_height_c;
+	} else {
+		scaler_rec_in_width_l = vp_width_l;
+		scaler_rec_in_width_c = vp_width_c;
+	}
+
+	refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
+			refclk_freq_in_mhz,
+			pclk_freq_in_mhz,
+			dst->odm_combine,
+			full_recout_width,
+			dst->hactive,
+			vratio_pre_l,
+			hscale_pixel_rate_l,
+			scaler_rec_in_width_l,
+			req_per_swath_ub_l);  // per req
+	refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib,
+			refclk_freq_in_mhz,
+			pclk_freq_in_mhz,
+			dst->odm_combine,
+			full_recout_width,
+			dst->hactive,
+			vratio_l,
+			hscale_pixel_rate_l,
+			scaler_rec_in_width_l,
+			req_per_swath_ub_l);  // per req
+
+	dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n",
+			__func__,
+			refcyc_per_req_delivery_pre_l);
+	dml_print("DML_DLG: %s: refcyc_per_req_delivery_l     = %3.2f\n",
+			__func__,
+			refcyc_per_req_delivery_l);
+
+	ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
+	ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
+
+	if (dual_plane) {
+		refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
+				refclk_freq_in_mhz,
+				pclk_freq_in_mhz,
+				dst->odm_combine,
+				full_recout_width,
+				dst->hactive,
+				vratio_pre_c,
+				hscale_pixel_rate_c,
+				scaler_rec_in_width_c,
+				req_per_swath_ub_c);  // per req
+		refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib,
+				refclk_freq_in_mhz,
+				pclk_freq_in_mhz,
+				dst->odm_combine,
+				full_recout_width,
+				dst->hactive,
+				vratio_c,
+				hscale_pixel_rate_c,
+				scaler_rec_in_width_c,
+				req_per_swath_ub_c);  // per req
+
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n",
+				__func__,
+				refcyc_per_req_delivery_pre_c);
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_c     = %3.2f\n",
+				__func__,
+				refcyc_per_req_delivery_c);
+
+		ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
+		ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
+	}
+
+	// XFC
+	xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	xfc_precharge_delay = get_xfc_precharge_delay(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency;
+	xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+
+	// TTU - Cursor
+	refcyc_per_req_delivery_pre_cur0 = 0.0;
+	refcyc_per_req_delivery_cur0 = 0.0;
+	if (src->num_cursors > 0) {
+		calculate_ttu_cursor(mode_lib,
+				&refcyc_per_req_delivery_pre_cur0,
+				&refcyc_per_req_delivery_cur0,
+				refclk_freq_in_mhz,
+				ref_freq_to_pix_freq,
+				hscale_pixel_rate_l,
+				scl->hscl_ratio,
+				vratio_pre_l,
+				vratio_l,
+				src->cur0_src_width,
+				(enum cursor_bpp)(src->cur0_bpp));
+	}
+
+	refcyc_per_req_delivery_pre_cur1 = 0.0;
+	refcyc_per_req_delivery_cur1 = 0.0;
+	if (src->num_cursors > 1) {
+		calculate_ttu_cursor(mode_lib,
+				&refcyc_per_req_delivery_pre_cur1,
+				&refcyc_per_req_delivery_cur1,
+				refclk_freq_in_mhz,
+				ref_freq_to_pix_freq,
+				hscale_pixel_rate_l,
+				scl->hscl_ratio,
+				vratio_pre_l,
+				vratio_l,
+				src->cur1_src_width,
+				(enum cursor_bpp)(src->cur1_bpp));
+	}
+
+	// TTU - Misc
+	// all hard-coded
+
+	// Assignment to register structures
+	disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
+	disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk
+	ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
+	disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
+
+	disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
+	disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
+
+	disp_dlg_regs->refcyc_per_pte_group_vblank_l =
+			(unsigned int) (dst_y_per_row_vblank * (double) htotal
+					* ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
+	ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
+
+	if (dual_plane) {
+		disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank
+				* (double) htotal * ref_freq_to_pix_freq
+				/ (double) dpte_groups_per_row_ub_c);
+		ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c
+						< (unsigned int) dml_pow(2, 13));
+	}
+
+	disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
+			(unsigned int) (dst_y_per_row_vblank * (double) htotal
+					* ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
+	ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
+
+	disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
+			disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0.  assigned to be the same as _l for now
+
+	disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
+			* ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l;
+	disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
+			* ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l;
+
+	if (dual_plane) {
+		disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip
+				* htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c;
+		disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip
+				* htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c;
+	}
+
+	disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
+			/ (double) vratio_l * dml_pow(2, 2));
+	ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
+
+	if (dual_plane) {
+		disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
+				/ (double) vratio_c * dml_pow(2, 2));
+		if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
+			dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n",
+					__func__,
+					disp_dlg_regs->dst_y_per_pte_row_nom_c,
+					(unsigned int) dml_pow(2, 17) - 1);
+		}
+	}
+
+	disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
+			/ (double) vratio_l * dml_pow(2, 2));
+	ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
+
+	disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0.  assigned to be the same as _l for now
+
+	disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
+			/ (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+			/ (double) dpte_groups_per_row_ub_l);
+	if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
+		disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
+	disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
+			/ (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+			/ (double) meta_chunks_per_row_ub_l);
+	if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
+		disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
+
+	if (dual_plane) {
+		disp_dlg_regs->refcyc_per_pte_group_nom_c =
+				(unsigned int) ((double) dpte_row_height_c / (double) vratio_c
+						* (double) htotal * ref_freq_to_pix_freq
+						/ (double) dpte_groups_per_row_ub_c);
+		if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
+			disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
+
+		// TODO: Is this the right calculation? Does htotal need to be halved?
+		disp_dlg_regs->refcyc_per_meta_chunk_nom_c =
+				(unsigned int) ((double) meta_row_height_c / (double) vratio_c
+						* (double) htotal * ref_freq_to_pix_freq
+						/ (double) meta_chunks_per_row_ub_c);
+		if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
+			disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1;
+	}
+
+	disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l,
+			1);
+	disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l,
+			1);
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
+
+	disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c,
+			1);
+	disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c,
+			1);
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
+
+	disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
+	disp_dlg_regs->dst_y_offset_cur0 = 0;
+	disp_dlg_regs->chunk_hdl_adjust_cur1 = 3;
+	disp_dlg_regs->dst_y_offset_cur1 = 0;
+
+	disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay;
+	disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay;
+	disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency;
+	disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz,
+			1);
+
+	// slave has to have this value also set to off
+	if (src->xfc_enable && !src->xfc_slave)
+		disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1);
+	else
+		disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
+
+	disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
+			(unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 =
+			(unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1
+			* dml_pow(2, 10));
+	disp_ttu_regs->qos_level_low_wm = 0;
+	ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
+	disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
+			* ref_freq_to_pix_freq);
+	/*ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14));*/
+
+	disp_ttu_regs->qos_level_flip = 14;
+	disp_ttu_regs->qos_level_fixed_l = 8;
+	disp_ttu_regs->qos_level_fixed_c = 8;
+	disp_ttu_regs->qos_level_fixed_cur0 = 8;
+	disp_ttu_regs->qos_ramp_disable_l = 0;
+	disp_ttu_regs->qos_ramp_disable_c = 0;
+	disp_ttu_regs->qos_ramp_disable_cur0 = 0;
+
+	disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz;
+	ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24));
+
+	print__ttu_regs_st(mode_lib, *disp_ttu_regs);
+	print__dlg_regs_st(mode_lib, *disp_dlg_regs);
+}
+
+void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
+		display_dlg_regs_st *dlg_regs,
+		display_ttu_regs_st *ttu_regs,
+		display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
+		const bool cstate_en,
+		const bool pstate_en,
+		const bool vm_en,
+		const bool ignore_viewport_pos,
+		const bool immediate_flip_support)
+{
+	display_rq_params_st rq_param = {0};
+	display_dlg_sys_params_st dlg_sys_param = {0};
+
+	// Get watermark and Tex.
+	dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib,
+			e2e_pipe_param,
+			num_pipes);
+	dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib,
+			e2e_pipe_param,
+			num_pipes);
+	dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
+			e2e_pipe_param,
+			num_pipes);
+	dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
+			/ dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
+
+	print__dlg_sys_params_st(mode_lib, dlg_sys_param);
+
+	// system parameter calculation done
+
+	dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
+	dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src);
+	dml20v2_rq_dlg_get_dlg_params(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx,
+			dlg_regs,
+			ttu_regs,
+			rq_param.dlg,
+			dlg_sys_param,
+			cstate_en,
+			pstate_en);
+	dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx);
+}
+
+static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+		double *refcyc_per_req_delivery_pre_cur,
+		double *refcyc_per_req_delivery_cur,
+		double refclk_freq_in_mhz,
+		double ref_freq_to_pix_freq,
+		double hscale_pixel_rate_l,
+		double hscl_ratio,
+		double vratio_pre_l,
+		double vratio_l,
+		unsigned int cur_width,
+		enum cursor_bpp cur_bpp)
+{
+	unsigned int cur_src_width = cur_width;
+	unsigned int cur_req_size = 0;
+	unsigned int cur_req_width = 0;
+	double cur_width_ub = 0.0;
+	double cur_req_per_width = 0.0;
+	double hactive_cur = 0.0;
+
+	ASSERT(cur_src_width <= 256);
+
+	*refcyc_per_req_delivery_pre_cur = 0.0;
+	*refcyc_per_req_delivery_cur = 0.0;
+	if (cur_src_width > 0) {
+		unsigned int cur_bit_per_pixel = 0;
+
+		if (cur_bpp == dm_cur_2bit) {
+			cur_req_size = 64; // byte
+			cur_bit_per_pixel = 2;
+		} else { // 32bit
+			cur_bit_per_pixel = 32;
+			if (cur_src_width >= 1 && cur_src_width <= 16)
+				cur_req_size = 64;
+			else if (cur_src_width >= 17 && cur_src_width <= 31)
+				cur_req_size = 128;
+			else
+				cur_req_size = 256;
+		}
+
+		cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0);
+		cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1)
+				* (double) cur_req_width;
+		cur_req_per_width = cur_width_ub / (double) cur_req_width;
+		hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor
+
+		if (vratio_pre_l <= 1.0) {
+			*refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq
+					/ (double) cur_req_per_width;
+		} else {
+			*refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz
+					* (double) cur_src_width / hscale_pixel_rate_l
+					/ (double) cur_req_per_width;
+		}
+
+		ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13));
+
+		if (vratio_l <= 1.0) {
+			*refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq
+					/ (double) cur_req_per_width;
+		} else {
+			*refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz
+					* (double) cur_src_width / hscale_pixel_rate_l
+					/ (double) cur_req_per_width;
+		}
+
+		dml_print("DML_DLG: %s: cur_req_width                     = %d\n",
+				__func__,
+				cur_req_width);
+		dml_print("DML_DLG: %s: cur_width_ub                      = %3.2f\n",
+				__func__,
+				cur_width_ub);
+		dml_print("DML_DLG: %s: cur_req_per_width                 = %3.2f\n",
+				__func__,
+				cur_req_per_width);
+		dml_print("DML_DLG: %s: hactive_cur                       = %3.2f\n",
+				__func__,
+				hactive_cur);
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur   = %3.2f\n",
+				__func__,
+				*refcyc_per_req_delivery_pre_cur);
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur       = %3.2f\n",
+				__func__,
+				*refcyc_per_req_delivery_cur);
+
+		ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
+	}
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h
new file mode 100644
index 000000000000..0378406bf7e7
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2018 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 __DML20V2_DISPLAY_RQ_DLG_CALC_H__
+#define __DML20V2_DISPLAY_RQ_DLG_CALC_H__
+
+#include "../dml_common_defs.h"
+#include "../display_rq_dlg_helpers.h"
+
+struct display_mode_lib;
+
+
+// Function: dml_rq_dlg_get_rq_reg
+//  Main entry point for test to get the register values out of this DML class.
+//  This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
+//  and then populate the rq_regs struct
+// Input:
+//  pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+// Output:
+//  rq_regs - struct that holds all the RQ registers field value.
+//            See also: <display_rq_regs_st>
+void dml20v2_rq_dlg_get_rq_reg(
+		struct display_mode_lib *mode_lib,
+		display_rq_regs_st *rq_regs,
+		const display_pipe_params_st pipe_param);
+
+
+// Function: dml_rq_dlg_get_dlg_reg
+//   Calculate and return DLG and TTU register struct given the system setting
+// Output:
+//  dlg_regs - output DLG register struct
+//  ttu_regs - output DLG TTU register struct
+// Input:
+//  e2e_pipe_param - "compacted" array of e2e pipe param struct
+//  num_pipes - num of active "pipe" or "route"
+//  pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
+//  cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
+//           Added for legacy or unrealistic timing tests.
+void dml20v2_rq_dlg_get_dlg_reg(
+		struct display_mode_lib *mode_lib,
+		display_dlg_regs_st *dlg_regs,
+		display_ttu_regs_st *ttu_regs,
+		display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
+		const bool cstate_en,
+		const bool pstate_en,
+		const bool vm_en,
+		const bool ignore_viewport_pos,
+		const bool immediate_flip_support);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
index 91810c7d5cf5..96dfcd8c36bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
@@ -28,6 +28,8 @@
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 #include "dcn20/display_mode_vba_20.h"
 #include "dcn20/display_rq_dlg_calc_20.h"
+#include "dcn20/display_mode_vba_20v2.h"
+#include "dcn20/display_rq_dlg_calc_20v2.h"
 #endif
 
 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
@@ -37,6 +39,13 @@ const struct dml_funcs dml20_funcs = {
 	.rq_dlg_get_dlg_reg = dml20_rq_dlg_get_dlg_reg,
 	.rq_dlg_get_rq_reg = dml20_rq_dlg_get_rq_reg
 };
+
+const struct dml_funcs dml20v2_funcs = {
+	.validate = dml20v2_ModeSupportAndSystemConfigurationFull,
+	.recalculate = dml20v2_recalculate,
+	.rq_dlg_get_dlg_reg = dml20v2_rq_dlg_get_dlg_reg,
+	.rq_dlg_get_rq_reg = dml20v2_rq_dlg_get_rq_reg
+};
 #endif
 
 void dml_init_instance(struct display_mode_lib *lib,
@@ -52,6 +61,9 @@ void dml_init_instance(struct display_mode_lib *lib,
 	case DML_PROJECT_NAVI10:
 		lib->funcs = dml20_funcs;
 		break;
+	case DML_PROJECT_NAVI10v2:
+		lib->funcs = dml20v2_funcs;
+		break;
 #endif
 	default:
 		break;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
index 5bf13d67f289..870716e3c132 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
@@ -36,6 +36,7 @@ enum dml_project {
 	DML_PROJECT_RAVEN1,
 #ifdef CONFIG_DRM_AMD_DC_DCN2_0
 	DML_PROJECT_NAVI10,
+	DML_PROJECT_NAVI10v2,
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index 5678472546ab..ab34fd26702f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -100,6 +100,7 @@ struct _vcs_dpi_soc_bounding_box_st {
 	unsigned int vmm_page_size_bytes;
 	unsigned int hostvm_min_page_size_bytes;
 	double dram_clock_change_latency_us;
+	double dummy_pstate_latency_us;
 	double writeback_dram_clock_change_latency_us;
 	unsigned int return_bus_width_bytes;
 	unsigned int voltage_override;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
index 4d2a1262d9db..88e63f16f7fc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
@@ -568,6 +568,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
 		if (src->is_hsplit) {
 			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
 				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
+				display_pipe_dest_params_st *dst_k = &pipes[k].pipe.dest;
 
 				if (src_k->is_hsplit && !visited[k]
 						&& src->hsplit_grp == src_k->hsplit_grp) {
@@ -575,12 +576,15 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
 							mode_lib->vba.NumberOfActivePlanes;
 					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
 					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
-							== dm_horz)
+							== dm_horz) {
 						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
 								src_k->viewport_width;
-					else
+						mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] +=
+								dst_k->recout_width;
+					} else {
 						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
 								src_k->viewport_height;
+					}
 
 					visited[k] = true;
 				}
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 82/87] drm/amd/display: Add SMU version field to clk_mgr_internal
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (80 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 81/87] drm/amd/display: support "dummy pstate" sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 83/87] drm/amd/display: avoid power gate domains that doesn't exist sunpeng.li-5C7GfCeVMHo
                     ` (4 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Yongqiang Sun, Fatemeh Darbehani

From: Fatemeh Darbehani <fatemeh.darbehani@amd.com>

For some platforms, we need to know SMU version for driver/SMU
compatibility. This change adds that field.

Change-Id: I2586161fb645bf0d16d30c91954a871f83e87edf
Signed-off-by: Fatemeh Darbehani <fatemeh.darbehani@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
index 3c105124dcdd..4b5505fa980c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
@@ -191,6 +191,7 @@ struct state_dependent_clocks {
 
 struct clk_mgr_internal {
 	struct clk_mgr base;
+	int smu_ver;
 	struct pp_smu_funcs *pp_smu;
 	struct clk_mgr_internal_funcs *funcs;
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 83/87] drm/amd/display: avoid power gate domains that doesn't exist
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (81 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 82/87] drm/amd/display: Add SMU version field to clk_mgr_internal sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 84/87] drm/amd/display: Add debug entry to destroy disconnected edp link sunpeng.li-5C7GfCeVMHo
                     ` (3 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Yongqiang Sun, Tony Cheng

From: Tony Cheng <tony.cheng@amd.com>

Change-Id: I7800685ccebbf8faa2b7185c501ac0ad78e13e48
Signed-off-by: Tony Cheng <tony.cheng@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/dce/dce_hwseq.h    |  4 ++--
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 24 ++++++++++++-------
 2 files changed, 17 insertions(+), 11 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 3a49f1ffb5dd..245b80b92681 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -227,8 +227,8 @@
 	SR(DOMAIN7_PG_CONFIG), \
 	SR(DOMAIN8_PG_CONFIG), \
 	SR(DOMAIN9_PG_CONFIG), \
-	SR(DOMAIN10_PG_CONFIG), \
-	SR(DOMAIN11_PG_CONFIG), \
+/*	SR(DOMAIN10_PG_CONFIG), Navi1x HUBP5 not powergate-able*/\
+/*	SR(DOMAIN11_PG_CONFIG), Navi1x DPP5 is not powergate-able */\
 	SR(DOMAIN16_PG_CONFIG), \
 	SR(DOMAIN17_PG_CONFIG), \
 	SR(DOMAIN18_PG_CONFIG), \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index b61774d2e8b2..6764ad845cd4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -94,25 +94,31 @@ static void enable_power_gating_plane(
 	REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, force_on);
-	REG_UPDATE(DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
-	/*Do not power gate DCHUB5, should be left at HW default, power on permanently*/
-	/*REG_UPDATE(DOMAIN10_PG_CONFIG, DOMAIN10_POWER_FORCEON, force_on);*/
+	if (REG(DOMAIN8_PG_CONFIG))
+		REG_UPDATE(DOMAIN8_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
+	if (REG(DOMAIN10_PG_CONFIG))
+		REG_UPDATE(DOMAIN10_PG_CONFIG, DOMAIN8_POWER_FORCEON, force_on);
 
 	/* DPP0/1/2/3/4/5 */
 	REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, force_on);
-	REG_UPDATE(DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
-	/*Do not power gate DPP5, should be left at HW default, power on permanently*/
-	/*REG_UPDATE(DOMAIN11_PG_CONFIG, DOMAIN11_POWER_FORCEON, force_on);*/
+	if (REG(DOMAIN9_PG_CONFIG))
+		REG_UPDATE(DOMAIN9_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
+	if (REG(DOMAIN11_PG_CONFIG))
+		REG_UPDATE(DOMAIN11_PG_CONFIG, DOMAIN9_POWER_FORCEON, force_on);
 
+	/* DCS0/1/2/3/4/5 */
 	REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN16_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN17_POWER_FORCEON, force_on);
 	REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN18_POWER_FORCEON, force_on);
-	REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, force_on);
-	REG_UPDATE(DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, force_on);
-	REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on);
+	if (REG(DOMAIN19_PG_CONFIG))
+		REG_UPDATE(DOMAIN19_PG_CONFIG, DOMAIN19_POWER_FORCEON, force_on);
+	if (REG(DOMAIN20_PG_CONFIG))
+		REG_UPDATE(DOMAIN20_PG_CONFIG, DOMAIN20_POWER_FORCEON, force_on);
+	if (REG(DOMAIN21_PG_CONFIG))
+		REG_UPDATE(DOMAIN21_PG_CONFIG, DOMAIN21_POWER_FORCEON, force_on);
 }
 
 void dcn20_dccg_init(struct dce_hwseq *hws)
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 84/87] drm/amd/display: Add debug entry to destroy disconnected edp link
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (82 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 83/87] drm/amd/display: avoid power gate domains that doesn't exist sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 85/87] drm/amd/display: Copy GSL groups when committing a new context sunpeng.li-5C7GfCeVMHo
                     ` (2 subsequent siblings)
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Lewis Huang, Yongqiang Sun

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

Add a flag to dc_debug_options to determine if a disconnected edp link
should be destroyed.

Change-Id: I49ccabe2cedc02d49fe3cd085710ea7459bca205
Signed-off-by: Lewis Huang <Lewis.Huang@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 20 ++++++++++++++++----
 drivers/gpu/drm/amd/display/dc/dc.h      |  1 +
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index c445de4d272e..dbfc530bcf68 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -178,13 +178,25 @@ static bool create_links(
 		link = link_create(&link_init_params);
 
 		if (link) {
-			if (dc->config.edp_not_connected &&
-					link->connector_signal == SIGNAL_TYPE_EDP) {
-				link_destroy(&link);
-			} else {
+			bool should_destory_link = false;
+
+			if (link->connector_signal == SIGNAL_TYPE_EDP) {
+				if (dc->config.edp_not_connected)
+					should_destory_link = true;
+				else if (dc->debug.remove_disconnect_edp) {
+					enum dc_connection_type type;
+					dc_link_detect_sink(link, &type);
+					if (type == dc_connection_none)
+						should_destory_link = true;
+				}
+			}
+
+			if (!should_destory_link) {
 				dc->links[dc->link_count] = link;
 				link->dc = dc;
 				++dc->link_count;
+			} else {
+				link_destroy(&link);
 			}
 		}
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 6da0a6fe2973..c585e16bc9f1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -378,6 +378,7 @@ struct dc_debug_options {
 	bool scl_reset_length10;
 	bool hdmi20_disable;
 	bool skip_detection_link_training;
+	bool remove_disconnect_edp;
 	unsigned int force_odm_combine; //bit vector based on otg inst
 	unsigned int force_fclk_khz;
 	bool disable_tri_buf;
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 85/87] drm/amd/display: Copy GSL groups when committing a new context
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (83 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 84/87] drm/amd/display: Add debug entry to destroy disconnected edp link sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 86/87] drm/amd/display: handle active dongle port type is DP++ or DP case sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 87/87] drm/amd/display: Force uclk to max for every state sunpeng.li-5C7GfCeVMHo
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Leo Li, Hersen Wu, Nicholas Kazlauskas

From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

[Why]
DC configures the GSL group for the pipe when pipe_split is enabled
and we're switching flip types (buffered <-> immediate flip) on DCN2.

In order to record what GSL group the pipe is using DC stores it in
the pipe's stream_res. DM is not aware of this internal grouping, nor
is DC resource.

So when DM creates a dc_state context and passes it to DC the current
GSL group is lost - DM never knew about it in the first place.

After 3 immediate flips we run out of GSL groups and we're no longer
able to correctly perform *any* flip for multi-pipe scenarios.

[How]
The gsl_group needs to be copied to the new context.

DM has no insight into GSL grouping and could even potentially create
a brand new context without referencing current hardware state. So this
makes the most sense to have happen in DC.

There are two places where DC can apply a new context:
- dc_commit_state
- dc_commit_updates_for_stream

But what's shared between both of these is apply_ctx_for_surface.

This logic only matters for DCN2, so it can be placed in
dcn20_apply_ctx_for_surface. Before doing any locking (where the GSL
group is setup) we can copy over the GSL groups before committing the
new context.

Change-Id: Id73647f50058dbe130e15fee23fa91ec37c67682
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Hersen Wu <hersen.wu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 6764ad845cd4..69e4d0d96c7f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1364,6 +1364,18 @@ static void dcn20_apply_ctx_for_surface(
 	if (!top_pipe_to_program)
 		return;
 
+	/* Carry over GSL groups in case the context is changing. */
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+		struct pipe_ctx *old_pipe_ctx =
+			&dc->current_state->res_ctx.pipe_ctx[i];
+
+		if (pipe_ctx->stream == stream &&
+		    pipe_ctx->stream == old_pipe_ctx->stream)
+			pipe_ctx->stream_res.gsl_group =
+				old_pipe_ctx->stream_res.gsl_group;
+	}
+
 	tg = top_pipe_to_program->stream_res.tg;
 
 	interdependent_update = top_pipe_to_program->plane_state &&
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 86/87] drm/amd/display: handle active dongle port type is DP++ or DP case
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (84 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 85/87] drm/amd/display: Copy GSL groups when committing a new context sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
  2019-07-15 21:20   ` [PATCH 87/87] drm/amd/display: Force uclk to max for every state sunpeng.li-5C7GfCeVMHo
  86 siblings, 0 replies; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Dale Zhao, Wenjing Liu

From: Dale Zhao <dale.zhao@amd.com>

[Why]:
Some active dongles have DP++ port and DP port at the same time. Current
code doesn't cover DP++ case and processes as default DVI case, in which
audio is disabled. Because of dual mode, DP case is also treat as DVI case
for the other port.

[How]:
According DP 1.4 spec, add DP++ procedure similar with HDMI case. Also
add None dongle type for DP case.

Change-Id: I15c02256326d319ba66c1bba44d8e669353aface
Signed-off-by: Dale Zhao <dale.zhao@amd.com>
Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_link_dp.c  | 30 ++++++++++++-------
 .../gpu/drm/amd/display/include/dpcd_defs.h   |  2 +-
 2 files changed, 21 insertions(+), 11 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 b512fecae061..08bd9c96b9b0 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
@@ -2398,8 +2398,8 @@ static void get_active_converter_info(
 	case DOWNSTREAM_VGA:
 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
 		break;
-	case DOWNSTREAM_DVI_HDMI:
-		/* At this point we don't know is it DVI or HDMI,
+	case DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS:
+		/* At this point we don't know is it DVI or HDMI or DP++,
 		 * assume DVI.*/
 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
 		break;
@@ -2416,6 +2416,10 @@ static void get_active_converter_info(
 				det_caps, sizeof(det_caps));
 
 		switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
+		/*Handle DP case as DONGLE_NONE*/
+		case DOWN_STREAM_DETAILED_DP:
+			link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
+			break;
 		case DOWN_STREAM_DETAILED_VGA:
 			link->dpcd_caps.dongle_type =
 				DISPLAY_DONGLE_DP_VGA_CONVERTER;
@@ -2425,6 +2429,8 @@ static void get_active_converter_info(
 				DISPLAY_DONGLE_DP_DVI_CONVERTER;
 			break;
 		case DOWN_STREAM_DETAILED_HDMI:
+		case DOWN_STREAM_DETAILED_DP_PLUS_PLUS:
+			/*Handle DP++ active converter case, process DP++ case as HDMI case according DP1.4 spec*/
 			link->dpcd_caps.dongle_type =
 				DISPLAY_DONGLE_DP_HDMI_CONVERTER;
 
@@ -2440,14 +2446,18 @@ static void get_active_converter_info(
 
 				link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
 					hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
-				link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
-					hdmi_caps.bits.YCrCr422_PASS_THROUGH;
-				link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
-					hdmi_caps.bits.YCrCr420_PASS_THROUGH;
-				link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
-					hdmi_caps.bits.YCrCr422_CONVERSION;
-				link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
-					hdmi_caps.bits.YCrCr420_CONVERSION;
+				/*YCBCR capability only for HDMI case*/
+				if (port_caps->bits.DWN_STRM_PORTX_TYPE
+						== DOWN_STREAM_DETAILED_HDMI) {
+					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
+							hdmi_caps.bits.YCrCr422_PASS_THROUGH;
+					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
+							hdmi_caps.bits.YCrCr420_PASS_THROUGH;
+					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
+							hdmi_caps.bits.YCrCr422_CONVERSION;
+					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
+							hdmi_caps.bits.YCrCr420_CONVERSION;
+				}
 
 				link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
 					translate_dpcd_max_bpc(
diff --git a/drivers/gpu/drm/amd/display/include/dpcd_defs.h b/drivers/gpu/drm/amd/display/include/dpcd_defs.h
index 1c66166d0a94..2c90d1b46c8b 100644
--- a/drivers/gpu/drm/amd/display/include/dpcd_defs.h
+++ b/drivers/gpu/drm/amd/display/include/dpcd_defs.h
@@ -43,7 +43,7 @@ enum dpcd_revision {
 enum dpcd_downstream_port_type {
 	DOWNSTREAM_DP = 0,
 	DOWNSTREAM_VGA,
-	DOWNSTREAM_DVI_HDMI,
+	DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS,/* DVI, HDMI, DP++ */
 	DOWNSTREAM_NONDDC /* has no EDID (TV,CV) */
 };
 
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* [PATCH 87/87] drm/amd/display: Force uclk to max for every state
       [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
                     ` (85 preceding siblings ...)
  2019-07-15 21:20   ` [PATCH 86/87] drm/amd/display: handle active dongle port type is DP++ or DP case sunpeng.li-5C7GfCeVMHo
@ 2019-07-15 21:20   ` sunpeng.li-5C7GfCeVMHo
       [not found]     ` <20190715212049.4584-88-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
  86 siblings, 1 reply; 91+ messages in thread
From: sunpeng.li-5C7GfCeVMHo @ 2019-07-15 21:20 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Leo Li, Nicholas Kazlauskas

From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

Workaround for now to avoid underflow.

The uclk switch time should really be bumped up to 404, but doing so
would expose p-state hang issues for higher bandwidth display
configurations.

Change-Id: I98060fc9c4eeece07ef54e13a144def88a3c3d21
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c   |  6 +++---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c  | 10 ++++++++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index 983a1bd56272..74697cef5dfe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -912,11 +912,11 @@ void dm_pp_get_funcs(
 		/* todo set_pme_wa_enable cause 4k@6ohz display not light up */
 		funcs->nv_funcs.set_pme_wa_enable = NULL;
 		/* todo debug waring message */
-		funcs->nv_funcs.set_hard_min_uclk_by_freq = NULL;
+		funcs->nv_funcs.set_hard_min_uclk_by_freq = pp_nv_set_hard_min_uclk_by_freq;
 		/* todo  compare data with window driver*/
-		funcs->nv_funcs.get_maximum_sustainable_clocks = NULL;
+		funcs->nv_funcs.get_maximum_sustainable_clocks = pp_nv_get_maximum_sustainable_clocks;
 		/*todo  compare data with window driver */
-		funcs->nv_funcs.get_uclk_dpm_states = NULL;
+		funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states;
 		break;
 #endif
 	default:
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 2cf788a3704e..44537651f0a1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2707,6 +2707,9 @@ static void cap_soc_clocks(
 						&& max_clocks.uClockInKhz != 0)
 			bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
 
+		// HACK: Force every uclk to max for now to "disable" uclk switching.
+		bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
+
 		if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
 						&& max_clocks.fabricClockInKhz != 0)
 			bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000);
@@ -2922,6 +2925,8 @@ static bool init_soc_bounding_box(struct dc *dc,
 				le32_to_cpu(bb->vmm_page_size_bytes);
 		dcn2_0_soc.dram_clock_change_latency_us =
 				fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us);
+		// HACK!! Lower uclock latency switch time so we don't switch
+		dcn2_0_soc.dram_clock_change_latency_us = 10;
 		dcn2_0_soc.writeback_dram_clock_change_latency_us =
 				fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us);
 		dcn2_0_soc.return_bus_width_bytes =
@@ -2963,6 +2968,7 @@ static bool init_soc_bounding_box(struct dc *dc,
 		struct pp_smu_nv_clock_table max_clocks = {0};
 		unsigned int uclk_states[8] = {0};
 		unsigned int num_states = 0;
+		int i;
 		enum pp_smu_status status;
 		bool clock_limits_available = false;
 		bool uclk_states_available = false;
@@ -2984,6 +2990,10 @@ static bool init_soc_bounding_box(struct dc *dc,
 			clock_limits_available = (status == PP_SMU_RESULT_OK);
 		}
 
+		// HACK: Use the max uclk_states value for all elements.
+		for (i = 0; i < num_states; i++)
+			uclk_states[i] = uclk_states[num_states - 1];
+
 		if (clock_limits_available && uclk_states_available && num_states)
 			update_bounding_box(dc, &dcn2_0_soc, &max_clocks, uclk_states, num_states);
 		else if (clock_limits_available)
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* Re: [PATCH 07/87] drm/amd/display: move bw calc code into helpers
       [not found]     ` <20190715212049.4584-8-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
@ 2019-07-18 14:49       ` Michel Dänzer
       [not found]         ` <66c6c4d7-34b3-b73b-4e21-f745fff470cd-otUistvHUpPR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 91+ messages in thread
From: Michel Dänzer @ 2019-07-18 14:49 UTC (permalink / raw)
  To: sunpeng.li-5C7GfCeVMHo
  Cc: Fatemeh Darbehani, Eric Yang, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 2019-07-15 11:19 p.m., sunpeng.li@amd.com wrote:
> From: Eric Yang <Eric.Yang2@amd.com>
> 
> [Why]
> For better readability and reusability
> 
> [How]
> Move snippets of BW calculation code into helpers.
> 
> Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
> Reviewed-by: Fatemeh Darbehani <Fatemeh.Darbehani@amd.com>
> Acked-by: Leo Li <sunpeng.li@amd.com>
> ---
>  [...]
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 086d2f3b0db3..e9ccf41e31ee 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -126,6 +126,7 @@ static DEVICE_ATTR(pcie_replay_count, S_IRUGO,
>  		amdgpu_device_get_pcie_replay_count, NULL);
>  
>  static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
> +static void amdgpu_device_parse_faked_did(struct amdgpu_device *adev);

This function isn't defined anywhere, producing a warning:

drivers/gpu/drm//amd/amdgpu/amdgpu_device.c:131:13: warning: ‘amdgpu_device_parse_faked_did’ declared ‘static’ but never defined [-Wunused-function]
 static void amdgpu_device_parse_faked_did(struct amdgpu_device *adev);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~


-- 
Earthling Michel Dänzer               |              https://www.amd.com
Libre software enthusiast             |             Mesa and X developer
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* RE: [PATCH 87/87] drm/amd/display: Force uclk to max for every state
       [not found]     ` <20190715212049.4584-88-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
@ 2019-07-18 15:51       ` Liu, Zhan
  0 siblings, 0 replies; 91+ messages in thread
From: Liu, Zhan @ 2019-07-18 15:51 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Li, Sun peng (Leo), Kazlauskas, Nicholas



Reviewed-by: Zhan Liu <Zhan.Liu@amd.com>




-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of sunpeng.li@amd.com
Sent: Monday, July 15, 2019 5:21 PM
To: amd-gfx@lists.freedesktop.org
Cc: Li, Sun peng (Leo) <Sunpeng.Li@amd.com>; Kazlauskas, Nicholas <Nicholas.Kazlauskas@amd.com>
Subject: [PATCH 87/87] drm/amd/display: Force uclk to max for every state

From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

Workaround for now to avoid underflow.

The uclk switch time should really be bumped up to 404, but doing so would expose p-state hang issues for higher bandwidth display configurations.

Change-Id: I98060fc9c4eeece07ef54e13a144def88a3c3d21
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Leo Li <sunpeng.li@amd.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c   |  6 +++---
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c  | 10 ++++++++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
index 983a1bd56272..74697cef5dfe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
@@ -912,11 +912,11 @@ void dm_pp_get_funcs(
 		/* todo set_pme_wa_enable cause 4k@6ohz display not light up */
 		funcs->nv_funcs.set_pme_wa_enable = NULL;
 		/* todo debug waring message */
-		funcs->nv_funcs.set_hard_min_uclk_by_freq = NULL;
+		funcs->nv_funcs.set_hard_min_uclk_by_freq = 
+pp_nv_set_hard_min_uclk_by_freq;
 		/* todo  compare data with window driver*/
-		funcs->nv_funcs.get_maximum_sustainable_clocks = NULL;
+		funcs->nv_funcs.get_maximum_sustainable_clocks = 
+pp_nv_get_maximum_sustainable_clocks;
 		/*todo  compare data with window driver */
-		funcs->nv_funcs.get_uclk_dpm_states = NULL;
+		funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states;
 		break;
 #endif
 	default:
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 2cf788a3704e..44537651f0a1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2707,6 +2707,9 @@ static void cap_soc_clocks(
 						&& max_clocks.uClockInKhz != 0)
 			bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) * 16;
 
+		// HACK: Force every uclk to max for now to "disable" uclk switching.
+		bb->clock_limits[i].dram_speed_mts = (max_clocks.uClockInKhz / 1000) 
+* 16;
+
 		if ((bb->clock_limits[i].fabricclk_mhz > (max_clocks.fabricClockInKhz / 1000))
 						&& max_clocks.fabricClockInKhz != 0)
 			bb->clock_limits[i].fabricclk_mhz = (max_clocks.fabricClockInKhz / 1000); @@ -2922,6 +2925,8 @@ static bool init_soc_bounding_box(struct dc *dc,
 				le32_to_cpu(bb->vmm_page_size_bytes);
 		dcn2_0_soc.dram_clock_change_latency_us =
 				fixed16_to_double_to_cpu(bb->dram_clock_change_latency_us);
+		// HACK!! Lower uclock latency switch time so we don't switch
+		dcn2_0_soc.dram_clock_change_latency_us = 10;
 		dcn2_0_soc.writeback_dram_clock_change_latency_us =
 				fixed16_to_double_to_cpu(bb->writeback_dram_clock_change_latency_us);
 		dcn2_0_soc.return_bus_width_bytes =
@@ -2963,6 +2968,7 @@ static bool init_soc_bounding_box(struct dc *dc,
 		struct pp_smu_nv_clock_table max_clocks = {0};
 		unsigned int uclk_states[8] = {0};
 		unsigned int num_states = 0;
+		int i;
 		enum pp_smu_status status;
 		bool clock_limits_available = false;
 		bool uclk_states_available = false;
@@ -2984,6 +2990,10 @@ static bool init_soc_bounding_box(struct dc *dc,
 			clock_limits_available = (status == PP_SMU_RESULT_OK);
 		}
 
+		// HACK: Use the max uclk_states value for all elements.
+		for (i = 0; i < num_states; i++)
+			uclk_states[i] = uclk_states[num_states - 1];
+
 		if (clock_limits_available && uclk_states_available && num_states)
 			update_bounding_box(dc, &dcn2_0_soc, &max_clocks, uclk_states, num_states);
 		else if (clock_limits_available)
--
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* Re: [PATCH 07/87] drm/amd/display: move bw calc code into helpers
       [not found]         ` <66c6c4d7-34b3-b73b-4e21-f745fff470cd-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2019-07-18 16:20           ` Li, Sun peng (Leo)
  0 siblings, 0 replies; 91+ messages in thread
From: Li, Sun peng (Leo) @ 2019-07-18 16:20 UTC (permalink / raw)
  To: Michel Dänzer
  Cc: Darbehani, Fatemeh, Yang, Eric, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 2019-07-18 10:49 a.m., Michel Dänzer wrote:
> On 2019-07-15 11:19 p.m., sunpeng.li@amd.com wrote:
>> From: Eric Yang <Eric.Yang2@amd.com>
>>
>> [Why]
>> For better readability and reusability
>>
>> [How]
>> Move snippets of BW calculation code into helpers.
>>
>> Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
>> Reviewed-by: Fatemeh Darbehani <Fatemeh.Darbehani@amd.com>
>> Acked-by: Leo Li <sunpeng.li@amd.com>
>> ---
>>  [...]
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 086d2f3b0db3..e9ccf41e31ee 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -126,6 +126,7 @@ static DEVICE_ATTR(pcie_replay_count, S_IRUGO,
>>  		amdgpu_device_get_pcie_replay_count, NULL);
>>  
>>  static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
>> +static void amdgpu_device_parse_faked_did(struct amdgpu_device *adev);
> 
> This function isn't defined anywhere, producing a warning:
> 
> drivers/gpu/drm//amd/amdgpu/amdgpu_device.c:131:13: warning: ‘amdgpu_device_parse_faked_did’ declared ‘static’ but never defined [-Wunused-function]
>  static void amdgpu_device_parse_faked_did(struct amdgpu_device *adev);
>              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Oops, I don't know how that managed to get in there. It's not even in
the display dir...

Sent a fix.

Leo
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

end of thread, other threads:[~2019-07-18 16:20 UTC | newest]

Thread overview: 91+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-15 21:19 [PATCH 00/87] DC Patches 15 Jul, 2019 sunpeng.li-5C7GfCeVMHo
     [not found] ` <20190715212049.4584-1-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
2019-07-15 21:19   ` [PATCH 01/87] drm/amd/display: initialize p_state to proper value sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 02/87] drm/amd/display: Add ability to set preferred link training parameters sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 03/87] drm/amd/display: 3.2.36 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 04/87] drm/amd/display: fix up HUBBUB hw programming for VM sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 05/87] drm/amd/display: fix dsc disable sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 06/87] drm/amd/display: 3.2.37 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 07/87] drm/amd/display: move bw calc code into helpers sunpeng.li-5C7GfCeVMHo
     [not found]     ` <20190715212049.4584-8-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
2019-07-18 14:49       ` Michel Dänzer
     [not found]         ` <66c6c4d7-34b3-b73b-4e21-f745fff470cd-otUistvHUpPR7s880joybQ@public.gmane.org>
2019-07-18 16:20           ` Li, Sun peng (Leo)
2019-07-15 21:19   ` [PATCH 08/87] drm/amd/display: cap DCFCLK hardmin to 507 for NV10 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 09/87] drm/amd/display: No audio endpoint for Dell MST display sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 10/87] drm/amd/display: Add aux tracing log in dce sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 11/87] drm/amd/display: Update drm_dsc to reflect native 4.2.0 DSC spec sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 12/87] drm/amd/display: early return when pipe_cnt is 0 in bw validation sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 13/87] drm/amd/display: Set default block_size, even in unexpected cases sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 14/87] drm/amd/display: Set one 4:2:0-related PPS field as recommended by DSC spec sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 15/87] drm/amd/display: swap system aperture high/low sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 16/87] drm/amd/display: skip retrain in dc_link_set_preferred_link_settings() if using passive dongle sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 17/87] drm/amd/display: Split out common HUBP registers and code sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 18/87] drm/amd/display: 3.2.38 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 19/87] drm/amd/display: Incorrect Read Interval Time For CR Sequence sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 20/87] drm/amd/display: Clock does not lower in Updateplanes sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 21/87] drm/amd/display: Copy max_clks_by_state after dce_clk_mgr_construct sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 22/87] drm/amd/display:Use Pixel clock in 100Hz units for HDMI Audio wall clock DTO sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 23/87] drm/amd/display: wait for the whole frame after global unlock sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 24/87] drm/amd/display: refactor dump_clk_registers sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 25/87] drm/amd/display: add hdmi2.1 dsc pps packet programming sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 26/87] drm/amd/display: add monitor patch to add T7 delay sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 27/87] drm/amd/display: Poll for GPUVM context ready sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 28/87] drm/amd/display: add functionality to grab DPRX CRC entries sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 29/87] drm/amd/display: add functionality to get pipe CRC source sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 30/87] drm/amd/display: Wait for backlight programming completion in set backlight level sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 31/87] drm/amd/display: 3.2.39 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 32/87] drm/amd/display: Expose enc2_set_dynamic_metadata sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 33/87] drm/amd/display: Check for valid stream_encode sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 34/87] drm/amd/display: Fix some HUBP programming issues sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 35/87] drm/amd/display: Read max down spread sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 36/87] drm/amd/display: Remove dsc disable_ich flag programming sunpeng.li-5C7GfCeVMHo
2019-07-15 21:19   ` [PATCH 37/87] drm/amd/display: Power-gate all DSCs at driver init time sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 38/87] drm/amd/display: Disable Audio on reinitialize hardware sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 39/87] drm/amd/display: fix DMCU hang when going into Modern Standby sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 40/87] drm/amd/display: Do not fill Null packet in the blank period sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 41/87] drm/amd/display: Remove unnecessary NULL check in set_preferred_link_settings sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 42/87] drm/amd/display: use encoder's engine id to find matched free audio device sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 43/87] drm/amd/display: fix not calling ppsmu to trigger PME sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 44/87] drm/amd/display: Change min_h_sync_width from 8 to 4 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 45/87] drm/amd/display: Remove second initialization of pp_smu sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 46/87] drm/amd/display: 3.2.40 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 47/87] drm/amd/display: Wait for flip to complete sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 48/87] drm/amd/display: Implement generic MUX registers sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 49/87] drm/amd/display: Use helper for determining HDMI signal sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 50/87] drm/amd/display: Set FEC_READY always before link training sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 51/87] drm/amd/display: put back front end initialization sequence sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 52/87] drm/amd/display: Optimize gamma calculations sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 53/87] drm/amd/display: Clear FEC_READY shadow register if DPCD write fails sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 54/87] drm/amd/display: Add debug option to disable timing sync sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 55/87] drm/amd/display: Add MPC 3DLUT resource management sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 56/87] drm/amd/display: Add CM_BYPASS via debug option sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 57/87] drm/amd/display: Add DIG_CLOCK_PATTERN register sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 58/87] drm/amd/display: Cache the use_pitch_c conditional sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 59/87] drm/amd/display: Fixes for some MPO cases sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 60/87] drm/amd/display: 3.2.41 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 61/87] drm/amd/display: Hook up calls to do stereo mux and dig programming to stereo control interface sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 62/87] drm/amd/display: allocate 4 ddc engines for RV2 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 63/87] drm/amd/display: add set and get clock for testing purposes sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 64/87] drm/amd/display: Change offset_to_id to reflect what id_to_offset returns sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 65/87] drm/amd/display: init res_pool dccg_ref, dchub_ref with xtalin_freq sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 66/87] drm/amd/display: add a option to force the clock at every mode change sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 67/87] drm/amd/display: use min disp and dpp clk debug option for dcn2 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 68/87] drm/amd/display: add pipe CRC sources without disabling dithering sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 69/87] drm/amd/display: Implement DAL3 GPU Integer Scaling sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 70/87] drm/amd/display: add dcc programming for dual plane sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 71/87] drm/amd/display: populate last calculated bb state with max clocks sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 72/87] drm/amd/display: Fix dc_create failure handling and 666 color depths sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 73/87] drm/amd/display: Only enable audio if speaker allocation exists sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 74/87] drm/amd/display: Clean up dynamic metadata logic sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 75/87] drm/amd/display: Set enabled to false at start of audio disable sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 76/87] drm/amd/display: drop ASSERT() if eDP panel is not connected sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 77/87] drm/amd/display: 3.2.42 sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 78/87] drm/amd/display: Increase size of audios array sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 79/87] drm/amd/display: do not read link setting if edp not connected sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 80/87] drm/amd/display: fix mpcc assert condition sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 81/87] drm/amd/display: support "dummy pstate" sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 82/87] drm/amd/display: Add SMU version field to clk_mgr_internal sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 83/87] drm/amd/display: avoid power gate domains that doesn't exist sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 84/87] drm/amd/display: Add debug entry to destroy disconnected edp link sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 85/87] drm/amd/display: Copy GSL groups when committing a new context sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 86/87] drm/amd/display: handle active dongle port type is DP++ or DP case sunpeng.li-5C7GfCeVMHo
2019-07-15 21:20   ` [PATCH 87/87] drm/amd/display: Force uclk to max for every state sunpeng.li-5C7GfCeVMHo
     [not found]     ` <20190715212049.4584-88-sunpeng.li-5C7GfCeVMHo@public.gmane.org>
2019-07-18 15:51       ` Liu, Zhan

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.