drm/amdgpu/display: Add dml support for DCN
authorHarry Wentland <harry.wentland@amd.com>
Mon, 8 May 2017 19:20:38 +0000 (15:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 22:06:49 +0000 (18:06 -0400)
Display mode lib handles clock, watermark, and bandwidth
calculations for DCN.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
20 files changed:
drivers/gpu/drm/amd/display/dc/dml/Makefile [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dc_features.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_watermark.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/display_watermark.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h [new file with mode: 0644]

diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
new file mode 100644 (file)
index 0000000..9d7791d
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Makefile for the 'utils' sub-component of DAL.
+# It provides the general basic services required by other DAL
+# subcomponents.
+
+CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_display_mode_support.o := -mhard-float -msse -mpreferred-stack-boundary=4
+
+
+DML = display_mode_lib.o display_pipe_clocks.o display_rq_dlg_calc.o \
+         display_rq_dlg_helpers.o display_watermark.o \
+         soc_bounding_box.o dml_common_defs.o display_mode_support.o
+
+AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DML)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
new file mode 100644 (file)
index 0000000..745c04c
--- /dev/null
@@ -0,0 +1,557 @@
+/*
+ * Copyright 2017 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 __DC_FEATURES_H__
+#define __DC_FEATURES_H__
+
+#define DC__PRESENT 1
+#define DC__PRESENT__1 1
+#define DC__NUM_DPP 4
+#define DC__NUM_DPP__4 1
+#define DC__NUM_DPP__0_PRESENT 1
+#define DC__NUM_DPP__1_PRESENT 1
+#define DC__NUM_DPP__2_PRESENT 1
+#define DC__NUM_DPP__3_PRESENT 1
+#define DC__NUM_DPP__MAX 8
+#define DC__NUM_DPP__MAX__8 1
+#define DC__PIPE_10BIT 0
+#define DC__PIPE_10BIT__0 1
+#define DC__PIPE_10BIT__MAX 1
+#define DC__PIPE_10BIT__MAX__1 1
+#define DC__NUM_OPP 4
+#define DC__NUM_OPP__4 1
+#define DC__NUM_OPP__0_PRESENT 1
+#define DC__NUM_OPP__1_PRESENT 1
+#define DC__NUM_OPP__2_PRESENT 1
+#define DC__NUM_OPP__3_PRESENT 1
+#define DC__NUM_OPP__MAX 6
+#define DC__NUM_OPP__MAX__6 1
+#define DC__NUM_DSC 0
+#define DC__NUM_DSC__0 1
+#define DC__NUM_DSC__MAX 6
+#define DC__NUM_DSC__MAX__6 1
+#define DC__NUM_ABM 1
+#define DC__NUM_ABM__1 1
+#define DC__NUM_ABM__0_PRESENT 1
+#define DC__NUM_ABM__MAX 2
+#define DC__NUM_ABM__MAX__2 1
+#define DC__ODM_PRESENT 0
+#define DC__ODM_PRESENT__0 1
+#define DC__NUM_OTG 4
+#define DC__NUM_OTG__4 1
+#define DC__NUM_OTG__0_PRESENT 1
+#define DC__NUM_OTG__1_PRESENT 1
+#define DC__NUM_OTG__2_PRESENT 1
+#define DC__NUM_OTG__3_PRESENT 1
+#define DC__NUM_OTG__MAX 6
+#define DC__NUM_OTG__MAX__6 1
+#define DC__NUM_DWB 2
+#define DC__NUM_DWB__2 1
+#define DC__NUM_DWB__0_PRESENT 1
+#define DC__NUM_DWB__1_PRESENT 1
+#define DC__NUM_DWB__MAX 2
+#define DC__NUM_DWB__MAX__2 1
+#define DC__NUM_DIG 4
+#define DC__NUM_DIG__4 1
+#define DC__NUM_DIG__0_PRESENT 1
+#define DC__NUM_DIG__1_PRESENT 1
+#define DC__NUM_DIG__2_PRESENT 1
+#define DC__NUM_DIG__3_PRESENT 1
+#define DC__NUM_DIG__MAX 6
+#define DC__NUM_DIG__MAX__6 1
+#define DC__NUM_AUX 4
+#define DC__NUM_AUX__4 1
+#define DC__NUM_AUX__0_PRESENT 1
+#define DC__NUM_AUX__1_PRESENT 1
+#define DC__NUM_AUX__2_PRESENT 1
+#define DC__NUM_AUX__3_PRESENT 1
+#define DC__NUM_AUX__MAX 6
+#define DC__NUM_AUX__MAX__6 1
+#define DC__NUM_AUDIO_STREAMS 4
+#define DC__NUM_AUDIO_STREAMS__4 1
+#define DC__NUM_AUDIO_STREAMS__0_PRESENT 1
+#define DC__NUM_AUDIO_STREAMS__1_PRESENT 1
+#define DC__NUM_AUDIO_STREAMS__2_PRESENT 1
+#define DC__NUM_AUDIO_STREAMS__3_PRESENT 1
+#define DC__NUM_AUDIO_STREAMS__MAX 8
+#define DC__NUM_AUDIO_STREAMS__MAX__8 1
+#define DC__NUM_AUDIO_ENDPOINTS 6
+#define DC__NUM_AUDIO_ENDPOINTS__6 1
+#define DC__NUM_AUDIO_ENDPOINTS__0_PRESENT 1
+#define DC__NUM_AUDIO_ENDPOINTS__1_PRESENT 1
+#define DC__NUM_AUDIO_ENDPOINTS__2_PRESENT 1
+#define DC__NUM_AUDIO_ENDPOINTS__3_PRESENT 1
+#define DC__NUM_AUDIO_ENDPOINTS__4_PRESENT 1
+#define DC__NUM_AUDIO_ENDPOINTS__5_PRESENT 1
+#define DC__NUM_AUDIO_ENDPOINTS__MAX 8
+#define DC__NUM_AUDIO_ENDPOINTS__MAX__8 1
+#define DC__NUM_AUDIO_INPUT_STREAMS 0
+#define DC__NUM_AUDIO_INPUT_STREAMS__0 1
+#define DC__NUM_AUDIO_INPUT_STREAMS__MAX 8
+#define DC__NUM_AUDIO_INPUT_STREAMS__MAX__8 1
+#define DC__NUM_AUDIO_INPUT_ENDPOINTS 0
+#define DC__NUM_AUDIO_INPUT_ENDPOINTS__0 1
+#define DC__NUM_AUDIO_INPUT_ENDPOINTS__MAX 8
+#define DC__NUM_AUDIO_INPUT_ENDPOINTS__MAX__8 1
+#define DC__NUM_CURSOR 1
+#define DC__NUM_CURSOR__1 1
+#define DC__NUM_CURSOR__0_PRESENT 1
+#define DC__NUM_CURSOR__MAX 2
+#define DC__NUM_CURSOR__MAX__2 1
+#define DC__DIGITAL_BYPASS_PRESENT 0
+#define DC__DIGITAL_BYPASS_PRESENT__0 1
+#define DC__HCID_HWMAJVER 1
+#define DC__HCID_HWMAJVER__1 1
+#define DC__HCID_HWMINVER 0
+#define DC__HCID_HWMINVER__0 1
+#define DC__HCID_HWREV 0
+#define DC__HCID_HWREV__0 1
+#define DC__ROMSTRAP_PRESENT 0
+#define DC__ROMSTRAP_PRESENT__0 1
+#define DC__NUM_RBBMIF_DECODES 30
+#define DC__NUM_RBBMIF_DECODES__30 1
+#define DC__NUM_DBG_REGS 36
+#define DC__NUM_DBG_REGS__36 1
+#define DC__NUM_PIPES_UNDERLAY 0
+#define DC__NUM_PIPES_UNDERLAY__0 1
+#define DC__NUM_PIPES_UNDERLAY__MAX 2
+#define DC__NUM_PIPES_UNDERLAY__MAX__2 1
+#define DC__NUM_VCE_ENGINE 1
+#define DC__NUM_VCE_ENGINE__1 1
+#define DC__NUM_VCE_ENGINE__0_PRESENT 1
+#define DC__NUM_VCE_ENGINE__MAX 2
+#define DC__NUM_VCE_ENGINE__MAX__2 1
+#define DC__OTG_EXTERNAL_SYNC_PRESENT 0
+#define DC__OTG_EXTERNAL_SYNC_PRESENT__0 1
+#define DC__OTG_CRC_PRESENT 1
+#define DC__OTG_CRC_PRESENT__1 1
+#define DC__VIP_PRESENT 0
+#define DC__VIP_PRESENT__0 1
+#define DC__DTMTEST_PRESENT 0
+#define DC__DTMTEST_PRESENT__0 1
+#define DC__POWER_GATE_PRESENT 1
+#define DC__POWER_GATE_PRESENT__1 1
+#define DC__MEM_PG 1
+#define DC__MEM_PG__1 1
+#define DC__FMT_SRC_SEL_PRESENT 0
+#define DC__FMT_SRC_SEL_PRESENT__0 1
+#define DC__DIG_FEATURES__HDMI_PRESENT 1
+#define DC__DIG_FEATURES__HDMI_PRESENT__1 1
+#define DC__DIG_FEATURES__DP_PRESENT 1
+#define DC__DIG_FEATURES__DP_PRESENT__1 1
+#define DC__DIG_FEATURES__DP_MST_PRESENT 1
+#define DC__DIG_FEATURES__DP_MST_PRESENT__1 1
+#define DC__DIG_LP_FEATURES__HDMI_PRESENT 0
+#define DC__DIG_LP_FEATURES__HDMI_PRESENT__0 1
+#define DC__DIG_LP_FEATURES__DP_PRESENT 1
+#define DC__DIG_LP_FEATURES__DP_PRESENT__1 1
+#define DC__DIG_LP_FEATURES__DP_MST_PRESENT 0
+#define DC__DIG_LP_FEATURES__DP_MST_PRESENT__0 1
+#define DC__DIG_RESYNC_FIFO_SIZE 14
+#define DC__DIG_RESYNC_FIFO_SIZE__14 1
+#define DC__DIG_RESYNC_FIFO_SIZE__0_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__1_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__2_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__3_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__4_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__5_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__6_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__7_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__8_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__9_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__10_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__11_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__12_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__13_PRESENT 1
+#define DC__DIG_RESYNC_FIFO_SIZE__MAX 16
+#define DC__DIG_RESYNC_FIFO_SIZE__MAX__16 1
+#define DC__DAC_RESYNC_FIFO_SIZE 12
+#define DC__DAC_RESYNC_FIFO_SIZE__12 1
+#define DC__DAC_RESYNC_FIFO_SIZE__0_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__1_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__2_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__3_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__4_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__5_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__6_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__7_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__8_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__9_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__10_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__11_PRESENT 1
+#define DC__DAC_RESYNC_FIFO_SIZE__MAX 16
+#define DC__DAC_RESYNC_FIFO_SIZE__MAX__16 1
+#define DC__DVO_RESYNC_FIFO_SIZE 12
+#define DC__DVO_RESYNC_FIFO_SIZE__12 1
+#define DC__DVO_RESYNC_FIFO_SIZE__0_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__1_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__2_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__3_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__4_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__5_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__6_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__7_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__8_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__9_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__10_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__11_PRESENT 1
+#define DC__DVO_RESYNC_FIFO_SIZE__MAX 16
+#define DC__DVO_RESYNC_FIFO_SIZE__MAX__16 1
+#define DC__MEM_CDC_PRESENT 1
+#define DC__MEM_CDC_PRESENT__1 1
+#define DC__NUM_HPD 4
+#define DC__NUM_HPD__4 1
+#define DC__NUM_HPD__0_PRESENT 1
+#define DC__NUM_HPD__1_PRESENT 1
+#define DC__NUM_HPD__2_PRESENT 1
+#define DC__NUM_HPD__3_PRESENT 1
+#define DC__NUM_HPD__MAX 6
+#define DC__NUM_HPD__MAX__6 1
+#define DC__NUM_DDC_PAIRS 4
+#define DC__NUM_DDC_PAIRS__4 1
+#define DC__NUM_DDC_PAIRS__0_PRESENT 1
+#define DC__NUM_DDC_PAIRS__1_PRESENT 1
+#define DC__NUM_DDC_PAIRS__2_PRESENT 1
+#define DC__NUM_DDC_PAIRS__3_PRESENT 1
+#define DC__NUM_DDC_PAIRS__MAX 6
+#define DC__NUM_DDC_PAIRS__MAX__6 1
+#define DC__NUM_AUDIO_PLL 0
+#define DC__NUM_AUDIO_PLL__0 1
+#define DC__NUM_AUDIO_PLL__MAX 2
+#define DC__NUM_AUDIO_PLL__MAX__2 1
+#define DC__NUM_PIXEL_PLL 1
+#define DC__NUM_PIXEL_PLL__1 1
+#define DC__NUM_PIXEL_PLL__0_PRESENT 1
+#define DC__NUM_PIXEL_PLL__MAX 4
+#define DC__NUM_PIXEL_PLL__MAX__4 1
+#define DC__NUM_CASCADED_PLL 0
+#define DC__NUM_CASCADED_PLL__0 1
+#define DC__NUM_CASCADED_PLL__MAX 3
+#define DC__NUM_CASCADED_PLL__MAX__3 1
+#define DC__PIXCLK_FROM_PHYPLL 1
+#define DC__PIXCLK_FROM_PHYPLL__1 1
+#define DC__NB_STUTTER_MODE_PRESENT 0
+#define DC__NB_STUTTER_MODE_PRESENT__0 1
+#define DC__I2S0_AND_SPDIF0_PRESENT 0
+#define DC__I2S0_AND_SPDIF0_PRESENT__0 1
+#define DC__I2S1_PRESENT 0
+#define DC__I2S1_PRESENT__0 1
+#define DC__SPDIF1_PRESENT 0
+#define DC__SPDIF1_PRESENT__0 1
+#define DC__DSI_PRESENT 0
+#define DC__DSI_PRESENT__0 1
+#define DC__DACA_PRESENT 0
+#define DC__DACA_PRESENT__0 1
+#define DC__DACB_PRESENT 0
+#define DC__DACB_PRESENT__0 1
+#define DC__NUM_PIPES 4
+#define DC__NUM_PIPES__4 1
+#define DC__NUM_PIPES__0_PRESENT 1
+#define DC__NUM_PIPES__1_PRESENT 1
+#define DC__NUM_PIPES__2_PRESENT 1
+#define DC__NUM_PIPES__3_PRESENT 1
+#define DC__NUM_PIPES__MAX 6
+#define DC__NUM_PIPES__MAX__6 1
+#define DC__NUM_DIG_LP 0
+#define DC__NUM_DIG_LP__0 1
+#define DC__NUM_DIG_LP__MAX 2
+#define DC__NUM_DIG_LP__MAX__2 1
+#define DC__DPDEBUG_PRESENT 0
+#define DC__DPDEBUG_PRESENT__0 1
+#define DC__DISPLAY_WB_PRESENT 1
+#define DC__DISPLAY_WB_PRESENT__1 1
+#define DC__NUM_CWB 0
+#define DC__NUM_CWB__0 1
+#define DC__NUM_CWB__MAX 2
+#define DC__NUM_CWB__MAX__2 1
+#define DC__MVP_PRESENT 0
+#define DC__MVP_PRESENT__0 1
+#define DC__DVO_PRESENT 0
+#define DC__DVO_PRESENT__0 1
+#define DC__ABM_PRESENT 0
+#define DC__ABM_PRESENT__0 1
+#define DC__BPHYC_PLL_PRESENT 0
+#define DC__BPHYC_PLL_PRESENT__0 1
+#define DC__BPHYC_UNIPHY_PRESENT 0
+#define DC__BPHYC_UNIPHY_PRESENT__0 1
+#define DC__PHY_BROADCAST_PRESENT 0
+#define DC__PHY_BROADCAST_PRESENT__0 1
+#define DC__NUM_OF_DCRX_SD 0
+#define DC__NUM_OF_DCRX_SD__0 1
+#define DC__DVO_17BIT_MAPPING 0
+#define DC__DVO_17BIT_MAPPING__0 1
+#define DC__AVSYNC_PRESENT 0
+#define DC__AVSYNC_PRESENT__0 1
+#define DC__NUM_OF_DCRX_PORTS 0
+#define DC__NUM_OF_DCRX_PORTS__0 1
+#define DC__NUM_OF_DCRX_PORTS__MAX 1
+#define DC__NUM_OF_DCRX_PORTS__MAX__1 1
+#define DC__NUM_PHY 4
+#define DC__NUM_PHY__4 1
+#define DC__NUM_PHY__0_PRESENT 1
+#define DC__NUM_PHY__1_PRESENT 1
+#define DC__NUM_PHY__2_PRESENT 1
+#define DC__NUM_PHY__3_PRESENT 1
+#define DC__NUM_PHY__MAX 7
+#define DC__NUM_PHY__MAX__7 1
+#define DC__NUM_PHY_LP 0
+#define DC__NUM_PHY_LP__0 1
+#define DC__NUM_PHY_LP__MAX 2
+#define DC__NUM_PHY_LP__MAX__2 1
+#define DC__SYNC_CELL vid_sync_gf14lpp
+#define DC__SYNC_CELL__VID_SYNC_GF14LPP 1
+#define DC__USE_NEW_VSS 1
+#define DC__USE_NEW_VSS__1 1
+#define DC__SYNC_CELL_DISPCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DISPCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_DVOCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DVOCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_PIXCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_PIXCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_SYMCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_SYMCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_DPPCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DPPCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_DPREFCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DPREFCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_REFCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_REFCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_PCIE_REFCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_PCIE_REFCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_MVPCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_MVPCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_SCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_SCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_DCEFCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DCEFCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_AMCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_AMCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_DSICLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DSICLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_BYTECLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_BYTECLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_ESCCLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_ESCCLK_NUM_LATCHES__6 1
+#define DC__SYNC_CELL_DB_CLK_NUM_LATCHES 6
+#define DC__SYNC_CELL_DB_CLK_NUM_LATCHES__6 1
+#define UNIPHYA_PRESENT 1
+#define UNIPHYA_PRESENT__1 1
+#define DC__UNIPHYA_PRESENT 1
+#define DC__UNIPHYA_PRESENT__1 1
+#define UNIPHYB_PRESENT 1
+#define UNIPHYB_PRESENT__1 1
+#define DC__UNIPHYB_PRESENT 1
+#define DC__UNIPHYB_PRESENT__1 1
+#define UNIPHYC_PRESENT 1
+#define UNIPHYC_PRESENT__1 1
+#define DC__UNIPHYC_PRESENT 1
+#define DC__UNIPHYC_PRESENT__1 1
+#define UNIPHYD_PRESENT 1
+#define UNIPHYD_PRESENT__1 1
+#define DC__UNIPHYD_PRESENT 1
+#define DC__UNIPHYD_PRESENT__1 1
+#define UNIPHYE_PRESENT 0
+#define UNIPHYE_PRESENT__0 1
+#define DC__UNIPHYE_PRESENT 0
+#define DC__UNIPHYE_PRESENT__0 1
+#define UNIPHYF_PRESENT 0
+#define UNIPHYF_PRESENT__0 1
+#define DC__UNIPHYF_PRESENT 0
+#define DC__UNIPHYF_PRESENT__0 1
+#define UNIPHYG_PRESENT 0
+#define UNIPHYG_PRESENT__0 1
+#define DC__UNIPHYG_PRESENT 0
+#define DC__UNIPHYG_PRESENT__0 1
+#define DC__TMDS_LINK tmds_link_dual
+#define DC__TMDS_LINK__TMDS_LINK_DUAL 1
+#define DC__WBSCL_PIXBW 8
+#define DC__WBSCL_PIXBW__8 1
+#define DC__DWB_CSC_PRESENT 0
+#define DC__DWB_CSC_PRESENT__0 1
+#define DC__DWB_LUMA_SCL_PRESENT 0
+#define DC__DWB_LUMA_SCL_PRESENT__0 1
+#define DC__DENTIST_INTERFACE_PRESENT 1
+#define DC__DENTIST_INTERFACE_PRESENT__1 1
+#define DC__GENERICA_PRESENT 1
+#define DC__GENERICA_PRESENT__1 1
+#define DC__GENERICB_PRESENT 1
+#define DC__GENERICB_PRESENT__1 1
+#define DC__GENERICC_PRESENT 0
+#define DC__GENERICC_PRESENT__0 1
+#define DC__GENERICD_PRESENT 0
+#define DC__GENERICD_PRESENT__0 1
+#define DC__GENERICE_PRESENT 0
+#define DC__GENERICE_PRESENT__0 1
+#define DC__GENERICF_PRESENT 0
+#define DC__GENERICF_PRESENT__0 1
+#define DC__GENERICG_PRESENT 0
+#define DC__GENERICG_PRESENT__0 1
+#define DC__UNIPHY_VOLTAGE_MODE 1
+#define DC__UNIPHY_VOLTAGE_MODE__1 1
+#define DC__BLON_TYPE dedicated
+#define DC__BLON_TYPE__DEDICATED 1
+#define DC__UNIPHY_STAGGER_CH_PRESENT 1
+#define DC__UNIPHY_STAGGER_CH_PRESENT__1 1
+#define DC__XDMA_PRESENT 0
+#define DC__XDMA_PRESENT__0 1
+#define XDMA__PRESENT 0
+#define XDMA__PRESENT__0 1
+#define DC__DP_MEM_PG 0
+#define DC__DP_MEM_PG__0 1
+#define DP__MEM_PG 0
+#define DP__MEM_PG__0 1
+#define DC__AFMT_MEM_PG 0
+#define DC__AFMT_MEM_PG__0 1
+#define AFMT__MEM_PG 0
+#define AFMT__MEM_PG__0 1
+#define DC__HDMI_MEM_PG 0
+#define DC__HDMI_MEM_PG__0 1
+#define HDMI__MEM_PG 0
+#define HDMI__MEM_PG__0 1
+#define DC__I2C_MEM_PG 0
+#define DC__I2C_MEM_PG__0 1
+#define I2C__MEM_PG 0
+#define I2C__MEM_PG__0 1
+#define DC__DSCL_MEM_PG 0
+#define DC__DSCL_MEM_PG__0 1
+#define DSCL__MEM_PG 0
+#define DSCL__MEM_PG__0 1
+#define DC__CM_MEM_PG 0
+#define DC__CM_MEM_PG__0 1
+#define CM__MEM_PG 0
+#define CM__MEM_PG__0 1
+#define DC__OBUF_MEM_PG 0
+#define DC__OBUF_MEM_PG__0 1
+#define OBUF__MEM_PG 0
+#define OBUF__MEM_PG__0 1
+#define DC__WBIF_MEM_PG 1
+#define DC__WBIF_MEM_PG__1 1
+#define WBIF__MEM_PG 1
+#define WBIF__MEM_PG__1 1
+#define DC__VGA_MEM_PG 0
+#define DC__VGA_MEM_PG__0 1
+#define VGA__MEM_PG 0
+#define VGA__MEM_PG__0 1
+#define DC__FMT_MEM_PG 0
+#define DC__FMT_MEM_PG__0 1
+#define FMT__MEM_PG 0
+#define FMT__MEM_PG__0 1
+#define DC__ODM_MEM_PG 0
+#define DC__ODM_MEM_PG__0 1
+#define ODM__MEM_PG 0
+#define ODM__MEM_PG__0 1
+#define DC__DSI_MEM_PG 0
+#define DC__DSI_MEM_PG__0 1
+#define DSI__MEM_PG 0
+#define DSI__MEM_PG__0 1
+#define DC__AZ_MEM_PG 1
+#define DC__AZ_MEM_PG__1 1
+#define AZ__MEM_PG 1
+#define AZ__MEM_PG__1 1
+#define DC__WBSCL_MEM1P1024X64QS_MEM_PG 1
+#define DC__WBSCL_MEM1P1024X64QS_MEM_PG__1 1
+#define WBSCL_MEM1P1024X64QS__MEM_PG 1
+#define WBSCL_MEM1P1024X64QS__MEM_PG__1 1
+#define DC__WBSCL_MEM1P528X64QS_MEM_PG 1
+#define DC__WBSCL_MEM1P528X64QS_MEM_PG__1 1
+#define WBSCL_MEM1P528X64QS__MEM_PG 1
+#define WBSCL_MEM1P528X64QS__MEM_PG__1 1
+#define DC__DMCU_MEM1P1024X32BQS_MEM_PG 1
+#define DC__DMCU_MEM1P1024X32BQS_MEM_PG__1 1
+#define DMCU_MEM1P1024X32BQS__MEM_PG 1
+#define DMCU_MEM1P1024X32BQS__MEM_PG__1 1
+#define DC__HUBBUB_SDP_TAG_INT_MEM_PG 0
+#define DC__HUBBUB_SDP_TAG_INT_MEM_PG__0 1
+#define HUBBUB_SDP_TAG_INT__MEM_PG 0
+#define HUBBUB_SDP_TAG_INT__MEM_PG__0 1
+#define DC__HUBBUB_SDP_TAG_EXT_MEM_PG 0
+#define DC__HUBBUB_SDP_TAG_EXT_MEM_PG__0 1
+#define HUBBUB_SDP_TAG_EXT__MEM_PG 0
+#define HUBBUB_SDP_TAG_EXT__MEM_PG__0 1
+#define DC__HUBBUB_RET_ZERO_MEM_PG 0
+#define DC__HUBBUB_RET_ZERO_MEM_PG__0 1
+#define HUBBUB_RET_ZERO__MEM_PG 0
+#define HUBBUB_RET_ZERO__MEM_PG__0 1
+#define DC__HUBBUB_RET_ROB_MEM_PG 0
+#define DC__HUBBUB_RET_ROB_MEM_PG__0 1
+#define HUBBUB_RET_ROB__MEM_PG 0
+#define HUBBUB_RET_ROB__MEM_PG__0 1
+#define DC__HUBPRET_CUR_ROB_MEM_PG 0
+#define DC__HUBPRET_CUR_ROB_MEM_PG__0 1
+#define HUBPRET_CUR_ROB__MEM_PG 0
+#define HUBPRET_CUR_ROB__MEM_PG__0 1
+#define DC__HUBPRET_CUR_CDC_MEM_PG 0
+#define DC__HUBPRET_CUR_CDC_MEM_PG__0 1
+#define HUBPRET_CUR_CDC__MEM_PG 0
+#define HUBPRET_CUR_CDC__MEM_PG__0 1
+#define DC__HUBPREQ_MPTE_MEM_PG 0
+#define DC__HUBPREQ_MPTE_MEM_PG__0 1
+#define HUBPREQ_MPTE__MEM_PG 0
+#define HUBPREQ_MPTE__MEM_PG__0 1
+#define DC__HUBPREQ_META_MEM_PG 0
+#define DC__HUBPREQ_META_MEM_PG__0 1
+#define HUBPREQ_META__MEM_PG 0
+#define HUBPREQ_META__MEM_PG__0 1
+#define DC__HUBPREQ_DPTE_MEM_PG 0
+#define DC__HUBPREQ_DPTE_MEM_PG__0 1
+#define HUBPREQ_DPTE__MEM_PG 0
+#define HUBPREQ_DPTE__MEM_PG__0 1
+#define DC__HUBPRET_DET_MEM_PG 0
+#define DC__HUBPRET_DET_MEM_PG__0 1
+#define HUBPRET_DET__MEM_PG 0
+#define HUBPRET_DET__MEM_PG__0 1
+#define DC__HUBPRET_PIX_CDC_MEM_PG 0
+#define DC__HUBPRET_PIX_CDC_MEM_PG__0 1
+#define HUBPRET_PIX_CDC__MEM_PG 0
+#define HUBPRET_PIX_CDC__MEM_PG__0 1
+#define DC__TOP_BLKS__DCCG 1
+#define DC__TOP_BLKS__DCHUBBUB 1
+#define DC__TOP_BLKS__DCHUBP 1
+#define DC__TOP_BLKS__HDA 1
+#define DC__TOP_BLKS__DIO 1
+#define DC__TOP_BLKS__DCIO 1
+#define DC__TOP_BLKS__DMU 1
+#define DC__TOP_BLKS__DPP 1
+#define DC__TOP_BLKS__MPC 1
+#define DC__TOP_BLKS__OPP 1
+#define DC__TOP_BLKS__OPTC 1
+#define DC__TOP_BLKS__MMHUBBUB 1
+#define DC__TOP_BLKS__WB 1
+#define DC__TOP_BLKS__MAX 13
+#define DC__TOP_BLKS__MAX__13 1
+#define DC__DCHUBP_DPP_SF_PIXEL_CREDITS 9
+#define DC__DCHUBP_DPP_SF_PIXEL_CREDITS__9 1
+#define DC__DPP_MPC_SF_PIXEL_CREDITS 9
+#define DC__DPP_MPC_SF_PIXEL_CREDITS__9 1
+#define DC__MPC_OPP_SF_PIXEL_CREDITS 8
+#define DC__MPC_OPP_SF_PIXEL_CREDITS__8 1
+#define DC__OPP_OPTC_SF_PIXEL_CREDITS 8
+#define DC__OPP_OPTC_SF_PIXEL_CREDITS__8 1
+#define DC__SFR_SFT_ROUND_TRIP_DELAY 5
+#define DC__SFR_SFT_ROUND_TRIP_DELAY__5 1
+#define DC__REPEATER_PROJECT_MAX 8
+#define DC__REPEATER_PROJECT_MAX__8 1
+#define DC__SURFACE_422_CAPABLE 0
+#define DC__SURFACE_422_CAPABLE__0 1
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
new file mode 100644 (file)
index 0000000..143a3d4
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2017 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 __DISPLAY_MODE_ENUMS_H__
+#define __DISPLAY_MODE_ENUMS_H__
+enum output_encoder_class {
+       dm_dp = 0,
+       dm_hdmi = 1,
+       dm_wb = 2
+};
+enum output_format_class {
+       dm_444 = 0,
+       dm_420 = 1
+};
+enum source_format_class {
+       dm_444_16 = 0,
+       dm_444_32 = 1,
+       dm_444_64 = 2,
+       dm_420_8 = 3,
+       dm_420_10 = 4,
+       dm_422_8 = 5,
+       dm_422_10 = 6
+};
+enum output_bpc_class {
+       dm_out_6 = 0,
+       dm_out_8 = 1,
+       dm_out_10 = 2,
+       dm_out_12 = 3,
+       dm_out_16 = 4
+};
+enum scan_direction_class {
+       dm_horz = 0,
+       dm_vert = 1
+};
+enum dm_swizzle_mode {
+       dm_sw_linear = 0,
+       dm_sw_256b_s = 1,
+       dm_sw_256b_d = 2,
+       dm_sw_SPARE_0 = 3,
+       dm_sw_SPARE_1 = 4,
+       dm_sw_4kb_s = 5,
+       dm_sw_4kb_d = 6,
+       dm_sw_SPARE_2 = 7,
+       dm_sw_SPARE_3 = 8,
+       dm_sw_64kb_s = 9,
+       dm_sw_64kb_d = 10,
+       dm_sw_SPARE_4 = 11,
+       dm_sw_SPARE_5 = 12,
+       dm_sw_var_s = 13,
+       dm_sw_var_d = 14,
+       dm_sw_SPARE_6 = 15,
+       dm_sw_SPARE_7 = 16,
+       dm_sw_64kb_s_t = 17,
+       dm_sw_64kb_d_t = 18,
+       dm_sw_SPARE_10 = 19,
+       dm_sw_SPARE_11 = 20,
+       dm_sw_4kb_s_x = 21,
+       dm_sw_4kb_d_x = 22,
+       dm_sw_SPARE_12 = 23,
+       dm_sw_SPARE_13 = 24,
+       dm_sw_64kb_s_x = 25,
+       dm_sw_64kb_d_x = 26,
+       dm_sw_SPARE_14 = 27,
+       dm_sw_SPARE_15 = 28,
+       dm_sw_var_s_x = 29,
+       dm_sw_var_d_x = 30
+};
+enum lb_depth {
+       dm_lb_10 = 30,
+       dm_lb_8 = 24,
+       dm_lb_6 = 18,
+       dm_lb_12 = 36
+};
+enum voltage_state {
+       dm_vmin = 0,
+       dm_vmid = 1,
+       dm_vnom = 2,
+       dm_vmax = 3,
+       dm_vmax_exceeded = 4
+};
+enum source_macro_tile_size {
+       dm_4k_tile = 0,
+       dm_64k_tile = 1,
+       dm_256k_tile = 2
+};
+enum cursor_bpp {
+       dm_cur_2bit = 0,
+       dm_cur_32bit = 1
+};
+#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
new file mode 100644 (file)
index 0000000..c02c552
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2017 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"
+
+static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project)
+{
+       if (project == DML_PROJECT_RAVEN1) {
+               soc->sr_exit_time_us = 9.0;
+               soc->sr_enter_plus_exit_time_us = 11.0;
+               soc->urgent_latency_us = 4.0;
+               soc->writeback_latency_us = 12.0;
+               soc->ideal_dram_bw_after_urgent_percent = 80.0;
+               soc->max_request_size_bytes = 256;
+
+               soc->vmin.dcfclk_mhz = 300.0;
+               soc->vmin.dispclk_mhz = 608.0;
+               soc->vmin.dppclk_mhz = 435.0;
+               soc->vmin.dram_bw_per_chan_gbps = 12.8;
+               soc->vmin.phyclk_mhz = 540.0;
+               soc->vmin.socclk_mhz = 208.0;
+
+               soc->vmid.dcfclk_mhz = 600.0;
+               soc->vmid.dispclk_mhz = 661.0;
+               soc->vmid.dppclk_mhz = 661.0;
+               soc->vmid.dram_bw_per_chan_gbps = 12.8;
+               soc->vmid.phyclk_mhz = 540.0;
+               soc->vmid.socclk_mhz = 208.0;
+
+               soc->vnom.dcfclk_mhz = 600.0;
+               soc->vnom.dispclk_mhz = 661.0;
+               soc->vnom.dppclk_mhz = 661.0;
+               soc->vnom.dram_bw_per_chan_gbps = 38.4;
+               soc->vnom.phyclk_mhz = 810;
+               soc->vnom.socclk_mhz = 208.0;
+
+               soc->vmax.dcfclk_mhz = 600.0;
+               soc->vmax.dispclk_mhz = 1086.0;
+               soc->vmax.dppclk_mhz = 661.0;
+               soc->vmax.dram_bw_per_chan_gbps = 38.4;
+               soc->vmax.phyclk_mhz = 810.0;
+               soc->vmax.socclk_mhz = 208.0;
+
+               soc->downspread_percent = 0.5;
+               soc->dram_page_open_time_ns = 50.0;
+               soc->dram_rw_turnaround_time_ns = 17.5;
+               soc->dram_return_buffer_per_channel_bytes = 8192;
+               soc->round_trip_ping_latency_dcfclk_cycles = 128;
+               soc->urgent_out_of_order_return_per_channel_bytes = 256;
+               soc->channel_interleave_bytes = 256;
+               soc->num_banks = 8;
+               soc->num_chans = 2;
+               soc->vmm_page_size_bytes = 4096;
+               soc->dram_clock_change_latency_us = 17.0;
+               soc->writeback_dram_clock_change_latency_us = 23.0;
+               soc->return_bus_width_bytes = 64;
+       } else {
+               BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
+       }
+}
+
+static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project project)
+{
+       if (project == DML_PROJECT_RAVEN1) {
+               ip->rob_buffer_size_kbytes = 64;
+               ip->det_buffer_size_kbytes = 164;
+               ip->dpte_buffer_size_in_pte_reqs = 42;
+               ip->dpp_output_buffer_pixels = 2560;
+               ip->opp_output_buffer_lines = 1;
+               ip->pixel_chunk_size_kbytes = 8;
+               ip->pte_enable = 1;
+               ip->pte_chunk_size_kbytes = 2;
+               ip->meta_chunk_size_kbytes = 2;
+               ip->writeback_chunk_size_kbytes = 2;
+               ip->line_buffer_size_bits = 589824;
+               ip->max_line_buffer_lines = 12;
+               ip->IsLineBufferBppFixed = 0;
+               ip->LineBufferFixedBpp = -1;
+               ip->writeback_luma_buffer_size_kbytes = 12;
+               ip->writeback_chroma_buffer_size_kbytes = 8;
+               ip->max_num_dpp = 4;
+               ip->max_num_wb = 2;
+               ip->max_dchub_pscl_bw_pix_per_clk = 4;
+               ip->max_pscl_lb_bw_pix_per_clk = 2;
+               ip->max_lb_vscl_bw_pix_per_clk = 4;
+               ip->max_vscl_hscl_bw_pix_per_clk = 4;
+               ip->max_hscl_ratio = 4;
+               ip->max_vscl_ratio = 4;
+               ip->hscl_mults = 4;
+               ip->vscl_mults = 4;
+               ip->max_hscl_taps = 8;
+               ip->max_vscl_taps = 8;
+               ip->dispclk_ramp_margin_percent = 1;
+               ip->underscan_factor = 1.10;
+               ip->min_vblank_lines = 14;
+               ip->dppclk_delay_subtotal = 90;
+               ip->dispclk_delay_subtotal = 42;
+               ip->dcfclk_cstate_latency = 10;
+               ip->max_inter_dcn_tile_repeaters = 8;
+               ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = 0;
+               ip->bug_forcing_LC_req_same_size_fixed = 0;
+       } else {
+               BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
+       }
+}
+
+static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project)
+{
+       if (project == DML_PROJECT_RAVEN1) {
+               me->voltage_override = dm_vmin;
+       } else {
+               BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
+       }
+}
+
+void dml_init_instance(struct display_mode_lib *lib, enum dml_project project)
+{
+       if (lib->project != project) {
+               set_soc_bounding_box(&lib->soc, project);
+               set_ip_params(&lib->ip, project);
+               set_mode_evaluation(&lib->me, project);
+               lib->project = project;
+       }
+}
+
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
new file mode 100644 (file)
index 0000000..e2e3111
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017 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 __DISPLAY_MODE_LIB_H__
+#define __DISPLAY_MODE_LIB_H__
+
+#include "dml_common_defs.h"
+#include "soc_bounding_box.h"
+#include "display_watermark.h"
+#include "display_pipe_clocks.h"
+#include "display_rq_dlg_calc.h"
+#include "display_mode_support.h"
+
+enum dml_project {
+       DML_PROJECT_UNDEFINED,
+       DML_PROJECT_RAVEN1
+};
+
+struct display_mode_lib {
+       struct _vcs_dpi_ip_params_st ip;
+       struct _vcs_dpi_soc_bounding_box_st soc;
+       struct _vcs_dpi_mode_evaluation_st me;
+       enum dml_project project;
+       struct dml_ms_internal_vars vars;
+       struct _vcs_dpi_wm_calc_pipe_params_st wm_param[DC__NUM_PIPES__MAX];
+       struct dal_logger *logger;
+};
+
+void dml_init_instance(struct display_mode_lib *lib, enum dml_project project);
+
+#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
new file mode 100644 (file)
index 0000000..e589a5e
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2017 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 __DISPLAY_MODE_STRUCTS_H__
+#define __DISPLAY_MODE_STRUCTS_H__
+
+struct _vcs_dpi_voltage_scaling_st {
+       double dcfclk_mhz;
+       double dispclk_mhz;
+       double dppclk_mhz;
+       double dram_bw_per_chan_gbps;
+       double phyclk_mhz;
+       double socclk_mhz;
+};
+
+struct _vcs_dpi_soc_bounding_box_st {
+       double sr_exit_time_us;
+       double sr_enter_plus_exit_time_us;
+       double urgent_latency_us;
+       double writeback_latency_us;
+       double ideal_dram_bw_after_urgent_percent;
+       unsigned int max_request_size_bytes;
+       struct _vcs_dpi_voltage_scaling_st vmin;
+       struct _vcs_dpi_voltage_scaling_st vmid;
+       struct _vcs_dpi_voltage_scaling_st vnom;
+       struct _vcs_dpi_voltage_scaling_st vmax;
+       double downspread_percent;
+       double dram_page_open_time_ns;
+       double dram_rw_turnaround_time_ns;
+       double dram_return_buffer_per_channel_bytes;
+       unsigned int round_trip_ping_latency_dcfclk_cycles;
+       unsigned int urgent_out_of_order_return_per_channel_bytes;
+       unsigned int channel_interleave_bytes;
+       unsigned int num_banks;
+       unsigned int num_chans;
+       unsigned int vmm_page_size_bytes;
+       double dram_clock_change_latency_us;
+       double writeback_dram_clock_change_latency_us;
+       unsigned int return_bus_width_bytes;
+};
+
+struct _vcs_dpi_ip_params_st {
+       unsigned int rob_buffer_size_kbytes;
+       unsigned int det_buffer_size_kbytes;
+       unsigned int dpte_buffer_size_in_pte_reqs;
+       unsigned int dpp_output_buffer_pixels;
+       unsigned int opp_output_buffer_lines;
+       unsigned int pixel_chunk_size_kbytes;
+       unsigned char pte_enable;
+       unsigned int pte_chunk_size_kbytes;
+       unsigned int meta_chunk_size_kbytes;
+       unsigned int writeback_chunk_size_kbytes;
+       unsigned int line_buffer_size_bits;
+       unsigned int max_line_buffer_lines;
+       unsigned int IsLineBufferBppFixed;
+       unsigned int LineBufferFixedBpp;
+       unsigned int writeback_luma_buffer_size_kbytes;
+       unsigned int writeback_chroma_buffer_size_kbytes;
+       unsigned int max_num_dpp;
+       unsigned int max_num_wb;
+       unsigned int max_dchub_pscl_bw_pix_per_clk;
+       unsigned int max_pscl_lb_bw_pix_per_clk;
+       unsigned int max_lb_vscl_bw_pix_per_clk;
+       unsigned int max_vscl_hscl_bw_pix_per_clk;
+       double max_hscl_ratio;
+       double max_vscl_ratio;
+       unsigned int hscl_mults;
+       unsigned int vscl_mults;
+       unsigned int max_hscl_taps;
+       unsigned int max_vscl_taps;
+       double dispclk_ramp_margin_percent;
+       double underscan_factor;
+       unsigned int min_vblank_lines;
+       unsigned int dppclk_delay_subtotal;
+       unsigned int dispclk_delay_subtotal;
+       unsigned int dcfclk_cstate_latency;
+       unsigned int max_inter_dcn_tile_repeaters;
+       unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
+       unsigned int bug_forcing_LC_req_same_size_fixed;
+};
+
+struct _vcs_dpi_display_pipe_source_params_st {
+       int source_format;
+       unsigned char dcc;
+       unsigned int dcc_rate;
+       unsigned char vm;
+       int source_scan;
+       int sw_mode;
+       int macro_tile_size;
+       unsigned char is_display_sw;
+       unsigned int viewport_width;
+       unsigned int viewport_height;
+       unsigned int viewport_width_c;
+       unsigned int viewport_height_c;
+       unsigned int data_pitch;
+       unsigned int data_pitch_c;
+       unsigned int meta_pitch;
+       unsigned int meta_pitch_c;
+       unsigned int cur0_src_width;
+       int cur0_bpp;
+       unsigned char is_hsplit;
+       unsigned int hsplit_grp;
+};
+
+struct _vcs_dpi_display_output_params_st {
+       int output_bpc;
+       int output_type;
+       int output_format;
+       int output_standard;
+};
+
+struct _vcs_dpi_display_bandwidth_st {
+       double total_bw_consumed_gbps;
+       double guaranteed_urgent_return_bw_gbps;
+};
+
+struct _vcs_dpi_scaler_ratio_depth_st {
+       double hscl_ratio;
+       double vscl_ratio;
+       double hscl_ratio_c;
+       double vscl_ratio_c;
+       double vinit;
+       double vinit_c;
+       double vinit_bot;
+       double vinit_bot_c;
+       int lb_depth;
+};
+
+struct _vcs_dpi_scaler_taps_st {
+       unsigned int htaps;
+       unsigned int vtaps;
+       unsigned int htaps_c;
+       unsigned int vtaps_c;
+};
+
+struct _vcs_dpi_display_pipe_dest_params_st {
+       unsigned int recout_width;
+       unsigned int recout_height;
+       unsigned int full_recout_width;
+       unsigned int full_recout_height;
+       unsigned int hblank_start;
+       unsigned int hblank_end;
+       unsigned int vblank_start;
+       unsigned int vblank_end;
+       unsigned int htotal;
+       unsigned int vtotal;
+       unsigned int vactive;
+       unsigned int vstartup_start;
+       unsigned int vupdate_offset;
+       unsigned int vupdate_width;
+       unsigned int vready_offset;
+       unsigned int vsync_plus_back_porch;
+       unsigned char interlaced;
+       unsigned char underscan;
+       double pixel_rate_mhz;
+       unsigned char syncronized_vblank_all_planes;
+};
+
+struct _vcs_dpi_display_pipe_params_st {
+       struct _vcs_dpi_display_pipe_source_params_st src;
+       struct _vcs_dpi_display_pipe_dest_params_st dest;
+       struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth;
+       struct _vcs_dpi_scaler_taps_st scale_taps;
+};
+
+struct _vcs_dpi_display_clocks_and_cfg_st {
+       int voltage;
+       double dppclk_mhz;
+       double refclk_mhz;
+       double dispclk_mhz;
+       double dcfclk_mhz;
+       double socclk_mhz;
+};
+
+struct _vcs_dpi_display_e2e_pipe_params_st {
+       struct _vcs_dpi_display_pipe_params_st pipe;
+       struct _vcs_dpi_display_output_params_st dout;
+       struct _vcs_dpi_display_clocks_and_cfg_st clks_cfg;
+};
+
+struct _vcs_dpi_dchub_buffer_sizing_st {
+       unsigned int swath_width_y;
+       unsigned int swath_height_y;
+       unsigned int swath_height_c;
+       unsigned int detail_buffer_size_y;
+};
+
+struct _vcs_dpi_watermarks_perf_st {
+       double stutter_eff_in_active_region_percent;
+       double urgent_latency_supported_us;
+       double non_urgent_latency_supported_us;
+       double dram_clock_change_margin_us;
+       double dram_access_eff_percent;
+};
+
+struct _vcs_dpi_cstate_pstate_watermarks_st {
+       double cstate_exit_us;
+       double cstate_enter_plus_exit_us;
+       double pstate_change_us;
+};
+
+struct _vcs_dpi_wm_calc_pipe_params_st {
+       unsigned int num_dpp;
+       int voltage;
+       int output_type;
+       double dcfclk_mhz;
+       double socclk_mhz;
+       double dppclk_mhz;
+       double pixclk_mhz;
+       unsigned char interlace_en;
+       unsigned char pte_enable;
+       unsigned char dcc_enable;
+       double dcc_rate;
+       double bytes_per_pixel_c;
+       double bytes_per_pixel_y;
+       unsigned int swath_width_y;
+       unsigned int swath_height_y;
+       unsigned int swath_height_c;
+       unsigned int det_buffer_size_y;
+       double h_ratio;
+       double v_ratio;
+       unsigned int h_taps;
+       unsigned int h_total;
+       unsigned int v_total;
+       unsigned int v_active;
+       unsigned int e2e_index;
+       double display_pipe_line_delivery_time;
+       double read_bw;
+       unsigned int lines_in_det_y;
+       unsigned int lines_in_det_y_rounded_down_to_swath;
+       double full_det_buffering_time;
+       double dcfclk_deepsleep_mhz_per_plane;
+};
+
+struct _vcs_dpi_vratio_pre_st {
+       double vratio_pre_l;
+       double vratio_pre_c;
+};
+
+struct _vcs_dpi_display_data_rq_misc_params_st {
+       unsigned int full_swath_bytes;
+       unsigned int stored_swath_bytes;
+       unsigned int blk256_height;
+       unsigned int blk256_width;
+       unsigned int req_height;
+       unsigned int req_width;
+};
+
+struct _vcs_dpi_display_data_rq_sizing_params_st {
+       unsigned int chunk_bytes;
+       unsigned int min_chunk_bytes;
+       unsigned int meta_chunk_bytes;
+       unsigned int min_meta_chunk_bytes;
+       unsigned int mpte_group_bytes;
+       unsigned int dpte_group_bytes;
+};
+
+struct _vcs_dpi_display_data_rq_dlg_params_st {
+       unsigned int swath_width_ub;
+       unsigned int swath_height;
+       unsigned int req_per_swath_ub;
+       unsigned int meta_pte_bytes_per_frame_ub;
+       unsigned int dpte_req_per_row_ub;
+       unsigned int dpte_groups_per_row_ub;
+       unsigned int dpte_row_height;
+       unsigned int dpte_bytes_per_row_ub;
+       unsigned int meta_chunks_per_row_ub;
+       unsigned int meta_req_per_row_ub;
+       unsigned int meta_row_height;
+       unsigned int meta_bytes_per_row_ub;
+};
+
+struct _vcs_dpi_display_cur_rq_dlg_params_st {
+       unsigned char enable;
+       unsigned int swath_height;
+       unsigned int req_per_line;
+};
+
+struct _vcs_dpi_display_rq_dlg_params_st {
+       struct _vcs_dpi_display_data_rq_dlg_params_st rq_l;
+       struct _vcs_dpi_display_data_rq_dlg_params_st rq_c;
+       struct _vcs_dpi_display_cur_rq_dlg_params_st rq_cur0;
+};
+
+struct _vcs_dpi_display_rq_sizing_params_st {
+       struct _vcs_dpi_display_data_rq_sizing_params_st rq_l;
+       struct _vcs_dpi_display_data_rq_sizing_params_st rq_c;
+};
+
+struct _vcs_dpi_display_rq_misc_params_st {
+       struct _vcs_dpi_display_data_rq_misc_params_st rq_l;
+       struct _vcs_dpi_display_data_rq_misc_params_st rq_c;
+};
+
+struct _vcs_dpi_display_rq_params_st {
+       unsigned char yuv420;
+       unsigned char yuv420_10bpc;
+       struct _vcs_dpi_display_rq_misc_params_st misc;
+       struct _vcs_dpi_display_rq_sizing_params_st sizing;
+       struct _vcs_dpi_display_rq_dlg_params_st dlg;
+};
+
+struct _vcs_dpi_display_dlg_regs_st {
+       unsigned int refcyc_h_blank_end;
+       unsigned int dlg_vblank_end;
+       unsigned int min_dst_y_next_start;
+       unsigned int refcyc_per_htotal;
+       unsigned int refcyc_x_after_scaler;
+       unsigned int dst_y_after_scaler;
+       unsigned int dst_y_prefetch;
+       unsigned int dst_y_per_vm_vblank;
+       unsigned int dst_y_per_row_vblank;
+       unsigned int ref_freq_to_pix_freq;
+       unsigned int vratio_prefetch;
+       unsigned int vratio_prefetch_c;
+       unsigned int refcyc_per_pte_group_vblank_l;
+       unsigned int refcyc_per_pte_group_vblank_c;
+       unsigned int refcyc_per_meta_chunk_vblank_l;
+       unsigned int refcyc_per_meta_chunk_vblank_c;
+       unsigned int dst_y_per_pte_row_nom_l;
+       unsigned int dst_y_per_pte_row_nom_c;
+       unsigned int refcyc_per_pte_group_nom_l;
+       unsigned int refcyc_per_pte_group_nom_c;
+       unsigned int dst_y_per_meta_row_nom_l;
+       unsigned int dst_y_per_meta_row_nom_c;
+       unsigned int refcyc_per_meta_chunk_nom_l;
+       unsigned int refcyc_per_meta_chunk_nom_c;
+       unsigned int refcyc_per_line_delivery_pre_l;
+       unsigned int refcyc_per_line_delivery_pre_c;
+       unsigned int refcyc_per_line_delivery_l;
+       unsigned int refcyc_per_line_delivery_c;
+       unsigned int chunk_hdl_adjust_cur0;
+};
+
+struct _vcs_dpi_display_ttu_regs_st {
+       unsigned int qos_level_low_wm;
+       unsigned int qos_level_high_wm;
+       unsigned int min_ttu_vblank;
+       unsigned int qos_level_flip;
+       unsigned int refcyc_per_req_delivery_l;
+       unsigned int refcyc_per_req_delivery_c;
+       unsigned int refcyc_per_req_delivery_cur0;
+       unsigned int refcyc_per_req_delivery_pre_l;
+       unsigned int refcyc_per_req_delivery_pre_c;
+       unsigned int refcyc_per_req_delivery_pre_cur0;
+       unsigned int qos_level_fixed_l;
+       unsigned int qos_level_fixed_c;
+       unsigned int qos_level_fixed_cur0;
+       unsigned int qos_ramp_disable_l;
+       unsigned int qos_ramp_disable_c;
+       unsigned int qos_ramp_disable_cur0;
+};
+
+struct _vcs_dpi_display_data_rq_regs_st {
+       unsigned int chunk_size;
+       unsigned int min_chunk_size;
+       unsigned int meta_chunk_size;
+       unsigned int min_meta_chunk_size;
+       unsigned int dpte_group_size;
+       unsigned int mpte_group_size;
+       unsigned int swath_height;
+       unsigned int pte_row_height_linear;
+};
+
+struct _vcs_dpi_display_rq_regs_st {
+       struct _vcs_dpi_display_data_rq_regs_st rq_regs_l;
+       struct _vcs_dpi_display_data_rq_regs_st rq_regs_c;
+       unsigned int drq_expansion_mode;
+       unsigned int prq_expansion_mode;
+       unsigned int mrq_expansion_mode;
+       unsigned int crq_expansion_mode;
+       unsigned int plane1_base_address;
+};
+
+struct _vcs_dpi_display_dlg_sys_params_st {
+       double t_mclk_wm_us;
+       double t_urg_wm_us;
+       double t_sr_wm_us;
+       double t_extra_us;
+       double t_srx_delay_us;
+       double deepsleep_dcfclk_mhz;
+       double total_flip_bw;
+       unsigned int total_flip_bytes;
+};
+
+struct _vcs_dpi_display_dlg_prefetch_param_st {
+       double prefetch_bw;
+       unsigned int flip_bytes;
+};
+
+struct _vcs_dpi_display_pipe_clock_st {
+       double dcfclk_mhz;
+       double dispclk_mhz;
+       double dppclk_mhz[4];
+       unsigned char dppclk_div[4];
+};
+
+struct _vcs_dpi_display_arb_params_st {
+       int max_req_outstanding;
+       int min_req_outstanding;
+       int sat_level_us;
+};
+
+struct _vcs_dpi_mode_evaluation_st {
+       int voltage_override;
+};
+
+#endif /*__DISPLAY_MODE_STRUCTS_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.c
new file mode 100644 (file)
index 0000000..3b4ee74
--- /dev/null
@@ -0,0 +1,2326 @@
+/*
+ * Copyright 2017 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_support.h"
+#include "display_mode_lib.h"
+
+int dml_ms_check(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               int num_pipes)
+{
+       struct _vcs_dpi_ip_params_st *ip;
+       struct _vcs_dpi_soc_bounding_box_st *soc;
+       struct _vcs_dpi_mode_evaluation_st *me;
+       struct dml_ms_internal_vars *v;
+       int num_planes, i, j, ij, k, ijk;
+
+       ip = &(mode_lib->ip);
+       soc = &(mode_lib->soc);
+       me = &(mode_lib->me);
+       v = &(mode_lib->vars);
+       num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, v->planes);
+
+       //instantiating variables to zero
+       v->MacroTileBlockWidthC = 0;
+       v->SwathWidthGranularityC = 0;
+
+       v->DCFCLKPerState[5] = 0;
+       v->DCFCLKPerState[4] = 0;
+       v->DCFCLKPerState[3] = 0;
+       v->DCFCLKPerState[2] = 0;
+       v->DCFCLKPerState[1] = 0;
+       v->DCFCLKPerState[0] = 0;
+
+       if (soc->vmin.dcfclk_mhz > 0) {
+               v->DCFCLKPerState[5] = soc->vmin.dcfclk_mhz;
+               v->DCFCLKPerState[4] = soc->vmin.dcfclk_mhz;
+               v->DCFCLKPerState[3] = soc->vmin.dcfclk_mhz;
+               v->DCFCLKPerState[2] = soc->vmin.dcfclk_mhz;
+               v->DCFCLKPerState[1] = soc->vmin.dcfclk_mhz;
+               v->DCFCLKPerState[0] = soc->vmin.dcfclk_mhz;
+       }
+
+       if (soc->vmid.dcfclk_mhz > 0) {
+               v->DCFCLKPerState[5] = soc->vmid.dcfclk_mhz;
+               v->DCFCLKPerState[4] = soc->vmid.dcfclk_mhz;
+               v->DCFCLKPerState[3] = soc->vmid.dcfclk_mhz;
+               v->DCFCLKPerState[2] = soc->vmid.dcfclk_mhz;
+               v->DCFCLKPerState[1] = soc->vmid.dcfclk_mhz;
+       }
+
+       if (soc->vnom.dcfclk_mhz > 0) {
+               v->DCFCLKPerState[5] = soc->vnom.dcfclk_mhz;
+               v->DCFCLKPerState[4] = soc->vnom.dcfclk_mhz;
+               v->DCFCLKPerState[3] = soc->vnom.dcfclk_mhz;
+               v->DCFCLKPerState[2] = soc->vnom.dcfclk_mhz;
+       }
+
+       if (soc->vmax.dcfclk_mhz > 0) {
+               v->DCFCLKPerState[5] = soc->vmax.dcfclk_mhz;
+               v->DCFCLKPerState[4] = soc->vmax.dcfclk_mhz;
+               v->DCFCLKPerState[3] = soc->vmax.dcfclk_mhz;
+       }
+
+       v->FabricAndDRAMBandwidthPerState[5] = 0;
+       v->FabricAndDRAMBandwidthPerState[4] = 0;
+       v->FabricAndDRAMBandwidthPerState[3] = 0;
+       v->FabricAndDRAMBandwidthPerState[2] = 0;
+       v->FabricAndDRAMBandwidthPerState[1] = 0;
+       v->FabricAndDRAMBandwidthPerState[0] = 0;
+
+       if (soc->vmin.dram_bw_per_chan_gbps > 0) {
+               v->FabricAndDRAMBandwidthPerState[5] = soc->vmin.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[4] = soc->vmin.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[3] = soc->vmin.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[2] = soc->vmin.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[1] = soc->vmin.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[0] = soc->vmin.dram_bw_per_chan_gbps;
+       }
+
+       if (soc->vmid.dram_bw_per_chan_gbps > 0) {
+               v->FabricAndDRAMBandwidthPerState[5] = soc->vmid.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[4] = soc->vmid.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[3] = soc->vmid.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[2] = soc->vmid.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[1] = soc->vmid.dram_bw_per_chan_gbps;
+       }
+
+       if (soc->vnom.dram_bw_per_chan_gbps > 0) {
+               v->FabricAndDRAMBandwidthPerState[5] = soc->vnom.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[4] = soc->vnom.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[3] = soc->vnom.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[2] = soc->vnom.dram_bw_per_chan_gbps;
+       }
+
+       if (soc->vmax.dram_bw_per_chan_gbps > 0) {
+               v->FabricAndDRAMBandwidthPerState[5] = soc->vmax.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[4] = soc->vmax.dram_bw_per_chan_gbps;
+               v->FabricAndDRAMBandwidthPerState[3] = soc->vmax.dram_bw_per_chan_gbps;
+       }
+
+       v->PHYCLKPerState[5] = 0;
+       v->PHYCLKPerState[4] = 0;
+       v->PHYCLKPerState[3] = 0;
+       v->PHYCLKPerState[2] = 0;
+       v->PHYCLKPerState[1] = 0;
+       v->PHYCLKPerState[0] = 0;
+
+       if (soc->vmin.phyclk_mhz > 0) {
+               v->PHYCLKPerState[5] = soc->vmin.phyclk_mhz;
+               v->PHYCLKPerState[4] = soc->vmin.phyclk_mhz;
+               v->PHYCLKPerState[3] = soc->vmin.phyclk_mhz;
+               v->PHYCLKPerState[2] = soc->vmin.phyclk_mhz;
+               v->PHYCLKPerState[1] = soc->vmin.phyclk_mhz;
+               v->PHYCLKPerState[0] = soc->vmin.phyclk_mhz;
+       }
+
+       if (soc->vmid.phyclk_mhz > 0) {
+               v->PHYCLKPerState[5] = soc->vmid.phyclk_mhz;
+               v->PHYCLKPerState[4] = soc->vmid.phyclk_mhz;
+               v->PHYCLKPerState[3] = soc->vmid.phyclk_mhz;
+               v->PHYCLKPerState[2] = soc->vmid.phyclk_mhz;
+               v->PHYCLKPerState[1] = soc->vmid.phyclk_mhz;
+       }
+
+       if (soc->vnom.phyclk_mhz > 0) {
+               v->PHYCLKPerState[5] = soc->vnom.phyclk_mhz;
+               v->PHYCLKPerState[4] = soc->vnom.phyclk_mhz;
+               v->PHYCLKPerState[3] = soc->vnom.phyclk_mhz;
+               v->PHYCLKPerState[2] = soc->vnom.phyclk_mhz;
+       }
+
+       if (soc->vmax.phyclk_mhz > 0) {
+               v->PHYCLKPerState[5] = soc->vmax.phyclk_mhz;
+               v->PHYCLKPerState[4] = soc->vmax.phyclk_mhz;
+               v->PHYCLKPerState[3] = soc->vmax.phyclk_mhz;
+       }
+
+       v->MaxDispclk[5] = 0;
+       v->MaxDispclk[4] = 0;
+       v->MaxDispclk[3] = 0;
+       v->MaxDispclk[2] = 0;
+       v->MaxDispclk[1] = 0;
+       v->MaxDispclk[0] = 0;
+
+       if (soc->vmin.dispclk_mhz > 0) {
+               v->MaxDispclk[5] = soc->vmin.dispclk_mhz;
+               v->MaxDispclk[4] = soc->vmin.dispclk_mhz;
+               v->MaxDispclk[3] = soc->vmin.dispclk_mhz;
+               v->MaxDispclk[2] = soc->vmin.dispclk_mhz;
+               v->MaxDispclk[1] = soc->vmin.dispclk_mhz;
+               v->MaxDispclk[0] = soc->vmin.dispclk_mhz;
+       }
+
+       if (soc->vmid.dispclk_mhz > 0) {
+               v->MaxDispclk[5] = soc->vmid.dispclk_mhz;
+               v->MaxDispclk[4] = soc->vmid.dispclk_mhz;
+               v->MaxDispclk[3] = soc->vmid.dispclk_mhz;
+               v->MaxDispclk[2] = soc->vmid.dispclk_mhz;
+               v->MaxDispclk[1] = soc->vmid.dispclk_mhz;
+       }
+
+       if (soc->vnom.dispclk_mhz > 0) {
+               v->MaxDispclk[5] = soc->vnom.dispclk_mhz;
+               v->MaxDispclk[4] = soc->vnom.dispclk_mhz;
+               v->MaxDispclk[3] = soc->vnom.dispclk_mhz;
+               v->MaxDispclk[2] = soc->vnom.dispclk_mhz;
+       }
+
+       if (soc->vmax.dispclk_mhz > 0) {
+               v->MaxDispclk[5] = soc->vmax.dispclk_mhz;
+               v->MaxDispclk[4] = soc->vmax.dispclk_mhz;
+               v->MaxDispclk[3] = soc->vmax.dispclk_mhz;
+       }
+
+       v->MaxDppclk[5] = 0;
+       v->MaxDppclk[4] = 0;
+       v->MaxDppclk[3] = 0;
+       v->MaxDppclk[2] = 0;
+       v->MaxDppclk[1] = 0;
+       v->MaxDppclk[0] = 0;
+
+       if (soc->vmin.dppclk_mhz > 0) {
+               v->MaxDppclk[5] = soc->vmin.dppclk_mhz;
+               v->MaxDppclk[4] = soc->vmin.dppclk_mhz;
+               v->MaxDppclk[3] = soc->vmin.dppclk_mhz;
+               v->MaxDppclk[2] = soc->vmin.dppclk_mhz;
+               v->MaxDppclk[1] = soc->vmin.dppclk_mhz;
+               v->MaxDppclk[0] = soc->vmin.dppclk_mhz;
+       }
+
+       if (soc->vmid.dppclk_mhz > 0) {
+               v->MaxDppclk[5] = soc->vmid.dppclk_mhz;
+               v->MaxDppclk[4] = soc->vmid.dppclk_mhz;
+               v->MaxDppclk[3] = soc->vmid.dppclk_mhz;
+               v->MaxDppclk[2] = soc->vmid.dppclk_mhz;
+               v->MaxDppclk[1] = soc->vmid.dppclk_mhz;
+       }
+
+       if (soc->vnom.dppclk_mhz > 0) {
+               v->MaxDppclk[5] = soc->vnom.dppclk_mhz;
+               v->MaxDppclk[4] = soc->vnom.dppclk_mhz;
+               v->MaxDppclk[3] = soc->vnom.dppclk_mhz;
+               v->MaxDppclk[2] = soc->vnom.dppclk_mhz;
+       }
+
+       if (soc->vmax.dppclk_mhz > 0) {
+               v->MaxDppclk[5] = soc->vmax.dppclk_mhz;
+               v->MaxDppclk[4] = soc->vmax.dppclk_mhz;
+               v->MaxDppclk[3] = soc->vmax.dppclk_mhz;
+       }
+
+       if (me->voltage_override == dm_vmax) {
+               v->VoltageOverrideLevel = NumberOfStates - 1;
+       } else if (me->voltage_override == dm_vnom) {
+               v->VoltageOverrideLevel = NumberOfStates - 2;
+       } else if (me->voltage_override == dm_vmid) {
+               v->VoltageOverrideLevel = NumberOfStates - 3;
+       } else {
+               v->VoltageOverrideLevel = 0;
+       }
+
+       // Scale Ratio Support Check
+
+       v->ScaleRatioSupport = 1;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+               struct _vcs_dpi_scaler_taps_st scale_taps =
+                               e2e[v->planes[k].e2e_index].pipe.scale_taps;
+               struct _vcs_dpi_display_pipe_source_params_st src =
+                               e2e[v->planes[k].e2e_index].pipe.src;
+
+               if (scale_ratio_depth.hscl_ratio > ip->max_hscl_ratio
+                               || scale_ratio_depth.vscl_ratio > ip->max_vscl_ratio
+                               || scale_ratio_depth.hscl_ratio > scale_taps.htaps
+                               || scale_ratio_depth.vscl_ratio > scale_taps.vtaps
+                               || (src.source_format != dm_444_64 && src.source_format != dm_444_32
+                                               && src.source_format != dm_444_16
+                                               && ((scale_ratio_depth.hscl_ratio / 2
+                                                               > scale_taps.htaps_c)
+                                                               || (scale_ratio_depth.vscl_ratio / 2
+                                                                               > scale_taps.vtaps_c))))
+
+                               {
+                       v->ScaleRatioSupport = 0;
+               }
+       }
+
+       // Source Format, Pixel Format and Scan Support Check
+
+       v->SourceFormatPixelAndScanSupport = 1;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_source_params_st src =
+                               e2e[v->planes[k].e2e_index].pipe.src;
+
+               if ((src.sw_mode == dm_sw_linear && src.source_scan != dm_horz)
+                               || ((src.sw_mode == dm_sw_4kb_d || src.sw_mode == dm_sw_4kb_d_x
+                                               || src.sw_mode == dm_sw_64kb_d
+                                               || src.sw_mode == dm_sw_64kb_d_t
+                                               || src.sw_mode == dm_sw_64kb_d_x
+                                               || src.sw_mode == dm_sw_var_d
+                                               || src.sw_mode == dm_sw_var_d_x)
+                                               && (src.source_format != dm_444_64))) {
+                       v->SourceFormatPixelAndScanSupport = 0;
+               }
+       }
+
+       // Bandwidth Support Check
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_source_params_st src =
+                               e2e[v->planes[k].e2e_index].pipe.src;
+
+               if (src.source_scan == dm_horz) {
+                       v->SwathWidthYSingleDPP[k] = src.viewport_width;
+               } else {
+                       v->SwathWidthYSingleDPP[k] = src.viewport_height;
+               }
+
+               if (src.source_format == dm_444_64) {
+                       v->BytePerPixelInDETY[k] = 8;
+                       v->BytePerPixelInDETC[k] = 0;
+               } else if (src.source_format == dm_444_32) {
+                       v->BytePerPixelInDETY[k] = 4;
+                       v->BytePerPixelInDETC[k] = 0;
+               } else if (src.source_format == dm_444_16) {
+                       v->BytePerPixelInDETY[k] = 2;
+                       v->BytePerPixelInDETC[k] = 0;
+               } else if (src.source_format == dm_420_8) {
+                       v->BytePerPixelInDETY[k] = 1;
+                       v->BytePerPixelInDETC[k] = 2;
+               } else {
+                       v->BytePerPixelInDETY[k] = 4.00 / 3.00;
+                       v->BytePerPixelInDETC[k] = 8.00 / 3.00;
+               }
+       }
+
+       v->TotalReadBandwidthConsumedGBytePerSecond = 0;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_source_params_st src =
+                               e2e[v->planes[k].e2e_index].pipe.src;
+               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                               e2e[v->planes[k].e2e_index].pipe.dest;
+               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+
+               v->ReadBandwidth[k] =
+                               v->SwathWidthYSingleDPP[k]
+                                               * (dml_ceil_ex(v->BytePerPixelInDETY[k], 1)
+                                                               * scale_ratio_depth.vscl_ratio
+                                                               + (dml_ceil_ex(
+                                                                               v->BytePerPixelInDETC[k],
+                                                                               2) / 2)
+                                                                               * (scale_ratio_depth.vscl_ratio
+                                                                                               / 2))
+                                               / (dest.htotal / dest.pixel_rate_mhz);
+
+               if (src.dcc == 1) {
+                       v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256);
+               }
+
+               if (ip->pte_enable == 1 && src.source_scan != dm_horz
+                               && (src.sw_mode == dm_sw_4kb_s || src.sw_mode == dm_sw_4kb_s_x
+                                               || src.sw_mode == dm_sw_4kb_d
+                                               || src.sw_mode == dm_sw_4kb_d_x)) {
+                       v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 64);
+               } else if (ip->pte_enable == 1 && src.source_scan == dm_horz
+                               && (src.source_format == dm_444_64 || src.source_format == dm_444_32)
+                               && (src.sw_mode == dm_sw_64kb_s || src.sw_mode == dm_sw_64kb_s_t
+                                               || src.sw_mode == dm_sw_64kb_s_x
+                                               || src.sw_mode == dm_sw_64kb_d
+                                               || src.sw_mode == dm_sw_64kb_d_t
+                                               || src.sw_mode == dm_sw_64kb_d_x)) {
+                       v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 256);
+               } else if (ip->pte_enable == 1) {
+                       v->ReadBandwidth[k] = v->ReadBandwidth[k] * (1 + 1 / 512);
+               }
+
+               v->TotalReadBandwidthConsumedGBytePerSecond =
+                               v->TotalReadBandwidthConsumedGBytePerSecond
+                                               + v->ReadBandwidth[k] / 1000;
+       }
+
+       v->TotalWriteBandwidthConsumedGBytePerSecond = 0;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                               e2e[v->planes[k].e2e_index].pipe.dest;
+               struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout;
+
+               if (dout.output_type == dm_wb && dout.output_format == dm_444) {
+                       v->WriteBandwidth[k] = dest.recout_width
+                                       / (dest.htotal / dest.pixel_rate_mhz) * 4;
+               } else if (dout.output_type == dm_wb) {
+                       v->WriteBandwidth[k] = dest.recout_width
+                                       / (dest.htotal / dest.pixel_rate_mhz) * 1.5;
+               } else {
+                       v->WriteBandwidth[k] = 0;
+               }
+
+               v->TotalWriteBandwidthConsumedGBytePerSecond =
+                               v->TotalWriteBandwidthConsumedGBytePerSecond
+                                               + v->WriteBandwidth[k] / 1000;
+       }
+
+       v->TotalBandwidthConsumedGBytePerSecond = v->TotalReadBandwidthConsumedGBytePerSecond
+                       + v->TotalWriteBandwidthConsumedGBytePerSecond;
+
+       v->DCCEnabledInAnyPlane = 0;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_source_params_st src =
+                               e2e[v->planes[k].e2e_index].pipe.src;
+
+               if (src.dcc == 1) {
+                       v->DCCEnabledInAnyPlane = 1;
+               }
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               v->ReturnBWToDCNPerState = dml_min(
+                               soc->return_bus_width_bytes * v->DCFCLKPerState[i],
+                               v->FabricAndDRAMBandwidthPerState[i] * 1000
+                                               * soc->ideal_dram_bw_after_urgent_percent / 100);
+
+               v->ReturnBWPerState[i] = v->ReturnBWToDCNPerState;
+
+               if (v->DCCEnabledInAnyPlane == 1
+                               && v->ReturnBWToDCNPerState
+                                               > (v->DCFCLKPerState[i]
+                                                               * soc->return_bus_width_bytes / 4)) {
+                       v->ReturnBWPerState[i] =
+                                       dml_min(
+                                                       v->ReturnBWPerState[i],
+                                                       v->ReturnBWToDCNPerState * 4
+                                                                       * (1
+                                                                                       - soc->urgent_latency_us
+                                                                                                       / ((ip->rob_buffer_size_kbytes
+                                                                                                                       - ip->pixel_chunk_size_kbytes)
+                                                                                                                       * 1024
+                                                                                                                       / (v->ReturnBWToDCNPerState
+                                                                                                                                       - v->DCFCLKPerState[i]
+                                                                                                                                                       * soc->return_bus_width_bytes
+                                                                                                                                                       / 4)
+                                                                                                                       + soc->urgent_latency_us)));
+               }
+
+               v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i]
+                               * soc->urgent_latency_us
+                               / (v->ReturnBWToDCNPerState * soc->urgent_latency_us
+                                               + (ip->rob_buffer_size_kbytes
+                                                               - ip->pixel_chunk_size_kbytes)
+                                                               * 1024);
+
+               if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) {
+                       v->ReturnBWPerState[i] =
+                                       dml_min(
+                                                       v->ReturnBWPerState[i],
+                                                       4 * v->ReturnBWToDCNPerState
+                                                                       * (ip->rob_buffer_size_kbytes
+                                                                                       - ip->pixel_chunk_size_kbytes)
+                                                                       * 1024
+                                                                       * soc->return_bus_width_bytes
+                                                                       * v->DCFCLKPerState[i]
+                                                                       * soc->urgent_latency_us
+                                                                       / dml_pow(
+                                                                                       (v->ReturnBWToDCNPerState
+                                                                                                       * soc->urgent_latency_us
+                                                                                                       + (ip->rob_buffer_size_kbytes
+                                                                                                                       - ip->pixel_chunk_size_kbytes)
+                                                                                                                       * 1024),
+                                                                                       2));
+               }
+
+               v->ReturnBWToDCNPerState = dml_min(
+                               soc->return_bus_width_bytes * v->DCFCLKPerState[i],
+                               v->FabricAndDRAMBandwidthPerState[i] * 1000);
+
+               if (v->DCCEnabledInAnyPlane == 1
+                               && v->ReturnBWToDCNPerState
+                                               > (v->DCFCLKPerState[i]
+                                                               * soc->return_bus_width_bytes / 4)) {
+                       v->ReturnBWPerState[i] =
+                                       dml_min(
+                                                       v->ReturnBWPerState[i],
+                                                       v->ReturnBWToDCNPerState * 4
+                                                                       * (1
+                                                                                       - soc->urgent_latency_us
+                                                                                                       / ((ip->rob_buffer_size_kbytes
+                                                                                                                       - ip->pixel_chunk_size_kbytes)
+                                                                                                                       * 1024
+                                                                                                                       / (v->ReturnBWToDCNPerState
+                                                                                                                                       - v->DCFCLKPerState[i]
+                                                                                                                                                       * soc->return_bus_width_bytes
+                                                                                                                                                       / 4)
+                                                                                                                       + soc->urgent_latency_us)));
+               }
+
+               v->CriticalPoint = 2 * soc->return_bus_width_bytes * v->DCFCLKPerState[i]
+                               * soc->urgent_latency_us
+                               / (v->ReturnBWToDCNPerState * soc->urgent_latency_us
+                                               + (ip->rob_buffer_size_kbytes
+                                                               - ip->pixel_chunk_size_kbytes)
+                                                               * 1024);
+
+               if (v->DCCEnabledInAnyPlane == 1 && v->CriticalPoint > 1 && v->CriticalPoint < 4) {
+                       v->ReturnBWPerState[i] =
+                                       dml_min(
+                                                       v->ReturnBWPerState[i],
+                                                       4 * v->ReturnBWToDCNPerState
+                                                                       * (ip->rob_buffer_size_kbytes
+                                                                                       - ip->pixel_chunk_size_kbytes)
+                                                                       * 1024
+                                                                       * soc->return_bus_width_bytes
+                                                                       * v->DCFCLKPerState[i]
+                                                                       * soc->urgent_latency_us
+                                                                       / dml_pow(
+                                                                                       (v->ReturnBWToDCNPerState
+                                                                                                       * soc->urgent_latency_us
+                                                                                                       + (ip->rob_buffer_size_kbytes
+                                                                                                                       - ip->pixel_chunk_size_kbytes)
+                                                                                                                       * 1024),
+                                                                                       2));
+               }
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               if ((v->TotalReadBandwidthConsumedGBytePerSecond * 1000 <= v->ReturnBWPerState[i])
+                               && (v->TotalBandwidthConsumedGBytePerSecond * 1000
+                                               <= v->FabricAndDRAMBandwidthPerState[i] * 1000
+                                                               * soc->ideal_dram_bw_after_urgent_percent
+                                                               / 100)) {
+                       v->BandwidthSupport[i] = 1;
+               } else {
+                       v->BandwidthSupport[i] = 0;
+               }
+       }
+
+       // Writeback Latency support check
+
+       v->WritebackLatencySupport = 1;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                               e2e[v->planes[k].e2e_index].pipe.dest;
+               struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout;
+
+               if (dout.output_type == dm_wb && dout.output_format == dm_444
+                               && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz) * 4)
+                                               > ((ip->writeback_luma_buffer_size_kbytes
+                                                               + ip->writeback_chroma_buffer_size_kbytes)
+                                                               * 1024 / soc->writeback_latency_us)) {
+                       v->WritebackLatencySupport = 0;
+               } else if (dout.output_type == dm_wb
+                               && (dest.recout_width / (dest.htotal / dest.pixel_rate_mhz))
+                                               > (dml_min(
+                                                               ip->writeback_luma_buffer_size_kbytes,
+                                                               2
+                                                                               * ip->writeback_chroma_buffer_size_kbytes)
+                                                               * 1024 / soc->writeback_latency_us)) {
+                       v->WritebackLatencySupport = 0;
+               }
+       }
+
+       // Re-ordering Buffer Support Check
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               v->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
+                               (soc->round_trip_ping_latency_dcfclk_cycles + 32)
+                                               / v->DCFCLKPerState[i]
+                                               + soc->urgent_out_of_order_return_per_channel_bytes
+                                                               * soc->num_chans
+                                                               / v->ReturnBWPerState[i];
+
+               if ((ip->rob_buffer_size_kbytes - ip->pixel_chunk_size_kbytes) * 1024
+                               / v->ReturnBWPerState[i]
+                               > v->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
+                       v->ROBSupport[i] = 1;
+               } else {
+                       v->ROBSupport[i] = 0;
+               }
+       }
+
+       // Display IO Support Check
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                               e2e[v->planes[k].e2e_index].pipe.dest;
+               struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout;
+
+               if (dout.output_format == dm_420) {
+                       v->RequiredOutputBW = dest.pixel_rate_mhz * 3 / 2;
+               } else {
+                       v->RequiredOutputBW = dest.pixel_rate_mhz * 3;
+               }
+
+               if (dout.output_type == dm_hdmi) {
+                       v->RequiredPHYCLK[k] = v->RequiredOutputBW / 3;
+               } else if (dout.output_type == dm_dp) {
+                       v->RequiredPHYCLK[k] = v->RequiredOutputBW / 4;
+               } else {
+                       v->RequiredPHYCLK[k] = 0;
+               }
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               v->DIOSupport[i] = 1;
+
+               for (k = 0; k < num_planes; k++) {
+                       struct _vcs_dpi_display_output_params_st dout =
+                                       e2e[v->planes[k].e2e_index].dout;
+
+                       if ((v->RequiredPHYCLK[k] > v->PHYCLKPerState[i])
+                                       || (dout.output_type == dm_hdmi
+                                                       && v->RequiredPHYCLK[k] > 600)) {
+                               v->DIOSupport[i] = 0;
+                       }
+               }
+       }
+
+       // Total Available Writeback Support Check
+
+       v->TotalNumberOfActiveWriteback = 0;
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_output_params_st dout = e2e[v->planes[k].e2e_index].dout;
+
+               if (dout.output_type == dm_wb) {
+                       v->TotalNumberOfActiveWriteback = v->TotalNumberOfActiveWriteback + 1;
+               }
+       }
+
+       if (v->TotalNumberOfActiveWriteback <= ip->max_num_wb) {
+               v->TotalAvailableWritebackSupport = 1;
+       } else {
+               v->TotalAvailableWritebackSupport = 0;
+       }
+
+       // Maximum DISPCLK/DPPCLK Support check
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                               e2e[v->planes[k].e2e_index].pipe.dest;
+               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+               struct _vcs_dpi_scaler_taps_st scale_taps =
+                               e2e[v->planes[k].e2e_index].pipe.scale_taps;
+
+               if (scale_ratio_depth.hscl_ratio > 1) {
+                       v->PSCL_FACTOR[k] = dml_min(
+                                       ip->max_dchub_pscl_bw_pix_per_clk,
+                                       ip->max_pscl_lb_bw_pix_per_clk
+                                                       * scale_ratio_depth.hscl_ratio
+                                                       / dml_ceil_ex(scale_taps.htaps / 6, 1));
+               } else {
+                       v->PSCL_FACTOR[k] = dml_min(
+                                       ip->max_dchub_pscl_bw_pix_per_clk,
+                                       ip->max_pscl_lb_bw_pix_per_clk);
+               }
+
+               if (v->BytePerPixelInDETC[k] == 0) {
+                       v->PSCL_FACTOR_CHROMA[k] = 0;
+                       v->MinDPPCLKUsingSingleDPP[k] =
+                                       dest.pixel_rate_mhz
+                                                       * dml_max(
+                                                                       scale_taps.vtaps / 6
+                                                                                       * dml_min(
+                                                                                                       1,
+                                                                                                       scale_ratio_depth.hscl_ratio),
+                                                                       dml_max(
+                                                                                       scale_ratio_depth.hscl_ratio
+                                                                                                       * scale_ratio_depth.vscl_ratio
+                                                                                                       / v->PSCL_FACTOR[k],
+                                                                                       1));
+
+               } else {
+                       if (scale_ratio_depth.hscl_ratio / 2 > 1) {
+                               v->PSCL_FACTOR_CHROMA[k] = dml_min(
+                                               ip->max_dchub_pscl_bw_pix_per_clk,
+                                               ip->max_pscl_lb_bw_pix_per_clk
+                                                               * scale_ratio_depth.hscl_ratio / 2
+                                                               / dml_ceil_ex(
+                                                                               scale_taps.htaps_c
+                                                                                               / 6,
+                                                                               1));
+                       } else {
+                               v->PSCL_FACTOR_CHROMA[k] = dml_min(
+                                               ip->max_dchub_pscl_bw_pix_per_clk,
+                                               ip->max_pscl_lb_bw_pix_per_clk);
+                       }
+                       v->MinDPPCLKUsingSingleDPP[k] =
+                                       dest.pixel_rate_mhz
+                                                       * dml_max(
+                                                                       dml_max(
+                                                                                       scale_taps.vtaps
+                                                                                                       / 6
+                                                                                                       * dml_min(
+                                                                                                                       1,
+                                                                                                                       scale_ratio_depth.hscl_ratio),
+                                                                                       scale_ratio_depth.hscl_ratio
+                                                                                                       * scale_ratio_depth.vscl_ratio
+                                                                                                       / v->PSCL_FACTOR[k]),
+                                                                       dml_max(
+                                                                                       dml_max(
+                                                                                                       scale_taps.vtaps_c
+                                                                                                                       / 6
+                                                                                                                       * dml_min(
+                                                                                                                                       1,
+                                                                                                                                       scale_ratio_depth.hscl_ratio
+                                                                                                                                                       / 2),
+                                                                                                       scale_ratio_depth.hscl_ratio
+                                                                                                                       * scale_ratio_depth.vscl_ratio
+                                                                                                                       / 4
+                                                                                                                       / v->PSCL_FACTOR_CHROMA[k]),
+                                                                                       1));
+
+               }
+       }
+
+       for (k = 0; k < num_planes; k++) {
+               struct _vcs_dpi_display_pipe_source_params_st src =
+                               e2e[v->planes[k].e2e_index].pipe.src;
+               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+               struct _vcs_dpi_scaler_taps_st scale_taps =
+                               e2e[v->planes[k].e2e_index].pipe.scale_taps;
+
+               if (src.source_format == dm_444_64 || src.source_format == dm_444_32
+                               || src.source_format == dm_444_16) {
+                       if (src.sw_mode == dm_sw_linear) {
+                               v->Read256BlockHeightY[k] = 1;
+                       } else if (src.source_format == dm_444_64) {
+                               v->Read256BlockHeightY[k] = 4;
+                       } else {
+                               v->Read256BlockHeightY[k] = 8;
+                       }
+
+                       v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1)
+                                       / v->Read256BlockHeightY[k];
+                       v->Read256BlockHeightC[k] = 0;
+                       v->Read256BlockWidthC[k] = 0;
+               } else {
+                       if (src.sw_mode == dm_sw_linear) {
+                               v->Read256BlockHeightY[k] = 1;
+                               v->Read256BlockHeightC[k] = 1;
+                       } else if (src.source_format == dm_420_8) {
+                               v->Read256BlockHeightY[k] = 16;
+                               v->Read256BlockHeightC[k] = 8;
+                       } else {
+                               v->Read256BlockHeightY[k] = 8;
+                               v->Read256BlockHeightC[k] = 8;
+                       }
+
+                       v->Read256BlockWidthY[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETY[k], 1)
+                                       / v->Read256BlockHeightY[k];
+                       v->Read256BlockWidthC[k] = 256 / dml_ceil_ex(v->BytePerPixelInDETC[k], 2)
+                                       / v->Read256BlockHeightC[k];
+               }
+
+               if (src.source_scan == dm_horz) {
+                       v->MaxSwathHeightY[k] = v->Read256BlockHeightY[k];
+                       v->MaxSwathHeightC[k] = v->Read256BlockHeightC[k];
+               } else {
+                       v->MaxSwathHeightY[k] = v->Read256BlockWidthY[k];
+                       v->MaxSwathHeightC[k] = v->Read256BlockWidthC[k];
+               }
+
+               if (src.source_format == dm_444_64 || src.source_format == dm_444_32
+                               || src.source_format == dm_444_16) {
+                       if (src.sw_mode == dm_sw_linear
+                                       || (src.source_format == dm_444_64
+                                                       && (src.sw_mode == dm_sw_4kb_s
+                                                                       || src.sw_mode
+                                                                                       == dm_sw_4kb_s_x
+                                                                       || src.sw_mode
+                                                                                       == dm_sw_64kb_s
+                                                                       || src.sw_mode
+                                                                                       == dm_sw_64kb_s_t
+                                                                       || src.sw_mode
+                                                                                       == dm_sw_64kb_s_x
+                                                                       || src.sw_mode
+                                                                                       == dm_sw_var_s
+                                                                       || src.sw_mode
+                                                                                       == dm_sw_var_s_x)
+                                                       && src.source_scan == dm_horz)) {
+                               v->MinSwathHeightY[k] = v->MaxSwathHeightY[k];
+                       } else {
+                               v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2;
+                       }
+                       v->MinSwathHeightC[k] = v->MaxSwathHeightC[k];
+               } else {
+                       if (src.sw_mode == dm_sw_linear) {
+                               v->MinSwathHeightY[k] = v->MaxSwathHeightY[k];
+                               v->MinSwathHeightC[k] = v->MaxSwathHeightC[k];
+                       } else if (src.source_format == dm_420_8 && src.source_scan == dm_horz) {
+                               v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2;
+                               if (ip->bug_forcing_LC_req_same_size_fixed == 1) {
+                                       v->MinSwathHeightC[k] = v->MaxSwathHeightC[k];
+                               } else {
+                                       v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2;
+                               }
+                       } else if (src.source_format == dm_420_10 && src.source_scan == dm_horz) {
+                               v->MinSwathHeightC[k] = v->MaxSwathHeightC[k] / 2;
+                               if (ip->bug_forcing_LC_req_same_size_fixed == 1) {
+                                       v->MinSwathHeightY[k] = v->MaxSwathHeightY[k];
+                               } else {
+                                       v->MinSwathHeightY[k] = v->MaxSwathHeightY[k] / 2;
+                               }
+                       } else {
+                               v->MinSwathHeightY[k] = v->MaxSwathHeightY[k];
+                               v->MinSwathHeightC[k] = v->MaxSwathHeightC[k];
+                       }
+               }
+
+               if (src.sw_mode == dm_sw_linear) {
+                       v->MaximumSwathWidth = 8192;
+               } else {
+                       v->MaximumSwathWidth = 5120;
+               }
+
+               v->NumberOfDPPRequiredForDETSize =
+                               dml_ceil_ex(
+                                               v->SwathWidthYSingleDPP[k]
+                                                               / dml_min(
+                                                                               v->MaximumSwathWidth,
+                                                                               ip->det_buffer_size_kbytes
+                                                                                               * 1024
+                                                                                               / 2
+                                                                                               / (v->BytePerPixelInDETY[k]
+                                                                                                               * v->MinSwathHeightY[k]
+                                                                                                               + v->BytePerPixelInDETC[k]
+                                                                                                                               / 2
+                                                                                                                               * v->MinSwathHeightC[k])),
+                                               1);
+
+               if (v->BytePerPixelInDETC[k] == 0) {
+                       v->NumberOfDPPRequiredForLBSize =
+                                       dml_ceil_ex(
+                                                       (scale_taps.vtaps
+                                                                       + dml_max(
+                                                                                       dml_ceil_ex(
+                                                                                                       scale_ratio_depth.vscl_ratio,
+                                                                                                       1)
+                                                                                                       - 2,
+                                                                                       0))
+                                                                       * v->SwathWidthYSingleDPP[k]
+                                                                       / dml_max(
+                                                                                       scale_ratio_depth.hscl_ratio,
+                                                                                       1)
+                                                                       * scale_ratio_depth.lb_depth
+                                                                       / ip->line_buffer_size_bits,
+                                                       1);
+               } else {
+                       v->NumberOfDPPRequiredForLBSize =
+                                       dml_max(
+                                                       dml_ceil_ex(
+                                                                       (scale_taps.vtaps
+                                                                                       + dml_max(
+                                                                                                       dml_ceil_ex(
+                                                                                                                       scale_ratio_depth.vscl_ratio,
+                                                                                                                       1)
+                                                                                                                       - 2,
+                                                                                                       0))
+                                                                                       * v->SwathWidthYSingleDPP[k]
+                                                                                       / dml_max(
+                                                                                                       scale_ratio_depth.hscl_ratio,
+                                                                                                       1)
+                                                                                       * scale_ratio_depth.lb_depth
+                                                                                       / ip->line_buffer_size_bits,
+                                                                       1),
+                                                       dml_ceil_ex(
+                                                                       (scale_taps.vtaps_c
+                                                                                       + dml_max(
+                                                                                                       dml_ceil_ex(
+                                                                                                                       scale_ratio_depth.vscl_ratio
+                                                                                                                                       / 2,
+                                                                                                                       1)
+                                                                                                                       - 2,
+                                                                                                       0))
+                                                                                       * v->SwathWidthYSingleDPP[k]
+                                                                                       / 2
+                                                                                       / dml_max(
+                                                                                                       scale_ratio_depth.hscl_ratio
+                                                                                                                       / 2,
+                                                                                                       1)
+                                                                                       * scale_ratio_depth.lb_depth
+                                                                                       / ip->line_buffer_size_bits,
+                                                                       1));
+               }
+
+               v->NumberOfDPPRequiredForDETAndLBSize[k] = dml_max(
+                               v->NumberOfDPPRequiredForDETSize,
+                               v->NumberOfDPPRequiredForLBSize);
+
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               for (j = 0; j < 2; j++) {
+                       v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0;
+                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0;
+                       v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1;
+
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                               e2e[v->planes[k].e2e_index].pipe.dest;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               v->MinDispclkUsingSingleDPP = dml_max(
+                                               dest.pixel_rate_mhz,
+                                               v->MinDPPCLKUsingSingleDPP[k] * (j + 1))
+                                               * (1 + soc->downspread_percent / 100);
+                               v->MinDispclkUsingDualDPP = dml_max(
+                                               dest.pixel_rate_mhz,
+                                               v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1))
+                                               * (1 + soc->downspread_percent / 100);
+
+                               if (i < NumberOfStates) {
+                                       v->MinDispclkUsingSingleDPP =
+                                                       v->MinDispclkUsingSingleDPP
+                                                                       * (1
+                                                                                       + ip->dispclk_ramp_margin_percent
+                                                                                                       / 100);
+                                       v->MinDispclkUsingDualDPP =
+                                                       v->MinDispclkUsingDualDPP
+                                                                       * (1
+                                                                                       + ip->dispclk_ramp_margin_percent
+                                                                                                       / 100);
+                               }
+
+                               if (v->MinDispclkUsingSingleDPP
+                                               <= dml_min(
+                                                               v->MaxDispclk[i],
+                                                               (j + 1) * v->MaxDppclk[i])
+                                               && v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) {
+                                       v->NoOfDPP[ijk] = 1;
+                                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max(
+                                                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo
+                                                                       + i],
+                                                       v->MinDispclkUsingSingleDPP);
+                               } else if (v->MinDispclkUsingDualDPP
+                                               <= dml_min(
+                                                               v->MaxDispclk[i],
+                                                               (j + 1) * v->MaxDppclk[i])) {
+                                       v->NoOfDPP[ijk] = 2;
+                                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max(
+                                                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo
+                                                                       + i],
+                                                       v->MinDispclkUsingDualDPP);
+                               } else {
+                                       v->NoOfDPP[ijk] = 2;
+                                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = dml_max(
+                                                       v->RequiredDISPCLK[j * NumberOfStatesPlusTwo
+                                                                       + i],
+                                                       v->MinDispclkUsingDualDPP);
+                                       v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] =
+                                                       0;
+                               }
+
+                               v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] =
+                                               v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo
+                                                               + i] + v->NoOfDPP[ijk];
+                       }
+
+                       if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i]
+                                       > ip->max_num_dpp) {
+                               v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] = 0;
+                               v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] = 0;
+                               v->DISPCLK_DPPCLK_Support[j * NumberOfStatesPlusTwo + i] = 1;
+
+                               for (k = 0; k < num_planes; k++) {
+                                       struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                                       e2e[v->planes[k].e2e_index].pipe.dest;
+                                       ijk = k * 2 * NumberOfStatesPlusTwo
+                                                       + j * NumberOfStatesPlusTwo + i;
+
+                                       v->MinDispclkUsingSingleDPP = dml_max(
+                                                       dest.pixel_rate_mhz,
+                                                       v->MinDPPCLKUsingSingleDPP[k] * (j + 1))
+                                                       * (1 + soc->downspread_percent / 100);
+                                       v->MinDispclkUsingDualDPP = dml_max(
+                                                       dest.pixel_rate_mhz,
+                                                       v->MinDPPCLKUsingSingleDPP[k] / 2 * (j + 1))
+                                                       * (1 + soc->downspread_percent / 100);
+
+                                       if (i < NumberOfStates) {
+                                               v->MinDispclkUsingSingleDPP =
+                                                               v->MinDispclkUsingSingleDPP
+                                                                               * (1
+                                                                                               + ip->dispclk_ramp_margin_percent
+                                                                                                               / 100);
+                                               v->MinDispclkUsingDualDPP =
+                                                               v->MinDispclkUsingDualDPP
+                                                                               * (1
+                                                                                               + ip->dispclk_ramp_margin_percent
+                                                                                                               / 100);
+                                       }
+
+                                       if (v->NumberOfDPPRequiredForDETAndLBSize[k] <= 1) {
+                                               v->NoOfDPP[ijk] = 1;
+                                               v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] =
+                                                               dml_max(
+                                                                               v->RequiredDISPCLK[j
+                                                                                               * NumberOfStatesPlusTwo
+                                                                                               + i],
+                                                                               v->MinDispclkUsingSingleDPP);
+                                               if (v->MinDispclkUsingSingleDPP
+                                                               > dml_min(
+                                                                               v->MaxDispclk[i],
+                                                                               (j + 1)
+                                                                                               * v->MaxDppclk[i])) {
+                                                       v->DISPCLK_DPPCLK_Support[j
+                                                                       * NumberOfStatesPlusTwo + i] =
+                                                                       0;
+                                               }
+                                       } else {
+                                               v->NoOfDPP[ijk] = 2;
+                                               v->RequiredDISPCLK[j * NumberOfStatesPlusTwo + i] =
+                                                               dml_max(
+                                                                               v->RequiredDISPCLK[j
+                                                                                               * NumberOfStatesPlusTwo
+                                                                                               + i],
+                                                                               v->MinDispclkUsingDualDPP);
+                                               if (v->MinDispclkUsingDualDPP
+                                                               > dml_min(
+                                                                               v->MaxDispclk[i],
+                                                                               (j + 1)
+                                                                                               * v->MaxDppclk[i])) {
+                                                       v->DISPCLK_DPPCLK_Support[j
+                                                                       * NumberOfStatesPlusTwo + i] =
+                                                                       0;
+                                               }
+                                       }
+                                       v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i] =
+                                                       v->TotalNumberOfActiveDPP[j
+                                                                       * NumberOfStatesPlusTwo + i]
+                                                                       + v->NoOfDPP[ijk];
+                               }
+                       }
+               }
+       }
+
+       // Viewport Size Check
+
+       v->ViewportSizeSupport = 1;
+
+       for (k = 0; k < num_planes; k++) {
+               if (v->NumberOfDPPRequiredForDETAndLBSize[k] > 2) {
+                       v->ViewportSizeSupport = 0;
+               }
+       }
+
+       // Total Available Pipes Support Check
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               for (j = 0; j < 2; j++) {
+                       if (v->TotalNumberOfActiveDPP[j * NumberOfStatesPlusTwo + i]
+                                       <= ip->max_num_dpp) {
+                               v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 1;
+                       } else {
+                               v->TotalAvailablePipesSupport[j * NumberOfStatesPlusTwo + i] = 0;
+                       }
+               }
+       }
+
+       // Urgent Latency Support Check
+
+       for (j = 0; j < 2; j++) {
+               for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+                       ij = j * NumberOfStatesPlusTwo + i;
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+                               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                               e2e[v->planes[k].e2e_index].pipe.dest;
+                               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+                               struct _vcs_dpi_scaler_taps_st scale_taps =
+                                               e2e[v->planes[k].e2e_index].pipe.scale_taps;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               v->SwathWidthYPerState[ijk] = v->SwathWidthYSingleDPP[k]
+                                               / v->NoOfDPP[ijk];
+
+                               v->SwathWidthGranularityY = 256
+                                               / dml_ceil_ex(v->BytePerPixelInDETY[k], 1)
+                                               / v->MaxSwathHeightY[k];
+                               v->RoundedUpMaxSwathSizeBytesY = (dml_ceil_ex(
+                                               v->SwathWidthYPerState[ijk] - 1,
+                                               v->SwathWidthGranularityY)
+                                               + v->SwathWidthGranularityY)
+                                               * v->BytePerPixelInDETY[k] * v->MaxSwathHeightY[k];
+                               if (src.source_format == dm_420_10) {
+                                       v->RoundedUpMaxSwathSizeBytesY = dml_ceil_ex(
+                                                       v->RoundedUpMaxSwathSizeBytesY,
+                                                       256) + 256;
+                               }
+                               if (v->MaxSwathHeightC[k] > 0) {
+                                       v->SwathWidthGranularityC = 256
+                                                       / dml_ceil_ex(v->BytePerPixelInDETC[k], 2)
+                                                       / v->MaxSwathHeightC[k];
+                               }
+                               v->RoundedUpMaxSwathSizeBytesC = (dml_ceil_ex(
+                                               v->SwathWidthYPerState[ijk] / 2 - 1,
+                                               v->SwathWidthGranularityC)
+                                               + v->SwathWidthGranularityC)
+                                               * v->BytePerPixelInDETC[k] * v->MaxSwathHeightC[k];
+                               if (src.source_format == dm_420_10) {
+                                       v->RoundedUpMaxSwathSizeBytesC = dml_ceil_ex(
+                                                       v->RoundedUpMaxSwathSizeBytesC,
+                                                       256) + 256;
+                               }
+
+                               if (v->RoundedUpMaxSwathSizeBytesY + v->RoundedUpMaxSwathSizeBytesC
+                                               <= ip->det_buffer_size_kbytes * 1024 / 2) {
+                                       v->SwathHeightYPerState[ijk] = v->MaxSwathHeightY[k];
+                                       v->SwathHeightCPerState[ijk] = v->MaxSwathHeightC[k];
+                               } else {
+                                       v->SwathHeightYPerState[ijk] = v->MinSwathHeightY[k];
+                                       v->SwathHeightCPerState[ijk] = v->MinSwathHeightC[k];
+                               }
+
+                               if (v->BytePerPixelInDETC[k] == 0) {
+                                       v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024
+                                                       / v->BytePerPixelInDETY[k]
+                                                       / v->SwathWidthYPerState[ijk];
+
+                                       v->LinesInDETChroma = 0;
+                               } else if (v->SwathHeightYPerState[ijk]
+                                               <= v->SwathHeightCPerState[ijk]) {
+                                       v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 / 2
+                                                       / v->BytePerPixelInDETY[k]
+                                                       / v->SwathWidthYPerState[ijk];
+                                       v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 2
+                                                       / v->BytePerPixelInDETC[k]
+                                                       / (v->SwathWidthYPerState[ijk] / 2);
+                               } else {
+                                       v->LinesInDETLuma = ip->det_buffer_size_kbytes * 1024 * 2
+                                                       / 3 / v->BytePerPixelInDETY[k]
+                                                       / v->SwathWidthYPerState[ijk];
+                                       v->LinesInDETChroma = ip->det_buffer_size_kbytes * 1024 / 3
+                                                       / v->BytePerPixelInDETY[k]
+                                                       / (v->SwathWidthYPerState[ijk] / 2);
+                               }
+
+                               v->EffectiveLBLatencyHidingSourceLinesLuma =
+                                               dml_min(
+                                                               ip->max_line_buffer_lines,
+                                                               dml_floor_ex(
+                                                                               ip->line_buffer_size_bits
+                                                                                               / scale_ratio_depth.lb_depth
+                                                                                               / (v->SwathWidthYPerState[ijk]
+                                                                                                               / dml_max(
+                                                                                                                               scale_ratio_depth.hscl_ratio,
+                                                                                                                               1)),
+                                                                               1))
+                                                               - (scale_taps.vtaps - 1);
+
+                               v->EffectiveLBLatencyHidingSourceLinesChroma =
+                                               dml_min(
+                                                               ip->max_line_buffer_lines,
+                                                               dml_floor_ex(
+                                                                               ip->line_buffer_size_bits
+                                                                                               / scale_ratio_depth.lb_depth
+                                                                                               / (v->SwathWidthYPerState[ijk]
+                                                                                                               / 2
+                                                                                                               / dml_max(
+                                                                                                                               scale_ratio_depth.hscl_ratio
+                                                                                                                                               / 2,
+                                                                                                                               1)),
+                                                                               1))
+                                                               - (scale_taps.vtaps_c - 1);
+
+                               v->EffectiveDETLBLinesLuma =
+                                               dml_floor_ex(
+                                                               v->LinesInDETLuma
+                                                                               + dml_min(
+                                                                                               v->LinesInDETLuma
+                                                                                                               * v->RequiredDISPCLK[ij]
+                                                                                                               * v->BytePerPixelInDETY[k]
+                                                                                                               * v->PSCL_FACTOR[k]
+                                                                                                               / v->ReturnBWPerState[i],
+                                                                                               v->EffectiveLBLatencyHidingSourceLinesLuma),
+                                                               v->SwathHeightYPerState[ijk]);
+
+                               v->EffectiveDETLBLinesChroma =
+                                               dml_floor_ex(
+                                                               v->LinesInDETChroma
+                                                                               + dml_min(
+                                                                                               v->LinesInDETChroma
+                                                                                                               * v->RequiredDISPCLK[ij]
+                                                                                                               * v->BytePerPixelInDETC[k]
+                                                                                                               * v->PSCL_FACTOR_CHROMA[k]
+                                                                                                               / v->ReturnBWPerState[i],
+                                                                                               v->EffectiveLBLatencyHidingSourceLinesChroma),
+                                                               v->SwathHeightCPerState[ijk]);
+
+                               if (v->BytePerPixelInDETC[k] == 0) {
+                                       v->UrgentLatencySupportUsPerState[ijk] =
+                                                       v->EffectiveDETLBLinesLuma
+                                                                       * (dest.htotal
+                                                                                       / dest.pixel_rate_mhz)
+                                                                       / scale_ratio_depth.vscl_ratio
+                                                                       - v->EffectiveDETLBLinesLuma
+                                                                                       * v->SwathWidthYPerState[ijk]
+                                                                                       * dml_ceil_ex(
+                                                                                                       v->BytePerPixelInDETY[k],
+                                                                                                       1)
+                                                                                       / (v->ReturnBWPerState[i]
+                                                                                                       / v->NoOfDPP[ijk]);
+                               } else {
+                                       v->UrgentLatencySupportUsPerState[ijk] =
+                                                       dml_min(
+                                                                       v->EffectiveDETLBLinesLuma
+                                                                                       * (dest.htotal
+                                                                                                       / dest.pixel_rate_mhz)
+                                                                                       / scale_ratio_depth.vscl_ratio
+                                                                                       - v->EffectiveDETLBLinesLuma
+                                                                                                       * v->SwathWidthYPerState[ijk]
+                                                                                                       * dml_ceil_ex(
+                                                                                                                       v->BytePerPixelInDETY[k],
+                                                                                                                       1)
+                                                                                                       / (v->ReturnBWPerState[i]
+                                                                                                                       / v->NoOfDPP[ijk]),
+                                                                       v->EffectiveDETLBLinesChroma
+                                                                                       * (dest.htotal
+                                                                                                       / dest.pixel_rate_mhz)
+                                                                                       / (scale_ratio_depth.vscl_ratio
+                                                                                                       / 2)
+                                                                                       - v->EffectiveDETLBLinesChroma
+                                                                                                       * v->SwathWidthYPerState[ijk]
+                                                                                                       / 2
+                                                                                                       * dml_ceil_ex(
+                                                                                                                       v->BytePerPixelInDETC[k],
+                                                                                                                       2)
+                                                                                                       / (v->ReturnBWPerState[i]
+                                                                                                                       / v->NoOfDPP[ijk]));
+                               }
+
+                       }
+               }
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               for (j = 0; j < 2; j++) {
+                       ij = j * NumberOfStatesPlusTwo + i;
+
+                       v->UrgentLatencySupport[ij] = 1;
+                       for (k = 0; k < num_planes; k++) {
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (v->UrgentLatencySupportUsPerState[ijk]
+                                               < soc->urgent_latency_us / 1) {
+                                       v->UrgentLatencySupport[ij] = 0;
+                               }
+                       }
+               }
+       }
+
+       // Prefetch Check
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               for (j = 0; j < 2; j++) {
+                       ij = j * NumberOfStatesPlusTwo + i;
+
+                       v->TotalNumberOfDCCActiveDPP[ij] = 0;
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (src.dcc == 1) {
+                                       v->TotalNumberOfDCCActiveDPP[ij] =
+                                                       v->TotalNumberOfDCCActiveDPP[ij]
+                                                                       + v->NoOfDPP[ijk];
+                               }
+                       }
+               }
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               for (j = 0; j < 2; j++) {
+                       ij = j * NumberOfStatesPlusTwo + i;
+
+                       v->ProjectedDCFCLKDeepSleep = 8;
+
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                               e2e[v->planes[k].e2e_index].pipe.dest;
+                               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               v->ProjectedDCFCLKDeepSleep = dml_max(
+                                               v->ProjectedDCFCLKDeepSleep,
+                                               dest.pixel_rate_mhz / 16);
+                               if (v->BytePerPixelInDETC[k] == 0) {
+                                       if (scale_ratio_depth.vscl_ratio <= 1) {
+                                               v->ProjectedDCFCLKDeepSleep =
+                                                               dml_max(
+                                                                               v->ProjectedDCFCLKDeepSleep,
+                                                                               1.1
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETY[k],
+                                                                                                               1)
+                                                                                               / 64
+                                                                                               * scale_ratio_depth.hscl_ratio
+                                                                                               * dest.pixel_rate_mhz
+                                                                                               / v->NoOfDPP[ijk]);
+                                       } else {
+                                               v->ProjectedDCFCLKDeepSleep =
+                                                               dml_max(
+                                                                               v->ProjectedDCFCLKDeepSleep,
+                                                                               1.1
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETY[k],
+                                                                                                               1)
+                                                                                               / 64
+                                                                                               * v->PSCL_FACTOR[k]
+                                                                                               * v->RequiredDISPCLK[ij]
+                                                                                               / (1
+                                                                                                               + j));
+                                       }
+
+                               } else {
+                                       if (scale_ratio_depth.vscl_ratio <= 1) {
+                                               v->ProjectedDCFCLKDeepSleep =
+                                                               dml_max(
+                                                                               v->ProjectedDCFCLKDeepSleep,
+                                                                               1.1
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETY[k],
+                                                                                                               1)
+                                                                                               / 32
+                                                                                               * scale_ratio_depth.hscl_ratio
+                                                                                               * dest.pixel_rate_mhz
+                                                                                               / v->NoOfDPP[ijk]);
+                                       } else {
+                                               v->ProjectedDCFCLKDeepSleep =
+                                                               dml_max(
+                                                                               v->ProjectedDCFCLKDeepSleep,
+                                                                               1.1
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETY[k],
+                                                                                                               1)
+                                                                                               / 32
+                                                                                               * v->PSCL_FACTOR[k]
+                                                                                               * v->RequiredDISPCLK[ij]
+                                                                                               / (1
+                                                                                                               + j));
+                                       }
+                                       if ((scale_ratio_depth.vscl_ratio / 2) <= 1) {
+                                               v->ProjectedDCFCLKDeepSleep =
+                                                               dml_max(
+                                                                               v->ProjectedDCFCLKDeepSleep,
+                                                                               1.1
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETC[k],
+                                                                                                               2)
+                                                                                               / 32
+                                                                                               * scale_ratio_depth.hscl_ratio
+                                                                                               / 2
+                                                                                               * dest.pixel_rate_mhz
+                                                                                               / v->NoOfDPP[ijk]);
+                                       } else {
+                                               v->ProjectedDCFCLKDeepSleep =
+                                                               dml_max(
+                                                                               v->ProjectedDCFCLKDeepSleep,
+                                                                               1.1
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETC[k],
+                                                                                                               2)
+                                                                                               / 32
+                                                                                               * v->PSCL_FACTOR_CHROMA[k]
+                                                                                               * v->RequiredDISPCLK[ij]
+                                                                                               / (1
+                                                                                                               + j));
+                                       }
+
+                               }
+                       }
+
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+                               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                               e2e[v->planes[k].e2e_index].pipe.dest;
+                               struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth =
+                                               e2e[v->planes[k].e2e_index].pipe.scale_ratio_depth;
+                               struct _vcs_dpi_scaler_taps_st scale_taps =
+                                               e2e[v->planes[k].e2e_index].pipe.scale_taps;
+                               struct _vcs_dpi_display_output_params_st dout =
+                                               e2e[v->planes[k].e2e_index].dout;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (src.dcc == 1) {
+                                       v->MetaReqHeightY = 8 * v->Read256BlockHeightY[k];
+                                       v->MetaReqWidthY = 64 * 256
+                                                       / dml_ceil_ex(v->BytePerPixelInDETY[k], 1)
+                                                       / v->MetaReqHeightY;
+                                       v->MetaSurfaceWidthY = dml_ceil_ex(
+                                                       src.viewport_width / v->NoOfDPP[ijk] - 1,
+                                                       v->MetaReqWidthY) + v->MetaReqWidthY;
+                                       v->MetaSurfaceHeightY = dml_ceil_ex(
+                                                       src.viewport_height - 1,
+                                                       v->MetaReqHeightY) + v->MetaReqHeightY;
+                                       if (ip->pte_enable == 1) {
+                                               v->MetaPteBytesPerFrameY =
+                                                               (dml_ceil_ex(
+                                                                               (v->MetaSurfaceWidthY
+                                                                                               * v->MetaSurfaceHeightY
+                                                                                               * dml_ceil_ex(
+                                                                                                               v->BytePerPixelInDETY[k],
+                                                                                                               1)
+                                                                                               / 256.0
+                                                                                               - 4096)
+                                                                                               / 8
+                                                                                               / 4096,
+                                                                               1) + 1) * 64;
+                                       } else {
+                                               v->MetaPteBytesPerFrameY = 0;
+                                       }
+                                       if (src.source_scan == dm_horz) {
+                                               v->MetaRowBytesY =
+                                                               v->MetaSurfaceWidthY
+                                                                               * v->MetaReqHeightY
+                                                                               * dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETY[k],
+                                                                                               1)
+                                                                               / 256;
+                                       } else {
+                                               v->MetaRowBytesY =
+                                                               v->MetaSurfaceHeightY
+                                                                               * v->MetaReqWidthY
+                                                                               * dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETY[k],
+                                                                                               1)
+                                                                               / 256;
+                                       }
+                               } else {
+                                       v->MetaPteBytesPerFrameY = 0;
+                                       v->MetaRowBytesY = 0;
+                               }
+
+                               if (ip->pte_enable == 1) {
+                                       if (src.sw_mode == dm_sw_linear) {
+                                               v->MacroTileBlockSizeBytesY = 256;
+                                               v->MacroTileBlockHeightY = 1;
+                                       } else if (src.sw_mode == dm_sw_4kb_s
+                                                       || src.sw_mode == dm_sw_4kb_s_x
+                                                       || src.sw_mode == dm_sw_4kb_d
+                                                       || src.sw_mode == dm_sw_4kb_d_x) {
+                                               v->MacroTileBlockSizeBytesY = 4096;
+                                               v->MacroTileBlockHeightY = 4
+                                                               * v->Read256BlockHeightY[k];
+                                       } else if (src.sw_mode == dm_sw_64kb_s
+                                                       || src.sw_mode == dm_sw_64kb_s_t
+                                                       || src.sw_mode == dm_sw_64kb_s_x
+                                                       || src.sw_mode == dm_sw_64kb_d
+                                                       || src.sw_mode == dm_sw_64kb_d_t
+                                                       || src.sw_mode == dm_sw_64kb_d_x) {
+                                               v->MacroTileBlockSizeBytesY = 64 * 1024;
+                                               v->MacroTileBlockHeightY = 16
+                                                               * v->Read256BlockHeightY[k];
+                                       } else {
+                                               v->MacroTileBlockSizeBytesY = 256 * 1024;
+                                               v->MacroTileBlockHeightY = 32
+                                                               * v->Read256BlockHeightY[k];
+                                       }
+                                       if (v->MacroTileBlockSizeBytesY <= 65536) {
+                                               v->DataPTEReqHeightY = v->MacroTileBlockHeightY;
+                                       } else {
+                                               v->DataPTEReqHeightY = 16
+                                                               * v->Read256BlockHeightY[k];
+                                       }
+                                       v->DataPTEReqWidthY = 4096
+                                                       / dml_ceil_ex(v->BytePerPixelInDETY[k], 1)
+                                                       / v->DataPTEReqHeightY * 8;
+                                       if (src.sw_mode == dm_sw_linear) {
+                                               v->DPTEBytesPerRowY =
+                                                               64
+                                                                               * (dml_ceil_ex(
+                                                                                               (src.viewport_width
+                                                                                                               / v->NoOfDPP[ijk]
+                                                                                                               * dml_min(
+                                                                                                                               128,
+                                                                                                                               dml_pow(
+                                                                                                                                               2,
+                                                                                                                                               dml_floor_ex(
+                                                                                                                                                               dml_log(
+                                                                                                                                                                               ip->dpte_buffer_size_in_pte_reqs
+                                                                                                                                                                                               * v->DataPTEReqWidthY
+                                                                                                                                                                                               / (src.viewport_width
+                                                                                                                                                                                                               / v->NoOfDPP[ijk]),
+                                                                                                                                                                               2),
+                                                                                                                                                               1)))
+                                                                                                               - 1)
+                                                                                                               / v->DataPTEReqWidthY,
+                                                                                               1)
+                                                                                               + 1);
+                                       } else if (src.source_scan == dm_horz) {
+                                               v->DPTEBytesPerRowY =
+                                                               64
+                                                                               * (dml_ceil_ex(
+                                                                                               (src.viewport_width
+                                                                                                               / v->NoOfDPP[ijk]
+                                                                                                               - 1)
+                                                                                                               / v->DataPTEReqWidthY,
+                                                                                               1)
+                                                                                               + 1);
+                                       } else {
+                                               v->DPTEBytesPerRowY =
+                                                               64
+                                                                               * (dml_ceil_ex(
+                                                                                               (src.viewport_height
+                                                                                                               - 1)
+                                                                                                               / v->DataPTEReqHeightY,
+                                                                                               1)
+                                                                                               + 1);
+                                       }
+                               } else {
+                                       v->DPTEBytesPerRowY = 0;
+                               }
+
+                               if (src.source_format != dm_444_64 && src.source_format != dm_444_32
+                                               && src.source_format != dm_444_16) {
+                                       if (src.dcc == 1) {
+                                               v->MetaReqHeightC = 8 * v->Read256BlockHeightC[k];
+                                               v->MetaReqWidthC =
+                                                               64 * 256
+                                                                               / dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETC[k],
+                                                                                               2)
+                                                                               / v->MetaReqHeightC;
+                                               v->MetaSurfaceWidthC = dml_ceil_ex(
+                                                               src.viewport_width / v->NoOfDPP[ijk]
+                                                                               / 2 - 1,
+                                                               v->MetaReqWidthC)
+                                                               + v->MetaReqWidthC;
+                                               v->MetaSurfaceHeightC = dml_ceil_ex(
+                                                               src.viewport_height / 2 - 1,
+                                                               v->MetaReqHeightC)
+                                                               + v->MetaReqHeightC;
+                                               if (ip->pte_enable == 1) {
+                                                       v->MetaPteBytesPerFrameC =
+                                                                       (dml_ceil_ex(
+                                                                                       (v->MetaSurfaceWidthC
+                                                                                                       * v->MetaSurfaceHeightC
+                                                                                                       * dml_ceil_ex(
+                                                                                                                       v->BytePerPixelInDETC[k],
+                                                                                                                       2)
+                                                                                                       / 256.0
+                                                                                                       - 4096)
+                                                                                                       / 8
+                                                                                                       / 4096,
+                                                                                       1) + 1)
+                                                                                       * 64;
+                                               } else {
+                                                       v->MetaPteBytesPerFrameC = 0;
+                                               }
+                                               if (src.source_scan == dm_horz) {
+                                                       v->MetaRowBytesC =
+                                                                       v->MetaSurfaceWidthC
+                                                                                       * v->MetaReqHeightC
+                                                                                       * dml_ceil_ex(
+                                                                                                       v->BytePerPixelInDETC[k],
+                                                                                                       2)
+                                                                                       / 256;
+                                               } else {
+                                                       v->MetaRowBytesC =
+                                                                       v->MetaSurfaceHeightC
+                                                                                       * v->MetaReqWidthC
+                                                                                       * dml_ceil_ex(
+                                                                                                       v->BytePerPixelInDETC[k],
+                                                                                                       2)
+                                                                                       / 256;
+                                               }
+                                       } else {
+                                               v->MetaPteBytesPerFrameC = 0;
+                                               v->MetaRowBytesC = 0;
+                                       }
+
+                                       if (ip->pte_enable == 1) {
+                                               if (src.sw_mode == dm_sw_linear) {
+                                                       v->MacroTileBlockSizeBytesC = 256;
+                                                       v->MacroTileBlockHeightC = 1;
+                                               } else if (src.sw_mode == dm_sw_4kb_s
+                                                               || src.sw_mode == dm_sw_4kb_s_x
+                                                               || src.sw_mode == dm_sw_4kb_d
+                                                               || src.sw_mode == dm_sw_4kb_d_x) {
+                                                       v->MacroTileBlockSizeBytesC = 4096;
+                                                       v->MacroTileBlockHeightC = 4
+                                                                       * v->Read256BlockHeightC[k];
+                                               } else if (src.sw_mode == dm_sw_64kb_s
+                                                               || src.sw_mode == dm_sw_64kb_s_t
+                                                               || src.sw_mode == dm_sw_64kb_s_x
+                                                               || src.sw_mode == dm_sw_64kb_d
+                                                               || src.sw_mode == dm_sw_64kb_d_t
+                                                               || src.sw_mode == dm_sw_64kb_d_x) {
+                                                       v->MacroTileBlockSizeBytesC = 64 * 1024;
+                                                       v->MacroTileBlockHeightC = 16
+                                                                       * v->Read256BlockHeightC[k];
+                                               } else {
+                                                       v->MacroTileBlockSizeBytesC = 256 * 1024;
+                                                       v->MacroTileBlockHeightC = 32
+                                                                       * v->Read256BlockHeightC[k];
+                                               }
+                                               v->MacroTileBlockWidthC =
+                                                               v->MacroTileBlockSizeBytesC
+                                                                               / dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETC[k],
+                                                                                               2)
+                                                                               / v->MacroTileBlockHeightC;
+                                               if (v->MacroTileBlockSizeBytesC <= 65536) {
+                                                       v->DataPTEReqHeightC =
+                                                                       v->MacroTileBlockHeightC;
+                                               } else {
+                                                       v->DataPTEReqHeightC = 16
+                                                                       * v->Read256BlockHeightC[k];
+                                               }
+                                               v->DataPTEReqWidthC =
+                                                               4096
+                                                                               / dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETC[k],
+                                                                                               2)
+                                                                               / v->DataPTEReqHeightC
+                                                                               * 8;
+                                               if (src.sw_mode == dm_sw_linear) {
+                                                       v->DPTEBytesPerRowC =
+                                                                       64
+                                                                                       * (dml_ceil_ex(
+                                                                                                       (src.viewport_width
+                                                                                                                       / v->NoOfDPP[ijk]
+                                                                                                                       / 2
+                                                                                                                       * dml_min(
+                                                                                                                                       128,
+                                                                                                                                       dml_pow(
+                                                                                                                                                       2,
+                                                                                                                                                       dml_floor_ex(
+                                                                                                                                                                       dml_log(
+                                                                                                                                                                                       ip->dpte_buffer_size_in_pte_reqs
+                                                                                                                                                                                                       * v->DataPTEReqWidthC
+                                                                                                                                                                                                       / (src.viewport_width
+                                                                                                                                                                                                                       / v->NoOfDPP[ijk]
+                                                                                                                                                                                                                       / 2),
+                                                                                                                                                                                       2),
+                                                                                                                                                                       1)))
+                                                                                                                       - 1)
+                                                                                                                       / v->DataPTEReqWidthC,
+                                                                                                       1)
+                                                                                                       + 1);
+                                               } else if (src.source_scan == dm_horz) {
+                                                       v->DPTEBytesPerRowC =
+                                                                       64
+                                                                                       * (dml_ceil_ex(
+                                                                                                       (src.viewport_width
+                                                                                                                       / v->NoOfDPP[ijk]
+                                                                                                                       / 2
+                                                                                                                       - 1)
+                                                                                                                       / v->DataPTEReqWidthC,
+                                                                                                       1)
+                                                                                                       + 1);
+                                               } else {
+                                                       v->DPTEBytesPerRowC =
+                                                                       64
+                                                                                       * (dml_ceil_ex(
+                                                                                                       (src.viewport_height
+                                                                                                                       / 2
+                                                                                                                       - 1)
+                                                                                                                       / v->DataPTEReqHeightC,
+                                                                                                       1)
+                                                                                                       + 1);
+                                               }
+                                       } else {
+                                               v->DPTEBytesPerRowC = 0;
+                                       }
+                               } else {
+                                       v->DPTEBytesPerRowC = 0;
+                                       v->MetaPteBytesPerFrameC = 0;
+                                       v->MetaRowBytesC = 0;
+                               }
+
+                               v->DPTEBytesPerRow[k] = v->DPTEBytesPerRowY + v->DPTEBytesPerRowC;
+                               v->MetaPTEBytesPerFrame[k] = v->MetaPteBytesPerFrameY
+                                               + v->MetaPteBytesPerFrameC;
+                               v->MetaRowBytes[k] = v->MetaRowBytesY + v->MetaRowBytesC;
+
+                               v->VInitY = (scale_ratio_depth.vscl_ratio + scale_taps.vtaps + 1
+                                               + dest.interlaced * 0.5
+                                                               * scale_ratio_depth.vscl_ratio)
+                                               / 2.0;
+                               v->PrefillY[k] = dml_floor_ex(v->VInitY, 1);
+                               v->MaxNumSwY[k] = dml_ceil_ex(
+                                               (v->PrefillY[k] - 1.0)
+                                                               / v->SwathHeightYPerState[ijk],
+                                               1) + 1.0;
+
+                               if (v->PrefillY[k] > 1) {
+                                       v->MaxPartialSwY = ((int) (v->PrefillY[k] - 2))
+                                                       % ((int) v->SwathHeightYPerState[ijk]);
+                               } else {
+                                       v->MaxPartialSwY = ((int) (v->PrefillY[k]
+                                                       + v->SwathHeightYPerState[ijk] - 2))
+                                                       % ((int) v->SwathHeightYPerState[ijk]);
+                               }
+                               v->MaxPartialSwY = dml_max(1, v->MaxPartialSwY);
+
+                               v->PrefetchLinesY[k] = v->MaxNumSwY[k]
+                                               * v->SwathHeightYPerState[ijk] + v->MaxPartialSwY;
+
+                               if (src.source_format != dm_444_64 && src.source_format != dm_444_32
+                                               && src.source_format != dm_444_16) {
+                                       v->VInitC =
+                                                       (scale_ratio_depth.vscl_ratio / 2
+                                                                       + scale_taps.vtaps + 1
+                                                                       + dest.interlaced * 0.5
+                                                                                       * scale_ratio_depth.vscl_ratio
+                                                                                       / 2) / 2.0;
+                                       v->PrefillC[k] = dml_floor_ex(v->VInitC, 1);
+                                       v->MaxNumSwC[k] =
+                                                       dml_ceil_ex(
+                                                                       (v->PrefillC[k] - 1.0)
+                                                                                       / v->SwathHeightCPerState[ijk],
+                                                                       1) + 1.0;
+                                       if (v->PrefillC[k] > 1) {
+                                               v->MaxPartialSwC =
+                                                               ((int) (v->PrefillC[k] - 2))
+                                                                               % ((int) v->SwathHeightCPerState[ijk]);
+                                       } else {
+                                               v->MaxPartialSwC =
+                                                               ((int) (v->PrefillC[k]
+                                                                               + v->SwathHeightCPerState[ijk]
+                                                                               - 2))
+                                                                               % ((int) v->SwathHeightCPerState[ijk]);
+                                       }
+                                       v->MaxPartialSwC = dml_max(1, v->MaxPartialSwC);
+
+                                       v->PrefetchLinesC[k] = v->MaxNumSwC[k]
+                                                       * v->SwathHeightCPerState[ijk]
+                                                       + v->MaxPartialSwC;
+                               } else {
+                                       v->PrefetchLinesC[k] = 0;
+                               }
+
+                               v->dst_x_after_scaler = 90 * dest.pixel_rate_mhz
+                                               / (v->RequiredDISPCLK[ij] / (j + 1))
+                                               + 42 * dest.pixel_rate_mhz / v->RequiredDISPCLK[ij];
+                               if (v->NoOfDPP[ijk] > 1) {
+                                       v->dst_x_after_scaler = v->dst_x_after_scaler
+                                                       + dest.recout_width / 2.0;
+                               }
+
+                               if (dout.output_format == dm_420) {
+                                       v->dst_y_after_scaler = 1;
+                               } else {
+                                       v->dst_y_after_scaler = 0;
+                               }
+
+                               v->TimeCalc = 24 / v->ProjectedDCFCLKDeepSleep;
+
+                               v->VUpdateOffset = dml_ceil_ex(dest.htotal / 4, 1);
+                               v->TotalRepeaterDelay = ip->max_inter_dcn_tile_repeaters
+                                               * (2 / (v->RequiredDISPCLK[ij] / (j + 1))
+                                                               + 3 / v->RequiredDISPCLK[ij]);
+                               v->VUpdateWidth = (14 / v->ProjectedDCFCLKDeepSleep
+                                               + 12 / (v->RequiredDISPCLK[ij] / (j + 1))
+                                               + v->TotalRepeaterDelay) * dest.pixel_rate_mhz;
+                               v->VReadyOffset =
+                                               dml_max(
+                                                               150
+                                                                               / (v->RequiredDISPCLK[ij]
+                                                                                               / (j
+                                                                                                               + 1)),
+                                                               v->TotalRepeaterDelay
+                                                                               + 20
+                                                                                               / v->ProjectedDCFCLKDeepSleep
+                                                                               + 10
+                                                                                               / (v->RequiredDISPCLK[ij]
+                                                                                                               / (j
+                                                                                                                               + 1)))
+                                                               * dest.pixel_rate_mhz;
+
+                               v->TimeSetup =
+                                               (v->VUpdateOffset + v->VUpdateWidth
+                                                               + v->VReadyOffset)
+                                                               / dest.pixel_rate_mhz;
+
+                               v->ExtraLatency =
+                                               v->UrgentRoundTripAndOutOfOrderLatencyPerState[i]
+                                                               + (v->TotalNumberOfActiveDPP[ij]
+                                                                               * ip->pixel_chunk_size_kbytes
+                                                                               + v->TotalNumberOfDCCActiveDPP[ij]
+                                                                                               * ip->meta_chunk_size_kbytes)
+                                                                               * 1024
+                                                                               / v->ReturnBWPerState[i];
+
+                               if (ip->pte_enable == 1) {
+                                       v->ExtraLatency = v->ExtraLatency
+                                                       + v->TotalNumberOfActiveDPP[ij]
+                                                                       * ip->pte_chunk_size_kbytes
+                                                                       * 1024
+                                                                       / v->ReturnBWPerState[i];
+                               }
+
+                               if (ip->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one
+                                               == 1) {
+                                       v->MaximumVStartup = dest.vtotal - dest.vactive - 1;
+                               } else {
+                                       v->MaximumVStartup = dest.vsync_plus_back_porch - 1;
+                               }
+
+                               v->LineTimesForPrefetch[k] =
+                                               v->MaximumVStartup
+                                                               - soc->urgent_latency_us
+                                                                               / (dest.htotal
+                                                                                               / dest.pixel_rate_mhz)
+                                                               - (v->TimeCalc + v->TimeSetup)
+                                                                               / (dest.htotal
+                                                                                               / dest.pixel_rate_mhz)
+                                                               - (v->dst_y_after_scaler
+                                                                               + v->dst_x_after_scaler
+                                                                                               / dest.htotal);
+
+                               v->LineTimesForPrefetch[k] = dml_floor_ex(
+                                               4.0 * (v->LineTimesForPrefetch[k] + 0.125),
+                                               1) / 4;
+
+                               v->PrefetchBW[k] =
+                                               (v->MetaPTEBytesPerFrame[k] + 2 * v->MetaRowBytes[k]
+                                                               + 2 * v->DPTEBytesPerRow[k]
+                                                               + v->PrefetchLinesY[k]
+                                                                               * v->SwathWidthYPerState[ijk]
+                                                                               * dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETY[k],
+                                                                                               1)
+                                                               + v->PrefetchLinesC[k]
+                                                                               * v->SwathWidthYPerState[ijk]
+                                                                               / 2
+                                                                               * dml_ceil_ex(
+                                                                                               v->BytePerPixelInDETC[k],
+                                                                                               2))
+                                                               / (v->LineTimesForPrefetch[k]
+                                                                               * dest.htotal
+                                                                               / dest.pixel_rate_mhz);
+                       }
+
+                       v->BWAvailableForImmediateFlip = v->ReturnBWPerState[i];
+
+                       for (k = 0; k < num_planes; k++) {
+                               v->BWAvailableForImmediateFlip = v->BWAvailableForImmediateFlip
+                                               - dml_max(v->ReadBandwidth[k], v->PrefetchBW[k]);
+                       }
+
+                       v->TotalImmediateFlipBytes = 0;
+
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+
+                               if (src.source_format != dm_420_8
+                                               && src.source_format != dm_420_10) {
+                                       v->TotalImmediateFlipBytes = v->TotalImmediateFlipBytes
+                                                       + v->MetaPTEBytesPerFrame[k]
+                                                       + v->MetaRowBytes[k]
+                                                       + v->DPTEBytesPerRow[k];
+                               }
+                       }
+
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+                               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                               e2e[v->planes[k].e2e_index].pipe.dest;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (ip->pte_enable == 1 && src.dcc == 1) {
+                                       v->TimeForMetaPTEWithImmediateFlip =
+                                                       dml_max(
+                                                                       v->MetaPTEBytesPerFrame[k]
+                                                                                       / v->PrefetchBW[k],
+                                                                       dml_max(
+                                                                                       v->MetaPTEBytesPerFrame[k]
+                                                                                                       * v->TotalImmediateFlipBytes
+                                                                                                       / (v->BWAvailableForImmediateFlip
+                                                                                                                       * (v->MetaPTEBytesPerFrame[k]
+                                                                                                                                       + v->MetaRowBytes[k]
+                                                                                                                                       + v->DPTEBytesPerRow[k])),
+                                                                                       dml_max(
+                                                                                                       v->ExtraLatency,
+                                                                                                       dml_max(
+                                                                                                                       soc->urgent_latency_us,
+                                                                                                                       dest.htotal
+                                                                                                                                       / dest.pixel_rate_mhz
+                                                                                                                                       / 4))));
+
+                                       v->TimeForMetaPTEWithoutImmediateFlip =
+                                                       dml_max(
+                                                                       v->MetaPTEBytesPerFrame[k]
+                                                                                       / v->PrefetchBW[k],
+                                                                       dml_max(
+                                                                                       v->ExtraLatency,
+                                                                                       dest.htotal
+                                                                                                       / dest.pixel_rate_mhz
+                                                                                                       / 4));
+                               } else {
+                                       v->TimeForMetaPTEWithImmediateFlip = dest.htotal
+                                                       / dest.pixel_rate_mhz / 4;
+                                       v->TimeForMetaPTEWithoutImmediateFlip = dest.htotal
+                                                       / dest.pixel_rate_mhz / 4;
+                               }
+
+                               if (ip->pte_enable == 1 || src.dcc == 1) {
+                                       v->TimeForMetaAndDPTERowWithImmediateFlip =
+                                                       dml_max(
+                                                                       (v->MetaRowBytes[k]
+                                                                                       + v->DPTEBytesPerRow[k])
+                                                                                       / v->PrefetchBW[k],
+                                                                       dml_max(
+                                                                                       (v->MetaRowBytes[k]
+                                                                                                       + v->DPTEBytesPerRow[k])
+                                                                                                       * v->TotalImmediateFlipBytes
+                                                                                                       / (v->BWAvailableForImmediateFlip
+                                                                                                                       * (v->MetaPTEBytesPerFrame[k]
+                                                                                                                                       + v->MetaRowBytes[k]
+                                                                                                                                       + v->DPTEBytesPerRow[k])),
+                                                                                       dml_max(
+                                                                                                       dest.htotal
+                                                                                                                       / dest.pixel_rate_mhz
+                                                                                                                       - v->TimeForMetaPTEWithImmediateFlip,
+                                                                                                       dml_max(
+                                                                                                                       v->ExtraLatency,
+                                                                                                                       2
+                                                                                                                                       * soc->urgent_latency_us))));
+
+                                       v->TimeForMetaAndDPTERowWithoutImmediateFlip =
+                                                       dml_max(
+                                                                       (v->MetaRowBytes[k]
+                                                                                       + v->DPTEBytesPerRow[k])
+                                                                                       / v->PrefetchBW[k],
+                                                                       dml_max(
+                                                                                       dest.htotal
+                                                                                                       / dest.pixel_rate_mhz
+                                                                                                       - v->TimeForMetaPTEWithoutImmediateFlip,
+                                                                                       v->ExtraLatency));
+                               } else {
+                                       v->TimeForMetaAndDPTERowWithImmediateFlip =
+                                                       dml_max(
+                                                                       dest.htotal
+                                                                                       / dest.pixel_rate_mhz
+                                                                                       - v->TimeForMetaPTEWithImmediateFlip,
+                                                                       v->ExtraLatency
+                                                                                       - v->TimeForMetaPTEWithImmediateFlip);
+                                       v->TimeForMetaAndDPTERowWithoutImmediateFlip =
+                                                       dml_max(
+                                                                       dest.htotal
+                                                                                       / dest.pixel_rate_mhz
+                                                                                       - v->TimeForMetaPTEWithoutImmediateFlip,
+                                                                       v->ExtraLatency
+                                                                                       - v->TimeForMetaPTEWithoutImmediateFlip);
+                               }
+
+                               v->LinesForMetaPTEWithImmediateFlip[k] =
+                                               dml_floor_ex(
+                                                               4.0
+                                                                               * (v->TimeForMetaPTEWithImmediateFlip
+                                                                                               / (dest.htotal
+                                                                                                               / dest.pixel_rate_mhz)
+                                                                                               + 0.125),
+                                                               1) / 4.0;
+
+                               v->LinesForMetaPTEWithoutImmediateFlip[k] =
+                                               dml_floor_ex(
+                                                               4.0
+                                                                               * (v->TimeForMetaPTEWithoutImmediateFlip
+                                                                                               / (dest.htotal
+                                                                                                               / dest.pixel_rate_mhz)
+                                                                                               + 0.125),
+                                                               1) / 4.0;
+
+                               v->LinesForMetaAndDPTERowWithImmediateFlip[k] =
+                                               dml_floor_ex(
+                                                               4.0
+                                                                               * (v->TimeForMetaAndDPTERowWithImmediateFlip
+                                                                                               / (dest.htotal
+                                                                                                               / dest.pixel_rate_mhz)
+                                                                                               + 0.125),
+                                                               1) / 4.0;
+
+                               v->LinesForMetaAndDPTERowWithoutImmediateFlip[k] =
+                                               dml_floor_ex(
+                                                               4.0
+                                                                               * (v->TimeForMetaAndDPTERowWithoutImmediateFlip
+                                                                                               / (dest.htotal
+                                                                                                               / dest.pixel_rate_mhz)
+                                                                                               + 0.125),
+                                                               1) / 4.0;
+
+                               v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip =
+                                               v->LineTimesForPrefetch[k]
+                                                               - v->LinesForMetaPTEWithImmediateFlip[k]
+                                                               - v->LinesForMetaAndDPTERowWithImmediateFlip[k];
+
+                               v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip =
+                                               v->LineTimesForPrefetch[k]
+                                                               - v->LinesForMetaPTEWithoutImmediateFlip[k]
+                                                               - v->LinesForMetaAndDPTERowWithoutImmediateFlip[k];
+
+                               if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip > 0) {
+                                       v->VRatioPreYWithImmediateFlip[ijk] =
+                                                       v->PrefetchLinesY[k]
+                                                                       / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip;
+                                       if (v->SwathHeightYPerState[ijk] > 4) {
+                                               if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip
+                                                               - (v->PrefillY[k] - 3.0) / 2.0
+                                                               > 0) {
+                                                       v->VRatioPreYWithImmediateFlip[ijk] =
+                                                                       dml_max(
+                                                                                       v->VRatioPreYWithImmediateFlip[ijk],
+                                                                                       (v->MaxNumSwY[k]
+                                                                                                       * v->SwathHeightYPerState[ijk])
+                                                                                                       / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip
+                                                                                                                       - (v->PrefillY[k]
+                                                                                                                                       - 3.0)
+                                                                                                                                       / 2.0));
+                                               } else {
+                                                       v->VRatioPreYWithImmediateFlip[ijk] =
+                                                                       999999;
+                                               }
+                                       }
+                                       v->VRatioPreCWithImmediateFlip[ijk] =
+                                                       v->PrefetchLinesC[k]
+                                                                       / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip;
+                                       if (v->SwathHeightCPerState[ijk] > 4) {
+                                               if (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip
+                                                               - (v->PrefillC[k] - 3.0) / 2.0
+                                                               > 0) {
+                                                       v->VRatioPreCWithImmediateFlip[ijk] =
+                                                                       dml_max(
+                                                                                       v->VRatioPreCWithImmediateFlip[ijk],
+                                                                                       (v->MaxNumSwC[k]
+                                                                                                       * v->SwathHeightCPerState[ijk])
+                                                                                                       / (v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip
+                                                                                                                       - (v->PrefillC[k]
+                                                                                                                                       - 3.0)
+                                                                                                                                       / 2.0));
+                                               } else {
+                                                       v->VRatioPreCWithImmediateFlip[ijk] =
+                                                                       999999;
+                                               }
+                                       }
+
+                                       v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] =
+                                                       v->NoOfDPP[ijk]
+                                                                       * (v->PrefetchLinesY[k]
+                                                                                       / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip
+                                                                                       * dml_ceil_ex(
+                                                                                                       v->BytePerPixelInDETY[k],
+                                                                                                       1)
+                                                                                       + v->PrefetchLinesC[k]
+                                                                                                       / v->LineTimesToRequestPrefetchPixelDataWithImmediateFlip
+                                                                                                       * dml_ceil_ex(
+                                                                                                                       v->BytePerPixelInDETC[k],
+                                                                                                                       2)
+                                                                                                       / 2)
+                                                                       * v->SwathWidthYPerState[ijk]
+                                                                       / (dest.htotal
+                                                                                       / dest.pixel_rate_mhz);
+                               } else {
+                                       v->VRatioPreYWithImmediateFlip[ijk] = 999999;
+                                       v->VRatioPreCWithImmediateFlip[ijk] = 999999;
+                                       v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk] =
+                                                       999999;
+                               }
+
+                               if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                               > 0) {
+                                       v->VRatioPreYWithoutImmediateFlip[ijk] =
+                                                       v->PrefetchLinesY[k]
+                                                                       / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip;
+                                       if (v->SwathHeightYPerState[ijk] > 4) {
+                                               if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                                               - (v->PrefillY[k] - 3.0) / 2.0
+                                                               > 0) {
+                                                       v->VRatioPreYWithoutImmediateFlip[ijk] =
+                                                                       dml_max(
+                                                                                       v->VRatioPreYWithoutImmediateFlip[ijk],
+                                                                                       (v->MaxNumSwY[k]
+                                                                                                       * v->SwathHeightYPerState[ijk])
+                                                                                                       / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                                                                                                       - (v->PrefillY[k]
+                                                                                                                                       - 3.0)
+                                                                                                                                       / 2.0));
+                                               } else {
+                                                       v->VRatioPreYWithoutImmediateFlip[ijk] =
+                                                                       999999;
+                                               }
+                                       }
+                                       v->VRatioPreCWithoutImmediateFlip[ijk] =
+                                                       v->PrefetchLinesC[k]
+                                                                       / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip;
+                                       if (v->SwathHeightCPerState[ijk] > 4) {
+                                               if (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                                               - (v->PrefillC[k] - 3.0) / 2.0
+                                                               > 0) {
+                                                       v->VRatioPreCWithoutImmediateFlip[ijk] =
+                                                                       dml_max(
+                                                                                       v->VRatioPreCWithoutImmediateFlip[ijk],
+                                                                                       (v->MaxNumSwC[k]
+                                                                                                       * v->SwathHeightCPerState[ijk])
+                                                                                                       / (v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                                                                                                       - (v->PrefillC[k]
+                                                                                                                                       - 3.0)
+                                                                                                                                       / 2.0));
+                                               } else {
+                                                       v->VRatioPreCWithoutImmediateFlip[ijk] =
+                                                                       999999;
+                                               }
+                                       }
+
+                                       v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] =
+                                                       v->NoOfDPP[ijk]
+                                                                       * (v->PrefetchLinesY[k]
+                                                                                       / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                                                                       * dml_ceil_ex(
+                                                                                                       v->BytePerPixelInDETY[k],
+                                                                                                       1)
+                                                                                       + v->PrefetchLinesC[k]
+                                                                                                       / v->LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip
+                                                                                                       * dml_ceil_ex(
+                                                                                                                       v->BytePerPixelInDETC[k],
+                                                                                                                       2)
+                                                                                                       / 2)
+                                                                       * v->SwathWidthYPerState[ijk]
+                                                                       / (dest.htotal
+                                                                                       / dest.pixel_rate_mhz);
+                               } else {
+                                       v->VRatioPreYWithoutImmediateFlip[ijk] = 999999;
+                                       v->VRatioPreCWithoutImmediateFlip[ijk] = 999999;
+                                       v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk] =
+                                                       999999;
+                               }
+                       }
+
+                       v->MaximumReadBandwidthWithPrefetchWithImmediateFlip = 0;
+
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+                               struct _vcs_dpi_display_pipe_dest_params_st dest =
+                                               e2e[v->planes[k].e2e_index].pipe.dest;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (src.source_format != dm_420_8
+                                               && src.source_format != dm_420_10) {
+                                       v->MaximumReadBandwidthWithPrefetchWithImmediateFlip =
+                                                       v->MaximumReadBandwidthWithPrefetchWithImmediateFlip
+                                                                       + dml_max(
+                                                                                       v->ReadBandwidth[k],
+                                                                                       v->RequiredPrefetchPixelDataBWWithImmediateFlip[ijk])
+                                                                       + dml_max(
+                                                                                       v->MetaPTEBytesPerFrame[k]
+                                                                                                       / (v->LinesForMetaPTEWithImmediateFlip[k]
+                                                                                                                       * dest.htotal
+                                                                                                                       / dest.pixel_rate_mhz),
+                                                                                       (v->MetaRowBytes[k]
+                                                                                                       + v->DPTEBytesPerRow[k])
+                                                                                                       / (v->LinesForMetaAndDPTERowWithImmediateFlip[k]
+                                                                                                                       * dest.htotal
+                                                                                                                       / dest.pixel_rate_mhz));
+                               } else {
+                                       v->MaximumReadBandwidthWithPrefetchWithImmediateFlip =
+                                                       v->MaximumReadBandwidthWithPrefetchWithImmediateFlip
+                                                                       + dml_max(
+                                                                                       v->ReadBandwidth[k],
+                                                                                       v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]);
+                               }
+                       }
+
+                       v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip = 0;
+
+                       for (k = 0; k < num_planes; k++) {
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip =
+                                               v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip
+                                                               + dml_max(
+                                                                               v->ReadBandwidth[k],
+                                                                               v->RequiredPrefetchPixelDataBWWithoutImmediateFlip[ijk]);
+                       }
+
+                       v->PrefetchSupportedWithImmediateFlip[ij] = 1;
+                       if (v->MaximumReadBandwidthWithPrefetchWithImmediateFlip
+                                       > v->ReturnBWPerState[i]) {
+                               v->PrefetchSupportedWithImmediateFlip[ij] = 0;
+                       }
+                       for (k = 0; k < num_planes; k++) {
+                               if (v->LineTimesForPrefetch[k] < 2
+                                               || v->LinesForMetaPTEWithImmediateFlip[k] >= 8
+                                               || v->LinesForMetaAndDPTERowWithImmediateFlip[k]
+                                                               >= 16) {
+                                       v->PrefetchSupportedWithImmediateFlip[ij] = 0;
+                               }
+                       }
+
+                       v->PrefetchSupportedWithoutImmediateFlip[ij] = 1;
+                       if (v->MaximumReadBandwidthWithPrefetchWithoutImmediateFlip
+                                       > v->ReturnBWPerState[i]) {
+                               v->PrefetchSupportedWithoutImmediateFlip[ij] = 0;
+                       }
+                       for (k = 0; k < num_planes; k++) {
+                               if (v->LineTimesForPrefetch[k] < 2
+                                               || v->LinesForMetaPTEWithoutImmediateFlip[k] >= 8
+                                               || v->LinesForMetaAndDPTERowWithoutImmediateFlip[k]
+                                                               >= 16) {
+                                       v->PrefetchSupportedWithoutImmediateFlip[ij] = 0;
+                               }
+                       }
+               }
+       }
+
+       for (i = 0; i < NumberOfStatesPlusTwo; i++) {
+               for (j = 0; j < 2; j++) {
+                       ij = j * NumberOfStatesPlusTwo + i;
+
+                       v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 1;
+                       for (k = 0; k < num_planes; k++) {
+                               struct _vcs_dpi_display_pipe_source_params_st src =
+                                               e2e[v->planes[k].e2e_index].pipe.src;
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (((src.source_format != dm_420_8
+                                               && src.source_format != dm_420_10)
+                                               && (v->VRatioPreYWithImmediateFlip[ijk] > 4
+                                                               || v->VRatioPreCWithImmediateFlip[ijk]
+                                                                               > 4))
+                                               || ((src.source_format == dm_420_8
+                                                               || src.source_format == dm_420_10)
+                                                               && (v->VRatioPreYWithoutImmediateFlip[ijk]
+                                                                               > 4
+                                                                               || v->VRatioPreCWithoutImmediateFlip[ijk]
+                                                                                               > 4))) {
+                                       v->VRatioInPrefetchSupportedWithImmediateFlip[ij] = 0;
+                               }
+                       }
+                       v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 1;
+                       for (k = 0; k < num_planes; k++) {
+                               ijk = k * 2 * NumberOfStatesPlusTwo + j * NumberOfStatesPlusTwo + i;
+
+                               if (v->VRatioPreYWithoutImmediateFlip[ijk] > 4
+                                               || v->VRatioPreCWithoutImmediateFlip[ijk] > 4) {
+                                       v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij] = 0;
+                               }
+                       }
+               }
+       }
+
+       // Mode Support, Voltage State and SOC Configuration
+
+       for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here
+                       {
+               for (j = 0; j < 2; j++) {
+                       ij = j * NumberOfStatesPlusTwo + i;
+
+                       if (v->ScaleRatioSupport == 1 && v->SourceFormatPixelAndScanSupport == 1
+                                       && v->ViewportSizeSupport == 1
+                                       && v->BandwidthSupport[i] == 1 && v->DIOSupport[i] == 1
+                                       && v->UrgentLatencySupport[ij] == 1 && v->ROBSupport[i] == 1
+                                       && v->DISPCLK_DPPCLK_Support[ij] == 1
+                                       && v->TotalAvailablePipesSupport[ij] == 1
+                                       && v->TotalAvailableWritebackSupport == 1
+                                       && v->WritebackLatencySupport == 1) {
+                               if (v->PrefetchSupportedWithImmediateFlip[ij] == 1
+                                               && v->VRatioInPrefetchSupportedWithImmediateFlip[ij]
+                                                               == 1) {
+                                       v->ModeSupportWithImmediateFlip[ij] = 1;
+                               } else {
+                                       v->ModeSupportWithImmediateFlip[ij] = 0;
+                               }
+                               if (v->PrefetchSupportedWithoutImmediateFlip[ij] == 1
+                                               && v->VRatioInPrefetchSupportedWithoutImmediateFlip[ij]
+                                                               == 1) {
+                                       v->ModeSupportWithoutImmediateFlip[ij] = 1;
+                               } else {
+                                       v->ModeSupportWithoutImmediateFlip[ij] = 0;
+                               }
+                       } else {
+                               v->ModeSupportWithImmediateFlip[ij] = 0;
+                               v->ModeSupportWithoutImmediateFlip[ij] = 0;
+                       }
+               }
+       }
+
+       for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here
+                       {
+               if ((i == (NumberOfStatesPlusTwo - 1)
+                               || v->ModeSupportWithImmediateFlip[1 * NumberOfStatesPlusTwo + i]
+                                               == 1
+                               || v->ModeSupportWithImmediateFlip[0 * NumberOfStatesPlusTwo + i]
+                                               == 1) && i >= v->VoltageOverrideLevel) {
+                       v->VoltageLevelWithImmediateFlip = i;
+               }
+       }
+
+       for (i = (NumberOfStatesPlusTwo - 1); i >= 0; i--) // use int type here
+                       {
+               if ((i == (NumberOfStatesPlusTwo - 1)
+                               || v->ModeSupportWithoutImmediateFlip[1 * NumberOfStatesPlusTwo + i]
+                                               == 1
+                               || v->ModeSupportWithoutImmediateFlip[0 * NumberOfStatesPlusTwo + i]
+                                               == 1) && i >= v->VoltageOverrideLevel) {
+                       v->VoltageLevelWithoutImmediateFlip = i;
+               }
+       }
+
+       if (v->VoltageLevelWithImmediateFlip == (NumberOfStatesPlusTwo - 1)) {
+               v->ImmediateFlipSupported = 0;
+               v->VoltageLevel = v->VoltageLevelWithoutImmediateFlip;
+       } else {
+               v->ImmediateFlipSupported = 1;
+               v->VoltageLevel = v->VoltageLevelWithImmediateFlip;
+       }
+
+       v->DCFCLK = v->DCFCLKPerState[(int) v->VoltageLevel];
+       v->FabricAndDRAMBandwidth = v->FabricAndDRAMBandwidthPerState[(int) v->VoltageLevel];
+
+       for (j = 0; j < 2; j++) {
+               v->RequiredDISPCLKPerRatio[j] = v->RequiredDISPCLK[j * NumberOfStatesPlusTwo
+                               + (int) v->VoltageLevel];
+               for (k = 0; k < num_planes; k++) {
+                       v->DPPPerPlanePerRatio[k * 2 + j] = v->NoOfDPP[k * 2 * NumberOfStatesPlusTwo
+                                       + j * NumberOfStatesPlusTwo + (int) v->VoltageLevel];
+               }
+               v->DISPCLK_DPPCLK_SupportPerRatio[j] = v->DISPCLK_DPPCLK_Support[j
+                               * NumberOfStatesPlusTwo + (int) v->VoltageLevel];
+       }
+
+       ASSERT(v->ImmediateFlipSupported || v->MacroTileBlockWidthC || v->DCFCLK || v->FabricAndDRAMBandwidth);
+
+       return (v->VoltageLevel);
+}
+
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h
new file mode 100644 (file)
index 0000000..ead4942
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2017 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 __DISPLAY_MODE_SUPPORT_H__
+#define __DISPLAY_MODE_SUPPORT_H__
+
+#include "dml_common_defs.h"
+
+struct display_mode_lib;
+
+#define NumberOfStates 4
+#define NumberOfStatesPlusTwo (NumberOfStates+2)
+
+struct dml_ms_internal_vars {
+       double ScaleRatioSupport;
+       double SourceFormatPixelAndScanSupport;
+       double TotalReadBandwidthConsumedGBytePerSecond;
+       double TotalWriteBandwidthConsumedGBytePerSecond;
+       double TotalBandwidthConsumedGBytePerSecond;
+       double DCCEnabledInAnyPlane;
+       double ReturnBWToDCNPerState;
+       double CriticalPoint;
+       double WritebackLatencySupport;
+       double RequiredOutputBW;
+       double TotalNumberOfActiveWriteback;
+       double TotalAvailableWritebackSupport;
+       double MaximumSwathWidth;
+       double NumberOfDPPRequiredForDETSize;
+       double NumberOfDPPRequiredForLBSize;
+       double MinDispclkUsingSingleDPP;
+       double MinDispclkUsingDualDPP;
+       double ViewportSizeSupport;
+       double SwathWidthGranularityY;
+       double RoundedUpMaxSwathSizeBytesY;
+       double SwathWidthGranularityC;
+       double RoundedUpMaxSwathSizeBytesC;
+       double LinesInDETLuma;
+       double LinesInDETChroma;
+       double EffectiveLBLatencyHidingSourceLinesLuma;
+       double EffectiveLBLatencyHidingSourceLinesChroma;
+       double EffectiveDETLBLinesLuma;
+       double EffectiveDETLBLinesChroma;
+       double ProjectedDCFCLKDeepSleep;
+       double MetaReqHeightY;
+       double MetaReqWidthY;
+       double MetaSurfaceWidthY;
+       double MetaSurfaceHeightY;
+       double MetaPteBytesPerFrameY;
+       double MetaRowBytesY;
+       double MacroTileBlockSizeBytesY;
+       double MacroTileBlockHeightY;
+       double DataPTEReqHeightY;
+       double DataPTEReqWidthY;
+       double DPTEBytesPerRowY;
+       double MetaReqHeightC;
+       double MetaReqWidthC;
+       double MetaSurfaceWidthC;
+       double MetaSurfaceHeightC;
+       double MetaPteBytesPerFrameC;
+       double MetaRowBytesC;
+       double MacroTileBlockSizeBytesC;
+       double MacroTileBlockHeightC;
+       double MacroTileBlockWidthC;
+       double DataPTEReqHeightC;
+       double DataPTEReqWidthC;
+       double DPTEBytesPerRowC;
+       double VInitY;
+       double MaxPartialSwY;
+       double VInitC;
+       double MaxPartialSwC;
+       double dst_x_after_scaler;
+       double dst_y_after_scaler;
+       double TimeCalc;
+       double VUpdateOffset;
+       double TotalRepeaterDelay;
+       double VUpdateWidth;
+       double VReadyOffset;
+       double TimeSetup;
+       double ExtraLatency;
+       double MaximumVStartup;
+       double BWAvailableForImmediateFlip;
+       double TotalImmediateFlipBytes;
+       double TimeForMetaPTEWithImmediateFlip;
+       double TimeForMetaPTEWithoutImmediateFlip;
+       double TimeForMetaAndDPTERowWithImmediateFlip;
+       double TimeForMetaAndDPTERowWithoutImmediateFlip;
+       double LineTimesToRequestPrefetchPixelDataWithImmediateFlip;
+       double LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip;
+       double MaximumReadBandwidthWithPrefetchWithImmediateFlip;
+       double MaximumReadBandwidthWithPrefetchWithoutImmediateFlip;
+       double VoltageOverrideLevel;
+       double VoltageLevelWithImmediateFlip;
+       double VoltageLevelWithoutImmediateFlip;
+       double ImmediateFlipSupported;
+       double VoltageLevel;
+       double DCFCLK;
+       double FabricAndDRAMBandwidth;
+       double SwathWidthYSingleDPP[DC__NUM_PIPES__MAX];
+       double BytePerPixelInDETY[DC__NUM_PIPES__MAX];
+       double BytePerPixelInDETC[DC__NUM_PIPES__MAX];
+       double ReadBandwidth[DC__NUM_PIPES__MAX];
+       double WriteBandwidth[DC__NUM_PIPES__MAX];
+       double DCFCLKPerState[NumberOfStatesPlusTwo];
+       double FabricAndDRAMBandwidthPerState[NumberOfStatesPlusTwo];
+       double ReturnBWPerState[NumberOfStatesPlusTwo];
+       double BandwidthSupport[NumberOfStatesPlusTwo];
+       double UrgentRoundTripAndOutOfOrderLatencyPerState[NumberOfStatesPlusTwo];
+       double ROBSupport[NumberOfStatesPlusTwo];
+       double RequiredPHYCLK[DC__NUM_PIPES__MAX];
+       double DIOSupport[NumberOfStatesPlusTwo];
+       double PHYCLKPerState[NumberOfStatesPlusTwo];
+       double PSCL_FACTOR[DC__NUM_PIPES__MAX];
+       double PSCL_FACTOR_CHROMA[DC__NUM_PIPES__MAX];
+       double MinDPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX];
+       double Read256BlockHeightY[DC__NUM_PIPES__MAX];
+       double Read256BlockWidthY[DC__NUM_PIPES__MAX];
+       double Read256BlockHeightC[DC__NUM_PIPES__MAX];
+       double Read256BlockWidthC[DC__NUM_PIPES__MAX];
+       double MaxSwathHeightY[DC__NUM_PIPES__MAX];
+       double MaxSwathHeightC[DC__NUM_PIPES__MAX];
+       double MinSwathHeightY[DC__NUM_PIPES__MAX];
+       double MinSwathHeightC[DC__NUM_PIPES__MAX];
+       double NumberOfDPPRequiredForDETAndLBSize[DC__NUM_PIPES__MAX];
+       double TotalNumberOfActiveDPP[NumberOfStatesPlusTwo * 2];
+       double RequiredDISPCLK[NumberOfStatesPlusTwo * 2];
+       double DISPCLK_DPPCLK_Support[NumberOfStatesPlusTwo * 2];
+       double MaxDispclk[NumberOfStatesPlusTwo];
+       double MaxDppclk[NumberOfStatesPlusTwo];
+       double NoOfDPP[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double TotalAvailablePipesSupport[NumberOfStatesPlusTwo * 2];
+       double SwathWidthYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double SwathHeightYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double SwathHeightCPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double DETBufferSizeYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double UrgentLatencySupportUsPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double UrgentLatencySupport[NumberOfStatesPlusTwo * 2];
+       double TotalNumberOfDCCActiveDPP[NumberOfStatesPlusTwo * 2];
+       double DPTEBytesPerRow[DC__NUM_PIPES__MAX];
+       double MetaPTEBytesPerFrame[DC__NUM_PIPES__MAX];
+       double MetaRowBytes[DC__NUM_PIPES__MAX];
+       double PrefillY[DC__NUM_PIPES__MAX];
+       double MaxNumSwY[DC__NUM_PIPES__MAX];
+       double PrefetchLinesY[DC__NUM_PIPES__MAX];
+       double PrefillC[DC__NUM_PIPES__MAX];
+       double MaxNumSwC[DC__NUM_PIPES__MAX];
+       double PrefetchLinesC[DC__NUM_PIPES__MAX];
+       double LineTimesForPrefetch[DC__NUM_PIPES__MAX];
+       double PrefetchBW[DC__NUM_PIPES__MAX];
+       double LinesForMetaPTEWithImmediateFlip[DC__NUM_PIPES__MAX];
+       double LinesForMetaPTEWithoutImmediateFlip[DC__NUM_PIPES__MAX];
+       double LinesForMetaAndDPTERowWithImmediateFlip[DC__NUM_PIPES__MAX];
+       double LinesForMetaAndDPTERowWithoutImmediateFlip[DC__NUM_PIPES__MAX];
+       double VRatioPreYWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double VRatioPreCWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double RequiredPrefetchPixelDataBWWithImmediateFlip[NumberOfStatesPlusTwo * 2
+                       * DC__NUM_PIPES__MAX];
+       double VRatioPreYWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double VRatioPreCWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
+       double RequiredPrefetchPixelDataBWWithoutImmediateFlip[NumberOfStatesPlusTwo * 2
+                       * DC__NUM_PIPES__MAX];
+       double PrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
+       double PrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
+       double VRatioInPrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
+       double VRatioInPrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
+       double ModeSupportWithImmediateFlip[NumberOfStatesPlusTwo * 2];
+       double ModeSupportWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
+       double RequiredDISPCLKPerRatio[2];
+       double DPPPerPlanePerRatio[2 * DC__NUM_PIPES__MAX];
+       double DISPCLK_DPPCLK_SupportPerRatio[2];
+       struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX];
+};
+
+int dml_ms_check(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               int num_pipes);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.c
new file mode 100644 (file)
index 0000000..2e4dc57
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Copyright 2017 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_pipe_clocks.h"
+#include "display_mode_lib.h"
+#include "soc_bounding_box.h"
+
+static enum voltage_state power_state(
+               struct display_mode_lib *mode_lib,
+               double dispclk,
+               double dppclk)
+{
+       enum voltage_state state1;
+       enum voltage_state state2;
+
+       if (dispclk <= mode_lib->soc.vmin.dispclk_mhz)
+               state1 = dm_vmin;
+       else if (dispclk <= mode_lib->soc.vnom.dispclk_mhz)
+               state1 = dm_vnom;
+       else if (dispclk <= mode_lib->soc.vmax.dispclk_mhz)
+               state1 = dm_vmax;
+       else
+               state1 = dm_vmax_exceeded;
+
+       if (dppclk <= mode_lib->soc.vmin.dppclk_mhz)
+               state2 = dm_vmin;
+       else if (dppclk <= mode_lib->soc.vnom.dppclk_mhz)
+               state2 = dm_vnom;
+       else if (dppclk <= mode_lib->soc.vmax.dppclk_mhz)
+               state2 = dm_vmax;
+       else
+               state2 = dm_vmax_exceeded;
+
+       if (state1 > state2)
+               return state1;
+       else
+               return state2;
+}
+
+static unsigned int dpp_in_grp(
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes,
+               unsigned int hsplit_grp)
+{
+       unsigned int num_dpp = 0;
+       unsigned int i;
+
+       for (i = 0; i < num_pipes; i++) {
+               if (e2e[i].pipe.src.is_hsplit) {
+                       if (e2e[i].pipe.src.hsplit_grp == hsplit_grp) {
+                               num_dpp++;
+                       }
+               }
+       }
+
+       if (0 == num_dpp)
+               num_dpp = 1;
+
+       return num_dpp;
+}
+
+static void calculate_pipe_clk_requirement(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_dpp_in_grp,
+               double *dppclk,
+               double *dispclk,
+               bool *dppdiv)
+{
+       double pscl_throughput = 0.0;
+       double max_hratio = e2e->pipe.scale_ratio_depth.hscl_ratio;
+       double max_vratio = e2e->pipe.scale_ratio_depth.vscl_ratio;
+       double max_htaps = e2e->pipe.scale_taps.htaps;
+       double max_vtaps = e2e->pipe.scale_taps.vtaps;
+       double dpp_clock_divider = (double) num_dpp_in_grp;
+       double dispclk_dppclk_ratio;
+       double dispclk_ramp_margin_percent;
+
+       if (max_hratio > 1.0) {
+               double pscl_to_lb = ((double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk * max_hratio)
+                               / dml_ceil(max_htaps / 6.0);
+               pscl_throughput = dml_min(
+                               pscl_to_lb,
+                               (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk);
+       } else {
+               pscl_throughput = dml_min(
+                               (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk,
+                               (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk);
+       }
+
+       DTRACE("pscl_throughput: %f pix per clk", pscl_throughput);
+       DTRACE("vtaps: %f hratio: %f vratio: %f", max_vtaps, max_hratio, max_vratio);
+       *dppclk = dml_max(
+                       max_vtaps / 6.0 * dml_min(1.0, max_hratio),
+                       max_hratio * max_vratio / pscl_throughput);
+       DTRACE("pixel rate multiplier: %f", *dppclk);
+       *dppclk = dml_max(*dppclk, 1.0);
+       DTRACE("pixel rate multiplier clamped: %f", *dppclk);
+       *dppclk = *dppclk * e2e->pipe.dest.pixel_rate_mhz;
+
+       *dppclk = *dppclk / dpp_clock_divider;
+       DTRACE("dppclk after split: %f", *dppclk);
+
+       if (dpp_clock_divider > 1.0 && (*dppclk < e2e->pipe.dest.pixel_rate_mhz)) {
+               dispclk_dppclk_ratio = 2.0;
+               *dppdiv = true;
+       } else {
+               dispclk_dppclk_ratio = 1.0;
+               *dppdiv = false;
+       }
+
+       dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent;
+
+       /* Comment this out because of Gabes possible bug in spreadsheet,
+        * just to make other cases evident during debug
+        *
+        *if(e2e->clks_cfg.voltage == dm_vmax)
+        *    dispclk_ramp_margin_percent = 0.0;
+        */
+
+       /* account for ramping margin and downspread */
+       *dispclk = dml_max(*dppclk * dispclk_dppclk_ratio, e2e->pipe.dest.pixel_rate_mhz)
+                       * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0)
+                       * (1.0 + (double) dispclk_ramp_margin_percent / 100.0);
+
+       return;
+}
+
+bool dml_clks_pipe_clock_requirement_fit_power_constraint(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_dpp_in_grp)
+{
+       double dppclk = 0;
+       double dispclk = 0;
+       bool dppdiv = 0;
+
+       calculate_pipe_clk_requirement(mode_lib, e2e, num_dpp_in_grp, &dppclk, &dispclk, &dppdiv);
+
+       if (power_state(mode_lib, dispclk, dppclk) > e2e->clks_cfg.voltage) {
+               return false;
+       }
+
+       return true;
+}
+
+static void get_plane_clks(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes,
+               double *dppclks,
+               double *dispclks,
+               bool *dppdiv)
+{
+       /* it is assumed that the scale ratios passed into the e2e pipe params have already been calculated
+        * for any split pipe configurations, where extra pixels inthe overlap region do not contribute to
+        * the scale ratio. This means that we can simply calculate the dppclk for each dpp independently
+        * and we would expect the same result on any split pipes, which would be handled
+        */
+       unsigned int i;
+
+       for (i = 0; i < num_pipes; i++) {
+               double num_dpp_in_grp;
+               double dispclk_ramp_margin_percent;
+               double dispclk_margined;
+
+               if (e2e[i].pipe.src.is_hsplit)
+                       num_dpp_in_grp = (double) dpp_in_grp(
+                                       e2e,
+                                       num_pipes,
+                                       e2e[i].pipe.src.hsplit_grp);
+               else
+                       num_dpp_in_grp = 1;
+
+               calculate_pipe_clk_requirement(
+                               mode_lib,
+                               &e2e[i],
+                               num_dpp_in_grp,
+                               &dppclks[i],
+                               &dispclks[i],
+                               &dppdiv[i]);
+
+               dispclk_ramp_margin_percent = mode_lib->ip.dispclk_ramp_margin_percent;
+
+               dispclk_margined = e2e[i].pipe.dest.pixel_rate_mhz
+                               * (1.0 + (double) mode_lib->soc.downspread_percent / 100.0)
+                               * (1.0 + (double) dispclk_ramp_margin_percent / 100.0);
+
+               DTRACE("p%d: requested power state: %d", i, (int) e2e[0].clks_cfg.voltage);
+
+               if (power_state(mode_lib, dispclks[i], dppclks[i])
+                               > power_state(mode_lib, dispclk_margined, dispclk_margined)
+                               && dispclk_margined > dppclks[i]) {
+                       if (power_state(mode_lib, dispclks[i], dppclks[i])
+                                       > e2e[0].clks_cfg.voltage) {
+                               dispclks[i] = dispclk_margined;
+                               dppclks[i] = dispclk_margined;
+                               dppdiv[i] = false;
+                       }
+               }
+
+               DTRACE("p%d: dispclk: %f", i, dispclks[i]);
+       }
+}
+
+static void get_dcfclk(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes,
+               double *dcfclk_mhz)
+{
+       double bytes_per_pixel_det_y[DC__NUM_PIPES__MAX];
+       double bytes_per_pixel_det_c[DC__NUM_PIPES__MAX];
+       double swath_width_y[DC__NUM_PIPES__MAX];
+       unsigned int i;
+       double total_read_bandwidth_gbps = 0.0;
+
+       for (i = 0; i < num_pipes; i++) {
+               if (e2e[i].pipe.src.source_scan == dm_horz) {
+                       swath_width_y[i] = e2e[i].pipe.src.viewport_width * 1.0;
+               } else {
+                       swath_width_y[i] = e2e[i].pipe.src.viewport_height * 1.0;
+               }
+
+               switch (e2e[i].pipe.src.source_format) {
+               case dm_444_64:
+                       bytes_per_pixel_det_y[i] = 8.0;
+                       bytes_per_pixel_det_c[i] = 0.0;
+                       break;
+               case dm_444_32:
+                       bytes_per_pixel_det_y[i] = 4.0;
+                       bytes_per_pixel_det_c[i] = 0.0;
+                       break;
+               case dm_444_16:
+                       bytes_per_pixel_det_y[i] = 2.0;
+                       bytes_per_pixel_det_c[i] = 0.0;
+                       break;
+               case dm_422_8:
+                       bytes_per_pixel_det_y[i] = 2.0;
+                       bytes_per_pixel_det_c[i] = 0.0;
+                       break;
+               case dm_422_10:
+                       bytes_per_pixel_det_y[i] = 4.0;
+                       bytes_per_pixel_det_c[i] = 0.0;
+                       break;
+               case dm_420_8:
+                       bytes_per_pixel_det_y[i] = 1.0;
+                       bytes_per_pixel_det_c[i] = 2.0;
+                       break;
+               case dm_420_10:
+                       bytes_per_pixel_det_y[i] = 4.0 / 3.0;
+                       bytes_per_pixel_det_c[i] = 8.0 / 3.0;
+                       break;
+               default:
+                       BREAK_TO_DEBUGGER(); /* invalid src_format in get_dcfclk */
+               }
+       }
+
+       for (i = 0; i < num_pipes; i++) {
+               double read_bandwidth_plane_mbps = 0.0;
+               read_bandwidth_plane_mbps = (double) swath_width_y[i]
+                               * ((double) bytes_per_pixel_det_y[i]
+                                               + (double) bytes_per_pixel_det_c[i] / 2.0)
+                               / ((double) e2e[i].pipe.dest.htotal
+                                               / (double) e2e[i].pipe.dest.pixel_rate_mhz)
+                               * e2e[i].pipe.scale_ratio_depth.vscl_ratio;
+
+               if (e2e[i].pipe.src.dcc) {
+                       read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 256.0);
+               }
+
+               if (e2e[i].pipe.src.vm) {
+                       read_bandwidth_plane_mbps += (read_bandwidth_plane_mbps / 1000.0 / 512.0);
+               }
+
+               total_read_bandwidth_gbps = total_read_bandwidth_gbps
+                               + read_bandwidth_plane_mbps / 1000.0;
+       }
+
+       DTRACE("total bandwidth = %f gbps", total_read_bandwidth_gbps);
+
+       (*dcfclk_mhz) = (total_read_bandwidth_gbps * 1000.0) / mode_lib->soc.return_bus_width_bytes;
+
+       DTRACE(
+                       "minimum theoretical dcfclk without stutter and full utilization = %f MHz",
+                       (*dcfclk_mhz));
+
+}
+
+struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes)
+{
+       struct _vcs_dpi_display_pipe_clock_st clocks;
+       double max_dispclk = 0.0;
+       double dcfclk;
+       double dispclks[DC__NUM_PIPES__MAX];
+       double dppclks[DC__NUM_PIPES__MAX];
+       bool dppdiv[DC__NUM_PIPES__MAX];
+       unsigned int i;
+
+       DTRACE("Calculating pipe clocks...");
+
+       /* this is the theoretical minimum, have to adjust based on valid values for soc */
+       get_dcfclk(mode_lib, e2e, num_pipes, &dcfclk);
+
+       /*    if(dcfclk > soc.vnom.dcfclk_mhz)
+        *        dcfclk = soc.vmax.dcfclk_mhz;
+        *    else if(dcfclk > soc.vmin.dcfclk_mhz)
+        *        dcfclk = soc.vnom.dcfclk_mhz;
+        *    else
+        *        dcfclk = soc.vmin.dcfclk_mhz;
+        */
+
+       dcfclk = dml_socbb_voltage_scaling(
+                       &mode_lib->soc,
+                       (enum voltage_state) e2e[0].clks_cfg.voltage).dcfclk_mhz;
+       clocks.dcfclk_mhz = dcfclk;
+
+       get_plane_clks(mode_lib, e2e, num_pipes, dppclks, dispclks, dppdiv);
+
+       for (i = 0; i < num_pipes; i++) {
+               max_dispclk = dml_max(max_dispclk, dispclks[i]);
+       }
+
+       clocks.dispclk_mhz = max_dispclk;
+       DTRACE("dispclk: %f Mhz", clocks.dispclk_mhz);
+       DTRACE("dcfclk: %f Mhz", clocks.dcfclk_mhz);
+
+       for (i = 0; i < num_pipes; i++) {
+               if (dppclks[i] * 2 < max_dispclk)
+                       dppdiv[i] = 1;
+
+               if (dppdiv[i])
+                       clocks.dppclk_div[i] = 1;
+               else
+                       clocks.dppclk_div[i] = 0;
+
+               clocks.dppclk_mhz[i] = max_dispclk / ((dppdiv[i]) ? 2.0 : 1.0);
+               DTRACE("dppclk%d: %f Mhz", i, clocks.dppclk_mhz[i]);
+       }
+
+       return clocks;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h b/drivers/gpu/drm/amd/display/dc/dml/display_pipe_clocks.h
new file mode 100644 (file)
index 0000000..aed5f33
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 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 __DISPLAY_PIPE_CLOCKS_H__
+#define __DISPLAY_PIPE_CLOCKS_H__
+
+#include "dml_common_defs.h"
+
+struct display_mode_lib;
+
+struct _vcs_dpi_display_pipe_clock_st dml_clks_get_pipe_clocks(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes);
+
+bool dml_clks_pipe_clock_requirement_fit_power_constraint(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_dpp_in_grp);
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
new file mode 100644 (file)
index 0000000..9fccbbf
--- /dev/null
@@ -0,0 +1,2254 @@
+/*
+ * Copyright 2017 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_rq_dlg_calc.h"
+#include "display_mode_lib.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;
+       }
+       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 void get_blk256_size(
+               unsigned int *blk256_width,
+               unsigned int *blk256_height,
+               unsigned int bytes_per_element)
+{
+       if (bytes_per_element == 1) {
+               *blk256_width = 16;
+               *blk256_height = 16;
+       } else if (bytes_per_element == 2) {
+               *blk256_width = 16;
+               *blk256_height = 8;
+       } else if (bytes_per_element == 4) {
+               *blk256_width = 8;
+               *blk256_height = 8;
+       } else if (bytes_per_element == 8) {
+               *blk256_width = 8;
+               *blk256_height = 4;
+       }
+}
+
+static double get_refcyc_per_delivery(
+               struct display_mode_lib *mode_lib,
+               double refclk_freq_in_mhz,
+               double pclk_freq_in_mhz,
+               int unsigned recout_width,
+               double vratio,
+               double hscale_pixel_rate,
+               int unsigned delivery_width,
+               int unsigned req_per_swath_ub)
+{
+       double refcyc_per_delivery = 0.0;
+       if (vratio <= 1.0) {
+               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;
+       }
+
+       DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
+       DTRACE("DLG: %s: pclk_freq_in_mhz   = %3.2f", __func__, pclk_freq_in_mhz);
+       DTRACE("DLG: %s: recout_width       = %d", __func__, recout_width);
+       DTRACE("DLG: %s: vratio             = %3.2f", __func__, vratio);
+       DTRACE("DLG: %s: req_per_swath_ub   = %d", __func__, req_per_swath_ub);
+       DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery);
+
+       return refcyc_per_delivery;
+
+}
+
+static double get_vratio_pre(
+               struct display_mode_lib *mode_lib,
+               unsigned int max_num_sw,
+               unsigned int max_partial_sw,
+               unsigned int swath_height,
+               double vinit,
+               double l_sw)
+{
+       double prefill = dml_floor(vinit);
+       double vratio_pre = 1.0;
+
+       vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw;
+
+       if (swath_height > 4) {
+               double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0);
+               if (tmp0 > vratio_pre)
+                       vratio_pre = tmp0;
+       }
+
+       DTRACE("DLG: %s: max_num_sw        = %0d", __func__, max_num_sw);
+       DTRACE("DLG: %s: max_partial_sw    = %0d", __func__, max_partial_sw);
+       DTRACE("DLG: %s: swath_height      = %0d", __func__, swath_height);
+       DTRACE("DLG: %s: vinit             = %3.2f", __func__, vinit);
+       DTRACE("DLG: %s: vratio_pre        = %3.2f", __func__, vratio_pre);
+
+       if (vratio_pre < 1.0) {
+               DTRACE("WARNING_DLG: %s:  vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre);
+               vratio_pre = 1.0;
+       }
+
+       if (vratio_pre > 4.0) {
+               DTRACE(
+                               "WARNING_DLG: %s:  vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0",
+                               __func__,
+                               vratio_pre);
+               vratio_pre = 4.0;
+       }
+
+       return vratio_pre;
+}
+
+static void get_swath_need(
+               struct display_mode_lib *mode_lib,
+               unsigned int *max_num_sw,
+               unsigned int *max_partial_sw,
+               unsigned int swath_height,
+               double vinit)
+{
+       double prefill = dml_floor(vinit);
+       unsigned int max_partial_sw_int;
+
+       DTRACE("DLG: %s: swath_height      = %0d", __func__, swath_height);
+       DTRACE("DLG: %s: vinit             = %3.2f", __func__, vinit);
+
+       ASSERT(prefill > 0.0 && prefill <= 8.0);
+
+       *max_num_sw = (int unsigned) (dml_ceil((prefill - 1.0) / (double) swath_height) + 1.0); /* prefill has to be >= 1 */
+       max_partial_sw_int =
+                       (prefill == 1) ?
+                                       (swath_height - 1) :
+                                       ((int unsigned) (prefill - 2.0) % swath_height);
+       *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */
+
+       DTRACE("DLG: %s: max_num_sw        = %0d", __func__, *max_num_sw);
+       DTRACE("DLG: %s: max_partial_sw    = %0d", __func__, *max_partial_sw);
+}
+
+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,
+               struct _vcs_dpi_display_data_rq_regs_st *rq_regs,
+               const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
+{
+       DTRACE("DLG: %s: rq_sizing param", __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;
+}
+
+void extract_rq_regs(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_regs_st *rq_regs,
+               const struct _vcs_dpi_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);
+       if (rq_param.yuv420)
+               extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
+
+       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,
+               struct _vcs_dpi_display_rq_params_st *rq_param,
+               const struct _vcs_dpi_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;
+               }
+
+               /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137)
+                * TODO: Remove after rtl fix
+                */
+               if (req128_l == 1) {
+                       req128_c = 1;
+                       DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__);
+               }
+
+               /* 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;
+
+       DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l);
+       DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c);
+       DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l);
+       DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c);
+}
+
+/* Need refactor. */
+void dml_rq_dlg_get_row_heights(
+               struct display_mode_lib *mode_lib,
+               unsigned int *o_dpte_row_height,
+               unsigned int *o_meta_row_height,
+               unsigned int vp_width,
+               unsigned int data_pitch,
+               int source_format,
+               int tiling,
+               int macro_tile_size,
+               int source_scan,
+               int is_chroma)
+{
+       bool surf_linear = (tiling == dm_sw_linear);
+       bool surf_vert = (source_scan == dm_vert);
+
+       unsigned int bytes_per_element = get_bytes_per_element(
+                       (enum source_format_class) source_format,
+                       is_chroma);
+       unsigned int log2_bytes_per_element = dml_log2(bytes_per_element);
+       unsigned int blk256_width = 0;
+       unsigned int blk256_height = 0;
+
+       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 log2_meta_row_height;
+       unsigned int log2_vmpg_bytes;
+       unsigned int dpte_buf_in_pte_reqs;
+       unsigned int log2_vmpg_height;
+       unsigned int log2_vmpg_width;
+       unsigned int log2_dpte_req_height_ptes;
+       unsigned int log2_dpte_req_width_ptes;
+       unsigned int log2_dpte_req_height;
+       unsigned int log2_dpte_req_width;
+       unsigned int log2_dpte_row_height_linear;
+       unsigned int log2_dpte_row_height;
+       unsigned int dpte_req_width;
+
+       if (surf_linear) {
+               blk256_width = 256;
+               blk256_height = 1;
+       } else {
+               get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
+       }
+
+       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);
+       else
+               log2_blk_height = 0; /* blk height of 1 */
+
+       log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
+
+       /* ------- */
+       /* 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 */
+       log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
+                       - log2_meta_req_height;
+       log2_meta_row_height = 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;
+       else
+               log2_meta_row_height = log2_meta_req_width;
+
+       *o_meta_row_height = 1 << log2_meta_row_height;
+
+       /* ------ */
+       /* dpte   */
+       /* ------ */
+       log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+       dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
+
+       log2_vmpg_height = 0;
+       log2_vmpg_width = 0;
+       log2_dpte_req_height_ptes = 0;
+       log2_dpte_req_width_ptes = 0;
+       log2_dpte_req_height = 0;
+       log2_dpte_req_width = 0;
+       log2_dpte_row_height_linear = 0;
+       log2_dpte_row_height = 0;
+       dpte_req_width = 0; /* 64b dpte req width in data element */
+
+       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 (log2_blk_bytes <= log2_vmpg_bytes)
+               log2_dpte_req_height_ptes = 0;
+       else if (log2_blk_height - log2_vmpg_height >= 2)
+               log2_dpte_req_height_ptes = 2;
+       else
+               log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
+       log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
+
+       ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
+                       (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
+                       (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
+
+       /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height
+        * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent
+        */
+       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_width = 1 << log2_dpte_req_width;
+
+       /* calculate pitch dpte row buffer can hold
+        * round the result down to a power of two.
+        */
+       if (surf_linear) {
+               log2_dpte_row_height_linear = dml_floor(
+                               dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch));
+
+               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;
+       } else {
+               /* the upper bound of the dpte_row_width without dependency on viewport position follows.  */
+               if (!surf_vert) {
+                       log2_dpte_row_height = log2_dpte_req_height;
+               } else {
+                       log2_dpte_row_height =
+                                       (log2_blk_width < log2_dpte_req_width) ?
+                                                       log2_blk_width : log2_dpte_req_width;
+               }
+       }
+
+       /* From programming guide:
+        * There is a special case of saving only half of ptes returned due to buffer space limits.
+        * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
+        * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
+        */
+       if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
+                       && log2_blk_bytes >= 16) {
+               log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
+       }
+
+       *o_dpte_row_height = 1 << log2_dpte_row_height;
+}
+
+static void get_surf_rq_param(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param,
+               struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param,
+               struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param,
+               const struct _vcs_dpi_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;
+       bool surf_linear;
+       bool surf_vert;
+       unsigned int bytes_per_element;
+       unsigned int log2_bytes_per_element;
+       unsigned int blk256_width;
+       unsigned int blk256_height;
+       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;
+       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;
+       unsigned int log2_vmpg_bytes;
+       unsigned int dpte_buf_in_pte_reqs;
+       unsigned int log2_vmpg_height;
+       unsigned int log2_vmpg_width;
+       unsigned int log2_dpte_req_height_ptes;
+       unsigned int log2_dpte_req_width_ptes;
+       unsigned int log2_dpte_req_height;
+       unsigned int log2_dpte_req_width;
+       unsigned int log2_dpte_row_height_linear;
+       unsigned int log2_dpte_row_height;
+       unsigned int log2_dpte_group_width;
+       unsigned int dpte_row_width_ub;
+       unsigned int dpte_row_height;
+       unsigned int dpte_req_height;
+       unsigned int dpte_req_width;
+       unsigned int dpte_group_width;
+       unsigned int log2_dpte_group_bytes;
+       unsigned int log2_dpte_group_length;
+       unsigned int func_meta_row_height, func_dpte_row_height;
+
+       /* 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;
+
+       surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
+       surf_vert = (pipe_src_param.source_scan == dm_vert);
+
+       bytes_per_element = get_bytes_per_element(
+                       (enum source_format_class) pipe_src_param.source_format,
+                       is_chroma);
+       log2_bytes_per_element = dml_log2(bytes_per_element);
+       blk256_width = 0;
+       blk256_height = 0;
+
+       if (surf_linear) {
+               blk256_width = 256 / bytes_per_element;
+               blk256_height = 1;
+       } else {
+               get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
+       }
+
+       DTRACE("DLG: %s: surf_linear        = %d", __func__, surf_linear);
+       DTRACE("DLG: %s: surf_vert          = %d", __func__, surf_vert);
+       DTRACE("DLG: %s: blk256_width       = %d", __func__, blk256_width);
+       DTRACE("DLG: %s: blk256_height      = %d", __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) pipe_src_param.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 (pipe_src_param.sw_mode != dm_sw_linear)
+               log2_blk_height = log2_blk256_height
+                               + dml_ceil((double) (log2_blk_bytes - 8) / 2.0);
+       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;
+
+       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;
+
+       DTRACE("DLG: %s: meta_blk_height             = %d", __func__, meta_blk_height);
+       DTRACE("DLG: %s: meta_blk_width              = %d", __func__, meta_blk_width);
+       DTRACE("DLG: %s: meta_surface_bytes          = %d", __func__, meta_surface_bytes);
+       DTRACE("DLG: %s: meta_pte_req_per_frame_ub   = %d", __func__, meta_pte_req_per_frame_ub);
+       DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __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;
+
+       rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
+
+       /* ------ */
+       /* dpte   */
+       /* ------ */
+       log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+       dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
+
+       log2_vmpg_height = 0;
+       log2_vmpg_width = 0;
+       log2_dpte_req_height_ptes = 0;
+       log2_dpte_req_width_ptes = 0;
+       log2_dpte_req_height = 0;
+       log2_dpte_req_width = 0;
+       log2_dpte_row_height_linear = 0;
+       log2_dpte_row_height = 0;
+       log2_dpte_group_width = 0;
+       dpte_row_width_ub = 0;
+       dpte_row_height = 0;
+       dpte_req_height = 0; /* 64b dpte req height in data element */
+       dpte_req_width = 0; /* 64b dpte req width in data element */
+       dpte_group_width = 0;
+       log2_dpte_group_bytes = 0;
+       log2_dpte_group_length = 0;
+
+       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 (log2_blk_bytes <= log2_vmpg_bytes)
+               log2_dpte_req_height_ptes = 0;
+       else if (log2_blk_height - log2_vmpg_height >= 2)
+               log2_dpte_req_height_ptes = 2;
+       else
+               log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
+       log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
+
+       /* Ensure we only have the 3 shapes */
+       ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
+                       (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
+                       (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
+
+       /* 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.
+        */
+       if (surf_linear) {
+               log2_dpte_row_height_linear = dml_floor(
+                               dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch));
+
+               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;
+               rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
+
+               /* 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_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 {
+               /* 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;
+               }
+               rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
+       }
+       rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64;
+
+       /* From programming guide:
+        * There is a special case of saving only half of ptes returned due to buffer space limits.
+        * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
+        * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
+        */
+       if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
+                       && log2_blk_bytes >= 16) {
+               log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
+               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;
+
+       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);
+
+       dml_rq_dlg_get_row_heights(
+                       mode_lib,
+                       &func_dpte_row_height,
+                       &func_meta_row_height,
+                       vp_width,
+                       data_pitch,
+                       pipe_src_param.source_format,
+                       pipe_src_param.sw_mode,
+                       pipe_src_param.macro_tile_size,
+                       pipe_src_param.source_scan,
+                       is_chroma);
+
+       /* Just a check to make sure this function and the new one give the same
+        * result. The standalone get_row_heights() function is based off of the
+        * code in this function so the same changes need to be made to both.
+        */
+       if (rq_dlg_param->meta_row_height != func_meta_row_height) {
+               DTRACE(
+                               "MISMATCH: rq_dlg_param->meta_row_height = %d",
+                               rq_dlg_param->meta_row_height);
+               DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height);
+               ASSERT(0);
+       }
+
+       if (rq_dlg_param->dpte_row_height != func_dpte_row_height) {
+               DTRACE(
+                               "MISMATCH: rq_dlg_param->dpte_row_height = %d",
+                               rq_dlg_param->dpte_row_height);
+               DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height);
+               ASSERT(0);
+       }
+}
+
+void dml_rq_dlg_get_rq_params(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_params_st *rq_param,
+               const struct _vcs_dpi_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 dml_rq_dlg_get_rq_reg(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_regs_st *rq_regs,
+               const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
+{
+       struct _vcs_dpi_display_rq_params_st rq_param = {0};
+
+       memset(rq_regs, 0, sizeof(*rq_regs));
+
+       dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_src_param);
+       extract_rq_regs(mode_lib, rq_regs, rq_param);
+
+       print__rq_regs_st(mode_lib, *rq_regs);
+}
+
+/* TODO: Need refactor, so this is used by dml_rq_dlg_get_dlg_params as well
+ *       The problem is that there are some intermediate terms that would need by
+ *       some dlg calculation (i.e. rest of prefetch and active prog guide calculation)
+ */
+void dml_rq_dlg_get_dlg_params_prefetch(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param,
+               struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
+               struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
+               struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+               const bool cstate_en,
+               const bool pstate_en,
+               const bool vm_en)
+{
+       /* Prefetch */
+       unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
+       bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
+       unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
+       const double prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
+       double min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
+       double t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
+
+       bool dcc_en = e2e_pipe_param.pipe.src.dcc;
+       bool dual_plane = is_dual_plane(
+                       (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
+       unsigned int bytes_per_element_l = get_bytes_per_element(
+                       (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
+                       0);
+       unsigned int bytes_per_element_c = get_bytes_per_element(
+                       (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
+                       1);
+
+       double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
+       double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
+       double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
+
+       double line_time_in_us = (htotal / pclk_freq_in_mhz);
+       double vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
+       double vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
+       double vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
+       double vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
+
+       unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height;
+       unsigned int 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;
+       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;
+       unsigned int swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
+       unsigned int dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
+       unsigned int vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
+       unsigned int vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
+       unsigned int vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
+
+       const unsigned int dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
+       const unsigned int dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
+       unsigned int 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;
+       unsigned int dst_y_after_scaler = 0;
+       unsigned int dst_x_after_scaler = 0;
+
+       unsigned int vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
+
+       double line_wait;
+       double line_o;
+       double line_setup;
+       double line_calc;
+       double dst_y_prefetch;
+       double t_pre_us;
+       int unsigned vm_bytes;
+       int unsigned meta_row_bytes;
+       int unsigned max_num_sw_l;
+       int unsigned max_num_sw_c;
+       int unsigned max_partial_sw_l;
+       int unsigned max_partial_sw_c;
+
+       double max_vinit_l;
+       double max_vinit_c;
+       int unsigned lsw_l;
+       int unsigned lsw_c;
+       int unsigned sw_bytes_ub_l;
+       int unsigned sw_bytes_ub_c;
+       int unsigned sw_bytes;
+       int unsigned dpte_row_bytes;
+
+       if (interlaced)
+               vstartup_start = vstartup_start / 2;
+
+       if (vstartup_start >= min_vblank) {
+               min_vblank = vstartup_start + 1;
+               DTRACE(
+                               "WARNING_DLG: %s:  vstartup_start=%d should be less than min_vblank=%d",
+                               __func__,
+                               vstartup_start,
+                               min_vblank);
+       }
+
+       if (e2e_pipe_param.pipe.src.is_hsplit)
+               dst_x_after_scaler = pixel_rate_delay_subtotal
+                               + e2e_pipe_param.pipe.dest.recout_width;
+       else
+               dst_x_after_scaler = pixel_rate_delay_subtotal;
+
+       if (e2e_pipe_param.dout.output_format == dm_420)
+               dst_y_after_scaler = 1;
+       else
+               dst_y_after_scaler = 0;
+
+       if (dst_x_after_scaler >= htotal) {
+               dst_x_after_scaler = dst_x_after_scaler - htotal;
+               dst_y_after_scaler = dst_y_after_scaler + 1;
+       }
+
+       DTRACE("DLG: %s: htotal                                 = %d", __func__, htotal);
+       DTRACE(
+                       "DLG: %s: pixel_rate_delay_subtotal              = %d",
+                       __func__,
+                       pixel_rate_delay_subtotal);
+       DTRACE("DLG: %s: dst_x_after_scaler                     = %d", __func__, dst_x_after_scaler);
+       DTRACE("DLG: %s: dst_y_after_scaler                     = %d", __func__, dst_y_after_scaler);
+
+       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;
+
+       line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
+       line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
+       line_calc = t_calc_us / line_time_in_us;
+
+       DTRACE(
+                       "DLG: %s: soc.sr_enter_plus_exit_time_us     = %3.2f",
+                       __func__,
+                       (double) mode_lib->soc.sr_enter_plus_exit_time_us);
+       DTRACE(
+                       "DLG: %s: soc.dram_clock_change_latency_us   = %3.2f",
+                       __func__,
+                       (double) mode_lib->soc.dram_clock_change_latency_us);
+
+       DTRACE("DLG: %s: urgent_latency_us  = %3.2f", __func__, mode_lib->soc.urgent_latency_us);
+       DTRACE(
+                       "DLG: %s: t_srx_delay_us     = %3.2f",
+                       __func__,
+                       (double) dlg_sys_param.t_srx_delay_us);
+       DTRACE("DLG: %s: line_time_in_us    = %3.2f", __func__, (double) line_time_in_us);
+       DTRACE("DLG: %s: vupdate_offset     = %d", __func__, vupdate_offset);
+       DTRACE("DLG: %s: vupdate_width      = %d", __func__, vupdate_width);
+       DTRACE("DLG: %s: vready_offset      = %d", __func__, vready_offset);
+       DTRACE("DLG: %s: line_wait          = %3.2f", __func__, line_wait);
+       DTRACE("DLG: %s: line_o             = %3.2f", __func__, line_o);
+       DTRACE("DLG: %s: line_setup         = %3.2f", __func__, line_setup);
+       DTRACE("DLG: %s: line_calc          = %3.2f", __func__, line_calc);
+
+       dst_y_prefetch = ((double) min_vblank - 1.0)
+                       - (line_setup + line_calc + line_wait + line_o);
+       DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
+       ASSERT(dst_y_prefetch >= 2.0);
+
+       dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4;
+       DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
+
+       t_pre_us = dst_y_prefetch * line_time_in_us;
+       vm_bytes = 0;
+       meta_row_bytes = 0;
+
+       if (dcc_en && vm_en)
+               vm_bytes = meta_pte_bytes_per_frame_ub_l;
+       if (dcc_en)
+               meta_row_bytes = meta_bytes_per_row_ub_l;
+
+       max_num_sw_l = 0;
+       max_num_sw_c = 0;
+       max_partial_sw_l = 0;
+       max_partial_sw_c = 0;
+
+       max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
+       max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
+
+       get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
+       if (dual_plane)
+               get_swath_need(
+                               mode_lib,
+                               &max_num_sw_c,
+                               &max_partial_sw_c,
+                               swath_height_c,
+                               max_vinit_c);
+
+       lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
+       lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
+       sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
+       sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
+       sw_bytes = 0;
+       dpte_row_bytes = 0;
+
+       if (vm_en) {
+               if (dual_plane)
+                       dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
+               else
+                       dpte_row_bytes = dpte_bytes_per_row_ub_l;
+       } else {
+               dpte_row_bytes = 0;
+       }
+
+       if (dual_plane)
+               sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
+       else
+               sw_bytes = sw_bytes_ub_l;
+
+       DTRACE("DLG: %s: sw_bytes_ub_l           = %d", __func__, sw_bytes_ub_l);
+       DTRACE("DLG: %s: sw_bytes_ub_c           = %d", __func__, sw_bytes_ub_c);
+       DTRACE("DLG: %s: sw_bytes                = %d", __func__, sw_bytes);
+       DTRACE("DLG: %s: vm_bytes                = %d", __func__, vm_bytes);
+       DTRACE("DLG: %s: meta_row_bytes          = %d", __func__, meta_row_bytes);
+       DTRACE("DLG: %s: dpte_row_bytes          = %d", __func__, dpte_row_bytes);
+
+       prefetch_param->prefetch_bw =
+                       (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
+       prefetch_param->flip_bytes = (vm_bytes + dpte_row_bytes + meta_row_bytes);
+}
+
+/* Note: currently taken in as is.
+ * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
+ */
+void dml_rq_dlg_get_dlg_params(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs,
+               struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs,
+               const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
+               const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
+               const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+               const bool cstate_en,
+               const bool pstate_en,
+               const bool vm_en,
+               const bool iflip_en)
+{
+       /* Timing */
+       unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
+       unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end;
+       unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start;
+       unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end;
+       bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
+       unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
+
+       double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
+       double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz;
+       double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
+       double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
+
+       double ref_freq_to_pix_freq;
+       double prefetch_xy_calc_in_dcfclk;
+       double min_dcfclk_mhz;
+       double t_calc_us;
+       double min_ttu_vblank;
+       double min_dst_y_ttu_vblank;
+       int unsigned dlg_vblank_start;
+       bool dcc_en;
+       bool dual_plane;
+       bool mode_422;
+       unsigned int access_dir;
+       unsigned int bytes_per_element_l;
+       unsigned int bytes_per_element_c;
+       unsigned int vp_height_l;
+       unsigned int vp_width_l;
+       unsigned int vp_height_c;
+       unsigned int vp_width_c;
+       unsigned int htaps_l;
+       unsigned int htaps_c;
+       double hratios_l;
+       double hratios_c;
+       double vratio_l;
+       double vratio_c;
+       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 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 line_o;
+       double line_setup;
+       double line_calc;
+       double dst_y_prefetch;
+       double t_pre_us;
+       int unsigned vm_bytes;
+       int unsigned meta_row_bytes;
+       int unsigned max_num_sw_l;
+       int unsigned max_num_sw_c;
+       int unsigned max_partial_sw_l;
+       int unsigned max_partial_sw_c;
+       double max_vinit_l;
+       double max_vinit_c;
+       int unsigned lsw_l;
+       int unsigned lsw_c;
+       int unsigned sw_bytes_ub_l;
+       int unsigned sw_bytes_ub_c;
+       int unsigned sw_bytes;
+       int unsigned dpte_row_bytes;
+       double prefetch_bw;
+       double flip_bw;
+       double t_vm_us;
+       double t_r0_us;
+       double dst_y_per_vm_vblank;
+       double dst_y_per_row_vblank;
+       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 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;
+       double refcyc_per_req_delivery_pre_cur0;
+       double refcyc_per_req_delivery_cur0;
+       int unsigned full_recout_width;
+       double hratios_cur0;
+       unsigned int cur0_src_width;
+       enum cursor_bpp cur0_bpp;
+       unsigned int cur0_req_size;
+       unsigned int cur0_req_width;
+       double cur0_width_ub;
+       double cur0_req_per_width;
+       double hactive_cur0;
+
+       memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
+       memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
+
+       DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en);
+       DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en);
+       DTRACE("DLG: %s: vm_en     = %d", __func__, vm_en);
+       DTRACE("DLG: %s: iflip_en  = %d", __func__, iflip_en);
+
+       /* ------------------------- */
+       /* Section 1.5.2.1: OTG dependent Params */
+       /* ------------------------- */
+       DTRACE("DLG: %s: dppclk_freq_in_mhz     = %3.2f", __func__, dppclk_freq_in_mhz);
+       DTRACE("DLG: %s: dispclk_freq_in_mhz    = %3.2f", __func__, dispclk_freq_in_mhz);
+       DTRACE("DLG: %s: refclk_freq_in_mhz     = %3.2f", __func__, refclk_freq_in_mhz);
+       DTRACE("DLG: %s: pclk_freq_in_mhz       = %3.2f", __func__, pclk_freq_in_mhz);
+       DTRACE("DLG: %s: interlaced             = %d", __func__, interlaced);
+
+       ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
+       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->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));
+       disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */
+
+       prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
+       min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
+       t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
+       min_ttu_vblank = dlg_sys_param.t_urg_wm_us;
+       if (cstate_en)
+               min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank);
+       if (pstate_en)
+               min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank);
+       min_ttu_vblank = min_ttu_vblank + t_calc_us;
+
+       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));
+
+       DTRACE("DLG: %s: min_dcfclk_mhz                         = %3.2f", __func__, min_dcfclk_mhz);
+       DTRACE("DLG: %s: min_ttu_vblank                         = %3.2f", __func__, min_ttu_vblank);
+       DTRACE(
+                       "DLG: %s: min_dst_y_ttu_vblank                   = %3.2f",
+                       __func__,
+                       min_dst_y_ttu_vblank);
+       DTRACE("DLG: %s: t_calc_us                              = %3.2f", __func__, t_calc_us);
+       DTRACE(
+                       "DLG: %s: disp_dlg_regs->min_dst_y_next_start    = 0x%0x",
+                       __func__,
+                       disp_dlg_regs->min_dst_y_next_start);
+       DTRACE(
+                       "DLG: %s: ref_freq_to_pix_freq                   = %3.2f",
+                       __func__,
+                       ref_freq_to_pix_freq);
+
+       /* ------------------------- */
+       /* Section 1.5.2.2: Prefetch, Active and TTU  */
+       /* ------------------------- */
+       /* Prefetch Calc */
+       /* Source */
+       dcc_en = e2e_pipe_param.pipe.src.dcc;
+       dual_plane = is_dual_plane(
+                       (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
+       mode_422 = 0; /* FIXME */
+       access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */
+       bytes_per_element_l = get_bytes_per_element(
+                       (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
+                       0);
+       bytes_per_element_c = get_bytes_per_element(
+                       (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
+                       1);
+       vp_height_l = e2e_pipe_param.pipe.src.viewport_height;
+       vp_width_l = e2e_pipe_param.pipe.src.viewport_width;
+       vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c;
+       vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c;
+
+       /* Scaling */
+       htaps_l = e2e_pipe_param.pipe.scale_taps.htaps;
+       htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c;
+       hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
+       hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c;
+       vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio;
+       vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c;
+
+       line_time_in_us = (htotal / pclk_freq_in_mhz);
+       vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
+       vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
+       vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
+       vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
+
+       swath_height_l = rq_dlg_param.rq_l.swath_height;
+       swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
+       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;
+       meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
+       meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
+
+       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;
+       vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
+       vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
+       vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
+
+       dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
+       dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
+       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 = e2e_pipe_param.pipe.dest.vstartup_start;
+
+       if (interlaced)
+               vstartup_start = vstartup_start / 2;
+
+       if (vstartup_start >= min_vblank) {
+               DTRACE(
+                               "WARNING_DLG: %s:  vblank_start=%d vblank_end=%d",
+                               __func__,
+                               vblank_start,
+                               vblank_end);
+               DTRACE(
+                               "WARNING_DLG: %s:  vstartup_start=%d should be less than min_vblank=%d",
+                               __func__,
+                               vstartup_start,
+                               min_vblank);
+               min_vblank = vstartup_start + 1;
+               DTRACE(
+                               "WARNING_DLG: %s:  vstartup_start=%d should be less than min_vblank=%d",
+                               __func__,
+                               vstartup_start,
+                               min_vblank);
+       }
+
+       dst_x_after_scaler = 0;
+       dst_y_after_scaler = 0;
+
+       if (e2e_pipe_param.pipe.src.is_hsplit)
+               dst_x_after_scaler = pixel_rate_delay_subtotal
+                               + e2e_pipe_param.pipe.dest.recout_width;
+       else
+               dst_x_after_scaler = pixel_rate_delay_subtotal;
+
+       if (e2e_pipe_param.dout.output_format == dm_420)
+               dst_y_after_scaler = 1;
+       else
+               dst_y_after_scaler = 0;
+
+       if (dst_x_after_scaler >= htotal) {
+               dst_x_after_scaler = dst_x_after_scaler - htotal;
+               dst_y_after_scaler = dst_y_after_scaler + 1;
+       }
+
+       DTRACE("DLG: %s: htotal                                 = %d", __func__, htotal);
+       DTRACE(
+                       "DLG: %s: pixel_rate_delay_subtotal              = %d",
+                       __func__,
+                       pixel_rate_delay_subtotal);
+       DTRACE("DLG: %s: dst_x_after_scaler                     = %d", __func__, dst_x_after_scaler);
+       DTRACE("DLG: %s: dst_y_after_scaler                     = %d", __func__, dst_y_after_scaler);
+
+       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;
+
+       line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
+       line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
+       line_calc = t_calc_us / line_time_in_us;
+
+       DTRACE(
+                       "DLG: %s: soc.sr_enter_plus_exit_time_us     = %3.2f",
+                       __func__,
+                       (double) mode_lib->soc.sr_enter_plus_exit_time_us);
+       DTRACE(
+                       "DLG: %s: soc.dram_clock_change_latency_us   = %3.2f",
+                       __func__,
+                       (double) mode_lib->soc.dram_clock_change_latency_us);
+       DTRACE(
+                       "DLG: %s: soc.urgent_latency_us              = %3.2f",
+                       __func__,
+                       mode_lib->soc.urgent_latency_us);
+
+       DTRACE("DLG: %s: swath_height_l     = %d", __func__, swath_height_l);
+       if (dual_plane)
+               DTRACE("DLG: %s: swath_height_c     = %d", __func__, swath_height_c);
+
+       DTRACE(
+                       "DLG: %s: t_srx_delay_us     = %3.2f",
+                       __func__,
+                       (double) dlg_sys_param.t_srx_delay_us);
+       DTRACE("DLG: %s: line_time_in_us    = %3.2f", __func__, (double) line_time_in_us);
+       DTRACE("DLG: %s: vupdate_offset     = %d", __func__, vupdate_offset);
+       DTRACE("DLG: %s: vupdate_width      = %d", __func__, vupdate_width);
+       DTRACE("DLG: %s: vready_offset      = %d", __func__, vready_offset);
+       DTRACE("DLG: %s: line_time_in_us    = %3.2f", __func__, line_time_in_us);
+       DTRACE("DLG: %s: line_wait          = %3.2f", __func__, line_wait);
+       DTRACE("DLG: %s: line_o             = %3.2f", __func__, line_o);
+       DTRACE("DLG: %s: line_setup         = %3.2f", __func__, line_setup);
+       DTRACE("DLG: %s: line_calc          = %3.2f", __func__, line_calc);
+
+       dst_y_prefetch = ((double) min_vblank - 1.0)
+                       - (line_setup + line_calc + line_wait + line_o);
+       DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
+       ASSERT(dst_y_prefetch >= 2.0);
+
+       dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4;
+       DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
+
+       t_pre_us = dst_y_prefetch * line_time_in_us;
+       vm_bytes = 0;
+       meta_row_bytes = 0;
+
+       if (dcc_en && vm_en)
+               vm_bytes = meta_pte_bytes_per_frame_ub_l;
+       if (dcc_en)
+               meta_row_bytes = meta_bytes_per_row_ub_l;
+
+       max_num_sw_l = 0;
+       max_num_sw_c = 0;
+       max_partial_sw_l = 0;
+       max_partial_sw_c = 0;
+
+       max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
+       max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
+
+       get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
+       if (dual_plane)
+               get_swath_need(
+                               mode_lib,
+                               &max_num_sw_c,
+                               &max_partial_sw_c,
+                               swath_height_c,
+                               max_vinit_c);
+
+       lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
+       lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
+       sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
+       sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
+       sw_bytes = 0;
+       dpte_row_bytes = 0;
+
+       if (vm_en) {
+               if (dual_plane)
+                       dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
+               else
+                       dpte_row_bytes = dpte_bytes_per_row_ub_l;
+       } else {
+               dpte_row_bytes = 0;
+       }
+
+       if (dual_plane)
+               sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
+       else
+               sw_bytes = sw_bytes_ub_l;
+
+       DTRACE("DLG: %s: sw_bytes_ub_l           = %d", __func__, sw_bytes_ub_l);
+       DTRACE("DLG: %s: sw_bytes_ub_c           = %d", __func__, sw_bytes_ub_c);
+       DTRACE("DLG: %s: sw_bytes                = %d", __func__, sw_bytes);
+       DTRACE("DLG: %s: vm_bytes                = %d", __func__, vm_bytes);
+       DTRACE("DLG: %s: meta_row_bytes          = %d", __func__, meta_row_bytes);
+       DTRACE("DLG: %s: dpte_row_bytes          = %d", __func__, dpte_row_bytes);
+
+       prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
+       flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw)
+                       / (double) dlg_sys_param.total_flip_bytes;
+       t_vm_us = line_time_in_us / 4.0;
+       if (vm_en && dcc_en) {
+               t_vm_us = dml_max(
+                               dlg_sys_param.t_extra_us,
+                               dml_max((double) vm_bytes / prefetch_bw, t_vm_us));
+
+               if (iflip_en && !dual_plane) {
+                       t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us);
+                       if (flip_bw > 0.)
+                               t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us);
+               }
+       }
+
+       t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us);
+
+       if (vm_en || dcc_en) {
+               t_r0_us = dml_max(
+                               (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw,
+                               dlg_sys_param.t_extra_us);
+               t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us);
+
+               if (iflip_en && !dual_plane) {
+                       t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us);
+                       if (flip_bw > 0.)
+                               t_r0_us = dml_max(
+                                               (dpte_row_bytes + meta_row_bytes) / flip_bw,
+                                               t_r0_us);
+               }
+       }
+
+       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));
+       DTRACE(
+                       "DLG: %s: disp_dlg_regs->dst_y_after_scaler      = 0x%0x",
+                       __func__,
+                       disp_dlg_regs->dst_y_after_scaler);
+       DTRACE(
+                       "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler   = 0x%0x",
+                       __func__,
+                       disp_dlg_regs->refcyc_x_after_scaler);
+
+       disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
+       DTRACE(
+                       "DLG: %s: disp_dlg_regs->dst_y_prefetch  = %d",
+                       __func__,
+                       disp_dlg_regs->dst_y_prefetch);
+
+       dst_y_per_vm_vblank = 0.0;
+       dst_y_per_row_vblank = 0.0;
+
+       dst_y_per_vm_vblank = t_vm_us / line_time_in_us;
+       dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125)) / 4.0;
+       disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
+
+       dst_y_per_row_vblank = t_r0_us / line_time_in_us;
+       dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125)) / 4.0;
+       disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
+
+       DTRACE("DLG: %s: lsw_l                   = %d", __func__, lsw_l);
+       DTRACE("DLG: %s: lsw_c                   = %d", __func__, lsw_c);
+       DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l);
+       DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c);
+
+       DTRACE("DLG: %s: prefetch_bw            = %3.2f", __func__, prefetch_bw);
+       DTRACE("DLG: %s: flip_bw                = %3.2f", __func__, flip_bw);
+       DTRACE("DLG: %s: t_pre_us               = %3.2f", __func__, t_pre_us);
+       DTRACE("DLG: %s: t_vm_us                = %3.2f", __func__, t_vm_us);
+       DTRACE("DLG: %s: t_r0_us                = %3.2f", __func__, t_r0_us);
+       DTRACE("DLG: %s: dst_y_per_vm_vblank    = %3.2f", __func__, dst_y_per_vm_vblank);
+       DTRACE("DLG: %s: dst_y_per_row_vblank   = %3.2f", __func__, dst_y_per_row_vblank);
+       DTRACE("DLG: %s: dst_y_prefetch         = %3.2f", __func__, dst_y_prefetch);
+
+       min_dst_y_per_vm_vblank = 8.0;
+       min_dst_y_per_row_vblank = 16.0;
+       if (htotal <= 75) {
+               min_vblank = 300;
+               min_dst_y_per_vm_vblank = 100.0;
+               min_dst_y_per_row_vblank = 100.0;
+       }
+
+       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);
+
+       DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw);
+
+       vratio_pre_l = get_vratio_pre(
+                       mode_lib,
+                       max_num_sw_l,
+                       max_partial_sw_l,
+                       swath_height_l,
+                       max_vinit_l,
+                       lsw);
+       vratio_pre_c = 1.0;
+       if (dual_plane)
+               vratio_pre_c = get_vratio_pre(
+                               mode_lib,
+                               max_num_sw_c,
+                               max_partial_sw_c,
+                               swath_height_c,
+                               max_vinit_c,
+                               lsw);
+
+       DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l);
+       DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c);
+
+       ASSERT(vratio_pre_l <= 4.0);
+       if (vratio_pre_l >= 4.0)
+               disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1;
+       else
+               disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
+
+       ASSERT(vratio_pre_c <= 4.0);
+       if (vratio_pre_c >= 4.0)
+               disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1;
+       else
+               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));
+
+       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 */
+
+       /* 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;
+       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;
+
+       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));
+
+       disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
+                       / (double) vratio_c * dml_pow(2, 2));
+       ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17));
+
+       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; /* 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_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;
+
+       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 (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 ((hratios_l * 2.0) > 4.0)
+                       min_hratio_fact_l = 4.0;
+               else
+                       min_hratio_fact_l = hratios_l * 2.0;
+       } else {
+               if (hratios_l > 4.0)
+                       min_hratio_fact_l = 4.0;
+               else
+                       min_hratio_fact_l = hratios_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 ((hratios_c * 2.0) > 4.0)
+                       min_hratio_fact_c = 4.0;
+               else
+                       min_hratio_fact_c = hratios_c * 2.0;
+       } else {
+               if (hratios_c > 4.0)
+                       min_hratio_fact_c = 4.0;
+               else
+                       min_hratio_fact_c = hratios_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.;
+       refcyc_per_req_delivery_pre_cur0 = 0.;
+       refcyc_per_req_delivery_cur0 = 0.;
+
+       full_recout_width = 0;
+       if (e2e_pipe_param.pipe.src.is_hsplit) {
+               if (e2e_pipe_param.pipe.dest.full_recout_width == 0) {
+                       DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__);
+                       full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */
+               } else
+                       full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width;
+       } else
+               full_recout_width = e2e_pipe_param.pipe.dest.recout_width;
+
+       refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(
+                       mode_lib,
+                       refclk_freq_in_mhz,
+                       pclk_freq_in_mhz,
+                       full_recout_width,
+                       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,
+                       full_recout_width,
+                       vratio_l,
+                       hscale_pixel_rate_l,
+                       swath_width_pixels_ub_l,
+                       1); /* per line */
+
+       DTRACE("DLG: %s: full_recout_width              = %d", __func__, full_recout_width);
+       DTRACE("DLG: %s: hscale_pixel_rate_l            = %3.2f", __func__, hscale_pixel_rate_l);
+       DTRACE(
+                       "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f",
+                       __func__,
+                       refcyc_per_line_delivery_pre_l);
+       DTRACE(
+                       "DLG: %s: refcyc_per_line_delivery_l     = %3.2f",
+                       __func__,
+                       refcyc_per_line_delivery_l);
+
+       disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(
+                       refcyc_per_line_delivery_pre_l);
+       disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(
+                       refcyc_per_line_delivery_l);
+       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));
+
+       if (dual_plane) {
+               refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(
+                               mode_lib,
+                               refclk_freq_in_mhz,
+                               pclk_freq_in_mhz,
+                               full_recout_width,
+                               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,
+                               full_recout_width,
+                               vratio_c,
+                               hscale_pixel_rate_c,
+                               swath_width_pixels_ub_c,
+                               1); /* per line */
+
+               DTRACE(
+                               "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
+                               __func__,
+                               refcyc_per_line_delivery_pre_c);
+               DTRACE(
+                               "DLG: %s: refcyc_per_line_delivery_c     = %3.2f",
+                               __func__,
+                               refcyc_per_line_delivery_c);
+
+               disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(
+                               refcyc_per_line_delivery_pre_c);
+               disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(
+                               refcyc_per_line_delivery_c);
+               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;
+
+       /* 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,
+                       full_recout_width,
+                       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,
+                       full_recout_width,
+                       vratio_l,
+                       hscale_pixel_rate_l,
+                       scaler_rec_in_width_l,
+                       req_per_swath_ub_l); /* per req */
+
+       DTRACE(
+                       "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
+                       __func__,
+                       refcyc_per_req_delivery_pre_l);
+       DTRACE(
+                       "DLG: %s: refcyc_per_req_delivery_l     = %3.2f",
+                       __func__,
+                       refcyc_per_req_delivery_l);
+
+       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));
+
+       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,
+                               full_recout_width,
+                               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,
+                               full_recout_width,
+                               vratio_c,
+                               hscale_pixel_rate_c,
+                               scaler_rec_in_width_c,
+                               req_per_swath_ub_c); /* per req */
+
+               DTRACE(
+                               "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
+                               __func__,
+                               refcyc_per_req_delivery_pre_c);
+               DTRACE(
+                               "DLG: %s: refcyc_per_req_delivery_c     = %3.2f",
+                               __func__,
+                               refcyc_per_req_delivery_c);
+
+               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));
+
+               ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
+               ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
+       }
+
+       /* TTU - Cursor */
+       hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
+       cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */
+       cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp;
+       cur0_req_size = 0;
+       cur0_req_width = 0;
+       cur0_width_ub = 0.0;
+       cur0_req_per_width = 0.0;
+       hactive_cur0 = 0.0;
+
+       ASSERT(cur0_src_width <= 256);
+
+       if (cur0_src_width > 0) {
+               unsigned int cur0_bit_per_pixel = 0;
+
+               if (cur0_bpp == dm_cur_2bit) {
+                       cur0_req_size = 64; /* byte */
+                       cur0_bit_per_pixel = 2;
+               } else { /* 32bit */
+                       cur0_bit_per_pixel = 32;
+                       if (cur0_src_width >= 1 && cur0_src_width <= 16)
+                               cur0_req_size = 64;
+                       else if (cur0_src_width >= 17 && cur0_src_width <= 31)
+                               cur0_req_size = 128;
+                       else
+                               cur0_req_size = 256;
+               }
+
+               cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0);
+               cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width)
+                               * (double) cur0_req_width;
+               cur0_req_per_width = cur0_width_ub / (double) cur0_req_width;
+               hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */
+
+               if (vratio_pre_l <= 1.0) {
+                       refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq
+                                       / (double) cur0_req_per_width;
+               } else {
+                       refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz
+                                       * (double) cur0_src_width / hscale_pixel_rate_l
+                                       / (double) cur0_req_per_width;
+               }
+
+               disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
+                               (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
+               ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13));
+
+               if (vratio_l <= 1.0) {
+                       refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq
+                                       / (double) cur0_req_per_width;
+               } else {
+                       refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz
+                                       * (double) cur0_src_width / hscale_pixel_rate_l
+                                       / (double) cur0_req_per_width;
+               }
+
+               DTRACE("DLG: %s: cur0_req_width                     = %d", __func__, cur0_req_width);
+               DTRACE(
+                               "DLG: %s: cur0_width_ub                      = %3.2f",
+                               __func__,
+                               cur0_width_ub);
+               DTRACE(
+                               "DLG: %s: cur0_req_per_width                 = %3.2f",
+                               __func__,
+                               cur0_req_per_width);
+               DTRACE(
+                               "DLG: %s: hactive_cur0                       = %3.2f",
+                               __func__,
+                               hactive_cur0);
+               DTRACE(
+                               "DLG: %s: refcyc_per_req_delivery_pre_cur0   = %3.2f",
+                               __func__,
+                               refcyc_per_req_delivery_pre_cur0);
+               DTRACE(
+                               "DLG: %s: refcyc_per_req_delivery_cur0       = %3.2f",
+                               __func__,
+                               refcyc_per_req_delivery_cur0);
+
+               disp_ttu_regs->refcyc_per_req_delivery_cur0 =
+                               (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10));
+               ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13));
+       } else {
+               disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0;
+               disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0;
+       }
+
+       /* TTU - Misc */
+       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 dml_rq_dlg_get_dlg_reg(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
+               struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param,
+               const int unsigned num_pipes,
+               const int unsigned pipe_idx,
+               const bool cstate_en,
+               const bool pstate_en,
+               const bool vm_en,
+               const bool iflip_en)
+{
+       struct _vcs_dpi_display_rq_params_st rq_param = {0};
+       struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0};
+       struct _vcs_dpi_wm_calc_pipe_params_st *wm_param = mode_lib->wm_param;
+       struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm;
+       struct _vcs_dpi_display_dlg_prefetch_param_st prefetch_param;
+       double total_ret_bw;
+       double total_active_bw;
+       double total_prefetch_bw;
+       int unsigned total_flip_bytes;
+       int unsigned num_planes;
+       int i;
+
+       memset(wm_param, 0, sizeof(mode_lib->wm_param));
+
+       /* Get watermark and Tex.  */
+       DTRACE("DLG: Start calculating system setting related parameters. num_pipes=%d", num_pipes);
+       num_planes = dml_wm_e2e_to_wm(mode_lib, e2e_pipe_param, num_pipes, wm_param);
+
+       cstate_pstate_wm = dml_wm_cstate_pstate_e2e(mode_lib, e2e_pipe_param, num_pipes);
+       dlg_sys_param.t_mclk_wm_us = cstate_pstate_wm.pstate_change_us;
+       dlg_sys_param.t_sr_wm_us = cstate_pstate_wm.cstate_enter_plus_exit_us;
+       dlg_sys_param.t_urg_wm_us = dml_wm_urgent_e2e(mode_lib, e2e_pipe_param, num_pipes);
+       dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
+                       / dml_wm_dcfclk_deepsleep_mhz_e2e(mode_lib, e2e_pipe_param, num_pipes);
+       dlg_sys_param.t_extra_us = dml_wm_urgent_extra(mode_lib, wm_param, num_planes);
+       dlg_sys_param.deepsleep_dcfclk_mhz = dml_wm_dcfclk_deepsleep_mhz_e2e(
+                       mode_lib,
+                       e2e_pipe_param,
+                       num_pipes);
+
+       print__dlg_sys_params_st(mode_lib, dlg_sys_param);
+
+       DTRACE("DLG: Start calculating total prefetch bw. num_planes=%d", num_planes);
+       total_ret_bw = dml_wm_calc_return_bw(mode_lib, wm_param, num_planes);
+       total_active_bw = dml_wm_calc_total_data_read_bw(mode_lib, wm_param, num_planes);
+       total_prefetch_bw = 0.0;
+       total_flip_bytes = 0;
+
+       for (i = 0; i < num_pipes; i++) {
+               dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[i].pipe.src);
+               dml_rq_dlg_get_dlg_params_prefetch(
+                               mode_lib,
+                               &prefetch_param,
+                               rq_param.dlg,
+                               dlg_sys_param,
+                               e2e_pipe_param[i],
+                               cstate_en,
+                               pstate_en,
+                               vm_en);
+               total_prefetch_bw += prefetch_param.prefetch_bw;
+               total_flip_bytes += prefetch_param.flip_bytes;
+               DTRACE(
+                               "DLG: pipe=%d, total_prefetch_bw=%3.2f total_flip_bytes=%d",
+                               i,
+                               total_prefetch_bw,
+                               total_flip_bytes);
+       }
+
+       dlg_sys_param.total_flip_bw = total_ret_bw - dml_max(total_active_bw, total_prefetch_bw);
+
+       DTRACE("DLG: Done calculating total prefetch bw");
+       DTRACE("DLG: num_pipes          = %d", num_pipes);
+       DTRACE("DLG: total_ret_bw       = %3.2f", total_ret_bw);
+       DTRACE("DLG: total_active_bw    = %3.2f", total_active_bw);
+       DTRACE("DLG: total_prefetch_bw  = %3.2f", total_prefetch_bw);
+       DTRACE("DLG: total_flip_bw      = %3.2f", dlg_sys_param.total_flip_bw);
+
+       if (dlg_sys_param.total_flip_bw < 0.0 && iflip_en) {
+               DTRACE("WARNING_DLG Insufficient bw for immediate flip!");
+               dlg_sys_param.total_flip_bw = 0;
+       }
+
+       dlg_sys_param.total_flip_bytes = total_flip_bytes;
+       DTRACE("DLG: total_flip_bytes   = %d", dlg_sys_param.total_flip_bytes);
+       DTRACE("DLG: Done calculating system setting related parameters.");
+
+       /* system parameter calculation done */
+
+       DTRACE("DLG: Calculation for pipe[%d] start", pipe_idx);
+       dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src);
+       dml_rq_dlg_get_dlg_params(
+                       mode_lib,
+                       dlg_regs,
+                       ttu_regs,
+                       rq_param.dlg,
+                       dlg_sys_param,
+                       e2e_pipe_param[pipe_idx],
+                       cstate_en,
+                       pstate_en,
+                       vm_en,
+                       iflip_en);
+       DTRACE("DLG: Calculation for pipe[%d] end", pipe_idx);
+}
+
+void dml_rq_dlg_get_arb_params(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_arb_params_st *arb_param)
+{
+       memset(arb_param, 0, sizeof(*arb_param));
+       arb_param->max_req_outstanding = 256;
+       arb_param->min_req_outstanding = 68;
+       arb_param->sat_level_us = 60;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h
new file mode 100644 (file)
index 0000000..e63b13f
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2017 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 __DISPLAY_RQ_DLG_CALC_H__
+#define __DISPLAY_RQ_DLG_CALC_H__
+
+#include "dml_common_defs.h"
+#include "display_rq_dlg_helpers.h"
+
+struct display_mode_lib;
+
+void extract_rq_regs(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_regs_st *rq_regs,
+               const struct _vcs_dpi_display_rq_params_st rq_param);
+/* Function: dml_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 defintion)
+ * 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.)
+ */
+void dml_rq_dlg_get_rq_params(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_params_st *rq_param,
+               const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
+
+/* 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 dml_rq_dlg_get_rq_reg(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_regs_st *rq_regs,
+               const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
+
+/* Function: dml_rq_dlg_get_dlg_params
+ *  Calculate deadline related parameters
+ */
+void dml_rq_dlg_get_dlg_params(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
+               struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
+               const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
+               const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
+               const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+               const bool cstate_en,
+               const bool pstate_en,
+               const bool vm_en,
+               const bool iflip_en);
+
+/* Function: dml_rq_dlg_get_dlg_param_prefetch
+ *   For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw
+ *   for ALL pipes and use this info to calculate the prefetch programming.
+ * Output: prefetch_param.prefetch_bw and flip_bytes
+ */
+void dml_rq_dlg_get_dlg_params_prefetch(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param,
+               struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
+               struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
+               struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+               const bool cstate_en,
+               const bool pstate_en,
+               const bool vm_en);
+
+/* 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 dml_rq_dlg_get_dlg_reg(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
+               struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
+               struct _vcs_dpi_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 iflip_en);
+
+/* Function: dml_rq_dlg_get_row_heights
+ *  Calculate dpte and meta row heights
+ */
+void dml_rq_dlg_get_row_heights(
+               struct display_mode_lib *mode_lib,
+               unsigned int *o_dpte_row_height,
+               unsigned int *o_meta_row_height,
+               unsigned int vp_width,
+               unsigned int data_pitch,
+               int source_format,
+               int tiling,
+               int macro_tile_size,
+               int source_scan,
+               int is_chroma);
+
+/* Function: dml_rq_dlg_get_arb_params */
+void dml_rq_dlg_get_arb_params(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_arb_params_st *arb_param);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
new file mode 100644 (file)
index 0000000..3dc1136
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2017 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_rq_dlg_helpers.h"
+
+void print__rq_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_params_st rq_param)
+{
+       DTRACE("RQ_DLG_CALC: *************************** ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST");
+       DTRACE("RQ_DLG_CALC:  <LUMA>");
+       print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l);
+       DTRACE("RQ_DLG_CALC:  <CHROMA> === ");
+       print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c);
+
+       DTRACE("RQ_DLG_CALC: <LUMA>");
+       print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l);
+       DTRACE("RQ_DLG_CALC: <CHROMA>");
+       print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c);
+
+       DTRACE("RQ_DLG_CALC: <LUMA>");
+       print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l);
+       DTRACE("RQ_DLG_CALC: <CHROMA>");
+       print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c);
+       DTRACE("RQ_DLG_CALC: *************************** ");
+}
+
+void print__data_rq_sizing_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST");
+       DTRACE("RQ_DLG_CALC:    chunk_bytes           = %0d", rq_sizing.chunk_bytes);
+       DTRACE("RQ_DLG_CALC:    min_chunk_bytes       = %0d", rq_sizing.min_chunk_bytes);
+       DTRACE("RQ_DLG_CALC:    meta_chunk_bytes      = %0d", rq_sizing.meta_chunk_bytes);
+       DTRACE("RQ_DLG_CALC:    min_meta_chunk_bytes  = %0d", rq_sizing.min_meta_chunk_bytes);
+       DTRACE("RQ_DLG_CALC:    mpte_group_bytes      = %0d", rq_sizing.mpte_group_bytes);
+       DTRACE("RQ_DLG_CALC:    dpte_group_bytes      = %0d", rq_sizing.dpte_group_bytes);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__data_rq_dlg_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST");
+       DTRACE("RQ_DLG_CALC:    swath_width_ub              = %0d", rq_dlg_param.swath_width_ub);
+       DTRACE("RQ_DLG_CALC:    swath_height                = %0d", rq_dlg_param.swath_height);
+       DTRACE("RQ_DLG_CALC:    req_per_swath_ub            = %0d", rq_dlg_param.req_per_swath_ub);
+       DTRACE(
+                       "RQ_DLG_CALC:    meta_pte_bytes_per_frame_ub = %0d",
+                       rq_dlg_param.meta_pte_bytes_per_frame_ub);
+       DTRACE(
+                       "RQ_DLG_CALC:    dpte_req_per_row_ub         = %0d",
+                       rq_dlg_param.dpte_req_per_row_ub);
+       DTRACE(
+                       "RQ_DLG_CALC:    dpte_groups_per_row_ub      = %0d",
+                       rq_dlg_param.dpte_groups_per_row_ub);
+       DTRACE("RQ_DLG_CALC:    dpte_row_height             = %0d", rq_dlg_param.dpte_row_height);
+       DTRACE(
+                       "RQ_DLG_CALC:    dpte_bytes_per_row_ub       = %0d",
+                       rq_dlg_param.dpte_bytes_per_row_ub);
+       DTRACE(
+                       "RQ_DLG_CALC:    meta_chunks_per_row_ub      = %0d",
+                       rq_dlg_param.meta_chunks_per_row_ub);
+       DTRACE(
+                       "RQ_DLG_CALC:    meta_req_per_row_ub         = %0d",
+                       rq_dlg_param.meta_req_per_row_ub);
+       DTRACE("RQ_DLG_CALC:    meta_row_height             = %0d", rq_dlg_param.meta_row_height);
+       DTRACE(
+                       "RQ_DLG_CALC:    meta_bytes_per_row_ub       = %0d",
+                       rq_dlg_param.meta_bytes_per_row_ub);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__data_rq_misc_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST");
+       DTRACE("RQ_DLG_CALC:     full_swath_bytes   = %0d", rq_misc_param.full_swath_bytes);
+       DTRACE("RQ_DLG_CALC:     stored_swath_bytes = %0d", rq_misc_param.stored_swath_bytes);
+       DTRACE("RQ_DLG_CALC:     blk256_width       = %0d", rq_misc_param.blk256_width);
+       DTRACE("RQ_DLG_CALC:     blk256_height      = %0d", rq_misc_param.blk256_height);
+       DTRACE("RQ_DLG_CALC:     req_width          = %0d", rq_misc_param.req_width);
+       DTRACE("RQ_DLG_CALC:     req_height         = %0d", rq_misc_param.req_height);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__rq_dlg_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST");
+       DTRACE("RQ_DLG_CALC:  <LUMA> ");
+       print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l);
+       DTRACE("RQ_DLG_CALC:  <CHROMA> ");
+       print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__dlg_sys_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST");
+       DTRACE("RQ_DLG_CALC:    t_mclk_wm_us         = %3.2f", dlg_sys_param.t_mclk_wm_us);
+       DTRACE("RQ_DLG_CALC:    t_urg_wm_us          = %3.2f", dlg_sys_param.t_urg_wm_us);
+       DTRACE("RQ_DLG_CALC:    t_sr_wm_us           = %3.2f", dlg_sys_param.t_sr_wm_us);
+       DTRACE("RQ_DLG_CALC:    t_extra_us           = %3.2f", dlg_sys_param.t_extra_us);
+       DTRACE("RQ_DLG_CALC:    t_srx_delay_us       = %3.2f", dlg_sys_param.t_srx_delay_us);
+       DTRACE("RQ_DLG_CALC:    deepsleep_dcfclk_mhz = %3.2f", dlg_sys_param.deepsleep_dcfclk_mhz);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__data_rq_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_regs_st rq_regs)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST");
+       DTRACE("RQ_DLG_CALC:    chunk_size              = 0x%0x", rq_regs.chunk_size);
+       DTRACE("RQ_DLG_CALC:    min_chunk_size          = 0x%0x", rq_regs.min_chunk_size);
+       DTRACE("RQ_DLG_CALC:    meta_chunk_size         = 0x%0x", rq_regs.meta_chunk_size);
+       DTRACE("RQ_DLG_CALC:    min_meta_chunk_size     = 0x%0x", rq_regs.min_meta_chunk_size);
+       DTRACE("RQ_DLG_CALC:    dpte_group_size         = 0x%0x", rq_regs.dpte_group_size);
+       DTRACE("RQ_DLG_CALC:    mpte_group_size         = 0x%0x", rq_regs.mpte_group_size);
+       DTRACE("RQ_DLG_CALC:    swath_height            = 0x%0x", rq_regs.swath_height);
+       DTRACE("RQ_DLG_CALC:    pte_row_height_linear   = 0x%0x", rq_regs.pte_row_height_linear);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__rq_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_regs_st rq_regs)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST");
+       DTRACE("RQ_DLG_CALC:  <LUMA> ");
+       print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l);
+       DTRACE("RQ_DLG_CALC:  <CHROMA> ");
+       print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c);
+       DTRACE("RQ_DLG_CALC:    drq_expansion_mode  = 0x%0x", rq_regs.drq_expansion_mode);
+       DTRACE("RQ_DLG_CALC:    prq_expansion_mode  = 0x%0x", rq_regs.prq_expansion_mode);
+       DTRACE("RQ_DLG_CALC:    mrq_expansion_mode  = 0x%0x", rq_regs.mrq_expansion_mode);
+       DTRACE("RQ_DLG_CALC:    crq_expansion_mode  = 0x%0x", rq_regs.crq_expansion_mode);
+       DTRACE("RQ_DLG_CALC:    plane1_base_address = 0x%0x", rq_regs.plane1_base_address);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__dlg_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_regs_st dlg_regs)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_DLG_REGS_ST ");
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_h_blank_end              = 0x%0x",
+                       dlg_regs.refcyc_h_blank_end);
+       DTRACE("RQ_DLG_CALC:    dlg_vblank_end                  = 0x%0x", dlg_regs.dlg_vblank_end);
+       DTRACE(
+                       "RQ_DLG_CALC:    min_dst_y_next_start            = 0x%0x",
+                       dlg_regs.min_dst_y_next_start);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_htotal               = 0x%0x",
+                       dlg_regs.refcyc_per_htotal);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_x_after_scaler           = 0x%0x",
+                       dlg_regs.refcyc_x_after_scaler);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_after_scaler              = 0x%0x",
+                       dlg_regs.dst_y_after_scaler);
+       DTRACE("RQ_DLG_CALC:    dst_y_prefetch                  = 0x%0x", dlg_regs.dst_y_prefetch);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_per_vm_vblank             = 0x%0x",
+                       dlg_regs.dst_y_per_vm_vblank);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_per_row_vblank            = 0x%0x",
+                       dlg_regs.dst_y_per_row_vblank);
+       DTRACE(
+                       "RQ_DLG_CALC:    ref_freq_to_pix_freq            = 0x%0x",
+                       dlg_regs.ref_freq_to_pix_freq);
+       DTRACE("RQ_DLG_CALC:    vratio_prefetch                 = 0x%0x", dlg_regs.vratio_prefetch);
+       DTRACE(
+                       "RQ_DLG_CALC:    vratio_prefetch_c               = 0x%0x",
+                       dlg_regs.vratio_prefetch_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_pte_group_vblank_l   = 0x%0x",
+                       dlg_regs.refcyc_per_pte_group_vblank_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_pte_group_vblank_c   = 0x%0x",
+                       dlg_regs.refcyc_per_pte_group_vblank_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_meta_chunk_vblank_l  = 0x%0x",
+                       dlg_regs.refcyc_per_meta_chunk_vblank_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_meta_chunk_vblank_c  = 0x%0x",
+                       dlg_regs.refcyc_per_meta_chunk_vblank_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_per_pte_row_nom_l         = 0x%0x",
+                       dlg_regs.dst_y_per_pte_row_nom_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_per_pte_row_nom_c         = 0x%0x",
+                       dlg_regs.dst_y_per_pte_row_nom_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_pte_group_nom_l      = 0x%0x",
+                       dlg_regs.refcyc_per_pte_group_nom_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_pte_group_nom_c      = 0x%0x",
+                       dlg_regs.refcyc_per_pte_group_nom_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_per_meta_row_nom_l        = 0x%0x",
+                       dlg_regs.dst_y_per_meta_row_nom_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    dst_y_per_meta_row_nom_c        = 0x%0x",
+                       dlg_regs.dst_y_per_meta_row_nom_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_meta_chunk_nom_l     = 0x%0x",
+                       dlg_regs.refcyc_per_meta_chunk_nom_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_meta_chunk_nom_c     = 0x%0x",
+                       dlg_regs.refcyc_per_meta_chunk_nom_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_line_delivery_pre_l  = 0x%0x",
+                       dlg_regs.refcyc_per_line_delivery_pre_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_line_delivery_pre_c  = 0x%0x",
+                       dlg_regs.refcyc_per_line_delivery_pre_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_line_delivery_l      = 0x%0x",
+                       dlg_regs.refcyc_per_line_delivery_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_line_delivery_c      = 0x%0x",
+                       dlg_regs.refcyc_per_line_delivery_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    chunk_hdl_adjust_cur0           = 0x%0x",
+                       dlg_regs.chunk_hdl_adjust_cur0);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
+
+void print__ttu_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_ttu_regs_st ttu_regs)
+{
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+       DTRACE("RQ_DLG_CALC: DISPLAY_TTU_REGS_ST ");
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_level_low_wm                  = 0x%0x",
+                       ttu_regs.qos_level_low_wm);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_level_high_wm                 = 0x%0x",
+                       ttu_regs.qos_level_high_wm);
+       DTRACE("RQ_DLG_CALC:    min_ttu_vblank                    = 0x%0x", ttu_regs.min_ttu_vblank);
+       DTRACE("RQ_DLG_CALC:    qos_level_flip                    = 0x%0x", ttu_regs.qos_level_flip);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_req_delivery_pre_l     = 0x%0x",
+                       ttu_regs.refcyc_per_req_delivery_pre_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_req_delivery_l         = 0x%0x",
+                       ttu_regs.refcyc_per_req_delivery_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_req_delivery_pre_c     = 0x%0x",
+                       ttu_regs.refcyc_per_req_delivery_pre_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_req_delivery_c         = 0x%0x",
+                       ttu_regs.refcyc_per_req_delivery_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_req_delivery_cur0      = 0x%0x",
+                       ttu_regs.refcyc_per_req_delivery_cur0);
+       DTRACE(
+                       "RQ_DLG_CALC:    refcyc_per_req_delivery_pre_cur0  = 0x%0x",
+                       ttu_regs.refcyc_per_req_delivery_pre_cur0);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_level_fixed_l                 = 0x%0x",
+                       ttu_regs.qos_level_fixed_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_ramp_disable_l                = 0x%0x",
+                       ttu_regs.qos_ramp_disable_l);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_level_fixed_c                 = 0x%0x",
+                       ttu_regs.qos_level_fixed_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_ramp_disable_c                = 0x%0x",
+                       ttu_regs.qos_ramp_disable_c);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_level_fixed_cur0              = 0x%0x",
+                       ttu_regs.qos_level_fixed_cur0);
+       DTRACE(
+                       "RQ_DLG_CALC:    qos_ramp_disable_cur0             = 0x%0x",
+                       ttu_regs.qos_ramp_disable_cur0);
+       DTRACE("RQ_DLG_CALC: ===================================== ");
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h
new file mode 100644 (file)
index 0000000..7403cca
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017 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 __DISPLAY_RQ_DLG_HELPERS_H__
+#define __DISPLAY_RQ_DLG_HELPERS_H__
+
+#include "dml_common_defs.h"
+#include "display_mode_lib.h"
+
+/* Function: Printer functions
+ *  Print various struct
+ */
+void print__rq_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_params_st rq_param);
+void print__data_rq_sizing_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing);
+void print__data_rq_dlg_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param);
+void print__data_rq_misc_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param);
+void print__rq_dlg_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param);
+void print__dlg_sys_params_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param);
+
+void print__data_rq_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_data_rq_regs_st data_rq_regs);
+void print__rq_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_rq_regs_st rq_regs);
+void print__dlg_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_dlg_regs_st dlg_regs);
+void print__ttu_regs_st(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_ttu_regs_st ttu_regs);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c
new file mode 100644 (file)
index 0000000..390f093
--- /dev/null
@@ -0,0 +1,1281 @@
+/*
+ * Copyright 2017 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_watermark.h"
+#include "display_mode_lib.h"
+
+static void get_bytes_per_pixel(
+               enum source_format_class format,
+               struct _vcs_dpi_wm_calc_pipe_params_st *plane)
+{
+       switch (format) {
+       case dm_444_64:
+               plane->bytes_per_pixel_y = 8.0;
+               plane->bytes_per_pixel_c = 0.0;
+               break;
+       case dm_444_32:
+               plane->bytes_per_pixel_y = 4.0;
+               plane->bytes_per_pixel_c = 0.0;
+               break;
+       case dm_444_16:
+               plane->bytes_per_pixel_y = 2.0;
+               plane->bytes_per_pixel_c = 0.0;
+               break;
+       case dm_422_10:
+               plane->bytes_per_pixel_y = 4.0;
+               plane->bytes_per_pixel_c = 0.0;
+               break;
+       case dm_422_8:
+               plane->bytes_per_pixel_y = 2.0;
+               plane->bytes_per_pixel_c = 0.0;
+               break;
+       case dm_420_8:
+               plane->bytes_per_pixel_y = 1.0;
+               plane->bytes_per_pixel_c = 2.0;
+               break;
+       case dm_420_10:
+               plane->bytes_per_pixel_y = 4.0 / 3;
+               plane->bytes_per_pixel_c = 8.0 / 3;
+               break;
+       default:
+               BREAK_TO_DEBUGGER(); /* invalid format in get_bytes_per_pixel */
+       }
+}
+
+static unsigned int get_swath_width_y(
+               struct _vcs_dpi_display_pipe_source_params_st *src_param,
+               unsigned int num_dpp)
+{
+       unsigned int val;
+
+       /* note that we don't divide by num_dpp here because we have an interface which has already split
+        * any viewports
+        */
+       if (src_param->source_scan == dm_horz) {
+               val = src_param->viewport_width;
+       } else {
+               val = src_param->viewport_height;
+       }
+
+       return val;
+}
+
+static void get_swath_height(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_pipe_source_params_st *src_param,
+               struct _vcs_dpi_wm_calc_pipe_params_st *plane,
+               unsigned int swath_width_y)
+{
+       double buffer_width;
+
+       if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32
+                       || src_param->source_format == dm_444_16) {
+               if (src_param->sw_mode == dm_sw_linear) {
+                       plane->swath_height_y = 1;
+               } else if (src_param->source_format == dm_444_64) {
+                       plane->swath_height_y = 4;
+               } else {
+                       plane->swath_height_y = 8;
+               }
+
+               if (src_param->source_scan != dm_horz) {
+                       plane->swath_height_y = 256 / (unsigned int) plane->bytes_per_pixel_y
+                                       / plane->swath_height_y;
+               }
+
+               plane->swath_height_c = 0;
+
+       } else {
+               if (src_param->sw_mode == dm_sw_linear) {
+                       plane->swath_height_y = 1;
+                       plane->swath_height_c = 1;
+               } else if (src_param->source_format == dm_420_8) {
+                       plane->swath_height_y = 16;
+                       plane->swath_height_c = 8;
+               } else {
+                       plane->swath_height_y = 8;
+                       plane->swath_height_c = 8;
+               }
+
+               if (src_param->source_scan != dm_horz) {
+                       double bytes_per_pixel_c_ceil;
+
+                       plane->swath_height_y = 256 / dml_ceil(plane->bytes_per_pixel_y)
+                                       / plane->swath_height_y;
+
+                       bytes_per_pixel_c_ceil = dml_ceil_2(plane->bytes_per_pixel_c);
+
+                       plane->swath_height_c = 256 / bytes_per_pixel_c_ceil
+                                       / plane->swath_height_c;
+               }
+       }
+
+       /* use swath height min if buffer isn't big enough */
+
+       buffer_width = ((double) mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0)
+                       / (plane->bytes_per_pixel_y * (double) plane->swath_height_y
+                                       + (plane->bytes_per_pixel_c / 2.0
+                                                       * (double) plane->swath_height_c));
+
+       if ((double) swath_width_y <= buffer_width) {
+               /* do nothing, just keep code structure from Gabes vba */
+       } else {
+               /* substitute swath height with swath height min */
+               if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32
+                               || src_param->source_format == dm_444_16) {
+                       if ((src_param->sw_mode == dm_sw_linear)
+                                       || (src_param->source_format == dm_444_64
+                                                       && (src_param->sw_mode == dm_sw_4kb_s
+                                                                       || src_param->sw_mode
+                                                                                       == dm_sw_4kb_s_x
+                                                                       || src_param->sw_mode
+                                                                                       == dm_sw_64kb_s
+                                                                       || src_param->sw_mode
+                                                                                       == dm_sw_64kb_s_t
+                                                                       || src_param->sw_mode
+                                                                                       == dm_sw_64kb_s_x
+                                                                       || src_param->sw_mode
+                                                                                       == dm_sw_var_s
+                                                                       || src_param->sw_mode
+                                                                                       == dm_sw_var_s_x)
+                                                       && src_param->source_scan == dm_horz)) {
+                               /* do nothing, just keep code structure from Gabes vba */
+                       } else {
+                               plane->swath_height_y = plane->swath_height_y / 2;
+                       }
+               } else {
+                       if (src_param->sw_mode == dm_sw_linear) {
+                               /* do nothing, just keep code structure from Gabes vba */
+                       } else if (src_param->source_format == dm_420_8
+                                       && src_param->source_scan == dm_horz) {
+                               plane->swath_height_y = plane->swath_height_y / 2;
+                       } else if (src_param->source_format == dm_420_10
+                                       && src_param->source_scan == dm_horz) {
+                               plane->swath_height_c = plane->swath_height_c / 2;
+                       }
+               }
+       }
+
+       if (plane->swath_height_c == 0) {
+               plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0;
+       } else if (plane->swath_height_c <= plane->swath_height_y) {
+               plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0;
+       } else {
+               plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 * 2.0 / 3.0;
+       }
+}
+
+static void calc_display_pipe_line_delivery_time(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].v_ratio <= 1.0) {
+                       planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y
+                                       * planes[i].num_dpp / planes[i].h_ratio
+                                       / planes[i].pixclk_mhz;
+               } else {
+                       double dchub_pscl_bw_per_clk;
+
+                       if (planes[i].h_ratio > 1) {
+                               double num_hscl_kernels;
+
+                               num_hscl_kernels = dml_ceil((double) planes[i].h_taps / 6);
+                               dchub_pscl_bw_per_clk =
+                                               dml_min(
+                                                               (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
+                                                               mode_lib->ip.max_pscl_lb_bw_pix_per_clk
+                                                                               * planes[i].h_ratio
+                                                                               / num_hscl_kernels);
+                       } else {
+                               dchub_pscl_bw_per_clk =
+                                               dml_min(
+                                                               (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
+                                                               (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk);
+                       }
+
+                       planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y
+                                       / dchub_pscl_bw_per_clk / planes[i].dppclk_mhz;
+               }
+       }
+}
+
+static double calc_total_data_read_bw(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       double val = 0.0;
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               double swath_width_y_plane = planes[i].swath_width_y * planes[i].num_dpp;
+
+               planes[i].read_bw = swath_width_y_plane
+                               * (dml_ceil(planes[i].bytes_per_pixel_y)
+                                               + dml_ceil_2(planes[i].bytes_per_pixel_c) / 2)
+                               / (planes[i].h_total / planes[i].pixclk_mhz) * planes[i].v_ratio;
+
+               val += planes[i].read_bw;
+
+               DTRACE("plane[%d] start", i);
+               DTRACE("read_bw = %f", planes[i].read_bw);
+               DTRACE("plane[%d] end", i);
+       }
+
+       return val;
+}
+
+double dml_wm_calc_total_data_read_bw(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       return calc_total_data_read_bw(mode_lib, planes, num_planes);
+}
+
+static double calc_dcfclk_mhz(
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       double dcfclk_mhz = -1.0;
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               /* voltage and dcfclk must be the same for all pipes */
+               ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == planes[i].dcfclk_mhz);
+               dcfclk_mhz = planes[i].dcfclk_mhz;
+       }
+
+       return dcfclk_mhz;
+}
+
+static enum voltage_state find_voltage(
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       int voltage = -1;
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               ASSERT(voltage == -1 || voltage == planes[i].voltage);
+               voltage = planes[i].voltage;
+       }
+
+       return (enum voltage_state) voltage;
+}
+
+static bool find_dcc_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].dcc_enable) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static double calc_return_bw(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       struct _vcs_dpi_soc_bounding_box_st *soc;
+       double return_bw_mbps;
+       double dcfclk_mhz;
+       double return_bus_bw;
+       enum voltage_state voltage;
+       double return_bw_to_dcn;
+       bool dcc_enable;
+       double rob_chunk_diff;
+       double urgent_latency_traffic;
+       double critical_compression;
+       struct _vcs_dpi_voltage_scaling_st state;
+
+       soc = &mode_lib->soc;
+
+       dcfclk_mhz = calc_dcfclk_mhz(planes, num_planes);
+       return_bus_bw = dcfclk_mhz * soc->return_bus_width_bytes;
+
+       DTRACE("INTERMEDIATE dcfclk_mhz        = %f", dcfclk_mhz);
+       DTRACE("INTERMEDIATE return_bus_bw        = %f", return_bus_bw);
+
+       voltage = find_voltage(planes, num_planes);
+       return_bw_to_dcn = dml_socbb_return_bw_mhz(soc, voltage);
+
+       dcc_enable = find_dcc_enable(planes, num_planes);
+
+       return_bw_mbps = return_bw_to_dcn;
+       DTRACE("INTERMEDIATE return_bw_mbps        = %f", return_bw_mbps);
+
+       rob_chunk_diff =
+                       (mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes)
+                                       * 1024.0;
+       DTRACE("INTERMEDIATE rob_chunk_diff        = %f", rob_chunk_diff);
+
+       if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) {
+               double dcc_return_bw =
+                               return_bw_to_dcn * 4.0
+                                               * (1.0
+                                                               - soc->urgent_latency_us
+                                                                               / (rob_chunk_diff
+                                                                                               / (return_bw_to_dcn
+                                                                                                               - return_bus_bw
+                                                                                                                               / 4.0)
+                                                                                               + soc->urgent_latency_us));
+               return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw);
+               DTRACE("INTERMEDIATE dcc_return_bw        = %f", dcc_return_bw);
+       }
+
+       urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us;
+       DTRACE("INTERMEDIATE urgent_latency_traffic        = %f", urgent_latency_traffic);
+       critical_compression = 2.0 * urgent_latency_traffic
+                       / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff);
+       DTRACE("INTERMEDIATE critical_compression        = %f", critical_compression);
+
+       if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) {
+               double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff
+                               * urgent_latency_traffic);
+               crit_return_bw = crit_return_bw
+                               / dml_pow(
+                                               return_bw_to_dcn * soc->urgent_latency_us
+                                                               + rob_chunk_diff,
+                                               2);
+               DTRACE("INTERMEDIATE critical_return_bw        = %f", crit_return_bw);
+               return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw);
+       }
+
+       /* Gabe does this again for some reason using the value of return_bw_mpbs from the previous calculation
+        * and a lightly different return_bw_to_dcn
+        */
+
+       state = dml_socbb_voltage_scaling(soc, voltage);
+       return_bw_to_dcn = dml_min(
+                       soc->return_bus_width_bytes * dcfclk_mhz,
+                       state.dram_bw_per_chan_gbps * 1000.0 * (double) soc->num_chans);
+
+       DTRACE("INTERMEDIATE rob_chunk_diff        = %f", rob_chunk_diff);
+
+       if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) {
+               double dcc_return_bw =
+                               return_bw_to_dcn * 4.0
+                                               * (1.0
+                                                               - soc->urgent_latency_us
+                                                                               / (rob_chunk_diff
+                                                                                               / (return_bw_to_dcn
+                                                                                                               - return_bus_bw
+                                                                                                                               / 4.0)
+                                                                                               + soc->urgent_latency_us));
+               return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw);
+               DTRACE("INTERMEDIATE dcc_return_bw        = %f", dcc_return_bw);
+       }
+
+       urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us;
+       DTRACE("INTERMEDIATE urgent_latency_traffic        = %f", urgent_latency_traffic);
+       critical_compression = 2.0 * urgent_latency_traffic
+                       / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff);
+       DTRACE("INTERMEDIATE critical_compression        = %f", critical_compression);
+
+       /* problem here? */
+       if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) {
+               double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff
+                               * urgent_latency_traffic);
+               crit_return_bw = crit_return_bw
+                               / dml_pow(
+                                               return_bw_to_dcn * soc->urgent_latency_us
+                                                               + rob_chunk_diff,
+                                               2);
+               DTRACE("INTERMEDIATE critical_return_bw       = %f", crit_return_bw);
+               DTRACE("INTERMEDIATE return_bw_to_dcn         = %f", return_bw_to_dcn);
+               DTRACE("INTERMEDIATE rob_chunk_diff           = %f", rob_chunk_diff);
+               DTRACE("INTERMEDIATE urgent_latency_traffic   = %f", urgent_latency_traffic);
+
+               return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw);
+       }
+
+       DTRACE("INTERMEDIATE final return_bw_mbps        = %f", return_bw_mbps);
+       return return_bw_mbps;
+}
+
+double dml_wm_calc_return_bw(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       return calc_return_bw(mode_lib, planes, num_planes);
+}
+
+static double calc_last_pixel_of_line_extra_wm_us(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       double val = 0.0;
+       double total_data_read_bw = calc_total_data_read_bw(mode_lib, planes, num_planes);
+       int voltage = -1;
+       unsigned int i;
+       double return_bw_mbps;
+
+       for (i = 0; i < num_planes; i++) {
+               /* voltage mode must be the same for all pipes */
+               ASSERT(voltage == -1 || voltage == planes[i].voltage);
+               voltage = planes[i].voltage;
+       }
+       return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
+
+       for (i = 0; i < num_planes; i++) {
+               double bytes_pp_y = dml_ceil(planes[i].bytes_per_pixel_y);
+               double bytes_pp_c = dml_ceil_2(planes[i].bytes_per_pixel_c);
+               double swath_bytes_y = (double) planes[i].swath_width_y
+                               * (double) planes[i].swath_height_y * (double) bytes_pp_y;
+               double swath_bytes_c = ((double) planes[i].swath_width_y / 2.0)
+                               * (double) planes[i].swath_height_c * (double) bytes_pp_c;
+               double data_fabric_line_delivery_time = (swath_bytes_y + swath_bytes_c)
+                               / (return_bw_mbps * planes[i].read_bw / (double) planes[i].num_dpp
+                                               / total_data_read_bw);
+
+               DTRACE(
+                               "bytes_pp_y = %f, swath_width_y = %f, swath_height_y = %f, swath_bytes_y = %f",
+                               bytes_pp_y,
+                               (double) planes[i].swath_width_y,
+                               (double) planes[i].swath_height_y,
+                               swath_bytes_y);
+               DTRACE(
+                               "bytes_pp_c = %f, swath_width_c = %f, swath_height_c = %f, swath_bytes_c = %f",
+                               bytes_pp_c,
+                               ((double) planes[i].swath_width_y / 2.0),
+                               (double) planes[i].swath_height_c,
+                               swath_bytes_c);
+               DTRACE(
+                               "return_bw_mbps = %f, read_bw = %f, num_dpp = %d, total_data_read_bw = %f",
+                               return_bw_mbps,
+                               planes[i].read_bw,
+                               planes[i].num_dpp,
+                               total_data_read_bw);
+               DTRACE("data_fabric_line_delivery_time  = %f", data_fabric_line_delivery_time);
+               DTRACE(
+                               "display_pipe_line_delivery_time = %f",
+                               planes[i].display_pipe_line_delivery_time);
+
+               val = dml_max(
+                               val,
+                               data_fabric_line_delivery_time
+                                               - planes[i].display_pipe_line_delivery_time);
+       }
+
+       DTRACE("last_pixel_of_line_extra_wm is %f us", val);
+       return val;
+}
+
+static bool calc_pte_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].pte_enable) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static void calc_lines_in_det_y(struct _vcs_dpi_wm_calc_pipe_params_st *plane)
+{
+       plane->lines_in_det_y = plane->det_buffer_size_y / plane->bytes_per_pixel_y
+                       / plane->swath_width_y;
+       plane->lines_in_det_y_rounded_down_to_swath = dml_floor(
+                       (double) plane->lines_in_det_y / plane->swath_height_y)
+                       * plane->swath_height_y;
+       plane->full_det_buffering_time = plane->lines_in_det_y_rounded_down_to_swath
+                       * (plane->h_total / plane->pixclk_mhz);
+}
+
+/* CHECKME: not obviously 1:1 with calculation described in architectural
+ * document or spreadsheet */
+static void calc_dcfclk_deepsleep_mhz_per_plane(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *plane)
+{
+       double bus_width_per_pixel;
+
+       if (plane->swath_height_c == 0) {
+               bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 64;
+       } else {
+               double bus_width_per_pixel_c;
+
+               bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 32;
+               bus_width_per_pixel_c = dml_ceil(plane->bytes_per_pixel_c) / 32;
+               if (bus_width_per_pixel < bus_width_per_pixel_c)
+                       bus_width_per_pixel = bus_width_per_pixel_c;
+       }
+
+       if (plane->v_ratio <= 1) {
+               plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->pixclk_mhz / plane->num_dpp
+                               * plane->h_ratio * bus_width_per_pixel;
+       } else if (plane->h_ratio > 1) {
+               double num_hscl_kernels = dml_ceil((double) plane->h_taps / 6);
+               double dchub_pscl_bw_per_clk = dml_min(
+                               (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
+                               mode_lib->ip.max_pscl_lb_bw_pix_per_clk * plane->h_ratio
+                                               / num_hscl_kernels);
+
+               plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz
+                               * dchub_pscl_bw_per_clk * bus_width_per_pixel;
+       } else {
+               double dchub_pscl_bw_per_clk = dml_min(
+                               (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
+                               (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk);
+
+               plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz
+                               * dchub_pscl_bw_per_clk * bus_width_per_pixel;
+       }
+
+       plane->dcfclk_deepsleep_mhz_per_plane = dml_max(
+                       plane->dcfclk_deepsleep_mhz_per_plane,
+                       plane->pixclk_mhz / 16);
+}
+
+/* Implementation of expected stutter efficiency from DCN1_Display_Mode.docx */
+double dml_wm_expected_stutter_eff_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes)
+{
+       double min_full_det_buffering_time_us;
+       double frame_time_for_min_full_det_buffering_time_us = 0.0;
+       struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
+       unsigned int num_planes;
+       unsigned int i;
+       double total_data_read_bw_mbps;
+       double average_read_bw_gbps;
+       double min_full_det_buffer_size_bytes;
+       double rob_fill_size_bytes;
+       double part_of_burst_that_fits_in_rob;
+       int voltage;
+       double dcfclk_mhz;
+       unsigned int total_writeback;
+       double return_bw_mbps;
+       double stutter_burst_time_us;
+       double stutter_eff_not_including_vblank;
+       double smallest_vblank_us;
+       double stutter_eff;
+
+       memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
+       DTRACE("calculating expected stutter efficiency");
+
+       num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes);
+
+       for (i = 0; i < num_planes; i++) {
+               calc_lines_in_det_y(&planes[i]);
+
+               DTRACE("swath width y plane                   %d = %d", i, planes[i].swath_width_y);
+               DTRACE("swath height y plane                  %d = %d", i, planes[i].swath_height_y);
+               DTRACE(
+                               "bytes per pixel det y plane           %d = %f",
+                               i,
+                               planes[i].bytes_per_pixel_y);
+               DTRACE(
+                               "bytes per pixel det c plane           %d = %f",
+                               i,
+                               planes[i].bytes_per_pixel_c);
+               DTRACE(
+                               "det buffer size plane                 %d = %d",
+                               i,
+                               planes[i].det_buffer_size_y);
+               DTRACE("lines in det plane                    %d = %d", i, planes[i].lines_in_det_y);
+               DTRACE(
+                               "lines in det rounded to swaths plane  %d = %d",
+                               i,
+                               planes[i].lines_in_det_y_rounded_down_to_swath);
+       }
+
+       min_full_det_buffering_time_us = 9999.0;
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) {
+                       min_full_det_buffering_time_us = planes[i].full_det_buffering_time;
+                       frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total
+                                       * planes[i].h_total / planes[i].pixclk_mhz;
+               }
+       }
+
+       DTRACE("INTERMEDIATE: min_full_det_buffering_time_us = %f", min_full_det_buffering_time_us);
+
+       total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes);
+
+       average_read_bw_gbps = 0.0;
+
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].dcc_enable) {
+                       average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000;
+               } else {
+                       average_read_bw_gbps += planes[i].read_bw / 1000;
+               }
+
+               if (planes[i].dcc_enable) {
+                       average_read_bw_gbps += planes[i].read_bw / 1000 / 256;
+               }
+
+               if (planes[i].pte_enable) {
+                       average_read_bw_gbps += planes[i].read_bw / 1000 / 512;
+               }
+       }
+
+       min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps;
+       rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps
+                       / (average_read_bw_gbps * 1000);
+       part_of_burst_that_fits_in_rob = dml_min(
+                       min_full_det_buffer_size_bytes,
+                       rob_fill_size_bytes);
+
+       voltage = -1;
+       dcfclk_mhz = -1.0;
+       total_writeback = 0;
+
+       for (i = 0; i < num_pipes; i++) {
+               /* voltage and dcfclk must be the same for all pipes */
+               ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage);
+               voltage = e2e[i].clks_cfg.voltage;
+               ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz);
+               dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
+
+               if (e2e[i].dout.output_type == dm_wb)
+                       total_writeback++;
+       }
+
+       return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
+
+       DTRACE("INTERMEDIATE: part_of_burst_that_fits_in_rob = %f", part_of_burst_that_fits_in_rob);
+       DTRACE("INTERMEDIATE: average_read_bw_gbps = %f", average_read_bw_gbps);
+       DTRACE("INTERMEDIATE: total_data_read_bw_mbps = %f", total_data_read_bw_mbps);
+       DTRACE("INTERMEDIATE: return_bw_mbps = %f", return_bw_mbps);
+
+       stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000)
+                       / total_data_read_bw_mbps / return_bw_mbps
+                       + (min_full_det_buffering_time_us * total_data_read_bw_mbps
+                                       - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64);
+       DTRACE("INTERMEDIATE: stutter_burst_time_us = %f", stutter_burst_time_us);
+
+       if (total_writeback == 0) {
+               stutter_eff_not_including_vblank = (1.0
+                               - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us)
+                                               / min_full_det_buffering_time_us)) * 100.0;
+       } else {
+               stutter_eff_not_including_vblank = 0.0;
+       }
+
+       DTRACE("stutter_efficiency_not_including_vblank = %f", stutter_eff_not_including_vblank);
+
+       smallest_vblank_us = 9999.0;
+
+       for (i = 0; i < num_pipes; i++) {
+               double vblank_us;
+               if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) {
+                       vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1
+                                       - e2e[i].pipe.dest.vblank_start
+                                       + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal)
+                                       / e2e[i].pipe.dest.pixel_rate_mhz;
+               } else {
+                       vblank_us = 0.0;
+               }
+
+               smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us);
+       }
+
+       DTRACE("smallest vblank = %f us", smallest_vblank_us);
+
+       stutter_eff = 100.0
+                       * (((stutter_eff_not_including_vblank / 100.0)
+                                       * (frame_time_for_min_full_det_buffering_time_us
+                                                       - smallest_vblank_us) + smallest_vblank_us)
+                                       / frame_time_for_min_full_det_buffering_time_us);
+
+       DTRACE("stutter_efficiency = %f", stutter_eff);
+
+       return stutter_eff_not_including_vblank;
+}
+
+double dml_wm_expected_stutter_eff_e2e_with_vblank(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes)
+{
+       double min_full_det_buffering_time_us;
+       double frame_time_for_min_full_det_buffering_time_us = 0.0;
+       struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
+       unsigned int num_planes;
+       unsigned int i;
+       double total_data_read_bw_mbps;
+       double average_read_bw_gbps;
+       double min_full_det_buffer_size_bytes;
+       double rob_fill_size_bytes;
+       double part_of_burst_that_fits_in_rob;
+       int voltage;
+       double dcfclk_mhz;
+       unsigned int total_writeback;
+       double return_bw_mbps;
+       double stutter_burst_time_us;
+       double stutter_eff_not_including_vblank;
+       double smallest_vblank_us;
+       double stutter_eff;
+
+       memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
+       num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes);
+
+       for (i = 0; i < num_planes; i++) {
+               calc_lines_in_det_y(&planes[i]);
+       }
+
+       min_full_det_buffering_time_us = 9999.0;
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) {
+                       min_full_det_buffering_time_us = planes[i].full_det_buffering_time;
+                       frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total
+                                       * planes[i].h_total / planes[i].pixclk_mhz;
+               }
+       }
+
+       total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes);
+       average_read_bw_gbps = 0.0;
+
+       for (i = 0; i < num_planes; i++) {
+               if (planes[i].dcc_enable) {
+                       average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000;
+               } else {
+                       average_read_bw_gbps += planes[i].read_bw / 1000;
+               }
+
+               if (planes[i].dcc_enable) {
+                       average_read_bw_gbps += planes[i].read_bw / 1000 / 256;
+               }
+
+               if (planes[i].pte_enable) {
+                       average_read_bw_gbps += planes[i].read_bw / 1000 / 512;
+               }
+       }
+
+       min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps;
+       rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps
+                       / (average_read_bw_gbps * 1000);
+       part_of_burst_that_fits_in_rob = dml_min(
+                       min_full_det_buffer_size_bytes,
+                       rob_fill_size_bytes);
+
+       voltage = -1;
+       dcfclk_mhz = -1.0;
+       total_writeback = 0;
+
+       for (i = 0; i < num_pipes; i++) {
+               /* voltage and dcfclk must be the same for all pipes */
+               ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage);
+               voltage = e2e[i].clks_cfg.voltage;
+               ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz);
+               dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
+
+               if (e2e[i].dout.output_type == dm_wb)
+                       total_writeback++;
+       }
+
+       return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
+
+       stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000)
+                       / total_data_read_bw_mbps / return_bw_mbps
+                       + (min_full_det_buffering_time_us * total_data_read_bw_mbps
+                                       - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64);
+
+       if (total_writeback == 0) {
+               stutter_eff_not_including_vblank = (1.0
+                               - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us)
+                                               / min_full_det_buffering_time_us)) * 100.0;
+       } else {
+               stutter_eff_not_including_vblank = 0.0;
+       }
+
+       smallest_vblank_us = 9999.0;
+
+       for (i = 0; i < num_pipes; i++) {
+               double vblank_us;
+               if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) {
+                       vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1
+                                       - e2e[i].pipe.dest.vblank_start
+                                       + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal)
+                                       / e2e[i].pipe.dest.pixel_rate_mhz;
+               } else {
+                       vblank_us = 0.0;
+               }
+
+               smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us);
+       }
+
+       stutter_eff = 100.0
+                       * (((stutter_eff_not_including_vblank / 100.0)
+                                       * (frame_time_for_min_full_det_buffering_time_us
+                                                       - smallest_vblank_us) + smallest_vblank_us)
+                                       / frame_time_for_min_full_det_buffering_time_us);
+
+
+       return stutter_eff;
+}
+
+double urgent_extra_calc(
+               struct display_mode_lib *mode_lib,
+               double dcfclk_mhz,
+               double return_bw_mbps,
+               unsigned int total_active_dpp,
+               unsigned int total_dcc_active_dpp)
+{
+       double urgent_extra_latency_us = 0.0;
+       double urgent_round_trip_ooo_latency_us;
+
+       urgent_round_trip_ooo_latency_us =
+                       (((double) mode_lib->soc.round_trip_ping_latency_dcfclk_cycles + 32)
+                                       / dcfclk_mhz)
+                                       + (((double) (mode_lib->soc.urgent_out_of_order_return_per_channel_bytes
+                                                       * mode_lib->soc.num_chans)) / return_bw_mbps);
+
+       DTRACE(
+                       "INTERMEDIATE round_trip_ping_latency_dcfclk_cycles        = %d",
+                       mode_lib->soc.round_trip_ping_latency_dcfclk_cycles);
+       DTRACE("INTERMEDIATE dcfclk_mhz                                   = %f", dcfclk_mhz);
+       DTRACE(
+                       "INTERMEDIATE urgent_out_of_order_return_per_channel_bytes = %d",
+                       mode_lib->soc.urgent_out_of_order_return_per_channel_bytes);
+
+       urgent_extra_latency_us = urgent_round_trip_ooo_latency_us
+                       + ((double) total_active_dpp * mode_lib->ip.pixel_chunk_size_kbytes
+                                       + (double) total_dcc_active_dpp
+                                                       * mode_lib->ip.meta_chunk_size_kbytes)
+                                       * 1024.0 / return_bw_mbps; /* to us */
+
+       DTRACE(
+                       "INTERMEDIATE urgent_round_trip_ooo_latency_us  = %f",
+                       urgent_round_trip_ooo_latency_us);
+       DTRACE("INTERMEDIATE total_active_dpp                  = %d", total_active_dpp);
+       DTRACE(
+                       "INTERMEDIATE pixel_chunk_size_kbytes           = %d",
+                       mode_lib->ip.pixel_chunk_size_kbytes);
+       DTRACE("INTERMEDIATE total_dcc_active_dpp              = %d", total_dcc_active_dpp);
+       DTRACE(
+                       "INTERMEDIATE meta_chunk_size_kbyte             = %d",
+                       mode_lib->ip.meta_chunk_size_kbytes);
+       DTRACE("INTERMEDIATE return_bw_mbps                    = %f", return_bw_mbps);
+
+       return urgent_extra_latency_us;
+}
+
+double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib)
+{
+       unsigned int total_active_dpp = DC__NUM_DPP;
+       unsigned int total_dcc_active_dpp = total_active_dpp;
+       double urgent_extra_latency_us = 0.0;
+       double dcfclk_mhz = 0.0;
+       double return_bw_mbps = 0.0;
+       int voltage = dm_vmin;
+
+       /* use minimum voltage */
+       return_bw_mbps = dml_socbb_return_bw_mhz(&mode_lib->soc, (enum voltage_state) voltage);
+       /* use minimum dcfclk */
+       dcfclk_mhz = mode_lib->soc.vmin.dcfclk_mhz;
+       /* use max dpps and dpps with dcc */
+
+       urgent_extra_latency_us = urgent_extra_calc(
+                       mode_lib,
+                       dcfclk_mhz,
+                       return_bw_mbps,
+                       total_active_dpp,
+                       total_dcc_active_dpp);
+
+       DTRACE("urgent extra max = %f", urgent_extra_latency_us);
+       return urgent_extra_latency_us;
+}
+
+double dml_wm_urgent_extra(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       unsigned int total_active_dpp = 0;
+       unsigned int total_dcc_active_dpp = 0;
+       double urgent_extra_latency_us = 0.0;
+       double dcfclk_mhz = 0.0;
+       double return_bw_mbps = 0.0;
+       int voltage = -1;
+       bool pte_enable = false;
+       unsigned int i;
+
+       for (i = 0; i < num_pipes; i++) {
+               /* num_dpp must be greater than 0 */
+               ASSERT(pipes[i].num_dpp > 0);
+
+               /* voltage mode must be the same for all pipes */
+               ASSERT(voltage == -1 || voltage == pipes[i].voltage);
+               voltage = pipes[i].voltage;
+
+               /* dcfclk for all pipes must be the same */
+               ASSERT(dcfclk_mhz == 0.0 || dcfclk_mhz == pipes[i].dcfclk_mhz);
+               dcfclk_mhz = pipes[i].dcfclk_mhz;
+
+               total_active_dpp += pipes[i].num_dpp;
+
+               if (pipes[i].dcc_enable) {
+                       total_dcc_active_dpp += pipes[i].num_dpp;
+               }
+       }
+
+       DTRACE("total active dpps %d", total_active_dpp);
+       DTRACE("total active dpps with dcc %d", total_dcc_active_dpp);
+       DTRACE("voltage state is %d", voltage);
+
+       return_bw_mbps = calc_return_bw(mode_lib, pipes, num_pipes);
+
+       DTRACE("return_bandwidth is %f MBps", return_bw_mbps);
+
+       pte_enable = calc_pte_enable(pipes, num_pipes);
+
+       /* calculate the maximum extra latency just for comparison purposes */
+       /* dml_wm_urgent_extra_max(); */
+       urgent_extra_latency_us = urgent_extra_calc(
+                       mode_lib,
+                       dcfclk_mhz,
+                       return_bw_mbps,
+                       total_active_dpp,
+                       total_dcc_active_dpp);
+
+       DTRACE("INTERMEDIATE urgent_extra_latency_us_before_pte = %f", urgent_extra_latency_us);
+
+       if (pte_enable) {
+               urgent_extra_latency_us += total_active_dpp * mode_lib->ip.pte_chunk_size_kbytes
+                               * 1024.0 / return_bw_mbps;
+
+               DTRACE("INTERMEDIATE pte_enable = true");
+               DTRACE("INTERMEDIATE total_active_dpp      = %d", total_active_dpp);
+               DTRACE(
+                               "INTERMEDIATE pte_chunk_size_kbytes = %d",
+                               mode_lib->ip.pte_chunk_size_kbytes);
+               DTRACE("INTERMEDIATE return_bw_mbps        = %f", return_bw_mbps);
+       }
+
+       return urgent_extra_latency_us;
+}
+
+double dml_wm_urgent_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
+       unsigned int combined_pipes;
+       double urgent_wm;
+
+       memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
+       combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
+
+       urgent_wm = dml_wm_urgent(mode_lib, wm, combined_pipes);
+
+       return urgent_wm;
+}
+
+double dml_wm_urgent(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       double urgent_watermark;
+       double urgent_extra_latency_us;
+       double last_pixel_of_line_extra_wm_us = 0.0;
+
+       DTRACE("calculating urgent watermark");
+       calc_display_pipe_line_delivery_time(mode_lib, planes, num_planes);
+       urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, planes, num_planes);
+
+       last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us(
+                       mode_lib,
+                       planes,
+                       num_planes);
+
+       urgent_watermark = mode_lib->soc.urgent_latency_us + last_pixel_of_line_extra_wm_us
+                       + urgent_extra_latency_us;
+
+       DTRACE("INTERMEDIATE urgent_latency_us              = %f", mode_lib->soc.urgent_latency_us);
+       DTRACE("INTERMEDIATE last_pixel_of_line_extra_wm_us = %f", last_pixel_of_line_extra_wm_us);
+       DTRACE("INTERMEDIATE urgent_extra_latency_us        = %f", urgent_extra_latency_us);
+
+       DTRACE("urgent_watermark_us = %f", urgent_watermark);
+       return urgent_watermark;
+}
+
+double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us)
+{
+       double val;
+
+       val = urgent_wm_us + 2.0 * mode_lib->soc.urgent_latency_us;
+       DTRACE("pte_meta_urgent_watermark_us = %f", val);
+
+       return val;
+}
+
+double dml_wm_dcfclk_deepsleep_mhz_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
+       unsigned int num_planes;
+       double val;
+
+       memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
+       num_planes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, planes);
+
+       val = dml_wm_dcfclk_deepsleep_mhz(mode_lib, planes, num_planes);
+
+       return val;
+}
+
+double dml_wm_dcfclk_deepsleep_mhz(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes)
+{
+       double val = 8.0;
+       unsigned int i;
+
+       for (i = 0; i < num_planes; i++) {
+               calc_dcfclk_deepsleep_mhz_per_plane(mode_lib, &planes[i]);
+
+               if (val < planes[i].dcfclk_deepsleep_mhz_per_plane) {
+                       val = planes[i].dcfclk_deepsleep_mhz_per_plane;
+               }
+
+               DTRACE("plane[%d] start", i);
+               DTRACE("dcfclk_deepsleep_per_plane = %f", planes[i].dcfclk_deepsleep_mhz_per_plane);
+               DTRACE("plane[%d] end", i);
+       }
+
+       DTRACE("dcfclk_deepsleep_mhz = %f", val);
+
+       return val;
+}
+
+struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
+       unsigned int combined_pipes;
+       struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm;
+
+       memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
+       combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
+       cstate_pstate_wm = dml_wm_cstate_pstate(mode_lib, wm, combined_pipes);
+
+
+       return cstate_pstate_wm;
+}
+
+struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       struct _vcs_dpi_cstate_pstate_watermarks_st wm;
+       double urgent_extra_latency_us;
+       double urgent_watermark_us;
+       double last_pixel_of_line_extra_wm_us;
+       double dcfclk_deepsleep_freq;
+
+       DTRACE("calculating cstate and pstate watermarks");
+       urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, pipes, num_pipes);
+       urgent_watermark_us = dml_wm_urgent(mode_lib, pipes, num_pipes);
+
+       last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us(
+                       mode_lib,
+                       pipes,
+                       num_pipes);
+       dcfclk_deepsleep_freq = dml_wm_dcfclk_deepsleep_mhz(mode_lib, pipes, num_pipes);
+
+       wm.cstate_exit_us = mode_lib->soc.sr_exit_time_us + last_pixel_of_line_extra_wm_us
+                       + urgent_extra_latency_us
+                       + mode_lib->ip.dcfclk_cstate_latency / dcfclk_deepsleep_freq;
+       wm.cstate_enter_plus_exit_us = mode_lib->soc.sr_enter_plus_exit_time_us
+                       + last_pixel_of_line_extra_wm_us + urgent_extra_latency_us;
+       wm.pstate_change_us = mode_lib->soc.dram_clock_change_latency_us + urgent_watermark_us;
+
+       DTRACE("stutter_exit_watermark_us = %f", wm.cstate_exit_us);
+       DTRACE("stutter_enter_plus_exit_watermark_us = %f", wm.cstate_enter_plus_exit_us);
+       DTRACE("dram_clock_change_watermark_us = %f", wm.pstate_change_us);
+
+       return wm;
+}
+
+double dml_wm_writeback_pstate_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
+       unsigned int combined_pipes;
+
+       memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
+       combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
+
+
+       return dml_wm_writeback_pstate(mode_lib, wm, combined_pipes);
+}
+
+double dml_wm_writeback_pstate(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
+               unsigned int num_pipes)
+{
+       unsigned int total_active_wb = 0;
+       double wm = 0.0;
+       double socclk_mhz = 0.0;
+       unsigned int i;
+
+       DTRACE("calculating wb pstate watermark");
+       for (i = 0; i < num_pipes; i++) {
+               if (pipes[i].output_type == dm_wb)
+                       total_active_wb++;
+               ASSERT(socclk_mhz == 0.0 || socclk_mhz == pipes[i].socclk_mhz);
+               socclk_mhz = pipes[i].socclk_mhz;
+       }
+
+       DTRACE("total wb outputs %d", total_active_wb);
+       DTRACE("socclk frequency %f Mhz", socclk_mhz);
+
+       if (total_active_wb <= 1) {
+               wm = mode_lib->soc.writeback_dram_clock_change_latency_us;
+       } else {
+               wm = mode_lib->soc.writeback_dram_clock_change_latency_us
+                               + (mode_lib->ip.writeback_chunk_size_kbytes * 1024.0) / 32.0
+                                               / socclk_mhz;
+       }
+
+       DTRACE("wb pstate watermark %f us", wm);
+       return wm;
+}
+
+unsigned int dml_wm_e2e_to_wm(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes,
+               struct _vcs_dpi_wm_calc_pipe_params_st *wm)
+{
+       unsigned int num_planes = 0;
+       bool visited[DC__NUM_PIPES];
+       unsigned int i, j;
+
+       for (i = 0; i < num_pipes; i++) {
+               visited[i] = false;
+       }
+
+       for (i = 0; i < num_pipes; i++) {
+               unsigned int num_dpp = 1;
+
+               if (visited[i]) {
+                       continue;
+               }
+
+               visited[i] = true;
+
+               if (e2e[i].pipe.src.is_hsplit) {
+                       for (j = i + 1; j < num_pipes; j++) {
+                               if (e2e[j].pipe.src.is_hsplit && !visited[j]
+                                               && (e2e[i].pipe.src.hsplit_grp
+                                                               == e2e[j].pipe.src.hsplit_grp)) {
+                                       num_dpp++;
+                                       visited[j] = true;
+                               }
+                       }
+               }
+
+               wm[num_planes].num_dpp = num_dpp;
+               wm[num_planes].voltage = e2e[i].clks_cfg.voltage;
+               wm[num_planes].output_type = e2e[i].dout.output_type;
+               wm[num_planes].dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
+               wm[num_planes].socclk_mhz = e2e[i].clks_cfg.socclk_mhz;
+               wm[num_planes].dppclk_mhz = e2e[i].clks_cfg.dppclk_mhz;
+               wm[num_planes].pixclk_mhz = e2e[i].pipe.dest.pixel_rate_mhz;
+
+               wm[num_planes].pte_enable = e2e[i].pipe.src.vm;
+               wm[num_planes].dcc_enable = e2e[i].pipe.src.dcc;
+               wm[num_planes].dcc_rate = e2e[i].pipe.src.dcc_rate;
+
+               get_bytes_per_pixel(
+                               (enum source_format_class) e2e[i].pipe.src.source_format,
+                               &wm[num_planes]);
+               wm[num_planes].swath_width_y = get_swath_width_y(&e2e[i].pipe.src, num_dpp);
+               get_swath_height(
+                               mode_lib,
+                               &e2e[i].pipe.src,
+                               &wm[num_planes],
+                               wm[num_planes].swath_width_y);
+
+               wm[num_planes].interlace_en = e2e[i].pipe.dest.interlaced;
+               wm[num_planes].h_ratio = e2e[i].pipe.scale_ratio_depth.hscl_ratio;
+               wm[num_planes].v_ratio = e2e[i].pipe.scale_ratio_depth.vscl_ratio;
+               if (wm[num_planes].interlace_en) {
+                       wm[num_planes].v_ratio = 2 * wm[num_planes].v_ratio;
+               }
+               wm[num_planes].h_taps = e2e[i].pipe.scale_taps.htaps;
+               wm[num_planes].h_total = e2e[i].pipe.dest.htotal;
+               wm[num_planes].v_total = e2e[i].pipe.dest.vtotal;
+               wm[num_planes].v_active = e2e[i].pipe.dest.vactive;
+               wm[num_planes].e2e_index = i;
+               num_planes++;
+       }
+
+       for (i = 0; i < num_planes; i++) {
+               DTRACE("plane[%d] start", i);
+               DTRACE("voltage    = %d", wm[i].voltage);
+               DTRACE("v_active   = %d", wm[i].v_active);
+               DTRACE("h_total    = %d", wm[i].h_total);
+               DTRACE("v_total    = %d", wm[i].v_total);
+               DTRACE("pixclk_mhz = %f", wm[i].pixclk_mhz);
+               DTRACE("dcfclk_mhz = %f", wm[i].dcfclk_mhz);
+               DTRACE("dppclk_mhz = %f", wm[i].dppclk_mhz);
+               DTRACE("h_ratio    = %f", wm[i].h_ratio);
+               DTRACE("v_ratio    = %f", wm[i].v_ratio);
+               DTRACE("interlaced = %d", wm[i].interlace_en);
+               DTRACE("h_taps     = %d", wm[i].h_taps);
+               DTRACE("num_dpp    = %d", wm[i].num_dpp);
+               DTRACE("swath_width_y = %d", wm[i].swath_width_y);
+               DTRACE("swath_height_y = %d", wm[i].swath_height_y);
+               DTRACE("swath_height_c = %d", wm[i].swath_height_c);
+               DTRACE("det_buffer_size_y = %d", wm[i].det_buffer_size_y);
+               DTRACE("dcc_rate   = %f", wm[i].dcc_rate);
+               DTRACE("dcc_enable = %s", wm[i].dcc_enable ? "true" : "false");
+               DTRACE("pte_enable = %s", wm[i].pte_enable ? "true" : "false");
+               DTRACE("plane[%d] end", i);
+       }
+
+       return num_planes;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h
new file mode 100644 (file)
index 0000000..94cde8b
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017 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 __DISPLAY_WATERMARK_H__
+#define __DISPLAY_WATERMARK_H__
+
+#include "dml_common_defs.h"
+
+struct display_mode_lib;
+
+double dml_wm_urgent_extra(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
+               unsigned int num_pipes);
+double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib);
+
+double dml_wm_urgent_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes);
+double dml_wm_urgent(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes);
+double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us);
+double dml_wm_dcfclk_deepsleep_mhz_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes);
+double dml_wm_dcfclk_deepsleep_mhz(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes);
+
+struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes);
+struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
+               unsigned int num_pipes);
+
+double dml_wm_writeback_pstate_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
+               unsigned int num_pipes);
+double dml_wm_writeback_pstate(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
+               unsigned int num_pipes);
+
+double dml_wm_expected_stutter_eff_e2e(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes);
+double dml_wm_expected_stutter_eff_e2e_with_vblank(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes);
+
+unsigned int dml_wm_e2e_to_wm(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
+               unsigned int num_pipes,
+               struct _vcs_dpi_wm_calc_pipe_params_st *wm);
+
+double dml_wm_calc_total_data_read_bw(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes);
+double dml_wm_calc_return_bw(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_wm_calc_pipe_params_st *planes,
+               unsigned int num_planes);
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c
new file mode 100644 (file)
index 0000000..21349a0
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2017 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 "dml_common_defs.h"
+#include "../calcs/dcn_calc_math.h"
+
+double dml_min(double a, double b)
+{
+       return (double) dcn_bw_min2(a, b);
+}
+
+double dml_max(double a, double b)
+{
+       return (double) dcn_bw_max2(a, b);
+}
+
+double dml_ceil(double a)
+{
+       return (double) dcn_bw_ceil2(a, 1);
+}
+
+double dml_floor(double a)
+{
+       return (double) dcn_bw_floor2(a, 1);
+}
+
+double dml_round(double a)
+{
+       double round_pt = 0.5;
+       double ceil = dml_ceil(a);
+       double floor = dml_floor(a);
+
+       if (a - floor >= round_pt)
+               return ceil;
+       else
+               return floor;
+}
+
+int dml_log2(double x)
+{
+       return dml_round((double)dcn_bw_log(x, 2));
+}
+
+double dml_pow(double a, int exp)
+{
+       return (double) dcn_bw_pow(a, exp);
+}
+
+unsigned int dml_round_to_multiple(
+       unsigned int num,
+       unsigned int multiple,
+       bool up)
+{
+       unsigned int remainder;
+
+       if (multiple == 0)
+               return num;
+
+       remainder = num % multiple;
+
+       if (remainder == 0)
+               return num;
+
+       if (up)
+               return (num + multiple - remainder);
+       else
+               return (num - remainder);
+}
+
+double dml_fmod(double f, int val)
+{
+       return (double) dcn_bw_mod(f, val);
+}
+
+double dml_ceil_2(double f)
+{
+       return (double) dcn_bw_ceil2(f, 2);
+}
+
+bool dml_util_is_420(enum source_format_class sorce_format)
+{
+       bool val = false;
+
+       switch (sorce_format) {
+       case dm_444_16:
+               val = false;
+               break;
+       case dm_444_32:
+               val = false;
+               break;
+       case dm_444_64:
+               val = false;
+               break;
+       case dm_420_8:
+               val = true;
+               break;
+       case dm_420_10:
+               val = true;
+               break;
+       case dm_422_8:
+               val = false;
+               break;
+       case dm_422_10:
+               val = false;
+               break;
+       default:
+               BREAK_TO_DEBUGGER();
+       }
+
+       return val;
+}
+
+double dml_ceil_ex(double x, double granularity)
+{
+       return (double) dcn_bw_ceil2(x, granularity);
+}
+
+double dml_floor_ex(double x, double granularity)
+{
+       return (double) dcn_bw_floor2(x, granularity);
+}
+
+double dml_log(double x, double base)
+{
+       return (double) dcn_bw_log(x, base);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h
new file mode 100644 (file)
index 0000000..c5340d4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 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 __DC_COMMON_DEFS_H__
+#define __DC_COMMON_DEFS_H__
+
+#include "dm_services.h"
+#include "dc_features.h"
+#include "display_mode_structs.h"
+#include "display_mode_enums.h"
+
+#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__);
+
+double dml_min(double a, double b);
+double dml_max(double a, double b);
+bool dml_util_is_420(enum source_format_class sorce_format);
+double dml_ceil_ex(double x, double granularity);
+double dml_floor_ex(double x, double granularity);
+double dml_log(double x, double base);
+double dml_ceil(double a);
+double dml_floor(double a);
+double dml_round(double a);
+int dml_log2(double x);
+double dml_pow(double a, int exp);
+unsigned int dml_round_to_multiple(
+                       unsigned int num, unsigned int multiple, bool up);
+double dml_fmod(double f, int val);
+double dml_ceil_2(double f);
+
+#endif /* __DC_COMMON_DEFS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
new file mode 100644 (file)
index 0000000..cb143d3
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017 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 "soc_bounding_box.h"
+#include "display_mode_lib.h"
+
+void dml_socbb_set_latencies(
+               struct display_mode_lib *mode_lib,
+               struct _vcs_dpi_soc_bounding_box_st *from_box)
+{
+       struct _vcs_dpi_soc_bounding_box_st *to_box = &mode_lib->soc;
+
+       to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us;
+       to_box->sr_exit_time_us = from_box->sr_exit_time_us;
+       to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us;
+       to_box->urgent_latency_us = from_box->urgent_latency_us;
+       to_box->writeback_latency_us = from_box->writeback_latency_us;
+       DTRACE("box.dram_clock_change_latency_us: %f", from_box->dram_clock_change_latency_us);
+       DTRACE("box.sr_exit_time_us: %f", from_box->sr_exit_time_us);
+       DTRACE("box.sr_enter_plus_exit_time_us: %f", from_box->sr_enter_plus_exit_time_us);
+       DTRACE("box.urgent_latency_us: %f", from_box->urgent_latency_us);
+       DTRACE("box.writeback_latency_us: %f", from_box->writeback_latency_us);
+
+}
+
+struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(
+               struct _vcs_dpi_soc_bounding_box_st *box,
+               enum voltage_state voltage)
+{
+       switch (voltage) {
+       case dm_vmin:
+               return box->vmin;
+       case dm_vnom:
+               return box->vnom;
+       case dm_vmax:
+       default:
+               return box->vmax;
+       }
+}
+
+double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage)
+{
+       double return_bw;
+
+       struct _vcs_dpi_voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
+
+       return_bw = dml_min(
+                       ((double) box->return_bus_width_bytes) * state.dcfclk_mhz,
+                       state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans
+                                       * box->ideal_dram_bw_after_urgent_percent / 100.0);
+       return return_bw;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h
new file mode 100644 (file)
index 0000000..7bbae33
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 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 __SOC_BOUNDING_BOX_H__
+#define __SOC_BOUNDING_BOX_H__
+
+#include "dml_common_defs.h"
+
+struct display_mode_lib;
+
+void dml_socbb_set_latencies(struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box);
+struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
+double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
+
+#endif