Prechádzať zdrojové kódy

Merge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux into drm-next

Last batch of new stuff for DC. Highlights:
- Fix some memory leaks
- S3 fixes
- Hotplug fixes
- Fix some CX multi-display issues
- MST fixes
- DML updates from the hw team
- Various code cleanups
- Misc bug fixes

* 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux: (155 commits)
  drm/amd/display:: Fix NULL pointer in Raven hotplug
  drm/amd/display: Fix memoryleak during S3 resume.
  drm/amd/display: add hardware_planes_only to list of affected planes
  drm/amd/display: Fix brace style
  drm/amd/display: Remove needless cast in amdgpu_dm_connector_init()
  drm/amd/display: Fix brace style in amdgpu_dm_connector_ddc_get_modes()
  drm/amd/display: Tidy up dm_drm_plane_reset()
  drm/amd/display: Fix indentation in create_eml_sink()
  drm/amd/display: Replace block with strncpy() in fill_audio_info()
  drm/amd/display: Fix brace style in amdgpu_dm_initialize_drm_device()
  drm/amd/display: Simplify handle_hpd_rx_irq()
  drm/amd/display: Fix brace style in dm_handle_hpd_rx_irq()
  drm/amd/display: Fix brace style in amdgpu_dm_update_connector_after_detect()
  drm/amd/display: Fix indentation in dm_resume()
  drm/amd/display: Fix indentation in dm_suspend()
  drm/amd/display: Simplify dm_late_init()
  amdgpu/dc: inline dml_round_to_multiple
  amdgpu/dc: drop dml_util_is_420
  drm/amd/display: Add bunch of missing license headers in DML
  amdgpu/dc: inline a bunch of the dml wrappers.
  ...
Dave Airlie 7 rokov pred
rodič
commit
af91113360
88 zmenil súbory, kde vykonal 13902 pridanie a 6076 odobranie
  1. 10 0
      drivers/gpu/drm/amd/display/Kconfig
  2. 141 66
      drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
  3. 9 12
      drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
  4. 55 80
      drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
  5. 6 0
      drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
  6. 22 56
      drivers/gpu/drm/amd/display/dc/basics/logger.c
  7. 0 37
      drivers/gpu/drm/amd/display/dc/basics/logger.h
  8. 5 5
      drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
  9. 1 1
      drivers/gpu/drm/amd/display/dc/calcs/Makefile
  10. 45 0
      drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
  11. 6 30
      drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h
  12. 117 107
      drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
  13. 218 254
      drivers/gpu/drm/amd/display/dc/core/dc.c
  14. 39 19
      drivers/gpu/drm/amd/display/dc/core/dc_link.c
  15. 14 2
      drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
  16. 9 8
      drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
  17. 77 34
      drivers/gpu/drm/amd/display/dc/core/dc_resource.c
  18. 57 6
      drivers/gpu/drm/amd/display/dc/core/dc_stream.c
  19. 1 0
      drivers/gpu/drm/amd/display/dc/core/dc_surface.c
  20. 103 38
      drivers/gpu/drm/amd/display/dc/dc.h
  21. 2 0
      drivers/gpu/drm/amd/display/dc/dc_hw_types.h
  22. 2 1
      drivers/gpu/drm/amd/display/dc/dc_types.h
  23. 106 69
      drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
  24. 2 0
      drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
  25. 4 249
      drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
  26. 3 17
      drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
  27. 1 4
      drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
  28. 1 1
      drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
  29. 1 1
      drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
  30. 1 1
      drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
  31. 295 37
      drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
  32. 10 1
      drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
  33. 23 10
      drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
  34. 2 2
      drivers/gpu/drm/amd/display/dc/dcn10/Makefile
  35. 1 1
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
  36. 2 2
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
  37. 128 71
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
  38. 74 53
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
  39. 132 131
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
  40. 121 129
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
  41. 249 95
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
  42. 127 12
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
  43. 276 210
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
  44. 0 189
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
  45. 152 63
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
  46. 34 11
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
  47. 59 41
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
  48. 15 0
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
  49. 5 10
      drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
  50. 2 45
      drivers/gpu/drm/amd/display/dc/dm_services.h
  51. 5 3
      drivers/gpu/drm/amd/display/dc/dml/Makefile
  52. 2 0
      drivers/gpu/drm/amd/display/dc/dml/dc_features.h
  53. 28 28
      drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
  54. 1 10
      drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
  55. 4 5
      drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
  56. 514 386
      drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
  57. 0 194
      drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h
  58. 6124 0
      drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
  59. 598 0
      drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
  60. 982 1475
      drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
  61. 80 71
      drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h
  62. 277 205
      drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
  63. 11 30
      drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h
  64. 0 1282
      drivers/gpu/drm/amd/display/dc/dml/display_watermark.c
  65. 0 98
      drivers/gpu/drm/amd/display/dc/dml/display_watermark.h
  66. 1905 0
      drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
  67. 67 0
      drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h
  68. 3 2
      drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c
  69. 3 1
      drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h
  70. 45 4
      drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
  71. 20 25
      drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
  72. 4 5
      drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h
  73. 3 5
      drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
  74. 8 7
      drivers/gpu/drm/amd/display/dc/inc/core_status.h
  75. 13 3
      drivers/gpu/drm/amd/display/dc/inc/core_types.h
  76. 134 0
      drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
  77. 105 0
      drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
  78. 1 5
      drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
  79. 9 2
      drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
  80. 11 4
      drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
  81. 57 0
      drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
  82. 10 2
      drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
  83. 4 0
      drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
  84. 5 0
      drivers/gpu/drm/amd/display/dc/inc/resource.h
  85. 40 0
      drivers/gpu/drm/amd/display/dc/os_types.h
  86. 2 11
      drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
  87. 28 0
      drivers/gpu/drm/amd/display/include/logger_interface.h
  88. 34 2
      drivers/gpu/drm/amd/display/include/logger_types.h

+ 10 - 0
drivers/gpu/drm/amd/display/Kconfig

@@ -17,6 +17,16 @@ config DRM_AMD_DC_PRE_VEGA
 	  by default. This includes Polaris, Carrizo, Tonga, Bonaire,
 	  and Hawaii.
 
+config DRM_AMD_DC_FBC
+	bool "AMD FBC - Enable Frame Buffer Compression"
+	depends on DRM_AMD_DC
+	help
+	  Choose this option if you want to use frame buffer compression
+	  support.
+	  This is a power optimisation feature, check its availability
+	  on your hardware before enabling this option.
+
+
 config DRM_AMD_DC_DCN1_0
 	bool "DCN 1.0 Raven family"
 	depends on DRM_AMD_DC && X86

+ 141 - 66
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

@@ -538,9 +538,8 @@ static int detect_mst_link_for_all_connectors(struct drm_device *dev)
 static int dm_late_init(void *handle)
 {
 	struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev;
-	int r = detect_mst_link_for_all_connectors(dev);
 
-	return r;
+	return detect_mst_link_for_all_connectors(dev);
 }
 
 static void s3_handle_mst(struct drm_device *dev, bool suspend)
@@ -599,10 +598,7 @@ static int dm_suspend(void *handle)
 	WARN_ON(adev->dm.cached_state);
 	adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev);
 
-	dc_set_power_state(
-		dm->dc,
-		DC_ACPI_CM_POWER_STATE_D3
-		);
+	dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
 
 	return ret;
 }
@@ -632,10 +628,7 @@ static int dm_resume(void *handle)
 	struct amdgpu_display_manager *dm = &adev->dm;
 
 	/* power on hardware */
-	dc_set_power_state(
-		dm->dc,
-		DC_ACPI_CM_POWER_STATE_D0
-		);
+	dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
 
 	return 0;
 }
@@ -648,6 +641,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
 	struct drm_connector *connector;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *new_crtc_state;
+	struct dm_crtc_state *dm_crtc_state;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	struct dm_plane_state *dm_plane_state;
+	struct dm_atomic_state *cached_state;
 	int ret = 0;
 	int i;
 
@@ -686,6 +684,34 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
 	for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i)
 		new_crtc_state->active_changed = true;
 
+	cached_state = to_dm_atomic_state(adev->dm.cached_state);
+
+	/*
+	 * During suspend, the cached state is saved before all streams are
+	 * disabled. Refresh cached state to match actual current state before
+	 * restoring it.
+	 */
+	WARN_ON(kref_read(&cached_state->context->refcount) > 1);
+	dc_release_state(cached_state->context);
+
+	for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) {
+		dm_crtc_state = to_dm_crtc_state(new_crtc_state);
+		if (dm_crtc_state->stream) {
+			WARN_ON(kref_read(&dm_crtc_state->stream->refcount) > 1);
+			dc_stream_release(dm_crtc_state->stream);
+			dm_crtc_state->stream = NULL;
+		}
+	}
+
+	for_each_new_plane_in_state(adev->dm.cached_state, plane, plane_state, i) {
+		dm_plane_state = to_dm_plane_state(plane_state);
+		if (dm_plane_state->dc_state) {
+			WARN_ON(kref_read(&dm_plane_state->dc_state->refcount) > 1);
+			dc_plane_state_release(dm_plane_state->dc_state);
+			dm_plane_state->dc_state = NULL;
+		}
+	}
+
 	ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);
 
 	drm_atomic_state_put(adev->dm.cached_state);
@@ -860,9 +886,9 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
 							connector);
 
 		aconnector->dc_sink = sink;
-		if (sink->dc_edid.length == 0)
+		if (sink->dc_edid.length == 0) {
 			aconnector->edid = NULL;
-		else {
+		} else {
 			aconnector->edid =
 				(struct edid *) sink->dc_edid.raw_edid;
 
@@ -980,8 +1006,9 @@ static void dm_handle_hpd_rx_irq(struct amdgpu_dm_connector *aconnector)
 				dpcd_bytes_to_read);
 
 			new_irq_handled = false;
-		} else
+		} else {
 			break;
+		}
 	}
 
 	if (process_count == max_process_count)
@@ -993,20 +1020,20 @@ static void handle_hpd_rx_irq(void *param)
 	struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
 	struct drm_connector *connector = &aconnector->base;
 	struct drm_device *dev = connector->dev;
-	const struct dc_link *dc_link = aconnector->dc_link;
+	struct dc_link *dc_link = aconnector->dc_link;
 	bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
 
 	/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
 	 * conflict, after implement i2c helper, this mutex should be
 	 * retired.
 	 */
-	if (aconnector->dc_link->type != dc_connection_mst_branch)
+	if (dc_link->type != dc_connection_mst_branch)
 		mutex_lock(&aconnector->hpd_lock);
 
-	if (dc_link_handle_hpd_rx_irq(aconnector->dc_link, NULL) &&
+	if (dc_link_handle_hpd_rx_irq(dc_link, NULL) &&
 			!is_mst_root_connector) {
 		/* Downstream Port status changed. */
-		if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPDRX)) {
+		if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
 			amdgpu_dm_update_connector_after_detect(aconnector);
 
 
@@ -1018,10 +1045,10 @@ static void handle_hpd_rx_irq(void *param)
 		}
 	}
 	if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
-				(dc_link->type == dc_connection_mst_branch))
+	    (dc_link->type == dc_connection_mst_branch))
 		dm_handle_hpd_rx_irq(aconnector);
 
-	if (aconnector->dc_link->type != dc_connection_mst_branch)
+	if (dc_link->type != dc_connection_mst_branch)
 		mutex_unlock(&aconnector->hpd_lock);
 }
 
@@ -1381,9 +1408,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
 			goto fail_free_planes;
 
 		aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL);
-		if (!aencoder) {
+		if (!aencoder)
 			goto fail_free_connector;
-		}
 
 		if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) {
 			DRM_ERROR("KMS: Failed to initialize encoder\n");
@@ -1754,7 +1780,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
 	int r = amdgpu_bo_reserve(rbo, false);
 
 	if (unlikely(r)) {
-		DRM_ERROR("Unable to reserve buffer\n");
+		// Don't show error msg. when return -ERESTARTSYS
+		if (r != -ERESTARTSYS)
+			DRM_ERROR("Unable to reserve buffer: %d\n", r);
 		return r;
 	}
 
@@ -2206,11 +2234,9 @@ static void fill_audio_info(struct audio_info *audio_info,
 
 	cea_revision = drm_connector->display_info.cea_rev;
 
-	while (i < AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS &&
-		edid_caps->display_name[i]) {
-		audio_info->display_name[i] = edid_caps->display_name[i];
-		i++;
-	}
+	strncpy(audio_info->display_name,
+		edid_caps->display_name,
+		AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1);
 
 	if (cea_revision >= 3) {
 		audio_info->mode_count = edid_caps->audio_mode_count;
@@ -2318,8 +2344,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
 
 	drm_connector = &aconnector->base;
 
-	if (!aconnector->dc_sink)
+	if (!aconnector->dc_sink) {
+		/*
+		 * Exclude MST from creating fake_sink
+		 * TODO: need to enable MST into fake_sink feature
+		 */
+		if (aconnector->mst_port)
+			goto stream_create_fail;
+
 		create_fake_sink(aconnector);
+	}
 
 	stream = dc_create_stream_for_sink(aconnector->dc_sink);
 
@@ -2453,7 +2487,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
 	 * 2. This interface *is called* in context of user-mode ioctl. Which
 	 * makes it a bad place for *any* MST-related activit. */
 
-	if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
+	if (aconnector->base.force == DRM_FORCE_UNSPECIFIED &&
+	    !aconnector->fake_enable)
 		connected = (aconnector->dc_sink != NULL);
 	else
 		connected = (aconnector->base.force == DRM_FORCE_ON);
@@ -2681,8 +2716,7 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
 		(edid->extensions + 1) * EDID_LENGTH,
 		&init_params);
 
-	if (aconnector->base.force
-					== DRM_FORCE_ON)
+	if (aconnector->base.force == DRM_FORCE_ON)
 		aconnector->dc_sink = aconnector->dc_link->local_sink ?
 		aconnector->dc_link->local_sink :
 		aconnector->dc_em_sink;
@@ -2746,7 +2780,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
 	stream->src.height = mode->vdisplay;
 	stream->dst = stream->src;
 
-	if (dc_validate_stream(adev->dm.dc, stream))
+	if (dc_validate_stream(adev->dm.dc, stream) == DC_OK)
 		result = MODE_OK;
 
 	dc_stream_release(stream);
@@ -2791,7 +2825,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
 	if (!dm_crtc_state->stream)
 		return 0;
 
-	if (dc_validate_stream(dc, dm_crtc_state->stream))
+	if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)
 		return 0;
 
 	return ret;
@@ -2835,13 +2869,13 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 		plane->funcs->atomic_destroy_state(plane, plane->state);
 
 	amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
-
+	WARN_ON(amdgpu_state == NULL);
+	
 	if (amdgpu_state) {
 		plane->state = &amdgpu_state->base;
 		plane->state->plane = plane;
 		plane->state->rotation = DRM_MODE_ROTATE_0;
-	} else
-		WARN_ON(1);
+	}
 }
 
 static struct drm_plane_state *
@@ -2986,7 +3020,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
 	if (!dm_plane_state->dc_state)
 		return 0;
 
-	if (dc_validate_plane(dc, dm_plane_state->dc_state))
+	if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
 		return 0;
 
 	return -EINVAL;
@@ -3272,8 +3306,9 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
 		drm_edid_to_eld(connector, edid);
 
 		amdgpu_dm_get_native_mode(connector);
-	} else
+	} else {
 		amdgpu_dm_connector->num_modes = 0;
+	}
 }
 
 static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
@@ -3421,7 +3456,8 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
 	struct dc *dc = dm->dc;
 	struct dc_link *link = dc_get_link_at_index(dc, link_index);
 	struct amdgpu_i2c_adapter *i2c;
-	((struct dc_link *)link)->priv = aconnector;
+
+	link->priv = aconnector;
 
 	DRM_DEBUG_DRIVER("%s()\n", __func__);
 
@@ -3661,10 +3697,10 @@ static void handle_cursor_update(struct drm_plane *plane,
 		return;
 
 	DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n",
-		         __func__,
-		         amdgpu_crtc->crtc_id,
-		         plane->state->crtc_w,
-		         plane->state->crtc_h);
+			 __func__,
+			 amdgpu_crtc->crtc_id,
+			 plane->state->crtc_w,
+			 plane->state->crtc_h);
 
 	ret = get_cursor_position(plane, crtc, &position);
 	if (ret)
@@ -3691,14 +3727,15 @@ static void handle_cursor_update(struct drm_plane *plane,
 
 	attributes.pitch = attributes.width;
 
-	if (!dc_stream_set_cursor_attributes(crtc_state->stream,
-					     &attributes))
-		DRM_ERROR("DC failed to set cursor attributes\n");
+	if (crtc_state->stream) {
+		if (!dc_stream_set_cursor_attributes(crtc_state->stream,
+							 &attributes))
+			DRM_ERROR("DC failed to set cursor attributes\n");
 
-	if (crtc_state->stream)
 		if (!dc_stream_set_cursor_position(crtc_state->stream,
 						   &position))
 			DRM_ERROR("DC failed to set cursor position\n");
+	}
 }
 
 static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
@@ -3726,7 +3763,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
  */
 static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
 			      struct drm_framebuffer *fb,
-			      uint32_t target)
+			      uint32_t target,
+			      struct dc_state *state)
 {
 	unsigned long flags;
 	uint32_t target_vblank;
@@ -3797,7 +3835,13 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
 	surface_updates->flip_addr = &addr;
 
 
-	dc_update_planes_and_stream(adev->dm.dc, surface_updates, 1, acrtc_state->stream, NULL);
+	dc_commit_updates_for_stream(adev->dm.dc,
+					     surface_updates,
+					     1,
+					     acrtc_state->stream,
+					     NULL,
+					     &surface_updates->surface,
+					     state);
 
 	DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
 			 __func__,
@@ -3823,6 +3867,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 	struct drm_crtc_state *new_pcrtc_state =
 			drm_atomic_get_new_crtc_state(state, pcrtc);
 	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
+	struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
 	int planes_count = 0;
 	unsigned long flags;
 
@@ -3880,7 +3925,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 			amdgpu_dm_do_flip(
 				crtc,
 				fb,
-				drm_crtc_vblank_count(crtc) + *wait_for_vblank);
+				drm_crtc_vblank_count(crtc) + *wait_for_vblank,
+				dm_state->context);
 		}
 
 	}
@@ -3900,7 +3946,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 		if (false == dc_commit_planes_to_stream(dm->dc,
 							plane_states_constructed,
 							planes_count,
-							dc_stream_attach))
+							dc_stream_attach,
+							dm_state->context))
 			dm_error("%s: Failed to attach plane!\n", __func__);
 	} else {
 		/*TODO BUG Here should go disable planes on CRTC. */
@@ -3931,6 +3978,8 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
 		if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
 			manage_dm_interrupts(adev, acrtc, false);
 	}
+	/* Add check here for SoC's that support hardware cursor plane, to
+	 * unset legacy_cursor_update */
 
 	return drm_atomic_helper_commit(dev, state, nonblock);
 
@@ -4120,7 +4169,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 				dm->dc,
 				status->plane_states,
 				status->plane_count,
-				dm_new_crtc_state->stream))
+				dm_new_crtc_state->stream,
+				dm_state->context))
 			dm_error("%s: Failed to update stream scaling!\n", __func__);
 	}
 
@@ -4339,7 +4389,8 @@ static int dm_update_crtcs_state(struct dc *dc,
 		aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
 
 		/* TODO This hack should go away */
-		if (aconnector) {
+		if (aconnector && enable) {
+			// Make sure fake sink is created in plug-in scenario
 			new_con_state = drm_atomic_get_connector_state(state,
  								    &aconnector->base);
 
@@ -4368,12 +4419,13 @@ static int dm_update_crtcs_state(struct dc *dc,
 			}
 		}
 
-		if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream)) {
+		if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
+				dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
 
 			new_crtc_state->mode_changed = false;
 
 			DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d",
-					new_crtc_state->mode_changed);
+				         new_crtc_state->mode_changed);
 		}
 
 
@@ -4402,10 +4454,10 @@ static int dm_update_crtcs_state(struct dc *dc,
 					crtc->base.id);
 
 			/* i.e. reset mode */
-			if (!dc_remove_stream_from_ctx(
+			if (dc_remove_stream_from_ctx(
 					dc,
 					dm_state->context,
-					dm_old_crtc_state->stream)) {
+					dm_old_crtc_state->stream) != DC_OK) {
 				ret = -EINVAL;
 				goto fail;
 			}
@@ -4416,6 +4468,13 @@ static int dm_update_crtcs_state(struct dc *dc,
 			*lock_and_validation_needed = true;
 
 		} else {/* Add stream for any updated/enabled CRTC */
+			/*
+			 * Quick fix to prevent NULL pointer on new_stream when
+			 * added MST connectors not found in existing crtc_state in the chained mode
+			 * TODO: need to dig out the root cause of that
+			 */
+			if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port))
+				goto next_crtc;
 
 			if (modereset_required(new_crtc_state))
 				goto next_crtc;
@@ -4431,10 +4490,10 @@ static int dm_update_crtcs_state(struct dc *dc,
 				DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n",
 							crtc->base.id);
 
-				if (!dc_add_stream_to_ctx(
+				if (dc_add_stream_to_ctx(
 						dc,
 						dm_state->context,
-						dm_new_crtc_state->stream)) {
+						dm_new_crtc_state->stream) != DC_OK) {
 					ret = -EINVAL;
 					goto fail;
 				}
@@ -4586,7 +4645,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 	struct drm_connector *connector;
 	struct drm_connector_state *old_con_state, *new_con_state;
 	struct drm_crtc *crtc;
-	struct drm_crtc_state *new_crtc_state;
+	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
 
 	/*
 	 * This bool will be set for true for any modeset/reset
@@ -4595,18 +4654,34 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 	bool lock_and_validation_needed = false;
 
 	ret = drm_atomic_helper_check_modeset(dev, state);
-
 	if (ret) {
 		DRM_ERROR("Atomic state validation failed with error :%d !\n", ret);
 		return ret;
 	}
 
 	/*
-	 * Hack: Commit needs planes right now, specifically for gamma
-	 * TODO rework commit to check CRTC for gamma change
+	 * legacy_cursor_update should be made false for SoC's having
+	 * a dedicated hardware plane for cursor in amdgpu_dm_atomic_commit(),
+	 * otherwise for software cursor plane,
+	 * we should not add it to list of affected planes.
 	 */
-	for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
-		if (new_crtc_state->color_mgmt_changed) {
+	if (state->legacy_cursor_update) {
+		for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+			if (new_crtc_state->color_mgmt_changed) {
+				ret = drm_atomic_add_affected_planes(state, crtc);
+				if (ret)
+					goto fail;
+			}
+		}
+	} else {
+		for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+			if (!new_crtc_state->enable)
+				continue;
+
+			ret = drm_atomic_add_affected_connectors(state, crtc);
+			if (ret)
+				return ret;
+
 			ret = drm_atomic_add_affected_planes(state, crtc);
 			if (ret)
 				goto fail;
@@ -4684,7 +4759,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		if (ret)
 			goto fail;
 
-		if (!dc_validate_global_state(dc, dm_state->context)) {
+		if (dc_validate_global_state(dc, dm_state->context) != DC_OK) {
 			ret = -EINVAL;
 			goto fail;
 		}

+ 9 - 12
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c

@@ -208,24 +208,21 @@ static void remove_timer_handler(struct amdgpu_device *adev,
 			DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
 		}
 
-		if (handler_in == NULL) {
-			/* Remove ALL handlers. */
+		/* Remove ALL handlers. */
+		if (handler_in == NULL)
 			continue;
-		}
 
-		if (handler_in == handler_temp) {
-			/* Remove a SPECIFIC handler.
-			 * Found our handler - we can stop here. */
+		/* Remove a SPECIFIC handler.
+		 * Found our handler - we can stop here. */
+		if (handler_in == handler_temp)
 			break;
-		}
 	}
 
 	DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
 
-	if (handler_in != NULL && handler_removed == false) {
+	if (handler_in != NULL && handler_removed == false)
 		DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
 				handler_in);
-	}
 }
 
 static bool
@@ -435,7 +432,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
 	 * Disable HW interrupt  for HPD and HPDRX only since FLIP and VBLANK
 	 * will be disabled from manage_dm_interrupts on disable CRTC.
 	 */
-	for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6RX; src++) {
+	for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
 		hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
 		hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
 		if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
@@ -462,7 +459,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
 	DRM_DEBUG_KMS("DM_IRQ: early resume\n");
 
 	/* re-enable short pulse interrupts HW interrupt */
-	for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) {
+	for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
 		hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
 		hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
 		if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
@@ -488,7 +485,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
 	 * Renable HW interrupt  for HPD and only since FLIP and VBLANK
 	 * will be enabled from manage_dm_interrupts on enable CRTC.
 	 */
-	for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6; src++) {
+	for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
 		hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
 		hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
 		if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))

+ 55 - 80
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

@@ -174,14 +174,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
 	.atomic_get_property = amdgpu_dm_connector_atomic_get_property
 };
 
+static int dm_connector_update_modes(struct drm_connector *connector,
+				struct edid *edid)
+{
+	int ret;
+
+	ret = drm_add_edid_modes(connector, edid);
+	drm_edid_to_eld(connector, edid);
+
+	return ret;
+}
+
 static int dm_dp_mst_get_modes(struct drm_connector *connector)
 {
 	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 	int ret = 0;
 
-	ret = drm_add_edid_modes(&aconnector->base, aconnector->edid);
+	if (!aconnector)
+		return dm_connector_update_modes(connector, NULL);
+
+	if (!aconnector->edid) {
+		struct edid *edid;
+		struct dc_sink *dc_sink;
+		struct dc_sink_init_data init_params = {
+				.link = aconnector->dc_link,
+				.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
+		edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
 
-	drm_edid_to_eld(&aconnector->base, aconnector->edid);
+		if (!edid) {
+			drm_mode_connector_update_edid_property(
+				&aconnector->base,
+				NULL);
+			return ret;
+		}
+
+		aconnector->edid = edid;
+
+		dc_sink = dc_link_add_remote_sink(
+			aconnector->dc_link,
+			(uint8_t *)edid,
+			(edid->extensions + 1) * EDID_LENGTH,
+			&init_params);
+
+		dc_sink->priv = aconnector;
+		aconnector->dc_sink = dc_sink;
+
+		if (aconnector->dc_sink)
+			amdgpu_dm_add_sink_to_freesync_module(
+					connector, edid);
+
+		drm_mode_connector_update_edid_property(
+						&aconnector->base, edid);
+	}
+
+	ret = dm_connector_update_modes(connector, aconnector->edid);
 
 	return ret;
 }
@@ -241,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 	struct amdgpu_device *adev = dev->dev_private;
 	struct amdgpu_dm_connector *aconnector;
 	struct drm_connector *connector;
+	struct drm_connector_list_iter conn_iter;
 
-	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+	drm_connector_list_iter_begin(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (aconnector->mst_port == master
 				&& !aconnector->port) {
@@ -253,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 			aconnector->port = port;
 			drm_mode_connector_set_path_property(connector, pathprop);
 
-			drm_modeset_unlock(&dev->mode_config.connection_mutex);
+			drm_connector_list_iter_end(&conn_iter);
 			return &aconnector->base;
 		}
 	}
-	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+	drm_connector_list_iter_end(&conn_iter);
 
 	aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
 	if (!aconnector)
@@ -343,92 +390,20 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
 {
 	struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
 	struct drm_device *dev = master->base.dev;
-	struct amdgpu_device *adev = dev->dev_private;
-	struct drm_connector *connector;
-	struct amdgpu_dm_connector *aconnector;
-	struct edid *edid;
-	struct dc_sink *dc_sink;
-
-	drm_modeset_lock_all(dev);
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		aconnector = to_amdgpu_dm_connector(connector);
-		if (aconnector->port &&
-				aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
-				aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
-				!aconnector->dc_sink) {
-			/*
-			 * This is plug in case, where port has been created but
-			 * sink hasn't been created yet
-			 */
-			if (!aconnector->edid) {
-				struct dc_sink_init_data init_params = {
-						.link = aconnector->dc_link,
-						.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
-				edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
-
-				if (!edid) {
-					drm_mode_connector_update_edid_property(
-						&aconnector->base,
-						NULL);
-					continue;
-				}
-
-				aconnector->edid = edid;
-
-				dc_sink = dc_link_add_remote_sink(
-					aconnector->dc_link,
-					(uint8_t *)edid,
-					(edid->extensions + 1) * EDID_LENGTH,
-					&init_params);
-
-				dc_sink->priv = aconnector;
-				aconnector->dc_sink = dc_sink;
-
-				if (aconnector->dc_sink)
-					amdgpu_dm_add_sink_to_freesync_module(
-							connector,
-							edid);
-
-				dm_restore_drm_connector_state(connector->dev, connector);
-			} else
-				edid = aconnector->edid;
-
-			DRM_DEBUG_KMS("edid retrieved %p\n", edid);
 
-			drm_mode_connector_update_edid_property(
-				&aconnector->base,
-				aconnector->edid);
-		}
-	}
-	drm_modeset_unlock_all(dev);
-
-	schedule_work(&adev->dm.mst_hotplug_work);
+	drm_kms_helper_hotplug_event(dev);
 }
 
 static void dm_dp_mst_register_connector(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
 	struct amdgpu_device *adev = dev->dev_private;
-	int i;
-
-	drm_modeset_lock_all(dev);
-	if (adev->mode_info.rfbdev) {
-		/*Do not add if already registered in past*/
-		for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) {
-			if (adev->mode_info.rfbdev->helper.connector_info[i]->connector
-					== connector) {
-				drm_modeset_unlock_all(dev);
-				return;
-			}
-		}
 
+	if (adev->mode_info.rfbdev)
 		drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
-	}
 	else
 		DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
 
-	drm_modeset_unlock_all(dev);
-
 	drm_connector_register(connector);
 
 }

+ 6 - 0
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c

@@ -35,6 +35,12 @@
 #include "amdgpu_dm_irq.h"
 #include "amdgpu_pm.h"
 
+unsigned long long dm_get_timestamp(struct dc_context *ctx)
+{
+	/* TODO: return actual timestamp */
+	return 0;
+}
+
 bool dm_write_persistent_data(struct dc_context *ctx,
 		const struct dc_sink *sink,
 		const char *module_name,

+ 22 - 56
drivers/gpu/drm/amd/display/dc/basics/logger.c

@@ -80,8 +80,6 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger,
 	logger->buffer_read_offset = 0;
 	logger->buffer_write_offset = 0;
 
-	logger->write_wrap_count = 0;
-	logger->read_wrap_count = 0;
 	logger->open_count = 0;
 
 	logger->flags.bits.ENABLE_CONSOLE = 1;
@@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry)
 }
 
 /* Print everything unread existing in log_buffer to debug console*/
-static void flush_to_debug_console(struct dal_logger *logger)
+void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn)
 {
-	int i = logger->buffer_read_offset;
-	char *string_start = &logger->log_buffer[i];
+	char *string_start = &logger->log_buffer[logger->buffer_read_offset];
 
-	dm_output_to_console(
-		"---------------- FLUSHING LOG BUFFER ----------------\n");
-	while (i < logger->buffer_write_offset)	{
+	if (should_warn)
+		dm_output_to_console(
+			"---------------- FLUSHING LOG BUFFER ----------------\n");
+	while (logger->buffer_read_offset < logger->buffer_write_offset) {
 
-		if (logger->log_buffer[i] == '\0') {
+		if (logger->log_buffer[logger->buffer_read_offset] == '\0') {
 			dm_output_to_console("%s", string_start);
-			string_start = (char *)logger->log_buffer + i + 1;
+			string_start = logger->log_buffer + logger->buffer_read_offset + 1;
 		}
-		i++;
+		logger->buffer_read_offset++;
 	}
-	dm_output_to_console(
-		"-------------- END FLUSHING LOG BUFFER --------------\n\n");
+	if (should_warn)
+		dm_output_to_console(
+			"-------------- END FLUSHING LOG BUFFER --------------\n\n");
 }
 
 static void log_to_internal_buffer(struct log_entry *entry)
@@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry)
 
 	if (size > 0 && size < logger->log_buffer_size) {
 
-		int total_free_space = 0;
-		int space_before_wrap = 0;
-
-		if (logger->buffer_write_offset > logger->buffer_read_offset) {
-			total_free_space = logger->log_buffer_size -
-					logger->buffer_write_offset +
-					logger->buffer_read_offset;
-			space_before_wrap = logger->log_buffer_size -
-					logger->buffer_write_offset;
-		} else if (logger->buffer_write_offset <
-				logger->buffer_read_offset) {
-			total_free_space = logger->log_buffer_size -
-					logger->buffer_read_offset +
-					logger->buffer_write_offset;
-			space_before_wrap = total_free_space;
-		} else if (logger->write_wrap_count !=
-				logger->read_wrap_count) {
-			/* Buffer is completely full already */
-			total_free_space = 0;
-			space_before_wrap = 0;
-		} else {
+		int buffer_space = logger->log_buffer_size -
+				logger->buffer_write_offset;
+
+		if (logger->buffer_write_offset == logger->buffer_read_offset) {
 			/* Buffer is empty, start writing at beginning */
-			total_free_space = logger->log_buffer_size;
-			space_before_wrap = logger->log_buffer_size;
+			buffer_space = logger->log_buffer_size;
 			logger->buffer_write_offset = 0;
 			logger->buffer_read_offset = 0;
 		}
 
-		if (space_before_wrap > size) {
+		if (buffer_space > size) {
 			/* No wrap around, copy 'size' bytes
 			 * from 'entry->buf' to 'log_buffer'
 			 */
@@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry)
 					entry->buf, size);
 			logger->buffer_write_offset += size;
 
-		} else if (total_free_space > size) {
-			/* We have enough room without flushing,
-			 * but need to wrap around */
-
-			int space_after_wrap = total_free_space -
-					space_before_wrap;
-
-			memmove(logger->log_buffer +
-					logger->buffer_write_offset,
-					entry->buf, space_before_wrap);
-			memmove(logger->log_buffer, entry->buf +
-					space_before_wrap, space_after_wrap);
-
-			logger->buffer_write_offset = space_after_wrap;
-			logger->write_wrap_count++;
-
 		} else {
 			/* Not enough room remaining, we should flush
 			 * existing logs */
 
 			/* Flush existing unread logs to console */
-			flush_to_debug_console(logger);
+			dm_logger_flush_buffer(logger, true);
 
 			/* Start writing to beginning of buffer */
 			memmove(logger->log_buffer, entry->buf, size);
@@ -325,9 +290,10 @@ void dm_logger_write(
 		log_heading(&entry);
 
 		size = dm_log_to_buffer(
-			buffer, LOG_MAX_LINE_SIZE, msg, args);
+			buffer, LOG_MAX_LINE_SIZE - 1, msg, args);
 
-		entry.buf_offset += size;
+		buffer[entry.buf_offset + size] = '\0';
+		entry.buf_offset += size + 1;
 
 		/* --Flush log_entry buffer-- */
 		/* print to kernel console */

+ 0 - 37
drivers/gpu/drm/amd/display/dc/basics/logger.h

@@ -26,42 +26,5 @@
 #ifndef __DAL_LOGGER_H__
 #define __DAL_LOGGER_H__
 
-/* Structure for keeping track of offsets, buffer, etc */
-
-#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
-
-/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
- * change log line size to 896 to meet the request.
- */
-#define LOG_MAX_LINE_SIZE 896
-
-#include "include/logger_types.h"
-
-struct dal_logger {
-
-	/* How far into the circular buffer has been read by dsat
-	 * Read offset should never cross write offset. Write \0's to
-	 * read data just to be sure?
-	 */
-	uint32_t buffer_read_offset;
-
-	/* How far into the circular buffer we have written
-	 * Write offset should never cross read offset
-	 */
-	uint32_t buffer_write_offset;
-
-	uint32_t write_wrap_count;
-	uint32_t read_wrap_count;
-
-	uint32_t open_count;
-
-	char *log_buffer;	/* Pointer to malloc'ed buffer */
-	uint32_t log_buffer_size; /* Size of circular buffer */
-
-	uint32_t mask; /*array of masks for major elements*/
-
-	union logger_flags flags;
-	struct dc_context *ctx;
-};
 
 #endif /* __DAL_LOGGER_H__ */

+ 5 - 5
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c

@@ -1042,13 +1042,13 @@ static enum bp_result get_embedded_panel_info_v2_1(
 	info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
 
 	info->lcd_timing.misc_info.H_REPLICATION_BY2 =
-		lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2;
+		!!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
 	info->lcd_timing.misc_info.V_REPLICATION_BY2 =
-		lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2;
+		!!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
 	info->lcd_timing.misc_info.COMPOSITE_SYNC =
-		lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC;
+		!!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
 	info->lcd_timing.misc_info.INTERLACE =
-		lvds->lcd_timing.miscinfo & ATOM_INTERLACE;
+		!!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
 
 	/* not provided by VBIOS*/
 	info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
@@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1(
 	info->ss_id = 0;
 
 	info->realtek_eDPToLVDS =
-			(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0);
+			!!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
 
 	return BP_RESULT_OK;
 }

+ 1 - 1
drivers/gpu/drm/amd/display/dc/calcs/Makefile

@@ -5,7 +5,7 @@
 
 CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4
 CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4
-CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 -Wno-tautological-compare
 
 BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
 

+ 45 - 0
drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c

@@ -25,6 +25,41 @@
 
 #include "dcn_calc_math.h"
 
+float dcn_bw_mod(const float arg1, const float arg2)
+{
+	if (arg1 != arg1)
+		return arg2;
+	if (arg2 != arg2)
+		return arg1;
+	return arg1 - arg1 * ((int) (arg1 / arg2));
+}
+
+float dcn_bw_min2(const float arg1, const float arg2)
+{
+	if (arg1 != arg1)
+		return arg2;
+	if (arg2 != arg2)
+		return arg1;
+	return arg1 < arg2 ? arg1 : arg2;
+}
+
+unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
+{
+	if (arg1 != arg1)
+		return arg2;
+	if (arg2 != arg2)
+		return arg1;
+	return arg1 > arg2 ? arg1 : arg2;
+}
+float dcn_bw_max2(const float arg1, const float arg2)
+{
+	if (arg1 != arg1)
+		return arg2;
+	if (arg2 != arg2)
+		return arg1;
+	return arg1 > arg2 ? arg1 : arg2;
+}
+
 float dcn_bw_floor2(const float arg, const float significance)
 {
 	if (significance == 0)
@@ -40,6 +75,16 @@ float dcn_bw_ceil2(const float arg, const float significance)
 	return flr + 0.00001 >= arg ? arg : flr + significance;
 }
 
+float dcn_bw_max3(float v1, float v2, float v3)
+{
+	return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
+}
+
+float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
+{
+	return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
+}
+
 float dcn_bw_pow(float a, float exp)
 {
 	float temp;

+ 6 - 30
drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h

@@ -26,38 +26,14 @@
 #ifndef _DCN_CALC_MATH_H_
 #define _DCN_CALC_MATH_H_
 
-static inline float dcn_bw_mod(const float arg1, const float arg2)
-{
-	return arg1 - arg1 * ((int) (arg1 / arg2));
-}
-
-static inline float dcn_bw_min2(const float arg1, const float arg2)
-{
-	return arg1 < arg2 ? arg1 : arg2;
-}
-
-static inline unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
-{
-	return arg1 > arg2 ? arg1 : arg2;
-}
-
-static inline float dcn_bw_max2(const float arg1, const float arg2)
-{
-	return arg1 > arg2 ? arg1 : arg2;
-}
-
-static inline float dcn_bw_max3(float v1, float v2, float v3)
-{
-	return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
-}
-
-static inline float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
-{
-	return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
-}
-
+float dcn_bw_mod(const float arg1, const float arg2);
+float dcn_bw_min2(const float arg1, const float arg2);
+unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
+float dcn_bw_max2(const float arg1, const float arg2);
 float dcn_bw_floor2(const float arg, const float significance);
 float dcn_bw_ceil2(const float arg, const float significance);
+float dcn_bw_max3(float v1, float v2, float v3);
+float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
 float dcn_bw_pow(float a, float exp);
 float dcn_bw_log(float a, float b);
 

+ 117 - 107
drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c

@@ -364,7 +364,8 @@ static void pipe_ctx_to_e2e_pipe_params (
 	}
 
 
-	input->dest.vactive        = pipe->stream->timing.v_addressable;
+	input->dest.vactive        = pipe->stream->timing.v_addressable + pipe->stream->timing.v_border_top
+			+ pipe->stream->timing.v_border_bottom;
 
 	input->dest.recout_width   = pipe->plane_res.scl_data.recout.width;
 	input->dest.recout_height  = pipe->plane_res.scl_data.recout.height;
@@ -385,10 +386,6 @@ static void pipe_ctx_to_e2e_pipe_params (
 			- pipe->stream->timing.v_addressable
 			- pipe->stream->timing.v_border_bottom
 			- pipe->stream->timing.v_border_top;
-
-	input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total
-			- pipe->stream->timing.v_addressable
-			- pipe->stream->timing.v_front_porch;
 	input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0;
 	input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start;
 	input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset;
@@ -458,9 +455,9 @@ static void dcn_bw_calc_rq_dlg_ttu(
 	/*todo: soc->sr_enter_plus_exit_time??*/
 	dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
 
-	dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
-	extract_rq_regs(dml, rq_regs, rq_param);
-	dml_rq_dlg_get_dlg_params(
+	dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
+	dml1_extract_rq_regs(dml, rq_regs, rq_param);
+	dml1_rq_dlg_get_dlg_params(
 			dml,
 			dlg_regs,
 			ttu_regs,
@@ -473,96 +470,6 @@ static void dcn_bw_calc_rq_dlg_ttu(
 			pipe->plane_state->flip_immediate);
 }
 
-static void dcn_dml_wm_override(
-		const struct dcn_bw_internal_vars *v,
-		struct display_mode_lib *dml,
-		struct dc_state *context,
-		const struct resource_pool *pool)
-{
-	int i, in_idx, active_count;
-
-	struct _vcs_dpi_display_e2e_pipe_params_st *input = kzalloc(pool->pipe_count * sizeof(struct _vcs_dpi_display_e2e_pipe_params_st),
-								    GFP_KERNEL);
-	struct wm {
-		double urgent;
-		struct _vcs_dpi_cstate_pstate_watermarks_st cpstate;
-		double pte_meta_urgent;
-	} a;
-
-
-	for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
-		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-		if (!pipe->stream || !pipe->plane_state)
-			continue;
-
-		input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk;
-		input[in_idx].clks_cfg.dispclk_mhz = v->dispclk;
-		input[in_idx].clks_cfg.dppclk_mhz = v->dppclk;
-		input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000;
-		input[in_idx].clks_cfg.socclk_mhz = v->socclk;
-		input[in_idx].clks_cfg.voltage = v->voltage_level;
-		input[in_idx].dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
-		input[in_idx].dout.output_type  = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
-		//input[in_idx].dout.output_standard;
-		switch (v->output_deep_color[in_idx]) {
-		case dcn_bw_encoder_12bpc:
-			input[in_idx].dout.output_bpc = dm_out_12;
-		break;
-		case dcn_bw_encoder_10bpc:
-			input[in_idx].dout.output_bpc = dm_out_10;
-		break;
-		case dcn_bw_encoder_8bpc:
-		default:
-			input[in_idx].dout.output_bpc = dm_out_8;
-		break;
-		}
-		pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe);
-		dml_rq_dlg_get_rq_reg(
-			dml,
-			&pipe->rq_regs,
-			input[in_idx].pipe.src);
-		in_idx++;
-	}
-	active_count = in_idx;
-
-	a.urgent = dml_wm_urgent_e2e(dml, input, active_count);
-	a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count);
-	a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent);
-
-	context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns =
-			a.cpstate.cstate_exit_us * 1000;
-	context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
-			a.cpstate.cstate_enter_plus_exit_us * 1000;
-	context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns =
-			a.cpstate.pstate_change_us * 1000;
-	context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000;
-	context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000;
-	context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a;
-	context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a;
-	context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a;
-
-
-	for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
-		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
-		if (!pipe->stream || !pipe->plane_state)
-			continue;
-
-		dml_rq_dlg_get_dlg_reg(dml,
-			&pipe->dlg_regs,
-			&pipe->ttu_regs,
-			input, active_count,
-			in_idx,
-			true,
-			true,
-			v->pte_enable == dcn_bw_yes,
-			pipe->plane_state->flip_immediate);
-		in_idx++;
-	}
-	kfree(input);
-}
-
 static void split_stream_across_pipes(
 		struct resource_context *res_ctx,
 		const struct resource_pool *pool,
@@ -578,8 +485,10 @@ static void split_stream_across_pipes(
 
 	secondary_pipe->pipe_idx = pipe_idx;
 	secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx];
+	secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx];
 	secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
 	secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
+	secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
 	if (primary_pipe->bottom_pipe) {
 		ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
 		secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
@@ -719,6 +628,49 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
 	return updated;
 }
 
+void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
+{
+	/*
+	 * disable optional pipe split by lower dispclk bounding box
+	 * at DPM0
+	 */
+	v->max_dispclk[0] = v->max_dppclk_vmin0p65;
+}
+
+void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
+		unsigned int pixel_rate_khz)
+{
+	float pixel_rate_mhz = pixel_rate_khz / 1000;
+
+	/*
+	 * force enabling pipe split by lower dpp clock for DPM0 to just
+	 * below the specify pixel_rate, so bw calc would split pipe.
+	 */
+	if (pixel_rate_mhz < v->max_dppclk[0])
+		v->max_dppclk[0] = pixel_rate_mhz;
+}
+
+void hack_bounding_box(struct dcn_bw_internal_vars *v,
+		struct dc_debug *dbg,
+		struct dc_state *context)
+{
+	if (dbg->pipe_split_policy == MPC_SPLIT_AVOID) {
+		hack_disable_optional_pipe_split(v);
+	}
+
+	if (dbg->pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP &&
+		context->stream_count >= 2) {
+		hack_disable_optional_pipe_split(v);
+	}
+
+	if (context->stream_count == 1 &&
+			dbg->force_single_disp_pipe_split) {
+		struct dc_stream_state *stream0 = context->streams[0];
+
+		hack_force_pipe_split(v, stream0->timing.pix_clk_khz);
+	}
+}
+
 bool dcn_validate_bandwidth(
 		struct dc *dc,
 		struct dc_state *context)
@@ -730,6 +682,7 @@ bool dcn_validate_bandwidth(
 	bool bw_limit_pass;
 	float bw_limit;
 
+	PERFORMANCE_TRACE_START();
 	if (dcn_bw_apply_registry_override(dc))
 		dcn_bw_sync_calcs_and_dml(dc);
 
@@ -850,9 +803,7 @@ bool dcn_validate_bandwidth(
 	v->phyclk_per_state[1] = v->phyclkv_mid0p72;
 	v->phyclk_per_state[0] = v->phyclkv_min0p65;
 
-	if (dc->debug.disable_pipe_split) {
-		v->max_dispclk[0] = v->max_dppclk_vmin0p65;
-	}
+	hack_bounding_box(v, &dc->debug, context);
 
 	if (v->voltage_override == dcn_bw_v_max0p9) {
 		v->voltage_override_level = number_of_states - 1;
@@ -882,10 +833,11 @@ bool dcn_validate_bandwidth(
 
 		v->htotal[input_idx] = pipe->stream->timing.h_total;
 		v->vtotal[input_idx] = pipe->stream->timing.v_total;
+		v->vactive[input_idx] = pipe->stream->timing.v_addressable +
+				pipe->stream->timing.v_border_top + pipe->stream->timing.v_border_bottom;
 		v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total
-				- pipe->stream->timing.v_addressable
+				- v->vactive[input_idx]
 				- pipe->stream->timing.v_front_porch;
-		v->vactive[input_idx] = pipe->stream->timing.v_addressable;
 		v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f;
 
 		if (!pipe->plane_state) {
@@ -1006,6 +958,10 @@ bool dcn_validate_bandwidth(
 		else
 			bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9;
 
+		if (bw_consumed < v->fabric_and_dram_bandwidth)
+			if (dc->debug.voltage_align_fclk)
+				bw_consumed = v->fabric_and_dram_bandwidth;
+
 		display_pipe_configuration(v);
 		calc_wm_sets_and_perf_params(context, v);
 		context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 /
@@ -1018,9 +974,17 @@ bool dcn_validate_bandwidth(
 		context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin);
 		context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000);
 		context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000);
+
 		context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000);
 		if (dc->debug.max_disp_clk == true)
 			context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000);
+
+		if (context->bw.dcn.calc_clk.dispclk_khz <
+				dc->debug.min_disp_clk_khz) {
+			context->bw.dcn.calc_clk.dispclk_khz =
+					dc->debug.min_disp_clk_khz;
+		}
+
 		context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2;
 
 		for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
@@ -1108,9 +1072,6 @@ bool dcn_validate_bandwidth(
 
 			input_idx++;
 		}
-		if (dc->debug.use_dml_wm)
-			dcn_dml_wm_override(v, (struct display_mode_lib *)
-					&dc->dml, context, pool);
 	}
 
 	if (v->voltage_level == 0) {
@@ -1129,6 +1090,8 @@ bool dcn_validate_bandwidth(
 
 	kernel_fpu_end();
 
+	PERFORMANCE_TRACE_END();
+
 	if (bw_limit_pass && v->voltage_level != 5)
 		return true;
 	else
@@ -1263,7 +1226,7 @@ unsigned int dcn_find_dcfclk_suits_all(
 	else
 		dcf_clk =  dc->dcn_soc->dcfclkv_min0p65*1000;
 
-	dm_logger_write(dc->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"\tdcf_clk for voltage = %d\n", dcf_clk);
 	return dcf_clk;
 }
@@ -1386,6 +1349,53 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
 	ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz;
 	ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz;
 
+	if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
+		ranges.reader_wm_sets[0].wm_inst = WM_A;
+		ranges.reader_wm_sets[0].min_drain_clk_khz = 300000;
+		ranges.reader_wm_sets[0].max_drain_clk_khz = 654000;
+		ranges.reader_wm_sets[0].min_fill_clk_khz = 800000;
+		ranges.reader_wm_sets[0].max_fill_clk_khz = 800000;
+		ranges.writer_wm_sets[0].wm_inst = WM_A;
+		ranges.writer_wm_sets[0].min_fill_clk_khz = 200000;
+		ranges.writer_wm_sets[0].max_fill_clk_khz = 757000;
+		ranges.writer_wm_sets[0].min_drain_clk_khz = 800000;
+		ranges.writer_wm_sets[0].max_drain_clk_khz = 800000;
+
+		ranges.reader_wm_sets[1].wm_inst = WM_B;
+		ranges.reader_wm_sets[1].min_drain_clk_khz = 300000;
+		ranges.reader_wm_sets[1].max_drain_clk_khz = 654000;
+		ranges.reader_wm_sets[1].min_fill_clk_khz = 933000;
+		ranges.reader_wm_sets[1].max_fill_clk_khz = 933000;
+		ranges.writer_wm_sets[1].wm_inst = WM_B;
+		ranges.writer_wm_sets[1].min_fill_clk_khz = 200000;
+		ranges.writer_wm_sets[1].max_fill_clk_khz = 757000;
+		ranges.writer_wm_sets[1].min_drain_clk_khz = 933000;
+		ranges.writer_wm_sets[1].max_drain_clk_khz = 933000;
+
+
+		ranges.reader_wm_sets[2].wm_inst = WM_C;
+		ranges.reader_wm_sets[2].min_drain_clk_khz = 300000;
+		ranges.reader_wm_sets[2].max_drain_clk_khz = 654000;
+		ranges.reader_wm_sets[2].min_fill_clk_khz = 1067000;
+		ranges.reader_wm_sets[2].max_fill_clk_khz = 1067000;
+		ranges.writer_wm_sets[2].wm_inst = WM_C;
+		ranges.writer_wm_sets[2].min_fill_clk_khz = 200000;
+		ranges.writer_wm_sets[2].max_fill_clk_khz = 757000;
+		ranges.writer_wm_sets[2].min_drain_clk_khz = 1067000;
+		ranges.writer_wm_sets[2].max_drain_clk_khz = 1067000;
+
+		ranges.reader_wm_sets[3].wm_inst = WM_D;
+		ranges.reader_wm_sets[3].min_drain_clk_khz = 300000;
+		ranges.reader_wm_sets[3].max_drain_clk_khz = 654000;
+		ranges.reader_wm_sets[3].min_fill_clk_khz = 1200000;
+		ranges.reader_wm_sets[3].max_fill_clk_khz = 1200000;
+		ranges.writer_wm_sets[3].wm_inst = WM_D;
+		ranges.writer_wm_sets[3].min_fill_clk_khz = 200000;
+		ranges.writer_wm_sets[3].max_fill_clk_khz = 757000;
+		ranges.writer_wm_sets[3].min_drain_clk_khz = 1200000;
+		ranges.writer_wm_sets[3].max_drain_clk_khz = 1200000;
+	}
+
 	/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
 	pp->set_wm_ranges(&pp->pp_smu, &ranges);
 }

+ 218 - 254
drivers/gpu/drm/amd/display/dc/core/dc.c

@@ -38,6 +38,7 @@
 #include "bios_parser_interface.h"
 #include "include/irq_service_interface.h"
 #include "transform.h"
+#include "dpp.h"
 #include "timing_generator.h"
 #include "virtual/virtual_link_encoder.h"
 
@@ -47,6 +48,7 @@
 #include "dc_link_ddc.h"
 #include "dm_helpers.h"
 #include "mem_input.h"
+#include "hubp.h"
 
 
 /*******************************************************************************
@@ -332,10 +334,19 @@ static void set_dither_option(struct dc_stream_state *stream,
 {
 	struct bit_depth_reduction_params params;
 	struct dc_link *link = stream->status.link;
-	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
+	struct pipe_ctx *pipes = NULL;
+	int i;
+
+	for (i = 0; i < MAX_PIPES; i++) {
+		if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
+				stream) {
+			pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
+			break;
+		}
+	}
 
 	memset(&params, 0, sizeof(params));
-	if (!stream)
+	if (!pipes)
 		return;
 	if (option > DITHER_OPTION_MAX)
 		return;
@@ -349,6 +360,36 @@ static void set_dither_option(struct dc_stream_state *stream,
 		opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
 }
 
+void set_dpms(
+	struct dc *dc,
+	struct dc_stream_state *stream,
+	bool dpms_off)
+{
+	struct pipe_ctx *pipe_ctx = NULL;
+	int i;
+
+	for (i = 0; i < MAX_PIPES; i++) {
+		if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
+			pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+			break;
+		}
+	}
+
+	if (!pipe_ctx) {
+		ASSERT(0);
+		return;
+	}
+
+	if (stream->dpms_off != dpms_off) {
+		stream->dpms_off = dpms_off;
+		if (dpms_off)
+			core_link_disable_stream(pipe_ctx,
+					KEEP_ACQUIRED_RESOURCE);
+		else
+			core_link_enable_stream(dc->current_state, pipe_ctx);
+	}
+}
+
 static void allocate_dc_stream_funcs(struct dc  *dc)
 {
 	if (dc->hwss.set_drr != NULL) {
@@ -371,6 +412,9 @@ static void allocate_dc_stream_funcs(struct dc  *dc)
 	dc->stream_funcs.set_dither_option =
 			set_dither_option;
 
+	dc->stream_funcs.set_dpms =
+			set_dpms;
+
 	dc->link_funcs.set_drive_settings =
 			set_drive_settings;
 
@@ -507,7 +551,7 @@ static bool construct(struct dc *dc,
 
 	dc_version = resource_parse_asic_id(init_params->asic_id);
 	dc->ctx->dce_version = dc_version;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr;
 #endif
 	/* Resource should construct all asic specific resources.
@@ -749,7 +793,7 @@ bool dc_enable_stereo(
  * Applies given context to HW and copy it into current context.
  * It's up to the user to release the src context afterwards.
  */
-static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
+static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
 {
 	struct dc_bios *dcb = dc->ctx->dc_bios;
 	enum dc_status result = DC_ERROR_UNEXPECTED;
@@ -763,41 +807,31 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
 	if (!dcb->funcs->is_accelerated_mode(dcb))
 		dc->hwss.enable_accelerated_mode(dc);
 
-	dc->hwss.ready_shared_resources(dc);
-
-	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		pipe = &context->res_ctx.pipe_ctx[i];
-		dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
-	}
-	result = dc->hwss.apply_ctx_to_hw(dc, context);
-
-	program_timing_sync(dc, context);
-
 	for (i = 0; i < context->stream_count; i++) {
 		const struct dc_sink *sink = context->streams[i]->sink;
 
-		for (j = 0; j < context->stream_status[i].plane_count; j++) {
-			dc->hwss.apply_ctx_for_surface(
-					dc, context->streams[i],
-					context->stream_status[i].plane_count,
-					context);
+		dc->hwss.apply_ctx_for_surface(
+				dc, context->streams[i],
+				context->stream_status[i].plane_count,
+				context);
 
-			/*
-			 * enable stereo
-			 * TODO rework dc_enable_stereo call to work with validation sets?
-			 */
-			for (k = 0; k < MAX_PIPES; k++) {
-				pipe = &context->res_ctx.pipe_ctx[k];
-
-				for (l = 0 ; pipe && l < context->stream_count; l++)  {
-					if (context->streams[l] &&
-					    context->streams[l] == pipe->stream &&
-					    dc->hwss.setup_stereo)
-						dc->hwss.setup_stereo(pipe, dc);
-				}
+		/*
+		 * enable stereo
+		 * TODO rework dc_enable_stereo call to work with validation sets?
+		 */
+		for (k = 0; k < MAX_PIPES; k++) {
+			pipe = &context->res_ctx.pipe_ctx[k];
+
+			for (l = 0 ; pipe && l < context->stream_count; l++)  {
+				if (context->streams[l] &&
+					context->streams[l] == pipe->stream &&
+					dc->hwss.setup_stereo)
+					dc->hwss.setup_stereo(pipe, dc);
 			}
 		}
 
+
+
 		CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
 				context->streams[i]->timing.h_addressable,
 				context->streams[i]->timing.v_addressable,
@@ -806,8 +840,27 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
 				context->streams[i]->timing.pix_clk_khz);
 	}
 
+	dc->hwss.ready_shared_resources(dc, context);
+
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		pipe = &context->res_ctx.pipe_ctx[i];
+		dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
+	}
+	result = dc->hwss.apply_ctx_to_hw(dc, context);
+
+	program_timing_sync(dc, context);
+
 	dc_enable_stereo(dc, context, dc_streams, context->stream_count);
 
+	for (i = 0; i < context->stream_count; i++) {
+		for (j = 0; j < MAX_PIPES; j++) {
+			pipe = &context->res_ctx.pipe_ctx[j];
+
+			if (!pipe->top_pipe && pipe->stream == context->streams[i])
+				dc->hwss.pipe_control_lock(dc, pipe, false);
+		}
+	}
+
 	dc_release_state(dc->current_state);
 
 	dc->current_state = context;
@@ -816,7 +869,7 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
 
 	dc->hwss.optimize_shared_resources(dc);
 
-	return (result == DC_OK);
+	return result;
 }
 
 bool dc_commit_state(struct dc *dc, struct dc_state *context)
@@ -865,16 +918,24 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
 	return true;
 }
 
+/*
+ * TODO this whole function needs to go
+ *
+ * dc_surface_update is needlessly complex. See if we can just replace this
+ * with a dc_plane_state and follow the atomic model a bit more closely here.
+ */
 bool dc_commit_planes_to_stream(
 		struct dc *dc,
 		struct dc_plane_state **plane_states,
 		uint8_t new_plane_count,
-		struct dc_stream_state *dc_stream)
+		struct dc_stream_state *dc_stream,
+		struct dc_state *state)
 {
+	/* no need to dynamically allocate this. it's pretty small */
 	struct dc_surface_update updates[MAX_SURFACES];
-	struct dc_flip_addrs flip_addr[MAX_SURFACES];
-	struct dc_plane_info plane_info[MAX_SURFACES];
-	struct dc_scaling_info scaling_info[MAX_SURFACES];
+	struct dc_flip_addrs *flip_addr;
+	struct dc_plane_info *plane_info;
+	struct dc_scaling_info *scaling_info;
 	int i;
 	struct dc_stream_update *stream_update =
 			kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
@@ -884,10 +945,14 @@ bool dc_commit_planes_to_stream(
 		return false;
 	}
 
+	flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs),
+			    GFP_KERNEL);
+	plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info),
+			     GFP_KERNEL);
+	scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info),
+			       GFP_KERNEL);
+
 	memset(updates, 0, sizeof(updates));
-	memset(flip_addr, 0, sizeof(flip_addr));
-	memset(plane_info, 0, sizeof(plane_info));
-	memset(scaling_info, 0, sizeof(scaling_info));
 
 	stream_update->src = dc_stream->src;
 	stream_update->dst = dc_stream->dst;
@@ -920,14 +985,15 @@ bool dc_commit_planes_to_stream(
 		updates[i].scaling_info = &scaling_info[i];
 	}
 
-	dc_update_planes_and_stream(
+	dc_commit_updates_for_stream(
 			dc,
 			updates,
 			new_plane_count,
-			dc_stream, stream_update);
-
-	dc_post_update_surfaces_to_stream(dc);
+			dc_stream, stream_update, plane_states, state);
 
+	kfree(flip_addr);
+	kfree(plane_info);
+	kfree(scaling_info);
 	kfree(stream_update);
 	return true;
 }
@@ -1030,7 +1096,6 @@ static enum surface_update_type get_plane_info_update_type(
 	temp_plane_info.plane_size = u->surface->plane_size;
 	temp_plane_info.rotation = u->surface->rotation;
 	temp_plane_info.stereo_format = u->surface->stereo_format;
-	temp_plane_info.tiling_info = u->surface->tiling_info;
 
 	if (surface_index == 0)
 		temp_plane_info.visible = u->plane_info->visible;
@@ -1043,10 +1108,26 @@ static enum surface_update_type get_plane_info_update_type(
 
 	if (pixel_format_to_bpp(u->plane_info->format) !=
 			pixel_format_to_bpp(u->surface->format)) {
+		/* different bytes per element will require full bandwidth
+		 * and DML calculation
+		 */
 		return UPDATE_TYPE_FULL;
-	} else {
-		return UPDATE_TYPE_MED;
 	}
+
+	if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
+			sizeof(union dc_tiling_info)) != 0) {
+		/* todo: below are HW dependent, we should add a hook to
+		 * DCE/N resource and validated there.
+		 */
+		if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
+			/* swizzled mode requires RQ to be setup properly,
+			 * thus need to run DML to calculate RQ settings
+			 */
+			return UPDATE_TYPE_FULL;
+		}
+	}
+
+	return UPDATE_TYPE_MED;
 }
 
 static enum surface_update_type  get_scaling_info_update_type(
@@ -1150,192 +1231,20 @@ static struct dc_stream_status *stream_get_status(
 
 static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
 
-void dc_update_planes_and_stream(struct dc *dc,
-		struct dc_surface_update *srf_updates, int surface_count,
+
+static void commit_planes_for_stream(struct dc *dc,
+		struct dc_surface_update *srf_updates,
+		int surface_count,
 		struct dc_stream_state *stream,
-		struct dc_stream_update *stream_update)
+		struct dc_stream_update *stream_update,
+		enum surface_update_type update_type,
+		struct dc_state *context)
 {
-	struct dc_state *context;
 	int i, j;
-	enum surface_update_type update_type;
-	const struct dc_stream_status *stream_status;
-	struct dc_context *dc_ctx = dc->ctx;
-
-	stream_status = dc_stream_get_status(stream);
-
-	ASSERT(stream_status);
-	if (!stream_status)
-		return; /* Cannot commit surface to stream that is not committed */
-
-#ifdef ENABLE_FBC
-	if (srf_updates->flip_addr) {
-		if (srf_updates->flip_addr->address.grph.addr.low_part == 0)
-			ASSERT(0);
-	}
-#endif
-	context = dc->current_state;
-
-	/* update current stream with the new updates */
-	if (stream_update) {
-		if ((stream_update->src.height != 0) &&
-				(stream_update->src.width != 0))
-			stream->src = stream_update->src;
-
-		if ((stream_update->dst.height != 0) &&
-				(stream_update->dst.width != 0))
-			stream->dst = stream_update->dst;
-
-		if (stream_update->out_transfer_func &&
-				stream_update->out_transfer_func !=
-						stream->out_transfer_func) {
-			if (stream->out_transfer_func != NULL)
-				dc_transfer_func_release(stream->out_transfer_func);
-			dc_transfer_func_retain(stream_update->out_transfer_func);
-			stream->out_transfer_func =
-				stream_update->out_transfer_func;
-		}
-	}
-
-	/* do not perform surface update if surface has invalid dimensions
-	 * (all zero) and no scaling_info is provided
-	 */
-	if (surface_count > 0 &&
-			srf_updates->surface->src_rect.width == 0 &&
-			srf_updates->surface->src_rect.height == 0 &&
-			srf_updates->surface->dst_rect.width == 0 &&
-			srf_updates->surface->dst_rect.height == 0 &&
-			!srf_updates->scaling_info) {
-		ASSERT(false);
-		return;
-	}
-
-	update_type = dc_check_update_surfaces_for_stream(
-			dc, srf_updates, surface_count, stream_update, stream_status);
-
-	if (update_type >= update_surface_trace_level)
-		update_surface_trace(dc, srf_updates, surface_count);
-
-	if (update_type >= UPDATE_TYPE_FULL) {
-		struct dc_plane_state *new_planes[MAX_SURFACES] = {0};
-
-		for (i = 0; i < surface_count; i++)
-			new_planes[i] = srf_updates[i].surface;
-
-		/* initialize scratch memory for building context */
-		context = dc_create_state();
-		if (context == NULL) {
-			DC_ERROR("Failed to allocate new validate context!\n");
-			return;
-		}
-
-		dc_resource_state_copy_construct(
-				dc->current_state, context);
-
-		/*remove old surfaces from context */
-		if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
-
-			BREAK_TO_DEBUGGER();
-			goto fail;
-		}
-
-		/* add surface to context */
-		if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
-
-			BREAK_TO_DEBUGGER();
-			goto fail;
-		}
-	}
-
-	/* save update parameters into surface */
-	for (i = 0; i < surface_count; i++) {
-		struct dc_plane_state *surface = srf_updates[i].surface;
-
-		if (srf_updates[i].flip_addr) {
-			surface->address = srf_updates[i].flip_addr->address;
-			surface->flip_immediate =
-					srf_updates[i].flip_addr->flip_immediate;
-		}
-
-		if (srf_updates[i].scaling_info) {
-			surface->scaling_quality =
-					srf_updates[i].scaling_info->scaling_quality;
-			surface->dst_rect =
-					srf_updates[i].scaling_info->dst_rect;
-			surface->src_rect =
-					srf_updates[i].scaling_info->src_rect;
-			surface->clip_rect =
-					srf_updates[i].scaling_info->clip_rect;
-		}
-
-		if (srf_updates[i].plane_info) {
-			surface->color_space =
-					srf_updates[i].plane_info->color_space;
-			surface->format =
-					srf_updates[i].plane_info->format;
-			surface->plane_size =
-					srf_updates[i].plane_info->plane_size;
-			surface->rotation =
-					srf_updates[i].plane_info->rotation;
-			surface->horizontal_mirror =
-					srf_updates[i].plane_info->horizontal_mirror;
-			surface->stereo_format =
-					srf_updates[i].plane_info->stereo_format;
-			surface->tiling_info =
-					srf_updates[i].plane_info->tiling_info;
-			surface->visible =
-					srf_updates[i].plane_info->visible;
-			surface->per_pixel_alpha =
-					srf_updates[i].plane_info->per_pixel_alpha;
-			surface->dcc =
-					srf_updates[i].plane_info->dcc;
-		}
-
-		if (update_type >= UPDATE_TYPE_MED) {
-			for (j = 0; j < dc->res_pool->pipe_count; j++) {
-				struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
-
-				if (pipe_ctx->plane_state != surface)
-					continue;
-
-				resource_build_scaling_params(pipe_ctx);
-			}
-		}
-
-		if (srf_updates[i].gamma &&
-			srf_updates[i].gamma != surface->gamma_correction) {
-			if (surface->gamma_correction != NULL)
-				dc_gamma_release(&surface->gamma_correction);
-
-			dc_gamma_retain(srf_updates[i].gamma);
-			surface->gamma_correction = srf_updates[i].gamma;
-		}
-
-		if (srf_updates[i].in_transfer_func &&
-			srf_updates[i].in_transfer_func != surface->in_transfer_func) {
-			if (surface->in_transfer_func != NULL)
-				dc_transfer_func_release(
-						surface->
-						in_transfer_func);
-
-			dc_transfer_func_retain(
-					srf_updates[i].in_transfer_func);
-			surface->in_transfer_func =
-					srf_updates[i].in_transfer_func;
-		}
-
-		if (srf_updates[i].hdr_static_metadata)
-			surface->hdr_static_ctx =
-				*(srf_updates[i].hdr_static_metadata);
-	}
 
 	if (update_type == UPDATE_TYPE_FULL) {
-		if (!dc->res_pool->funcs->validate_bandwidth(dc, context)) {
-			BREAK_TO_DEBUGGER();
-			goto fail;
-		} else {
-			dc->hwss.set_bandwidth(dc, context, false);
-			context_clock_trace(dc, context);
-		}
+		dc->hwss.set_bandwidth(dc, context, false);
+		context_clock_trace(dc, context);
 	}
 
 	if (update_type > UPDATE_TYPE_FAST) {
@@ -1346,8 +1255,14 @@ void dc_update_planes_and_stream(struct dc *dc,
 		}
 	}
 
-	if (surface_count == 0)
+	if (surface_count == 0) {
+		/*
+		 * In case of turning off screen, no need to program front end a second time.
+		 * just return after program front end.
+		 */
 		dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context);
+		return;
+	}
 
 	/* Lock pipes for provided surfaces, or all active if full update*/
 	for (i = 0; i < surface_count; i++) {
@@ -1373,10 +1288,6 @@ void dc_update_planes_and_stream(struct dc *dc,
 	/* Full fe update*/
 	for (j = 0; j < dc->res_pool->pipe_count; j++) {
 		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
-		struct pipe_ctx *cur_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[j];
-		bool is_new_pipe_surface = cur_pipe_ctx->plane_state != pipe_ctx->plane_state;
-		struct dc_cursor_position position = { 0 };
-
 
 		if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state)
 			continue;
@@ -1387,17 +1298,6 @@ void dc_update_planes_and_stream(struct dc *dc,
 			dc->hwss.apply_ctx_for_surface(
 					dc, pipe_ctx->stream, stream_status->plane_count, context);
 		}
-
-		/* TODO: this is a hack w/a for switching from mpo to pipe split */
-		dc_stream_set_cursor_position(pipe_ctx->stream, &position);
-
-		if (is_new_pipe_surface) {
-			dc->hwss.update_plane_addr(dc, pipe_ctx);
-			dc->hwss.set_input_transfer_func(
-					pipe_ctx, pipe_ctx->plane_state);
-			dc->hwss.set_output_transfer_func(
-					pipe_ctx, pipe_ctx->stream);
-		}
 	}
 
 	if (update_type > UPDATE_TYPE_FAST)
@@ -1423,7 +1323,9 @@ void dc_update_planes_and_stream(struct dc *dc,
 			if (update_type == UPDATE_TYPE_FAST)
 				continue;
 
-			if (srf_updates[i].in_transfer_func)
+			/* work around to program degamma regs for split pipe after set mode. */
+			if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe &&
+					pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state))
 				dc->hwss.set_input_transfer_func(
 						pipe_ctx, pipe_ctx->plane_state);
 
@@ -1459,16 +1361,79 @@ void dc_update_planes_and_stream(struct dc *dc,
 			break;
 		}
 	}
+}
 
-	if (dc->current_state != context) {
+void dc_commit_updates_for_stream(struct dc *dc,
+		struct dc_surface_update *srf_updates,
+		int surface_count,
+		struct dc_stream_state *stream,
+		struct dc_stream_update *stream_update,
+		struct dc_plane_state **plane_states,
+		struct dc_state *state)
+{
+	const struct dc_stream_status *stream_status;
+	enum surface_update_type update_type;
+	struct dc_state *context;
+	struct dc_context *dc_ctx = dc->ctx;
+	int i, j;
+
+	stream_status = dc_stream_get_status(stream);
+	context = dc->current_state;
+
+	update_type = dc_check_update_surfaces_for_stream(
+				dc, srf_updates, surface_count, stream_update, stream_status);
+
+	if (update_type >= update_surface_trace_level)
+		update_surface_trace(dc, srf_updates, surface_count);
+
+
+	if (update_type >= UPDATE_TYPE_FULL) {
+
+		/* initialize scratch memory for building context */
+		context = dc_create_state();
+		if (context == NULL) {
+			DC_ERROR("Failed to allocate new validate context!\n");
+			return;
+		}
+
+		dc_resource_state_copy_construct(state, context);
+	}
+
+
+	for (i = 0; i < surface_count; i++) {
+		struct dc_plane_state *surface = srf_updates[i].surface;
 
-		/* Since memory free requires elevated IRQL, an interrupt
-		 * request is generated by mem free. If this happens
-		 * between freeing and reassigning the context, our vsync
-		 * interrupt will call into dc and cause a memory
-		 * corruption BSOD. Hence, we first reassign the context,
-		 * then free the old context.
+		/* TODO: On flip we don't build the state, so it still has the
+		 * old address. Which is why we are updating the address here
 		 */
+		if (srf_updates[i].flip_addr)
+			surface->address = srf_updates[i].flip_addr->address;
+
+		if (update_type >= UPDATE_TYPE_MED) {
+			for (j = 0; j < dc->res_pool->pipe_count; j++) {
+				struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
+
+				if (pipe_ctx->plane_state != surface)
+					continue;
+
+				resource_build_scaling_params(pipe_ctx);
+			}
+		}
+	}
+
+	commit_planes_for_stream(
+				dc,
+				srf_updates,
+				surface_count,
+				stream,
+				stream_update,
+				update_type,
+				context);
+
+	if (update_type >= UPDATE_TYPE_FULL)
+		dc_post_update_surfaces_to_stream(dc);
+
+	if (dc->current_state != context) {
 
 		struct dc_state *old = dc->current_state;
 
@@ -1476,10 +1441,9 @@ void dc_update_planes_and_stream(struct dc *dc,
 		dc_release_state(old);
 
 	}
+
 	return;
 
-fail:
-	dc_release_state(context);
 }
 
 uint8_t dc_get_current_stream_count(struct dc *dc)

+ 39 - 19
drivers/gpu/drm/amd/display/dc/core/dc_link.c

@@ -45,6 +45,7 @@
 #include "dce/dce_11_0_enum.h"
 #include "dce/dce_11_0_sh_mask.h"
 
+#define EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK	0x007C /* Copied from atombios.h */
 #define LINK_INFO(...) \
 	dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \
 		__VA_ARGS__)
@@ -78,14 +79,15 @@ static void destruct(struct dc_link *link)
 		dc_sink_release(link->remote_sinks[i]);
 }
 
-static struct gpio *get_hpd_gpio(const struct dc_link *link)
+struct gpio *get_hpd_gpio(struct dc_bios *dcb,
+		struct graphics_object_id link_id,
+		struct gpio_service *gpio_service)
 {
 	enum bp_result bp_result;
-	struct dc_bios *dcb = link->ctx->dc_bios;
 	struct graphics_object_hpd_info hpd_info;
 	struct gpio_pin_info pin_info;
 
-	if (dcb->funcs->get_hpd_info(dcb, link->link_id, &hpd_info) != BP_RESULT_OK)
+	if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
 		return NULL;
 
 	bp_result = dcb->funcs->get_gpio_pin_info(dcb,
@@ -97,7 +99,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link)
 	}
 
 	return dal_gpio_service_create_irq(
-		link->ctx->gpio_service,
+		gpio_service,
 		pin_info.offset,
 		pin_info.mask);
 }
@@ -153,7 +155,7 @@ static bool program_hpd_filter(
 	}
 
 	/* Obtain HPD handle */
-	hpd = get_hpd_gpio(link);
+	hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
 
 	if (!hpd)
 		return result;
@@ -186,7 +188,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
 	struct gpio *hpd_pin;
 
 	/* todo: may need to lock gpio access */
-	hpd_pin = get_hpd_gpio(link);
+	hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
 	if (hpd_pin == NULL)
 		goto hpd_gpio_failure;
 
@@ -496,6 +498,7 @@ static void detect_dp(
 		}
 		if (is_mst_supported(link)) {
 			sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
+			link->type = dc_connection_mst_branch;
 
 			/*
 			 * This call will initiate MST topology discovery. Which
@@ -524,12 +527,11 @@ static void detect_dp(
 			if (reason == DETECT_REASON_BOOT)
 				boot = true;
 
-			if (dm_helpers_dp_mst_start_top_mgr(
+			if (!dm_helpers_dp_mst_start_top_mgr(
 				link->ctx,
 				link, boot)) {
-				link->type = dc_connection_mst_branch;
-			} else {
 				/* MST not supported */
+				link->type = dc_connection_single;
 				sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
 			}
 		}
@@ -638,8 +640,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 		if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
 			link->dpcd_sink_count = link->dpcd_caps.sink_count.
 					bits.SINK_COUNT;
-			else
-				link->dpcd_sink_count = 1;
+		else
+			link->dpcd_sink_count = 1;
 
 		dal_ddc_service_set_transaction_type(
 						link->ddc,
@@ -746,6 +748,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 		if (link->type == dc_connection_mst_branch) {
 			LINK_INFO("link=%d, mst branch is now Disconnected\n",
 				link->link_index);
+
 			dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
 
 			link->mst_stream_alloc_table.stream_count = 0;
@@ -770,7 +773,7 @@ static enum hpd_source_id get_hpd_line(
 	struct gpio *hpd;
 	enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
 
-	hpd = get_hpd_gpio(link);
+	hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
 
 	if (hpd) {
 		switch (dal_irq_get_source(hpd)) {
@@ -940,7 +943,7 @@ static bool construct(
 		goto create_fail;
 	}
 
-	hpd_gpio = get_hpd_gpio(link);
+	hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
 
 	if (hpd_gpio != NULL)
 		link->irq_source_hpd = dal_irq_get_source(hpd_gpio);
@@ -1343,7 +1346,18 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
 					sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
 			result = true;
 			break;
-
+		case ENGINE_ID_DIGD:
+			settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
+			settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
+			settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
+			memmove(settings->reg_settings,
+					integrated_info->dp3_ext_hdmi_reg_settings,
+					sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
+			memmove(settings->reg_settings_6g,
+					integrated_info->dp3_ext_hdmi_6g_reg_settings,
+					sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
+			result = true;
+			break;
 		default:
 			break;
 		}
@@ -1680,7 +1694,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
 		is_over_340mhz = true;
 
 	if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
-		if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) {
+		unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
+				EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
+		if (masked_chip_caps == (0x2 << 2)) {
 			/* DP159, Retimer settings */
 			eng_id = pipe_ctx->stream_res.stream_enc->id;
 
@@ -1691,7 +1707,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
 				write_i2c_default_retimer_setting(pipe_ctx,
 						is_vga_mode, is_over_340mhz);
 			}
-		} else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) {
+		} else if (masked_chip_caps == (0x1 << 2)) {
 			/* PI3EQX1204, Redriver settings */
 			write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
 		}
@@ -1782,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
 		else
 			dp_disable_link_phy_mst(link, signal);
 	} else
-		link->link_enc->funcs->disable_output(link->link_enc, signal);
+		link->link_enc->funcs->disable_output(link->link_enc, signal, link);
 }
 
 enum dc_status dc_link_validate_mode_timing(
@@ -2319,16 +2335,20 @@ void core_link_enable_stream(
 
 	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
 		allocate_mst_payload(pipe_ctx);
+
+	if (dc_is_dp_signal(pipe_ctx->stream->signal))
+		core_dc->hwss.unblank_stream(pipe_ctx,
+			&pipe_ctx->stream->sink->link->cur_link_settings);
 }
 
-void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
+void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
 {
 	struct dc  *core_dc = pipe_ctx->stream->ctx->dc;
 
 	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
 		deallocate_mst_payload(pipe_ctx);
 
-	core_dc->hwss.disable_stream(pipe_ctx);
+	core_dc->hwss.disable_stream(pipe_ctx, option);
 
 	disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
 }

+ 14 - 2
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c

@@ -1700,6 +1700,12 @@ static void dp_test_send_link_training(struct dc_link *link)
 	dp_retrain_link_dp_test(link, &link_settings, false);
 }
 
+/* TODO hbr2 compliance eye output is unstable
+ * (toggling on and off) with debugger break
+ * This caueses intermittent PHY automation failure
+ * Need to look into the root cause */
+static uint8_t force_tps4_for_cp2520 = 1;
+
 static void dp_test_send_phy_test_pattern(struct dc_link *link)
 {
 	union phy_test_pattern dpcd_test_pattern;
@@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
 		test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
 		break;
 	case PHY_TEST_PATTERN_CP2520_1:
-		test_pattern = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
+		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
+		test_pattern = (force_tps4_for_cp2520 == 1) ?
+				DP_TEST_PATTERN_TRAINING_PATTERN4 :
+				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
 		break;
 	case PHY_TEST_PATTERN_CP2520_2:
-		test_pattern = DP_TEST_PATTERN_CP2520_2;
+		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
+		test_pattern = (force_tps4_for_cp2520 == 1) ?
+				DP_TEST_PATTERN_TRAINING_PATTERN4 :
+				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
 		break;
 	case PHY_TEST_PATTERN_CP2520_3:
 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;

+ 9 - 8
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c

@@ -89,12 +89,12 @@ void dp_enable_link_phy(
 
 	if (dc_is_dp_sst_signal(signal)) {
 		if (signal == SIGNAL_TYPE_EDP) {
-			link_enc->funcs->power_control(link_enc, true);
+			link->dc->hwss.edp_power_control(link->link_enc, true);
 			link_enc->funcs->enable_dp_output(
 						link_enc,
 						link_settings,
 						clock_source);
-			link_enc->funcs->backlight_control(link_enc, true);
+			link->dc->hwss.edp_backlight_control(link, true);
 		} else
 			link_enc->funcs->enable_dp_output(
 						link_enc,
@@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
 		dp_receiver_power_ctrl(link, false);
 
 	if (signal == SIGNAL_TYPE_EDP) {
-		link->link_enc->funcs->backlight_control(link->link_enc, false);
+		link->dc->hwss.edp_backlight_control(link, false);
 		edp_receiver_ready_T9(link);
-		link->link_enc->funcs->disable_output(link->link_enc, signal);
-		link->link_enc->funcs->power_control(link->link_enc, false);
+		link->link_enc->funcs->disable_output(link->link_enc, signal, link);
+		link->dc->hwss.edp_power_control(link->link_enc, false);
 	} else
-		link->link_enc->funcs->disable_output(link->link_enc, signal);
+		link->link_enc->funcs->disable_output(link->link_enc, signal, link);
 
 	/* Clear current link setting.*/
 	memset(&link->cur_link_settings, 0,
@@ -282,11 +282,12 @@ void dp_retrain_link_dp_test(struct dc_link *link,
 
 			dp_receiver_power_ctrl(link, false);
 
-			link->dc->hwss.disable_stream(&pipes[i]);
+			link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
 
 			link->link_enc->funcs->disable_output(
 					link->link_enc,
-					SIGNAL_TYPE_DISPLAY_PORT);
+					SIGNAL_TYPE_DISPLAY_PORT,
+					link);
 
 			/* Clear current link setting. */
 			memset(&link->cur_link_settings, 0,

+ 77 - 34
drivers/gpu/drm/amd/display/dc/core/dc_resource.c

@@ -31,6 +31,7 @@
 #include "opp.h"
 #include "timing_generator.h"
 #include "transform.h"
+#include "dpp.h"
 #include "core_types.h"
 #include "set_mode_types.h"
 #include "virtual/virtual_stream_encoder.h"
@@ -242,7 +243,10 @@ bool resource_construct(
 			pool->stream_enc_count++;
 		}
 	}
-
+	dc->caps.dynamic_audio = false;
+	if (pool->audio_count < pool->stream_enc_count) {
+		dc->caps.dynamic_audio = true;
+	}
 	for (i = 0; i < num_virtual_links; i++) {
 		pool->stream_enc[pool->stream_enc_count] =
 			virtual_stream_encoder_create(
@@ -846,12 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 	 */
 	pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
 
-	pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable;
-	pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable;
+	pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
+	pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
+
+	pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
+	pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
 
 	/* Taps calculations */
-	res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
-		pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+	if (pipe_ctx->plane_res.xfm != NULL)
+		res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
+				pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+	if (pipe_ctx->plane_res.dpp != NULL)
+		res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
+				pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
 
 	if (!res) {
 		/* Try 24 bpp linebuffer */
@@ -859,6 +871,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 
 		res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
 			pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+		res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
+			pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
 	}
 
 	if (res)
@@ -1021,9 +1036,9 @@ static int acquire_first_split_pipe(
 
 			memset(pipe_ctx, 0, sizeof(*pipe_ctx));
 			pipe_ctx->stream_res.tg = pool->timing_generators[i];
-			pipe_ctx->plane_res.mi = pool->mis[i];
+			pipe_ctx->plane_res.hubp = pool->hubps[i];
 			pipe_ctx->plane_res.ipp = pool->ipps[i];
-			pipe_ctx->plane_res.xfm = pool->transforms[i];
+			pipe_ctx->plane_res.dpp = pool->dpps[i];
 			pipe_ctx->stream_res.opp = pool->opps[i];
 			pipe_ctx->pipe_idx = i;
 
@@ -1070,9 +1085,6 @@ bool dc_add_plane_to_context(
 		return false;
 	}
 
-	/* retain new surfaces */
-	dc_plane_state_retain(plane_state);
-
 	free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
 
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
@@ -1082,11 +1094,11 @@ bool dc_add_plane_to_context(
 			free_pipe = &context->res_ctx.pipe_ctx[pipe_idx];
 	}
 #endif
-	if (!free_pipe) {
-		stream_status->plane_states[i] = NULL;
+	if (!free_pipe)
 		return false;
-	}
 
+	/* retain new surfaces */
+	dc_plane_state_retain(plane_state);
 	free_pipe->plane_state = plane_state;
 
 	if (head_pipe != free_pipe) {
@@ -1178,8 +1190,8 @@ bool dc_remove_plane_from_context(
 
 	stream_status->plane_count--;
 
-	/* Trim back arrays */
-	for (i = 0; i < stream_status->plane_count; i++)
+	/* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */
+	for (; i < stream_status->plane_count; i++)
 		stream_status->plane_states[i] = stream_status->plane_states[i + 1];
 
 	stream_status->plane_states[stream_status->plane_count] = NULL;
@@ -1312,6 +1324,28 @@ bool dc_is_stream_unchanged(
 	return true;
 }
 
+bool dc_is_stream_scaling_unchanged(
+	struct dc_stream_state *old_stream, struct dc_stream_state *stream)
+{
+	if (old_stream == stream)
+		return true;
+
+	if (old_stream == NULL || stream == NULL)
+		return false;
+
+	if (memcmp(&old_stream->src,
+			&stream->src,
+			sizeof(struct rect)) != 0)
+		return false;
+
+	if (memcmp(&old_stream->dst,
+			&stream->dst,
+			sizeof(struct rect)) != 0)
+		return false;
+
+	return true;
+}
+
 /* Maximum TMDS single link pixel clock 165MHz */
 #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
 
@@ -1330,7 +1364,7 @@ static void update_stream_engine_usage(
 }
 
 /* TODO: release audio object */
-static void update_audio_usage(
+void update_audio_usage(
 		struct resource_context *res_ctx,
 		const struct resource_pool *pool,
 		struct audio *audio,
@@ -1356,8 +1390,10 @@ static int acquire_first_free_pipe(
 
 			pipe_ctx->stream_res.tg = pool->timing_generators[i];
 			pipe_ctx->plane_res.mi = pool->mis[i];
+			pipe_ctx->plane_res.hubp = pool->hubps[i];
 			pipe_ctx->plane_res.ipp = pool->ipps[i];
 			pipe_ctx->plane_res.xfm = pool->transforms[i];
+			pipe_ctx->plane_res.dpp = pool->dpps[i];
 			pipe_ctx->stream_res.opp = pool->opps[i];
 			pipe_ctx->pipe_idx = i;
 
@@ -1414,12 +1450,17 @@ static struct audio *find_first_free_audio(
 		const struct resource_pool *pool)
 {
 	int i;
+	for (i = 0; i < pool->audio_count; i++) {
+		if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {
+			return pool->audios[i];
+		}
+	}
+	/*not found the matching one, first come first serve*/
 	for (i = 0; i < pool->audio_count; i++) {
 		if (res_ctx->is_audio_acquired[i] == false) {
 			return pool->audios[i];
 		}
 	}
-
 	return 0;
 }
 
@@ -1438,7 +1479,7 @@ bool resource_is_stream_unchanged(
 	return false;
 }
 
-bool dc_add_stream_to_ctx(
+enum dc_status dc_add_stream_to_ctx(
 		struct dc *dc,
 		struct dc_state *new_ctx,
 		struct dc_stream_state *stream)
@@ -1459,10 +1500,10 @@ bool dc_add_stream_to_ctx(
 	if (res != DC_OK)
 		DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res);
 
-	return res == DC_OK;
+	return res;
 }
 
-bool dc_remove_stream_from_ctx(
+enum dc_status dc_remove_stream_from_ctx(
 			struct dc *dc,
 			struct dc_state *new_ctx,
 			struct dc_stream_state *stream)
@@ -1632,10 +1673,11 @@ enum dc_status resource_map_pool_resources(
 	/* acquire new resources */
 	pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
 
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
 	if (pipe_idx < 0)
-		acquire_first_split_pipe(&context->res_ctx, pool, stream);
+		pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
 #endif
+
 	if (pipe_idx < 0)
 		return DC_NO_CONTROLLER_RESOURCE;
 
@@ -1716,17 +1758,18 @@ void dc_resource_state_construct(
 	dst_ctx->dis_clk = dc->res_pool->display_clock;
 }
 
-bool dc_validate_global_state(
+enum dc_status dc_validate_global_state(
 		struct dc *dc,
 		struct dc_state *new_ctx)
 {
 	enum dc_status result = DC_ERROR_UNEXPECTED;
 	int i, j;
 
-	if (dc->res_pool->funcs->validate_global &&
-			dc->res_pool->funcs->validate_global(
-			dc, new_ctx) != DC_OK)
-		return false;
+	if (dc->res_pool->funcs->validate_global) {
+			result = dc->res_pool->funcs->validate_global(dc, new_ctx);
+			if (result != DC_OK)
+				return result;
+	}
 
 	for (i = 0; new_ctx && i < new_ctx->stream_count; i++) {
 		struct dc_stream_state *stream = new_ctx->streams[i];
@@ -2713,7 +2756,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
 	fmt_bit_depth->pixel_encoding = pixel_encoding;
 }
 
-bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
+enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
 {
 	struct dc  *core_dc = dc;
 	struct dc_link *link = stream->sink->link;
@@ -2737,16 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
 		      link,
 		      &stream->timing);
 
-	return res == DC_OK;
+	return res;
 }
 
-bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
+enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
 {
-	struct dc *core_dc = dc;
+	enum dc_status res = DC_OK;
 
 	/* TODO For now validates pixel format only */
-	if (core_dc->res_pool->funcs->validate_plane)
-		return core_dc->res_pool->funcs->validate_plane(plane_state) == DC_OK;
+	if (dc->res_pool->funcs->validate_plane)
+		return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
 
-	return true;
+	return res;
 }

+ 57 - 6
drivers/gpu/drm/amd/display/dc/core/dc_stream.c

@@ -173,7 +173,7 @@ struct dc_stream_status *dc_stream_get_status(
  * Update the cursor attributes and set cursor surface address
  */
 bool dc_stream_set_cursor_attributes(
-	const struct dc_stream_state *stream,
+	struct dc_stream_state *stream,
 	const struct dc_cursor_attributes *attributes)
 {
 	int i;
@@ -189,21 +189,51 @@ bool dc_stream_set_cursor_attributes(
 			return false;
 	}
 
+	if (attributes->address.quad_part == 0) {
+		dm_output_to_console("DC: Cursor address is 0!\n");
+		return false;
+	}
+
 	core_dc = stream->ctx->dc;
 	res_ctx = &core_dc->current_state->res_ctx;
 
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 
-		if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp)
+		if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
 			continue;
 		if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
 			continue;
 
-		pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
-				pipe_ctx->plane_res.ipp, attributes);
+
+		if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
+			pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
+						pipe_ctx->plane_res.ipp, attributes);
+
+		if (pipe_ctx->plane_res.hubp != NULL &&
+				pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
+			pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+					pipe_ctx->plane_res.hubp, attributes);
+
+		if (pipe_ctx->plane_res.mi != NULL &&
+				pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
+			pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
+					pipe_ctx->plane_res.mi, attributes);
+
+
+		if (pipe_ctx->plane_res.xfm != NULL &&
+				pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
+			pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
+				pipe_ctx->plane_res.xfm, attributes);
+
+		if (pipe_ctx->plane_res.dpp != NULL &&
+				pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
+			pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+				pipe_ctx->plane_res.dpp, attributes);
 	}
 
+	stream->cursor_attributes = *attributes;
+
 	return true;
 }
 
@@ -231,6 +261,10 @@ bool dc_stream_set_cursor_position(
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 		struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+		struct mem_input *mi = pipe_ctx->plane_res.mi;
+		struct hubp *hubp = pipe_ctx->plane_res.hubp;
+		struct transform *xfm = pipe_ctx->plane_res.xfm;
+		struct dpp *dpp = pipe_ctx->plane_res.dpp;
 		struct dc_cursor_position pos_cpy = *position;
 		struct dc_cursor_mi_param param = {
 			.pixel_clk_khz = stream->timing.pix_clk_khz,
@@ -241,7 +275,9 @@ bool dc_stream_set_cursor_position(
 		};
 
 		if (pipe_ctx->stream != stream ||
-				!pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state)
+				(!pipe_ctx->plane_res.mi  && !pipe_ctx->plane_res.hubp) ||
+				!pipe_ctx->plane_state ||
+				(!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
 			continue;
 
 		if (pipe_ctx->plane_state->address.type
@@ -251,7 +287,22 @@ bool dc_stream_set_cursor_position(
 		if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
 			pos_cpy.enable = false;
 
-		ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+
+		if (ipp->funcs->ipp_cursor_set_position != NULL)
+			ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+
+		if (mi != NULL && mi->funcs->set_cursor_position != NULL)
+			mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+
+		if (hubp != NULL && hubp->funcs->set_cursor_position != NULL)
+			hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+
+		if (xfm != NULL && xfm->funcs->set_cursor_position != NULL)
+			xfm->funcs->set_cursor_position(xfm, &pos_cpy, &param, hubp->curs_attr.width);
+
+		if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
+			dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
+
 	}
 
 	return true;

+ 1 - 0
drivers/gpu/drm/amd/display/dc/core/dc_surface.c

@@ -30,6 +30,7 @@
 /* DC core (private) */
 #include "core_types.h"
 #include "transform.h"
+#include "dpp.h"
 
 /*******************************************************************************
  * Private functions

+ 103 - 38
drivers/gpu/drm/amd/display/dc/dc.h

@@ -38,7 +38,7 @@
 #include "inc/compressor.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.1.01"
+#define DC_VER "3.1.07"
 
 #define MAX_SURFACES 3
 #define MAX_STREAMS 6
@@ -56,11 +56,12 @@ struct dc_caps {
 	uint32_t max_planes;
 	uint32_t max_downscale_ratio;
 	uint32_t i2c_speed_in_khz;
-
 	unsigned int max_cursor_size;
+	unsigned int max_video_width;
+	bool dcc_const_color;
+	bool dynamic_audio;
 };
 
-
 struct dc_dcc_surface_param {
 	struct dc_size surface_size;
 	enum surface_pixel_format format;
@@ -132,6 +133,10 @@ struct dc_stream_state_funcs {
 
 	void (*set_dither_option)(struct dc_stream_state *stream,
 			enum dc_dither_option option);
+
+	void (*set_dpms)(struct dc *dc,
+			struct dc_stream_state *stream,
+			bool dpms_off);
 };
 
 struct link_training_settings;
@@ -162,6 +167,23 @@ struct dc_config {
 	bool disable_disp_pll_sharing;
 };
 
+enum dcc_option {
+	DCC_ENABLE = 0,
+	DCC_DISABLE = 1,
+	DCC_HALF_REQ_DISALBE = 2,
+};
+
+enum pipe_split_policy {
+	MPC_SPLIT_DYNAMIC = 0,
+	MPC_SPLIT_AVOID = 1,
+	MPC_SPLIT_AVOID_MULT_DISP = 2,
+};
+
+enum wm_report_mode {
+	WM_REPORT_DEFAULT = 0,
+	WM_REPORT_OVERRIDE = 1,
+};
+
 struct dc_debug {
 	bool surface_visual_confirm;
 	bool sanity_checks;
@@ -170,14 +192,21 @@ struct dc_debug {
 	bool timing_trace;
 	bool clock_trace;
 	bool validation_trace;
+
+	/* stutter efficiency related */
 	bool disable_stutter;
-	bool disable_dcc;
+	bool use_max_lb;
+	enum dcc_option disable_dcc;
+	enum pipe_split_policy pipe_split_policy;
+	bool force_single_disp_pipe_split;
+	bool voltage_align_fclk;
+
 	bool disable_dfs_bypass;
 	bool disable_dpp_power_gate;
 	bool disable_hubp_power_gate;
 	bool disable_pplib_wm_range;
-	bool use_dml_wm;
-	bool disable_pipe_split;
+	enum wm_report_mode pplib_wm_report_mode;
+	unsigned int min_disp_clk_khz;
 	int sr_exit_time_dpm0_ns;
 	int sr_enter_plus_exit_time_dpm0_ns;
 	int sr_exit_time_ns;
@@ -191,6 +220,11 @@ struct dc_debug {
 	bool disable_dmcu;
 	bool disable_psr;
 	bool force_abm_enable;
+	bool disable_hbup_pg;
+	bool disable_dpp_pg;
+	bool disable_stereo_support;
+	bool vsr_support;
+	bool performance_trace;
 };
 struct dc_state;
 struct resource_pool;
@@ -233,7 +267,7 @@ struct dc {
 	struct dm_pp_display_configuration prev_display_config;
 
 	/* FBC compressor */
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	struct compressor *fbc_compressor;
 #endif
 };
@@ -268,7 +302,7 @@ struct dc_init_data {
 
 	struct dc_config flags;
 	uint32_t log_mask;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	uint64_t fbc_gpu_addr;
 #endif
 };
@@ -285,6 +319,38 @@ enum {
 	TRANSFER_FUNC_POINTS = 1025
 };
 
+// Moved here from color module for linux
+enum color_transfer_func {
+	transfer_func_unknown,
+	transfer_func_srgb,
+	transfer_func_bt709,
+	transfer_func_pq2084,
+	transfer_func_pq2084_interim,
+	transfer_func_linear_0_1,
+	transfer_func_linear_0_125,
+	transfer_func_dolbyvision,
+	transfer_func_gamma_22,
+	transfer_func_gamma_26
+};
+
+enum color_color_space {
+	color_space_unsupported,
+	color_space_srgb,
+	color_space_bt601,
+	color_space_bt709,
+	color_space_xv_ycc_bt601,
+	color_space_xv_ycc_bt709,
+	color_space_xr_rgb,
+	color_space_bt2020,
+	color_space_adobe,
+	color_space_dci_p3,
+	color_space_sc_rgb_ms_ref,
+	color_space_display_native,
+	color_space_app_ctrl,
+	color_space_dolby_vision,
+	color_space_custom_coordinates
+};
+
 struct dc_hdr_static_metadata {
 	/* display chromaticities and white point in units of 0.00001 */
 	unsigned int chromaticity_green_x;
@@ -365,6 +431,12 @@ struct dc_plane_state {
 	struct dc_gamma *gamma_correction;
 	struct dc_transfer_func *in_transfer_func;
 
+	// sourceContentAttribute cache
+	bool is_source_input_valid;
+	struct dc_hdr_static_metadata source_input_mastering_info;
+	enum color_color_space source_input_color_space;
+	enum color_transfer_func source_input_tf;
+
 	enum dc_color_space color_space;
 	enum surface_pixel_format format;
 	enum dc_rotation_angle rotation;
@@ -449,23 +521,6 @@ struct dc_flip_addrs {
 	/* TODO: add flip duration for FreeSync */
 };
 
-/*
- * Set up surface attributes and associate to a stream
- * The surfaces parameter is an absolute set of all surface active for the stream.
- * If no surfaces are provided, the stream will be blanked; no memory read.
- * Any flip related attribute changes must be done through this interface.
- *
- * After this call:
- *   Surfaces attributes are programmed and configured to be composed into stream.
- *   This does not trigger a flip.  No surface address is programmed.
- */
-
-bool dc_commit_planes_to_stream(
-		struct dc *dc,
-		struct dc_plane_state **plane_states,
-		uint8_t new_plane_count,
-		struct dc_stream_state *stream);
-
 bool dc_post_update_surfaces_to_stream(
 		struct dc *dc);
 
@@ -554,9 +609,12 @@ struct dc_stream_state {
 
 	int phy_pix_clk;
 	enum signal_type signal;
+	bool dpms_off;
 
 	struct dc_stream_status status;
 
+	struct dc_cursor_attributes cursor_attributes;
+
 	/* from stream struct */
 	struct kref refcount;
 };
@@ -569,11 +627,10 @@ struct dc_stream_update {
 
 bool dc_is_stream_unchanged(
 	struct dc_stream_state *old_stream, struct dc_stream_state *stream);
+bool dc_is_stream_scaling_unchanged(
+	struct dc_stream_state *old_stream, struct dc_stream_state *stream);
 
 /*
- * Setup stream attributes if no stream updates are provided
- * there will be no impact on the stream parameters
- *
  * Set up surface attributes and associate to a stream
  * The surfaces parameter is an absolute set of all surface active for the stream.
  * If no surfaces are provided, the stream will be blanked; no memory read.
@@ -582,14 +639,22 @@ bool dc_is_stream_unchanged(
  * After this call:
  *   Surfaces attributes are programmed and configured to be composed into stream.
  *   This does not trigger a flip.  No surface address is programmed.
- *
  */
 
-void dc_update_planes_and_stream(struct dc *dc,
-		struct dc_surface_update *surface_updates, int surface_count,
+bool dc_commit_planes_to_stream(
+		struct dc *dc,
+		struct dc_plane_state **plane_states,
+		uint8_t new_plane_count,
 		struct dc_stream_state *dc_stream,
-		struct dc_stream_update *stream_update);
+		struct dc_state *state);
 
+void dc_commit_updates_for_stream(struct dc *dc,
+		struct dc_surface_update *srf_updates,
+		int surface_count,
+		struct dc_stream_state *stream,
+		struct dc_stream_update *stream_update,
+		struct dc_plane_state **plane_states,
+		struct dc_state *state);
 /*
  * Log the current stream state.
  */
@@ -616,12 +681,12 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
 				  uint32_t *h_position,
 				  uint32_t *v_position);
 
-bool dc_add_stream_to_ctx(
+enum dc_status dc_add_stream_to_ctx(
 			struct dc *dc,
 		struct dc_state *new_ctx,
 		struct dc_stream_state *stream);
 
-bool dc_remove_stream_from_ctx(
+enum dc_status dc_remove_stream_from_ctx(
 		struct dc *dc,
 			struct dc_state *new_ctx,
 			struct dc_stream_state *stream);
@@ -660,11 +725,11 @@ struct dc_validation_set {
 	uint8_t plane_count;
 };
 
-bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
+enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
 
-bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
+enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
 
-bool dc_validate_global_state(
+enum dc_status dc_validate_global_state(
 		struct dc *dc,
 		struct dc_state *new_ctx);
 
@@ -991,7 +1056,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
  ******************************************************************************/
 /* TODO: Deprecated once we switch to dc_set_cursor_position */
 bool dc_stream_set_cursor_attributes(
-	const struct dc_stream_state *stream,
+	struct dc_stream_state *stream,
 	const struct dc_cursor_attributes *attributes);
 
 bool dc_stream_set_cursor_position(

+ 2 - 0
drivers/gpu/drm/amd/display/dc/dc_hw_types.h

@@ -204,6 +204,8 @@ enum surface_pixel_format {
 	/*grow 444 video here if necessary */
 };
 
+
+
 /* Pixel format */
 enum pixel_format {
 	/*graph*/

+ 2 - 1
drivers/gpu/drm/amd/display/dc/dc_types.h

@@ -92,7 +92,7 @@ struct dc_context {
 	bool created_bios;
 	struct gpio_service *gpio_service;
 	struct i2caux *i2caux;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	uint64_t fbc_gpu_addr;
 #endif
 };
@@ -151,6 +151,7 @@ enum dc_edid_status {
 	EDID_BAD_INPUT,
 	EDID_NO_RESPONSE,
 	EDID_BAD_CHECKSUM,
+	EDID_THE_SAME,
 };
 
 /* audio capability from EDID*/

+ 106 - 69
drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h

@@ -27,6 +27,10 @@
 
 #include "hw_sequencer.h"
 
+#define BL_REG_LIST()\
+	SR(LVTMA_PWRSEQ_CNTL), \
+	SR(LVTMA_PWRSEQ_STATE)
+
 #define HWSEQ_DCEF_REG_LIST_DCE8() \
 	.DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
 	.DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \
@@ -86,24 +90,27 @@
 	SRII(BLND_CONTROL, BLND, 0),\
 	SRII(BLND_CONTROL, BLND, 1),\
 	SR(BLNDV_CONTROL),\
-	HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+	HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
+	BL_REG_LIST()
 
 #define HWSEQ_DCE8_REG_LIST() \
 	HWSEQ_DCEF_REG_LIST_DCE8(), \
 	HWSEQ_BLND_REG_LIST(), \
-	HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+	HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
+	BL_REG_LIST()
 
 #define HWSEQ_DCE10_REG_LIST() \
 	HWSEQ_DCEF_REG_LIST(), \
 	HWSEQ_BLND_REG_LIST(), \
-	HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+	HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
+	BL_REG_LIST()
 
 #define HWSEQ_ST_REG_LIST() \
 	HWSEQ_DCE11_REG_LIST_BASE(), \
 	.DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
 	.CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
 	.BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
-	.BLND_CONTROL[2] = mmBLNDV_CONTROL,
+	.BLND_CONTROL[2] = mmBLNDV_CONTROL
 
 #define HWSEQ_CZ_REG_LIST() \
 	HWSEQ_DCE11_REG_LIST_BASE(), \
@@ -123,16 +130,16 @@
 	SR(DCHUB_FB_LOCATION),\
 	SR(DCHUB_AGP_BASE),\
 	SR(DCHUB_AGP_BOT),\
-	SR(DCHUB_AGP_TOP)
+	SR(DCHUB_AGP_TOP), \
+	BL_REG_LIST()
 
 #define HWSEQ_DCE112_REG_LIST() \
 	HWSEQ_DCE10_REG_LIST(), \
 	HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
-	HWSEQ_PHYPLL_REG_LIST(CRTC)
+	HWSEQ_PHYPLL_REG_LIST(CRTC), \
+	BL_REG_LIST()
 
 #define HWSEQ_DCN_REG_LIST()\
-	HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
-	HWSEQ_PHYPLL_REG_LIST(OTG), \
 	SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \
 	SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 1), \
 	SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 2), \
@@ -156,23 +163,15 @@
 	SR(REFCLK_CNTL), \
 	SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
 	SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
 	SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\
 	SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\
 	SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
 	SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\
 	SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
 	SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
 	SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\
 	SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\
 	SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
-	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\
 	SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\
 	SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
 	SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
@@ -181,32 +180,11 @@
 	SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
 	SR(DCHUBBUB_TEST_DEBUG_INDEX), \
 	SR(DCHUBBUB_TEST_DEBUG_DATA), \
-	SR(DC_IP_REQUEST_CNTL), \
-	SR(DOMAIN0_PG_CONFIG), \
-	SR(DOMAIN1_PG_CONFIG), \
-	SR(DOMAIN2_PG_CONFIG), \
-	SR(DOMAIN3_PG_CONFIG), \
-	SR(DOMAIN4_PG_CONFIG), \
-	SR(DOMAIN5_PG_CONFIG), \
-	SR(DOMAIN6_PG_CONFIG), \
-	SR(DOMAIN7_PG_CONFIG), \
-	SR(DOMAIN0_PG_STATUS), \
-	SR(DOMAIN1_PG_STATUS), \
-	SR(DOMAIN2_PG_STATUS), \
-	SR(DOMAIN3_PG_STATUS), \
-	SR(DOMAIN4_PG_STATUS), \
-	SR(DOMAIN5_PG_STATUS), \
-	SR(DOMAIN6_PG_STATUS), \
-	SR(DOMAIN7_PG_STATUS), \
 	SR(DIO_MEM_PWR_CTRL), \
 	SR(DCCG_GATE_DISABLE_CNTL), \
 	SR(DCCG_GATE_DISABLE_CNTL2), \
 	SR(DCFCLK_CNTL),\
 	SR(DCFCLK_CNTL), \
-	SR(D1VGA_CONTROL), \
-	SR(D2VGA_CONTROL), \
-	SR(D3VGA_CONTROL), \
-	SR(D4VGA_CONTROL), \
 	/* todo:  get these from GVM instead of reading registers ourselves */\
 	MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
 	MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
@@ -221,17 +199,56 @@
 	MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
 	MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
 
+#define HWSEQ_SR_WATERMARK_REG_LIST()\
+	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
+	SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D)
+
 #define HWSEQ_DCN1_REG_LIST()\
 	HWSEQ_DCN_REG_LIST(), \
+	HWSEQ_SR_WATERMARK_REG_LIST(), \
+	HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
+	HWSEQ_PHYPLL_REG_LIST(OTG), \
 	SR(DCHUBBUB_SDPIF_FB_TOP),\
 	SR(DCHUBBUB_SDPIF_FB_BASE),\
 	SR(DCHUBBUB_SDPIF_FB_OFFSET),\
 	SR(DCHUBBUB_SDPIF_AGP_BASE),\
 	SR(DCHUBBUB_SDPIF_AGP_BOT),\
-	SR(DCHUBBUB_SDPIF_AGP_TOP)
-
+	SR(DCHUBBUB_SDPIF_AGP_TOP),\
+	SR(DOMAIN0_PG_CONFIG), \
+	SR(DOMAIN1_PG_CONFIG), \
+	SR(DOMAIN2_PG_CONFIG), \
+	SR(DOMAIN3_PG_CONFIG), \
+	SR(DOMAIN4_PG_CONFIG), \
+	SR(DOMAIN5_PG_CONFIG), \
+	SR(DOMAIN6_PG_CONFIG), \
+	SR(DOMAIN7_PG_CONFIG), \
+	SR(DOMAIN0_PG_STATUS), \
+	SR(DOMAIN1_PG_STATUS), \
+	SR(DOMAIN2_PG_STATUS), \
+	SR(DOMAIN3_PG_STATUS), \
+	SR(DOMAIN4_PG_STATUS), \
+	SR(DOMAIN5_PG_STATUS), \
+	SR(DOMAIN6_PG_STATUS), \
+	SR(DOMAIN7_PG_STATUS), \
+	SR(D1VGA_CONTROL), \
+	SR(D2VGA_CONTROL), \
+	SR(D3VGA_CONTROL), \
+	SR(D4VGA_CONTROL), \
+	SR(DC_IP_REQUEST_CNTL), \
+	BL_REG_LIST()
 
 struct dce_hwseq_registers {
+
+		/* Backlight registers */
+	uint32_t LVTMA_PWRSEQ_CNTL;
+	uint32_t LVTMA_PWRSEQ_STATE;
+
 	uint32_t DCFE_CLOCK_CONTROL[6];
 	uint32_t DCFEV_CLOCK_CONTROL;
 	uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
@@ -376,20 +393,28 @@ struct dce_hwseq_registers {
 	HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
 	HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
 	HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
 	HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
 
 #define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
 	HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
 	HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
-	HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
+	HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
 
 #define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
 	HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
 	SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
 	HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
 
 #define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
 	HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
 	HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
 
 #define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\
@@ -397,14 +422,18 @@ struct dce_hwseq_registers {
 	SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\
 	SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\
 	SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\
-	SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh)
+	SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
 
 #define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\
 	HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\
 	HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\
 	HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\
 	HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\
-	HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)
+	HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
 
 #define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
 	HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
@@ -416,35 +445,12 @@ struct dce_hwseq_registers {
 	HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \
 	HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\
 	HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
-	HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
-	HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
-	HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
-	HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
-	HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
 	HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
 	HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
 	HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
 	HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
+	HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
+	HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
 	HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
 	HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
 	HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh)
@@ -468,7 +474,34 @@ struct dce_hwseq_registers {
 	HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
 	HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
 	HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
-	HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh)
+	HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\
+	HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+	HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+	HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+	HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+	HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
 
 #define HWSEQ_REG_FIELD_LIST(type) \
 	type DCFE_CLOCK_ENABLE; \
@@ -498,7 +531,9 @@ struct dce_hwseq_registers {
 	type PHYSICAL_PAGE_NUMBER_LSB;\
 	type LOGICAL_ADDR; \
 	type ENABLE_L1_TLB;\
-	type SYSTEM_ACCESS_MODE;
+	type SYSTEM_ACCESS_MODE;\
+	type LVTMA_BLON;\
+	type LVTMA_PWRSEQ_TARGET_STATE_R;
 
 #define HWSEQ_DCN_REG_FIELD_LIST(type) \
 	type VUPDATE_NO_LOCK_EVENT_CLEAR; \
@@ -524,6 +559,8 @@ struct dce_hwseq_registers {
 	type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\
 	type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE;\
 	type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE;\
+	type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE;\
+	type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE;\
 	type DCHUBBUB_ARB_SAT_LEVEL;\
 	type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\
 	type OPP_PIPE_CLOCK_EN;\

+ 2 - 0
drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c

@@ -37,6 +37,7 @@
 #define CTX \
 	ipp_dce->base.ctx
 
+
 static void dce_ipp_cursor_set_position(
 	struct input_pixel_processor *ipp,
 	const struct dc_cursor_position *position,
@@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
 	REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
 }
 
+
 static void dce_ipp_program_prescale(
 	struct input_pixel_processor *ipp,
 	struct ipp_prescale_params *params)

+ 4 - 249
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c

@@ -82,13 +82,6 @@
 #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
 
-/* all values are in milliseconds */
-/* For eDP, after power-up/power/down,
- * 300/500 msec max. delay from LCDVCC to black video generation */
-#define PANEL_POWER_UP_TIMEOUT 300
-#define PANEL_POWER_DOWN_TIMEOUT 500
-#define HPD_CHECK_INTERVAL 10
-
 /* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
 #define TMDS_MIN_PIXEL_CLOCK 25000
 /* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
@@ -122,8 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
 	.psr_program_dp_dphy_fast_training =
 			dce110_psr_program_dp_dphy_fast_training,
 	.psr_program_secondary_packet = dce110_psr_program_secondary_packet,
-	.backlight_control = dce110_link_encoder_edp_backlight_control,
-	.power_control = dce110_link_encoder_edp_power_control,
 	.connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
 	.enable_hpd = dce110_link_encoder_enable_hpd,
 	.disable_hpd = dce110_link_encoder_disable_hpd,
@@ -493,165 +484,6 @@ static void configure_encoder(
 	REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
 }
 
-static bool is_panel_powered_on(struct dce110_link_encoder *enc110)
-{
-	bool ret;
-	uint32_t value;
-
-	REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
-	ret = value;
-
-	return ret == 1;
-}
-
-
-/* TODO duplicate of dc_link.c version */
-static struct gpio *get_hpd_gpio(const struct link_encoder *enc)
-{
-	enum bp_result bp_result;
-	struct dc_bios *dcb = enc->ctx->dc_bios;
-	struct graphics_object_hpd_info hpd_info;
-	struct gpio_pin_info pin_info;
-
-	if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK)
-		return NULL;
-
-	bp_result = dcb->funcs->get_gpio_pin_info(dcb,
-		hpd_info.hpd_int_gpio_uid, &pin_info);
-
-	if (bp_result != BP_RESULT_OK) {
-		ASSERT(bp_result == BP_RESULT_NORECORD);
-		return NULL;
-	}
-
-	return dal_gpio_service_create_irq(
-		enc->ctx->gpio_service,
-		pin_info.offset,
-		pin_info.mask);
-}
-
-/*
- * @brief
- * eDP only.
- */
-static void link_encoder_edp_wait_for_hpd_ready(
-	struct dce110_link_encoder *enc110,
-	bool power_up)
-{
-	struct dc_context *ctx = enc110->base.ctx;
-	struct graphics_object_id connector = enc110->base.connector;
-	struct gpio *hpd;
-	bool edp_hpd_high = false;
-	uint32_t time_elapsed = 0;
-	uint32_t timeout = power_up ?
-		PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
-
-	if (dal_graphics_object_id_get_connector_id(connector) !=
-		CONNECTOR_ID_EDP) {
-		BREAK_TO_DEBUGGER();
-		return;
-	}
-
-	if (!power_up)
-		/* from KV, we will not HPD low after turning off VCC -
-		 * instead, we will check the SW timer in power_up(). */
-		return;
-
-	/* when we power on/off the eDP panel,
-	 * we need to wait until SENSE bit is high/low */
-
-	/* obtain HPD */
-	/* TODO what to do with this? */
-	hpd = get_hpd_gpio(&enc110->base);
-
-	if (!hpd) {
-		BREAK_TO_DEBUGGER();
-		return;
-	}
-
-	dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
-
-	/* wait until timeout or panel detected */
-
-	do {
-		uint32_t detected = 0;
-
-		dal_gpio_get_value(hpd, &detected);
-
-		if (!(detected ^ power_up)) {
-			edp_hpd_high = true;
-			break;
-		}
-
-		msleep(HPD_CHECK_INTERVAL);
-
-		time_elapsed += HPD_CHECK_INTERVAL;
-	} while (time_elapsed < timeout);
-
-	dal_gpio_close(hpd);
-
-	dal_gpio_destroy_irq(&hpd);
-
-	if (false == edp_hpd_high) {
-		dm_logger_write(ctx->logger, LOG_ERROR,
-				"%s: wait timed out!\n", __func__);
-	}
-}
-
-/*
- * @brief
- * eDP only. Control the power of the eDP panel.
- */
-void dce110_link_encoder_edp_power_control(
-	struct link_encoder *enc,
-	bool power_up)
-{
-	struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-	struct dc_context *ctx = enc110->base.ctx;
-	struct bp_transmitter_control cntl = { 0 };
-	enum bp_result bp_result;
-
-	if (dal_graphics_object_id_get_connector_id(enc110->base.connector) !=
-		CONNECTOR_ID_EDP) {
-		BREAK_TO_DEBUGGER();
-		return;
-	}
-
-	if ((power_up && !is_panel_powered_on(enc110)) ||
-		(!power_up && is_panel_powered_on(enc110))) {
-
-		/* Send VBIOS command to prompt eDP panel power */
-
-		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
-				"%s: Panel Power action: %s\n",
-				__func__, (power_up ? "On":"Off"));
-
-		cntl.action = power_up ?
-			TRANSMITTER_CONTROL_POWER_ON :
-			TRANSMITTER_CONTROL_POWER_OFF;
-		cntl.transmitter = enc110->base.transmitter;
-		cntl.connector_obj_id = enc110->base.connector;
-		cntl.coherent = false;
-		cntl.lanes_number = LANE_COUNT_FOUR;
-		cntl.hpd_sel = enc110->base.hpd_source;
-
-		bp_result = link_transmitter_control(enc110, &cntl);
-
-		if (BP_RESULT_OK != bp_result) {
-
-			dm_logger_write(ctx->logger, LOG_ERROR,
-					"%s: Panel Power bp_result: %d\n",
-					__func__, bp_result);
-		}
-	} else {
-		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
-				"%s: Skipping Panel Power action: %s\n",
-				__func__, (power_up ? "On":"Off"));
-	}
-
-	link_encoder_edp_wait_for_hpd_ready(enc110, true);
-}
-
 static void aux_initialize(
 	struct dce110_link_encoder *enc110)
 {
@@ -674,16 +506,6 @@ static void aux_initialize(
 
 }
 
-/*todo: cloned in stream enc, fix*/
-static bool is_panel_backlight_on(struct dce110_link_encoder *enc110)
-{
-	uint32_t value;
-
-	REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
-
-	return value;
-}
-
 void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
 			bool exit_link_training_required)
 {
@@ -718,69 +540,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
 		DP_SEC_GSP0_PRIORITY, 1);
 }
 
-/*todo: cloned in stream enc, fix*/
-/*
- * @brief
- * eDP only. Control the backlight of the eDP panel
- */
-void dce110_link_encoder_edp_backlight_control(
-	struct link_encoder *enc,
-	bool enable)
-{
-	struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-	struct dc_context *ctx = enc110->base.ctx;
-	struct bp_transmitter_control cntl = { 0 };
-
-	if (dal_graphics_object_id_get_connector_id(enc110->base.connector)
-		!= CONNECTOR_ID_EDP) {
-		BREAK_TO_DEBUGGER();
-		return;
-	}
-
-	if (enable && is_panel_backlight_on(enc110)) {
-		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
-				"%s: panel already powered up. Do nothing.\n",
-				__func__);
-		return;
-	}
-
-	if (!enable && !is_panel_backlight_on(enc110)) {
-		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
-				"%s: panel already powered down. Do nothing.\n",
-				__func__);
-		return;
-	}
-
-	/* Send VBIOS command to control eDP panel backlight */
-
-	dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
-			"%s: backlight action: %s\n",
-			__func__, (enable ? "On":"Off"));
-
-	cntl.action = enable ?
-		TRANSMITTER_CONTROL_BACKLIGHT_ON :
-		TRANSMITTER_CONTROL_BACKLIGHT_OFF;
-	/*cntl.engine_id = ctx->engine;*/
-	cntl.transmitter = enc110->base.transmitter;
-	cntl.connector_obj_id = enc110->base.connector;
-	/*todo: unhardcode*/
-	cntl.lanes_number = LANE_COUNT_FOUR;
-	cntl.hpd_sel = enc110->base.hpd_source;
-
-	/* For eDP, the following delays might need to be considered
-	 * after link training completed:
-	 * idle period - min. accounts for required BS-Idle pattern,
-	 * max. allows for source frame synchronization);
-	 * 50 msec max. delay from valid video data from source
-	 * to video on dislpay or backlight enable.
-	 *
-	 * Disable the delay for now.
-	 * Enable it in the future if necessary.
-	 */
-	/* dc_service_sleep_in_milliseconds(50); */
-	link_transmitter_control(enc110, &cntl);
-}
-
 static bool is_dig_enabled(const struct dce110_link_encoder *enc110)
 {
 	uint32_t value;
@@ -998,11 +757,6 @@ void dce110_link_encoder_construct(
 		enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
 	}
 
-	dm_logger_write(init_data->ctx->logger, LOG_I2C_AUX,
-			"Using channel: %s [%d]\n",
-			DECODE_CHANNEL_ID(init_data->channel),
-			init_data->channel);
-
 	/* Override features with DCE-specific values */
 	if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
 			enc110->base.ctx->dc_bios, enc110->base.id,
@@ -1092,7 +846,7 @@ void dce110_link_encoder_hw_init(
 		ASSERT(result == BP_RESULT_OK);
 
 	} else if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
-		enc->funcs->power_control(&enc110->base, true);
+		ctx->dc->hwss.edp_power_control(enc, true);
 	}
 	aux_initialize(enc110);
 
@@ -1279,7 +1033,8 @@ void dce110_link_encoder_enable_dp_mst_output(
  */
 void dce110_link_encoder_disable_output(
 	struct link_encoder *enc,
-	enum signal_type signal)
+	enum signal_type signal,
+	struct dc_link *link)
 {
 	struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
 	struct dc_context *ctx = enc110->base.ctx;
@@ -1291,7 +1046,7 @@ void dce110_link_encoder_disable_output(
 		return;
 	}
 	if (enc110->base.connector.id == CONNECTOR_ID_EDP)
-		dce110_link_encoder_edp_backlight_control(enc, false);
+		ctx->dc->hwss.edp_backlight_control(link, false);
 	/* Power-down RX and disable GPU PHY should be paired.
 	 * Disabling PHY without powering down RX may cause
 	 * symbol lock loss, on which we will get DP Sink interrupt. */

+ 3 - 17
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h

@@ -44,8 +44,6 @@
 	SRI(DC_HPD_CONTROL, HPD, id)
 
 #define LE_COMMON_REG_LIST_BASE(id) \
-	SR(LVTMA_PWRSEQ_CNTL), \
-	SR(LVTMA_PWRSEQ_STATE), \
 	SR(DMCU_RAM_ACCESS_CTRL), \
 	SR(DMCU_IRAM_RD_CTRL), \
 	SR(DMCU_IRAM_RD_DATA), \
@@ -104,8 +102,7 @@
 	LE_COMMON_REG_LIST_BASE(id), \
 	SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
 	SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
-	SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \
-	SR(DMU_MEM_PWR_CNTL)
+	SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
 
 struct dce110_link_enc_aux_registers {
 	uint32_t AUX_CONTROL;
@@ -117,10 +114,6 @@ struct dce110_link_enc_hpd_registers {
 };
 
 struct dce110_link_enc_registers {
-	/* Backlight registers */
-	uint32_t LVTMA_PWRSEQ_CNTL;
-	uint32_t LVTMA_PWRSEQ_STATE;
-
 	/* DMCU registers */
 	uint32_t MASTER_COMM_DATA_REG1;
 	uint32_t MASTER_COMM_DATA_REG2;
@@ -236,7 +229,8 @@ void dce110_link_encoder_enable_dp_mst_output(
 /* disable PHY output */
 void dce110_link_encoder_disable_output(
 	struct link_encoder *link_enc,
-	enum signal_type signal);
+	enum signal_type signal,
+	struct dc_link *link);
 
 /* set DP lane settings */
 void dce110_link_encoder_dp_set_lane_settings(
@@ -252,14 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table(
 	struct link_encoder *enc,
 	const struct link_mst_stream_allocation_table *table);
 
-void dce110_link_encoder_edp_backlight_control(
-	struct link_encoder *enc,
-	bool enable);
-
-void dce110_link_encoder_edp_power_control(
-	struct link_encoder *enc,
-	bool power_up);
-
 void dce110_link_encoder_connect_dig_be_to_fe(
 	struct link_encoder *enc,
 	enum engine_id engine,

+ 1 - 4
drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c

@@ -361,7 +361,7 @@ static void program_grph_pixel_format(
 	enum surface_pixel_format format)
 {
 	uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
-	uint32_t grph_depth, grph_format;
+	uint32_t grph_depth = 0, grph_format = 0;
 	uint32_t sign = 0, floating = 0;
 
 	if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
@@ -685,9 +685,6 @@ void dce_mem_input_construct(
 	dce_mi->regs = regs;
 	dce_mi->shifts = mi_shift;
 	dce_mi->masks = mi_mask;
-
-	dce_mi->base.mpcc_id = 0xf;
-	dce_mi->base.opp_id = 0xf;
 }
 
 void dce112_mem_input_construct(

+ 1 - 1
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c

@@ -743,7 +743,7 @@ static void dce100_destroy_resource_pool(struct resource_pool **pool)
 	*pool = NULL;
 }
 
-enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state)
+enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
 {
 
 	if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)

+ 1 - 1
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h

@@ -16,7 +16,7 @@ struct resource_pool *dce100_create_resource_pool(
 	uint8_t num_virtual_links,
 	struct dc *dc);
 
-enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state);
+enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps);
 
 enum dc_status dce100_add_stream_to_ctx(
 		struct dc *dc,

+ 1 - 1
drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c

@@ -514,7 +514,7 @@ void dce110_compressor_construct(struct dce110_compressor *compressor,
 	compressor->base.lpt_channels_num = 0;
 	compressor->base.attached_inst = 0;
 	compressor->base.is_enabled = false;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	compressor->base.funcs = &dce110_compressor_funcs;
 
 #endif

+ 295 - 37
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c

@@ -32,8 +32,9 @@
 #include "dce110_hw_sequencer.h"
 #include "dce110_timing_generator.h"
 #include "dce/dce_hwseq.h"
+#include "gpio_service_interface.h"
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 #include "dce110_compressor.h"
 #endif
 
@@ -45,10 +46,10 @@
 #include "transform.h"
 #include "stream_encoder.h"
 #include "link_encoder.h"
+#include "link_hwss.h"
 #include "clock_source.h"
 #include "abm.h"
 #include "audio.h"
-#include "dce/dce_hwseq.h"
 #include "reg_helper.h"
 
 /* include DCE11 register header files */
@@ -56,6 +57,24 @@
 #include "dce/dce_11_0_sh_mask.h"
 #include "custom_float.h"
 
+/*
+ * All values are in milliseconds;
+ * For eDP, after power-up/power/down,
+ * 300/500 msec max. delay from LCDVCC to black video generation
+ */
+#define PANEL_POWER_UP_TIMEOUT 300
+#define PANEL_POWER_DOWN_TIMEOUT 500
+#define HPD_CHECK_INTERVAL 10
+
+#define CTX \
+	hws->ctx
+#define REG(reg)\
+	hws->regs->reg
+
+#undef FN
+#define FN(reg_name, field_name) \
+	hws->shifts->field_name, hws->masks->field_name
+
 struct dce110_hw_seq_reg_offsets {
 	uint32_t crtc;
 };
@@ -761,10 +780,216 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
 
 }
 
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
+/*todo: cloned in stream enc, fix*/
+static bool is_panel_backlight_on(struct dce_hwseq *hws)
+{
+	uint32_t value;
+
+	REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
+
+	return value;
+}
+
+static bool is_panel_powered_on(struct dce_hwseq *hws)
+{
+	uint32_t value;
+
+	REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
+	return value == 1;
+}
+
+static enum bp_result link_transmitter_control(
+		struct dc_bios *bios,
+	struct bp_transmitter_control *cntl)
+{
+	enum bp_result result;
+
+	result = bios->funcs->transmitter_control(bios, cntl);
+
+	return result;
+}
+
+/*
+ * @brief
+ * eDP only.
+ */
+void hwss_edp_wait_for_hpd_ready(
+	struct link_encoder *enc,
+	bool power_up)
+{
+	struct dc_context *ctx = enc->ctx;
+	struct graphics_object_id connector = enc->connector;
+	struct gpio *hpd;
+	bool edp_hpd_high = false;
+	uint32_t time_elapsed = 0;
+	uint32_t timeout = power_up ?
+		PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
+
+	if (dal_graphics_object_id_get_connector_id(connector)
+			!= CONNECTOR_ID_EDP) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
+
+	if (!power_up)
+		/*
+		 * From KV, we will not HPD low after turning off VCC -
+		 * instead, we will check the SW timer in power_up().
+		 */
+		return;
+
+	/*
+	 * When we power on/off the eDP panel,
+	 * we need to wait until SENSE bit is high/low.
+	 */
+
+	/* obtain HPD */
+	/* TODO what to do with this? */
+	hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
+
+	if (!hpd) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
+
+	dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
+
+	/* wait until timeout or panel detected */
+
+	do {
+		uint32_t detected = 0;
+
+		dal_gpio_get_value(hpd, &detected);
+
+		if (!(detected ^ power_up)) {
+			edp_hpd_high = true;
+			break;
+		}
+
+		msleep(HPD_CHECK_INTERVAL);
+
+		time_elapsed += HPD_CHECK_INTERVAL;
+	} while (time_elapsed < timeout);
+
+	dal_gpio_close(hpd);
+
+	dal_gpio_destroy_irq(&hpd);
+
+	if (false == edp_hpd_high) {
+		dm_logger_write(ctx->logger, LOG_ERROR,
+				"%s: wait timed out!\n", __func__);
+	}
+}
+
+void hwss_edp_power_control(
+	struct link_encoder *enc,
+	bool power_up)
+{
+	struct dc_context *ctx = enc->ctx;
+	struct dce_hwseq *hwseq = ctx->dc->hwseq;
+	struct bp_transmitter_control cntl = { 0 };
+	enum bp_result bp_result;
+
+
+	if (dal_graphics_object_id_get_connector_id(enc->connector)
+			!= CONNECTOR_ID_EDP) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
+
+	if (power_up != is_panel_powered_on(hwseq)) {
+		/* Send VBIOS command to prompt eDP panel power */
+
+		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+				"%s: Panel Power action: %s\n",
+				__func__, (power_up ? "On":"Off"));
+
+		cntl.action = power_up ?
+			TRANSMITTER_CONTROL_POWER_ON :
+			TRANSMITTER_CONTROL_POWER_OFF;
+		cntl.transmitter = enc->transmitter;
+		cntl.connector_obj_id = enc->connector;
+		cntl.coherent = false;
+		cntl.lanes_number = LANE_COUNT_FOUR;
+		cntl.hpd_sel = enc->hpd_source;
+
+		bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
+
+		if (bp_result != BP_RESULT_OK)
+			dm_logger_write(ctx->logger, LOG_ERROR,
+					"%s: Panel Power bp_result: %d\n",
+					__func__, bp_result);
+	} else {
+		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+				"%s: Skipping Panel Power action: %s\n",
+				__func__, (power_up ? "On":"Off"));
+	}
+
+	hwss_edp_wait_for_hpd_ready(enc, true);
+}
+
+/*todo: cloned in stream enc, fix*/
+/*
+ * @brief
+ * eDP only. Control the backlight of the eDP panel
+ */
+void hwss_edp_backlight_control(
+	struct dc_link *link,
+	bool enable)
+{
+	struct dce_hwseq *hws = link->dc->hwseq;
+	struct dc_context *ctx = link->dc->ctx;
+	struct bp_transmitter_control cntl = { 0 };
+
+	if (dal_graphics_object_id_get_connector_id(link->link_id)
+		!= CONNECTOR_ID_EDP) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
+
+	if (enable && is_panel_backlight_on(hws)) {
+		dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+				"%s: panel already powered up. Do nothing.\n",
+				__func__);
+		return;
+	}
+
+	/* Send VBIOS command to control eDP panel backlight */
+
+	dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+			"%s: backlight action: %s\n",
+			__func__, (enable ? "On":"Off"));
+
+	cntl.action = enable ?
+		TRANSMITTER_CONTROL_BACKLIGHT_ON :
+		TRANSMITTER_CONTROL_BACKLIGHT_OFF;
+
+	/*cntl.engine_id = ctx->engine;*/
+	cntl.transmitter = link->link_enc->transmitter;
+	cntl.connector_obj_id = link->link_enc->connector;
+	/*todo: unhardcode*/
+	cntl.lanes_number = LANE_COUNT_FOUR;
+	cntl.hpd_sel = link->link_enc->hpd_source;
+
+	/* For eDP, the following delays might need to be considered
+	 * after link training completed:
+	 * idle period - min. accounts for required BS-Idle pattern,
+	 * max. allows for source frame synchronization);
+	 * 50 msec max. delay from valid video data from source
+	 * to video on dislpay or backlight enable.
+	 *
+	 * Disable the delay for now.
+	 * Enable it in the future if necessary.
+	 */
+	/* dc_service_sleep_in_milliseconds(50); */
+	link_transmitter_control(link->dc->ctx->dc_bios, &cntl);
+}
+
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
 {
 	struct dc_stream_state *stream = pipe_ctx->stream;
 	struct dc_link *link = stream->sink->link;
+	struct dc *dc = pipe_ctx->stream->ctx->dc;
 
 	if (pipe_ctx->stream_res.audio) {
 		pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
@@ -775,6 +1000,13 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 		else
 			pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
 					pipe_ctx->stream_res.stream_enc);
+		/*don't free audio if it is from retrain or internal disable stream*/
+		if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
+			/*we have to dynamic arbitrate the audio endpoints*/
+			pipe_ctx->stream_res.audio = NULL;
+			/*we free the resource, need reset is_audio_acquired*/
+			update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
+		}
 
 		/* TODO: notify audio driver for if audio modes list changed
 		 * add audio mode list change flag */
@@ -798,7 +1030,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
 	/* blank at encoder level */
 	if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
 		if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
-			link->link_enc->funcs->backlight_control(link->link_enc, false);
+			hwss_edp_backlight_control(link, false);
 		pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
 	}
 	link->link_enc->funcs->connect_dig_be_to_fe(
@@ -820,7 +1052,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
 	params.link_settings.link_rate = link_settings->link_rate;
 	pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
 	if (link->connector_signal == SIGNAL_TYPE_EDP)
-			link->link_enc->funcs->backlight_control(link->link_enc, true);
+		hwss_edp_backlight_control(link, true);
 }
 
 
@@ -1132,33 +1364,21 @@ static enum dc_status apply_single_controller_ctx_to_hw(
 	resource_build_info_frame(pipe_ctx);
 	dce110_update_info_frame(pipe_ctx);
 	if (!pipe_ctx_old->stream) {
-		core_link_enable_stream(context, pipe_ctx);
-
-
-		if (dc_is_dp_signal(pipe_ctx->stream->signal))
-			dce110_unblank_stream(pipe_ctx,
-				&stream->sink->link->cur_link_settings);
+		if (!pipe_ctx->stream->dpms_off)
+			core_link_enable_stream(context, pipe_ctx);
 	}
 
 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
-	/* program_scaler and allocate_mem_input are not new asic */
-	if ((!pipe_ctx_old ||
-	     memcmp(&pipe_ctx_old->plane_res.scl_data, &pipe_ctx->plane_res.scl_data,
-		    sizeof(struct scaler_data)) != 0) &&
-	     pipe_ctx->plane_state) {
-		program_scaler(dc, pipe_ctx);
-	}
 
 	/* mst support - use total stream count */
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
-	if (pipe_ctx->plane_res.mi->funcs->allocate_mem_input != NULL)
-#endif
+	if (pipe_ctx->plane_res.mi != NULL) {
 		pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
-					pipe_ctx->plane_res.mi,
-					stream->timing.h_total,
-					stream->timing.v_total,
-					stream->timing.pix_clk_khz,
-					context->stream_count);
+				pipe_ctx->plane_res.mi,
+				stream->timing.h_total,
+				stream->timing.v_total,
+				stream->timing.pix_clk_khz,
+				context->stream_count);
+	}
 
 	pipe_ctx->stream->sink->link->psr_enabled = false;
 
@@ -1171,6 +1391,16 @@ static void power_down_encoders(struct dc *dc)
 {
 	int i;
 	enum connector_id connector_id;
+	enum signal_type signal = SIGNAL_TYPE_NONE;
+
+	/* do not know BIOS back-front mapping, simply blank all. It will not
+	 * hurt for non-DP
+	 */
+	for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
+		dc->res_pool->stream_enc[i]->funcs->dp_blank(
+					dc->res_pool->stream_enc[i]);
+	}
+
 	for (i = 0; i < dc->link_count; i++) {
 		connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
 		if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
@@ -1178,10 +1408,12 @@ static void power_down_encoders(struct dc *dc)
 
 			if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
 				dp_receiver_power_ctrl(dc->links[i], false);
+			if (connector_id == CONNECTOR_ID_EDP)
+				signal = SIGNAL_TYPE_EDP;
 		}
 
 		dc->links[i]->link_enc->funcs->disable_output(
-				dc->links[i]->link_enc, SIGNAL_TYPE_NONE);
+				dc->links[i]->link_enc, signal, dc->links[i]);
 	}
 }
 
@@ -1218,7 +1450,7 @@ static void power_down_all_hw_blocks(struct dc *dc)
 
 	power_down_clock_sources(dc);
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	if (dc->fbc_compressor)
 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
 #endif
@@ -1325,7 +1557,7 @@ static void set_safe_displaymarks(
 		SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
 
 	for (i = 0; i < MAX_PIPES; i++) {
-		if (res_ctx->pipe_ctx[i].stream == NULL)
+		if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
 			continue;
 
 		res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
@@ -1334,6 +1566,7 @@ static void set_safe_displaymarks(
 				max_marks,
 				max_marks,
 				MAX_WATERMARK);
+
 		if (i == underlay_idx)
 			res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
 				res_ctx->pipe_ctx[i].plane_res.mi,
@@ -1341,6 +1574,7 @@ static void set_safe_displaymarks(
 				max_marks,
 				max_marks,
 				MAX_WATERMARK);
+
 	}
 }
 
@@ -1391,7 +1625,7 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
 	if (events->cursor_update)
 		value |= 0x2;
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	value |= 0x84;
 #endif
 
@@ -1521,7 +1755,7 @@ static void apply_min_clocks(
 	}
 }
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 
 /*
  *  Check if FBC can be enabled
@@ -1644,7 +1878,10 @@ static void dce110_reset_hw_ctx_wrap(
 				pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
 			struct clock_source *old_clk = pipe_ctx_old->clock_source;
 
-			core_link_disable_stream(pipe_ctx_old);
+			/* disable already, no need to disable again */
+			if (pipe_ctx->stream && !pipe_ctx->stream->dpms_off)
+				core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
+
 			pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
 			if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
 				dm_error("DC: failed to blank crtc!\n");
@@ -1713,7 +1950,7 @@ enum dc_status dce110_apply_ctx_to_hw(
 
 	set_safe_displaymarks(&context->res_ctx, dc->res_pool);
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	if (dc->fbc_compressor)
 		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
 #endif
@@ -1889,6 +2126,7 @@ enum dc_status dce110_apply_ctx_to_hw(
 			return status;
 	}
 
+	/* pplib is notified if disp_num changed */
 	dc->hwss.set_bandwidth(dc, context, true);
 
 	/* to save power */
@@ -1896,7 +2134,7 @@ enum dc_status dce110_apply_ctx_to_hw(
 
 	dcb->funcs->set_scratch_critical_state(dcb, false);
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	if (dc->fbc_compressor)
 		enable_fbc(dc, context);
 
@@ -2305,7 +2543,7 @@ static void init_hw(struct dc *dc)
 		abm->funcs->init_backlight(abm);
 		abm->funcs->abm_init(abm);
 	}
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	if (dc->fbc_compressor)
 		dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
 #endif
@@ -2490,6 +2728,8 @@ static void dce110_program_front_end_for_pipe(
 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 	struct xfm_grph_csc_adjustment adjust;
 	struct out_csc_color_matrix tbl_entry;
+	struct pipe_ctx *cur_pipe_ctx =
+					&dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
 	unsigned int i;
 
 	memset(&tbl_entry, 0, sizeof(tbl_entry));
@@ -2553,6 +2793,15 @@ static void dce110_program_front_end_for_pipe(
 
 	program_scaler(dc, pipe_ctx);
 
+#if defined(CONFIG_DRM_AMD_DC_FBC)
+	if (dc->fbc_compressor && old_pipe->stream) {
+		if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
+			dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
+		else
+			enable_fbc(dc, dc->current_state);
+	}
+#endif
+
 	mi->funcs->mem_input_program_surface_config(
 			mi,
 			plane_state->format,
@@ -2571,6 +2820,14 @@ static void dce110_program_front_end_for_pipe(
 				&plane_state->tiling_info,
 				plane_state->rotation);
 
+	/* Moved programming gamma from dc to hwss */
+	if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
+		dc->hwss.set_input_transfer_func(
+				pipe_ctx, pipe_ctx->plane_state);
+		dc->hwss.set_output_transfer_func(
+				pipe_ctx, pipe_ctx->stream);
+	}
+
 	dm_logger_write(dc->ctx->logger, LOG_SURFACE,
 			"Pipe:%d 0x%x: addr hi:0x%x, "
 			"addr low:0x%x, "
@@ -2683,7 +2940,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
 	}
 }
 
-static void ready_shared_resources(struct dc *dc) {}
+static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
 
 static void optimize_shared_resources(struct dc *dc) {}
 
@@ -2720,7 +2977,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
 	.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
 	.ready_shared_resources = ready_shared_resources,
 	.optimize_shared_resources = optimize_shared_resources,
-
+	.edp_backlight_control = hwss_edp_backlight_control,
+	.edp_power_control = hwss_edp_power_control,
 };
 
 void dce110_hw_sequencer_construct(struct dc *dc)

+ 10 - 1
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h

@@ -47,7 +47,7 @@ void dce110_set_displaymarks(
 
 void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
 
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx);
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option);
 
 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
 		struct dc_link_settings *link_settings);
@@ -68,5 +68,14 @@ void dce110_fill_display_configs(
 uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
 
 void dp_receiver_power_ctrl(struct dc_link *link, bool on);
+
+void hwss_edp_power_control(
+	struct link_encoder *enc,
+	bool power_up);
+
+void hwss_edp_backlight_control(
+	struct dc_link *link,
+	bool enable);
+
 #endif /* __DC_HWSS_DCE110_H__ */
 

+ 23 - 10
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c

@@ -52,7 +52,7 @@
 #include "dce/dce_abm.h"
 #include "dce/dce_dmcu.h"
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 #include "dce110/dce110_compressor.h"
 #endif
 
@@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth(
 static bool dce110_validate_surface_sets(
 		struct dc_state *context)
 {
-	int i;
+	int i, j;
 
 	for (i = 0; i < context->stream_count; i++) {
 		if (context->stream_status[i].plane_count == 0)
@@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets(
 		if (context->stream_status[i].plane_count > 2)
 			return false;
 
-		if ((context->stream_status[i].plane_states[i]->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) &&
-		    (context->stream_status[i].plane_states[i]->src_rect.width > 1920 ||
-		     context->stream_status[i].plane_states[i]->src_rect.height > 1080))
-			return false;
+		for (j = 0; j < context->stream_status[i].plane_count; j++) {
+			struct dc_plane_state *plane =
+				context->stream_status[i].plane_states[j];
 
-		/* irrespective of plane format, stream should be RGB encoded */
-		if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB)
-			return false;
+			/* underlay validation */
+			if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+
+				if ((plane->src_rect.width > 1920 ||
+					plane->src_rect.height > 1080))
+					return false;
+
+				/* irrespective of plane format,
+				 * stream should be RGB encoded
+				 */
+				if (context->streams[i]->timing.pixel_encoding
+						!= PIXEL_ENCODING_RGB)
+					return false;
+
+			}
+
+		}
 	}
 
 	return true;
@@ -1266,7 +1279,7 @@ static bool construct(
 		}
 	}
 
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
 	dc->fbc_compressor = dce110_compressor_create(ctx);
 
 

+ 2 - 2
drivers/gpu/drm/amd/display/dc/dcn10/Makefile

@@ -3,8 +3,8 @@
 
 DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
 		dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \
-		dcn10_mem_input.o dcn10_mpc.o \
-		dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_dpp_cm_helper.o
+		dcn10_hubp.o dcn10_mpc.o \
+		dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o
 
 AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
 

+ 1 - 1
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c → drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c

@@ -26,7 +26,7 @@
 #include "reg_helper.h"
 #include "dcn10_dpp.h"
 
-#include "dcn10_dpp_cm_helper.h"
+#include "dcn10_cm_common.h"
 
 #define REG(reg) reg
 

+ 2 - 2
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h → drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h

@@ -23,8 +23,8 @@
  *
  */
 
-#ifndef __DAL_DPP_DCN10_CM_HELPER_H__
-#define __DAL_DPP_DCN10_CM_HELPER_H__
+#ifndef __DAL_DCN10_CM_COMMON_H__
+#define __DAL_DCN10_CM_COMMON_H__
 
 #define TF_HELPER_REG_FIELD_LIST(type) \
 	type exp_region0_lut_offset; \

+ 128 - 71
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c

@@ -39,14 +39,14 @@
 #define BLACK_OFFSET_CBCR  0x8000
 
 #define REG(reg)\
-	xfm->tf_regs->reg
+	dpp->tf_regs->reg
 
 #define CTX \
-	xfm->base.ctx
+	dpp->base.ctx
 
 #undef FN
 #define FN(reg_name, field_name) \
-	xfm->tf_shift->field_name, xfm->tf_mask->field_name
+	dpp->tf_shift->field_name, dpp->tf_mask->field_name
 
 enum pixel_format_description {
 	PIXEL_FORMAT_FIXED = 0,
@@ -99,7 +99,7 @@ enum gamut_remap_select {
 };
 
 /* Program gamut remap in bypass mode */
-void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
+void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp)
 {
 	REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
 			CM_GAMUT_REMAP_MODE, 0);
@@ -110,7 +110,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
 
 
 bool dpp_get_optimal_number_of_taps(
-		struct transform *xfm,
+		struct dpp *dpp,
 		struct scaler_data *scl_data,
 		const struct scaling_taps *in_taps)
 {
@@ -154,28 +154,29 @@ bool dpp_get_optimal_number_of_taps(
 	else
 		scl_data->taps.h_taps_c = in_taps->h_taps_c;
 
-	if (!xfm->ctx->dc->debug.always_scale) {
+	if (!dpp->ctx->dc->debug.always_scale) {
 		if (IDENTITY_RATIO(scl_data->ratios.horz))
 			scl_data->taps.h_taps = 1;
 		if (IDENTITY_RATIO(scl_data->ratios.vert))
 			scl_data->taps.v_taps = 1;
-		if (IDENTITY_RATIO(scl_data->ratios.horz_c))
-			scl_data->taps.h_taps_c = 1;
-		if (IDENTITY_RATIO(scl_data->ratios.vert_c))
-			scl_data->taps.v_taps_c = 1;
+		/*
+		 * Spreadsheet doesn't handle taps_c is one properly,
+		 * need to force Chroma to always be scaled to pass
+		 * bandwidth validation.
+		 */
 	}
 
 	return true;
 }
 
-void dpp_reset(struct transform *xfm_base)
+void dpp_reset(struct dpp *dpp_base)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
-	xfm->filter_h_c = NULL;
-	xfm->filter_v_c = NULL;
-	xfm->filter_h = NULL;
-	xfm->filter_v = NULL;
+	dpp->filter_h_c = NULL;
+	dpp->filter_v_c = NULL;
+	dpp->filter_h = NULL;
+	dpp->filter_v = NULL;
 
 	/* set boundary mode to 0 */
 	REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0);
@@ -183,28 +184,28 @@ void dpp_reset(struct transform *xfm_base)
 
 
 
-static void dcn10_dpp_cm_set_regamma_pwl(
-	struct transform *xfm_base, const struct pwl_params *params)
+static void dpp1_cm_set_regamma_pwl(
+	struct dpp *dpp_base, const struct pwl_params *params)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
-	dcn10_dpp_cm_power_on_regamma_lut(xfm_base, true);
-	dcn10_dpp_cm_configure_regamma_lut(xfm_base, xfm->is_write_to_ram_a_safe);
+	dpp1_cm_power_on_regamma_lut(dpp_base, true);
+	dpp1_cm_configure_regamma_lut(dpp_base, dpp->is_write_to_ram_a_safe);
 
-	if (xfm->is_write_to_ram_a_safe)
-		dcn10_dpp_cm_program_regamma_luta_settings(xfm_base, params);
+	if (dpp->is_write_to_ram_a_safe)
+		dpp1_cm_program_regamma_luta_settings(dpp_base, params);
 	else
-		dcn10_dpp_cm_program_regamma_lutb_settings(xfm_base, params);
+		dpp1_cm_program_regamma_lutb_settings(dpp_base, params);
 
-	dcn10_dpp_cm_program_regamma_lut(
-			xfm_base, params->rgb_resulted, params->hw_points_num);
+	dpp1_cm_program_regamma_lut(
+			dpp_base, params->rgb_resulted, params->hw_points_num);
 }
 
-static void dcn10_dpp_cm_set_regamma_mode(
-	struct transform *xfm_base,
+static void dpp1_cm_set_regamma_mode(
+	struct dpp *dpp_base,
 	enum opp_regamma mode)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	uint32_t re_mode = 0;
 	uint32_t obuf_bypass = 0; /* need for pipe split */
 	uint32_t obuf_hupscale = 0;
@@ -220,8 +221,8 @@ static void dcn10_dpp_cm_set_regamma_mode(
 		re_mode = 2;
 		break;
 	case OPP_REGAMMA_USER:
-		re_mode = xfm->is_write_to_ram_a_safe ? 3 : 4;
-		xfm->is_write_to_ram_a_safe = !xfm->is_write_to_ram_a_safe;
+		re_mode = dpp->is_write_to_ram_a_safe ? 3 : 4;
+		dpp->is_write_to_ram_a_safe = !dpp->is_write_to_ram_a_safe;
 		break;
 	default:
 		break;
@@ -233,7 +234,7 @@ static void dcn10_dpp_cm_set_regamma_mode(
 			OBUF_H_2X_UPSCALE_EN, obuf_hupscale);
 }
 
-static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
+static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
 						enum pixel_format_description *fmt)
 {
 
@@ -246,11 +247,11 @@ static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
 		*fmt = PIXEL_FORMAT_FIXED;
 }
 
-static void ippn10_set_degamma_format_float(
-		struct transform *xfm_base,
+static void dpp1_set_degamma_format_float(
+		struct dpp *dpp_base,
 		bool is_float)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	if (is_float) {
 		REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3);
@@ -261,8 +262,8 @@ static void ippn10_set_degamma_format_float(
 	}
 }
 
-void ippn10_cnv_setup (
-		struct transform *xfm_base,
+void dpp1_cnv_setup (
+		struct dpp *dpp_base,
 		enum surface_pixel_format input_format,
 		enum expansion_mode mode)
 {
@@ -272,10 +273,10 @@ void ippn10_cnv_setup (
 	enum dc_color_space color_space;
 	enum dcn10_input_csc_select select;
 	bool is_float;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	bool force_disable_cursor = false;
 
-	ippn10_setup_format_flags(input_format, &fmt);
+	dpp1_setup_format_flags(input_format, &fmt);
 	alpha_en = 1;
 	pixel_format = 0;
 	color_space = COLOR_SPACE_SRGB;
@@ -303,7 +304,7 @@ void ippn10_cnv_setup (
 		break;
 	}
 
-	ippn10_set_degamma_format_float(xfm_base, is_float);
+	dpp1_set_degamma_format_float(dpp_base, is_float);
 
 	switch (input_format) {
 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
@@ -361,7 +362,7 @@ void ippn10_cnv_setup (
 			CNVC_SURFACE_PIXEL_FORMAT, pixel_format);
 	REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
 
-	ippn10_program_input_csc(xfm_base, color_space, select);
+	dpp1_program_input_csc(dpp_base, color_space, select);
 
 	if (force_disable_cursor) {
 		REG_UPDATE(CURSOR_CONTROL,
@@ -371,54 +372,110 @@ void ippn10_cnv_setup (
 	}
 }
 
-static const struct transform_funcs dcn10_dpp_funcs = {
-		.transform_reset = dpp_reset,
-		.transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale,
-		.transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
-		.transform_set_gamut_remap = dcn10_dpp_cm_set_gamut_remap,
-		.opp_set_csc_adjustment = dcn10_dpp_cm_set_output_csc_adjustment,
-		.opp_set_csc_default = dcn10_dpp_cm_set_output_csc_default,
-		.opp_power_on_regamma_lut = dcn10_dpp_cm_power_on_regamma_lut,
-		.opp_program_regamma_lut = dcn10_dpp_cm_program_regamma_lut,
-		.opp_configure_regamma_lut = dcn10_dpp_cm_configure_regamma_lut,
-		.opp_program_regamma_lutb_settings = dcn10_dpp_cm_program_regamma_lutb_settings,
-		.opp_program_regamma_luta_settings = dcn10_dpp_cm_program_regamma_luta_settings,
-		.opp_program_regamma_pwl = dcn10_dpp_cm_set_regamma_pwl,
-		.opp_set_regamma_mode = dcn10_dpp_cm_set_regamma_mode,
-		.ipp_set_degamma = ippn10_set_degamma,
-		.ipp_program_input_lut		= ippn10_program_input_lut,
-		.ipp_program_degamma_pwl	= ippn10_set_degamma_pwl,
-		.ipp_setup			= ippn10_cnv_setup,
-		.ipp_full_bypass		= ippn10_full_bypass,
+void dpp1_set_cursor_attributes(
+		struct dpp *dpp_base,
+		const struct dc_cursor_attributes *attr)
+{
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+	enum dc_cursor_color_format color_format = attr->color_format;
+
+	REG_UPDATE_2(CURSOR0_CONTROL,
+			CUR0_MODE, color_format,
+			CUR0_EXPANSION_MODE, 0);
+
+	if (color_format == CURSOR_MODE_MONO) {
+		/* todo: clarify what to program these to */
+		REG_UPDATE(CURSOR0_COLOR0,
+				CUR0_COLOR0, 0x00000000);
+		REG_UPDATE(CURSOR0_COLOR1,
+				CUR0_COLOR1, 0xFFFFFFFF);
+	}
+
+	/* TODO: Fixed vs float */
+
+	REG_UPDATE_3(FORMAT_CONTROL,
+				CNVC_BYPASS, 0,
+				FORMAT_CONTROL__ALPHA_EN, 1,
+				FORMAT_EXPANSION_MODE, 0);
+}
+
+
+void dpp1_set_cursor_position(
+		struct dpp *dpp_base,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param,
+		uint32_t width)
+{
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+	int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
+	uint32_t cur_en = pos->enable ? 1 : 0;
+
+	if (src_x_offset >= (int)param->viewport_width)
+		cur_en = 0;  /* not visible beyond right edge*/
+
+	if (src_x_offset + (int)width < 0)
+		cur_en = 0;  /* not visible beyond left edge*/
+
+	REG_UPDATE(CURSOR0_CONTROL,
+			CUR0_ENABLE, cur_en);
+
+}
+
+static const struct dpp_funcs dcn10_dpp_funcs = {
+		.dpp_reset = dpp_reset,
+		.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
+		.dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
+		.dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
+		.opp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment,
+		.opp_set_csc_default = dpp1_cm_set_output_csc_default,
+		.opp_power_on_regamma_lut = dpp1_cm_power_on_regamma_lut,
+		.opp_program_regamma_lut = dpp1_cm_program_regamma_lut,
+		.opp_configure_regamma_lut = dpp1_cm_configure_regamma_lut,
+		.opp_program_regamma_lutb_settings = dpp1_cm_program_regamma_lutb_settings,
+		.opp_program_regamma_luta_settings = dpp1_cm_program_regamma_luta_settings,
+		.opp_program_regamma_pwl = dpp1_cm_set_regamma_pwl,
+		.opp_set_regamma_mode = dpp1_cm_set_regamma_mode,
+		.ipp_set_degamma = dpp1_set_degamma,
+		.ipp_program_input_lut		= dpp1_program_input_lut,
+		.ipp_program_degamma_pwl	= dpp1_set_degamma_pwl,
+		.ipp_setup			= dpp1_cnv_setup,
+		.ipp_full_bypass		= dpp1_full_bypass,
+		.set_cursor_attributes = dpp1_set_cursor_attributes,
+		.set_cursor_position = dpp1_set_cursor_position,
 };
 
+static struct dpp_caps dcn10_dpp_cap = {
+	.dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT,
+	.dscl_calc_lb_num_partitions = dpp1_dscl_calc_lb_num_partitions,
+};
 
 /*****************************************/
 /* Constructor, Destructor               */
 /*****************************************/
 
-void dcn10_dpp_construct(
-	struct dcn10_dpp *xfm,
+void dpp1_construct(
+	struct dcn10_dpp *dpp,
 	struct dc_context *ctx,
 	uint32_t inst,
 	const struct dcn_dpp_registers *tf_regs,
 	const struct dcn_dpp_shift *tf_shift,
 	const struct dcn_dpp_mask *tf_mask)
 {
-	xfm->base.ctx = ctx;
+	dpp->base.ctx = ctx;
 
-	xfm->base.inst = inst;
-	xfm->base.funcs = &dcn10_dpp_funcs;
+	dpp->base.inst = inst;
+	dpp->base.funcs = &dcn10_dpp_funcs;
+	dpp->base.caps = &dcn10_dpp_cap;
 
-	xfm->tf_regs = tf_regs;
-	xfm->tf_shift = tf_shift;
-	xfm->tf_mask = tf_mask;
+	dpp->tf_regs = tf_regs;
+	dpp->tf_shift = tf_shift;
+	dpp->tf_mask = tf_mask;
 
-	xfm->lb_pixel_depth_supported =
+	dpp->lb_pixel_depth_supported =
 		LB_PIXEL_DEPTH_18BPP |
 		LB_PIXEL_DEPTH_24BPP |
 		LB_PIXEL_DEPTH_30BPP;
 
-	xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY;
-	xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
+	dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
+	dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
 }

+ 74 - 53
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h

@@ -25,10 +25,10 @@
 #ifndef __DAL_DPP_DCN10_H__
 #define __DAL_DPP_DCN10_H__
 
-#include "transform.h"
+#include "dpp.h"
 
-#define TO_DCN10_DPP(transform)\
-	container_of(transform, struct dcn10_dpp, base)
+#define TO_DCN10_DPP(dpp)\
+	container_of(dpp, struct dcn10_dpp, base)
 
 /* TODO: Use correct number of taps. Using polaris values for now */
 #define LB_TOTAL_NUMBER_OF_ENTRIES 5124
@@ -112,7 +112,9 @@
 	SRI(CM_DGAM_CONTROL, CM, id), \
 	SRI(FORMAT_CONTROL, CNVC_CFG, id), \
 	SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
-	SRI(CURSOR0_CONTROL, CNVC_CUR, id)
+	SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
+	SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
+	SRI(CURSOR0_COLOR1, CNVC_CUR, id)
 
 
 
@@ -162,7 +164,8 @@
 	SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \
 	SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \
 	SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \
-	SRI(CURSOR_CONTROL, CURSOR, id)
+	SRI(CURSOR_CONTROL, CURSOR, id), \
+	SRI(CM_CMOUT_CONTROL, CM, id)
 
 
 #define TF_REG_LIST_SH_MASK_DCN(mask_sh)\
@@ -302,7 +305,9 @@
 	TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
 	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
 	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
-	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh)
+	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
+	TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
+	TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
 
 #define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
 	TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@@ -397,6 +402,7 @@
 	TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \
 	TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \
 	TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \
+	TF_SF(CM0_CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, mask_sh), \
 	TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
 	TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
 	TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
@@ -545,6 +551,7 @@
 	type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \
 	type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \
 	type CM_RGAM_LUT_MODE; \
+	type CM_CMOUT_ROUND_TRUNC_MODE; \
 	type OBUF_BYPASS; \
 	type OBUF_H_2X_UPSCALE_EN; \
 	type CM_BLNDGAM_LUT_MODE; \
@@ -989,7 +996,9 @@
 	type CUR0_EXPANSION_MODE; \
 	type CUR0_ENABLE; \
 	type CM_BYPASS; \
-	type FORMAT_CONTROL__ALPHA_EN
+	type FORMAT_CONTROL__ALPHA_EN; \
+	type CUR0_COLOR0; \
+	type CUR0_COLOR1
 
 
 
@@ -1075,6 +1084,7 @@ struct dcn_dpp_registers {
 	uint32_t CM_RGAM_RAMA_REGION_0_1;
 	uint32_t CM_RGAM_RAMA_REGION_32_33;
 	uint32_t CM_RGAM_CONTROL;
+	uint32_t CM_CMOUT_CONTROL;
 	uint32_t OBUF_CONTROL;
 	uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK;
 	uint32_t CM_BLNDGAM_CONTROL;
@@ -1237,10 +1247,12 @@ struct dcn_dpp_registers {
 	uint32_t CNVC_SURFACE_PIXEL_FORMAT;
 	uint32_t CURSOR_CONTROL;
 	uint32_t CURSOR0_CONTROL;
+	uint32_t CURSOR0_COLOR0;
+	uint32_t CURSOR0_COLOR1;
 };
 
 struct dcn10_dpp {
-	struct transform base;
+	struct dpp base;
 
 	const struct dcn_dpp_registers *tf_regs;
 	const struct dcn_dpp_shift *tf_shift;
@@ -1256,107 +1268,116 @@ struct dcn10_dpp {
 	bool is_write_to_ram_a_safe;
 };
 
-
-
 enum dcn10_input_csc_select {
 	INPUT_CSC_SELECT_BYPASS = 0,
 	INPUT_CSC_SELECT_ICSC,
 	INPUT_CSC_SELECT_COMA
 };
 
-void ippn10_degamma_ram_select(
-		struct transform *xfm_base,
+bool dpp1_dscl_is_lb_conf_valid(
+		int ceil_vratio,
+		int num_partitions,
+		int vtaps);
+
+void dpp1_dscl_calc_lb_num_partitions(
+		const struct scaler_data *scl_data,
+		enum lb_memory_config lb_config,
+		int *num_part_y,
+		int *num_part_c);
+
+void dpp1_degamma_ram_select(
+		struct dpp *dpp_base,
 							bool use_ram_a);
 
-void ippn10_program_degamma_luta_settings(
-		struct transform *xfm_base,
+void dpp1_program_degamma_luta_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params);
 
-void ippn10_program_degamma_lutb_settings(
-		struct transform *xfm_base,
+void dpp1_program_degamma_lutb_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params);
 
-void ippn10_program_degamma_lut(
-		struct transform *xfm_base,
+void dpp1_program_degamma_lut(
+		struct dpp *dpp_base,
 		const struct pwl_result_data *rgb,
 		uint32_t num,
 		bool is_ram_a);
 
-void ippn10_power_on_degamma_lut(
-		struct transform *xfm_base,
+void dpp1_power_on_degamma_lut(
+		struct dpp *dpp_base,
 	bool power_on);
 
-void ippn10_program_input_csc(
-		struct transform *xfm_base,
+void dpp1_program_input_csc(
+		struct dpp *dpp_base,
 		enum dc_color_space color_space,
 		enum dcn10_input_csc_select select);
 
-void ippn10_program_input_lut(
-		struct transform *xfm_base,
+void dpp1_program_input_lut(
+		struct dpp *dpp_base,
 		const struct dc_gamma *gamma);
 
-void ippn10_full_bypass(struct transform *xfm_base);
+void dpp1_full_bypass(struct dpp *dpp_base);
 
-void ippn10_set_degamma(
-		struct transform *xfm_base,
+void dpp1_set_degamma(
+		struct dpp *dpp_base,
 		enum ipp_degamma_mode mode);
 
-void ippn10_set_degamma_pwl(struct transform *xfm_base,
+void dpp1_set_degamma_pwl(struct dpp *dpp_base,
 								 const struct pwl_params *params);
 
 bool dpp_get_optimal_number_of_taps(
-		struct transform *xfm,
+		struct dpp *dpp,
 		struct scaler_data *scl_data,
 		const struct scaling_taps *in_taps);
 
-void dpp_reset(struct transform *xfm_base);
+void dpp_reset(struct dpp *dpp_base);
 
-void dcn10_dpp_cm_program_regamma_lut(
-		struct transform *xfm_base,
+void dpp1_cm_program_regamma_lut(
+		struct dpp *dpp_base,
 		const struct pwl_result_data *rgb,
 		uint32_t num);
 
-void dcn10_dpp_cm_power_on_regamma_lut(
-	struct transform *xfm_base,
+void dpp1_cm_power_on_regamma_lut(
+	struct dpp *dpp_base,
 	bool power_on);
 
-void dcn10_dpp_cm_configure_regamma_lut(
-		struct transform *xfm_base,
+void dpp1_cm_configure_regamma_lut(
+		struct dpp *dpp_base,
 		bool is_ram_a);
 
 /*program re gamma RAM A*/
-void dcn10_dpp_cm_program_regamma_luta_settings(
-		struct transform *xfm_base,
+void dpp1_cm_program_regamma_luta_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params);
 
 /*program re gamma RAM B*/
-void dcn10_dpp_cm_program_regamma_lutb_settings(
-		struct transform *xfm_base,
+void dpp1_cm_program_regamma_lutb_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params);
-void dcn10_dpp_cm_set_output_csc_adjustment(
-		struct transform *xfm_base,
+void dpp1_cm_set_output_csc_adjustment(
+		struct dpp *dpp_base,
 		const struct out_csc_color_matrix *tbl_entry);
 
-void dcn10_dpp_cm_set_output_csc_default(
-		struct transform *xfm_base,
+void dpp1_cm_set_output_csc_default(
+		struct dpp *dpp_base,
 		const struct default_adjustment *default_adjust);
 
-void dcn10_dpp_cm_set_gamut_remap(
-	struct transform *xfm,
-	const struct xfm_grph_csc_adjustment *adjust);
+void dpp1_cm_set_gamut_remap(
+	struct dpp *dpp,
+	const struct dpp_grph_csc_adjustment *adjust);
 
-void dcn10_dpp_dscl_set_scaler_manual_scale(
-	struct transform *xfm_base,
+void dpp1_dscl_set_scaler_manual_scale(
+	struct dpp *dpp_base,
 	const struct scaler_data *scl_data);
 
-void ippn10_cnv_setup (
-		struct transform *xfm_base,
+void dpp1_cnv_setup (
+		struct dpp *dpp_base,
 		enum surface_pixel_format input_format,
 		enum expansion_mode mode);
 
-void ippn10_full_bypass(struct transform *xfm_base);
+void dpp1_full_bypass(struct dpp *dpp_base);
 
-void dcn10_dpp_construct(struct dcn10_dpp *xfm110,
+void dpp1_construct(struct dcn10_dpp *dpp1,
 	struct dc_context *ctx,
 	uint32_t inst,
 	const struct dcn_dpp_registers *tf_regs,

+ 132 - 131
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c

@@ -29,8 +29,8 @@
 
 #include "reg_helper.h"
 #include "dcn10_dpp.h"
-#include "dcn10_dpp_cm_helper.h"
 #include "basics/conversion.h"
+#include "dcn10_cm_common.h"
 
 #define NUM_PHASES    64
 #define HORZ_MAX_TAPS 8
@@ -40,14 +40,14 @@
 #define BLACK_OFFSET_CBCR  0x8000
 
 #define REG(reg)\
-	xfm->tf_regs->reg
+	dpp->tf_regs->reg
 
 #define CTX \
-	xfm->base.ctx
+	dpp->base.ctx
 
 #undef FN
 #define FN(reg_name, field_name) \
-	xfm->tf_shift->field_name, xfm->tf_mask->field_name
+	dpp->tf_shift->field_name, dpp->tf_mask->field_name
 
 struct dcn10_input_csc_matrix {
 	enum dc_color_space color_space;
@@ -120,7 +120,7 @@ static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = {
 
 
 static void program_gamut_remap(
-		struct dcn10_dpp *xfm,
+		struct dcn10_dpp *dpp,
 		const uint16_t *regval,
 		enum gamut_remap_select select)
 {
@@ -146,10 +146,10 @@ static void program_gamut_remap(
 		break;
 	}
 
-	gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_GAMUT_REMAP_C11;
-	gam_regs.masks.csc_c11  = xfm->tf_mask->CM_GAMUT_REMAP_C11;
-	gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_GAMUT_REMAP_C12;
-	gam_regs.masks.csc_c12 = xfm->tf_mask->CM_GAMUT_REMAP_C12;
+	gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
+	gam_regs.masks.csc_c11  = dpp->tf_mask->CM_GAMUT_REMAP_C11;
+	gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
+	gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
 
 
 	if (select == GAMUT_REMAP_COEFF) {
@@ -157,7 +157,7 @@ static void program_gamut_remap(
 		gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				regval,
 				&gam_regs);
 
@@ -167,7 +167,7 @@ static void program_gamut_remap(
 		gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				regval,
 				&gam_regs);
 
@@ -177,7 +177,7 @@ static void program_gamut_remap(
 		gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				regval,
 				&gam_regs);
 	}
@@ -188,15 +188,15 @@ static void program_gamut_remap(
 
 }
 
-void dcn10_dpp_cm_set_gamut_remap(
-	struct transform *xfm,
-	const struct xfm_grph_csc_adjustment *adjust)
+void dpp1_cm_set_gamut_remap(
+	struct dpp *dpp_base,
+	const struct dpp_grph_csc_adjustment *adjust)
 {
-	struct dcn10_dpp *dcn_xfm = TO_DCN10_DPP(xfm);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
 		/* Bypass if type is bypass or hw */
-		program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS);
+		program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS);
 	else {
 		struct fixed31_32 arr_matrix[12];
 		uint16_t arr_reg_val[12];
@@ -219,16 +219,16 @@ void dcn10_dpp_cm_set_gamut_remap(
 		convert_float_matrix(
 			arr_reg_val, arr_matrix, 12);
 
-		program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF);
+		program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF);
 	}
 }
 
-void dcn10_dpp_cm_set_output_csc_default(
-		struct transform *xfm_base,
+void dpp1_cm_set_output_csc_default(
+		struct dpp *dpp_base,
 		const struct default_adjustment *default_adjust)
 {
 
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	uint32_t ocsc_mode = 0;
 
 	if (default_adjust != NULL) {
@@ -260,35 +260,35 @@ void dcn10_dpp_cm_set_output_csc_default(
 
 }
 
-static void dcn10_dpp_cm_get_reg_field(
-		struct dcn10_dpp *xfm,
+static void dpp1_cm_get_reg_field(
+		struct dcn10_dpp *dpp,
 		struct xfer_func_reg *reg)
 {
-	reg->shifts.exp_region0_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
-	reg->masks.exp_region0_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
-	reg->shifts.exp_region0_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
-	reg->masks.exp_region0_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
-	reg->shifts.exp_region1_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
-	reg->masks.exp_region1_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
-	reg->shifts.exp_region1_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
-	reg->masks.exp_region1_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
-
-	reg->shifts.field_region_end = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
-	reg->masks.field_region_end = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
-	reg->shifts.field_region_end_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
-	reg->masks.field_region_end_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
-	reg->shifts.field_region_end_base = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
-	reg->masks.field_region_end_base = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
-	reg->shifts.field_region_linear_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
-	reg->masks.field_region_linear_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
-	reg->shifts.exp_region_start = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
-	reg->masks.exp_region_start = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
-	reg->shifts.exp_resion_start_segment = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
-	reg->masks.exp_resion_start_segment = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+	reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+	reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+	reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+	reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+	reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+	reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+	reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+	reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+
+	reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
+	reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
+	reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
+	reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
+	reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
+	reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
+	reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+	reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+	reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
+	reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
+	reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+	reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
 }
 
-static void dcn10_dpp_cm_program_color_matrix(
-		struct dcn10_dpp *xfm,
+static void dpp1_cm_program_color_matrix(
+		struct dcn10_dpp *dpp,
 		const struct out_csc_color_matrix *tbl_entry)
 {
 	uint32_t mode;
@@ -301,10 +301,10 @@ static void dcn10_dpp_cm_program_color_matrix(
 		return;
 	}
 
-	gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_OCSC_C11;
-	gam_regs.masks.csc_c11  = xfm->tf_mask->CM_OCSC_C11;
-	gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_OCSC_C12;
-	gam_regs.masks.csc_c12 = xfm->tf_mask->CM_OCSC_C12;
+	gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
+	gam_regs.masks.csc_c11  = dpp->tf_mask->CM_OCSC_C11;
+	gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
+	gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12;
 
 	if (mode == 4) {
 
@@ -312,7 +312,7 @@ static void dcn10_dpp_cm_program_color_matrix(
 		gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				tbl_entry->regval,
 				&gam_regs);
 
@@ -322,17 +322,17 @@ static void dcn10_dpp_cm_program_color_matrix(
 		gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				tbl_entry->regval,
 				&gam_regs);
 	}
 }
 
-void dcn10_dpp_cm_set_output_csc_adjustment(
-		struct transform *xfm_base,
+void dpp1_cm_set_output_csc_adjustment(
+		struct dpp *dpp_base,
 		const struct out_csc_color_matrix *tbl_entry)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	//enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
 	uint32_t ocsc_mode = 4;
 
@@ -364,26 +364,26 @@ void dcn10_dpp_cm_set_output_csc_adjustment(
 	*/
 
 	REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
-	dcn10_dpp_cm_program_color_matrix(xfm, tbl_entry);
+	dpp1_cm_program_color_matrix(dpp, tbl_entry);
 }
 
-void dcn10_dpp_cm_power_on_regamma_lut(
-	struct transform *xfm_base,
+void dpp1_cm_power_on_regamma_lut(
+	struct dpp *dpp_base,
 	bool power_on)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	REG_SET(CM_MEM_PWR_CTRL, 0,
 			RGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
 
 }
 
-void dcn10_dpp_cm_program_regamma_lut(
-		struct transform *xfm_base,
+void dpp1_cm_program_regamma_lut(
+		struct dpp *dpp_base,
 		const struct pwl_result_data *rgb,
 		uint32_t num)
 {
 	uint32_t i;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	for (i = 0 ; i < num; i++) {
 		REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg);
 		REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg);
@@ -400,11 +400,11 @@ void dcn10_dpp_cm_program_regamma_lut(
 
 }
 
-void dcn10_dpp_cm_configure_regamma_lut(
-		struct transform *xfm_base,
+void dpp1_cm_configure_regamma_lut(
+		struct dpp *dpp_base,
 		bool is_ram_a)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK,
 			CM_RGAM_LUT_WRITE_EN_MASK, 7);
@@ -414,14 +414,14 @@ void dcn10_dpp_cm_configure_regamma_lut(
 }
 
 /*program re gamma RAM A*/
-void dcn10_dpp_cm_program_regamma_luta_settings(
-		struct transform *xfm_base,
+void dpp1_cm_program_regamma_luta_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	struct xfer_func_reg gam_regs;
 
-	dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+	dpp1_cm_get_reg_field(dpp, &gam_regs);
 
 	gam_regs.start_cntl_b = REG(CM_RGAM_RAMA_START_CNTL_B);
 	gam_regs.start_cntl_g = REG(CM_RGAM_RAMA_START_CNTL_G);
@@ -438,19 +438,19 @@ void dcn10_dpp_cm_program_regamma_luta_settings(
 	gam_regs.region_start = REG(CM_RGAM_RAMA_REGION_0_1);
 	gam_regs.region_end = REG(CM_RGAM_RAMA_REGION_32_33);
 
-	cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 
 }
 
 /*program re gamma RAM B*/
-void dcn10_dpp_cm_program_regamma_lutb_settings(
-		struct transform *xfm_base,
+void dpp1_cm_program_regamma_lutb_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	struct xfer_func_reg gam_regs;
 
-	dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+	dpp1_cm_get_reg_field(dpp, &gam_regs);
 
 	gam_regs.start_cntl_b = REG(CM_RGAM_RAMB_START_CNTL_B);
 	gam_regs.start_cntl_g = REG(CM_RGAM_RAMB_START_CNTL_G);
@@ -467,15 +467,15 @@ void dcn10_dpp_cm_program_regamma_lutb_settings(
 	gam_regs.region_start = REG(CM_RGAM_RAMB_REGION_0_1);
 	gam_regs.region_end = REG(CM_RGAM_RAMB_REGION_32_33);
 
-	cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 }
 
-void ippn10_program_input_csc(
-		struct transform *xfm_base,
+void dpp1_program_input_csc(
+		struct dpp *dpp_base,
 		enum dc_color_space color_space,
 		enum dcn10_input_csc_select select)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	int i;
 	int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix);
 	const uint16_t *regval = NULL;
@@ -503,10 +503,10 @@ void ippn10_program_input_csc(
 	REG_SET(CM_ICSC_CONTROL, 0,
 			CM_ICSC_MODE, selection);
 
-	gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_ICSC_C11;
-	gam_regs.masks.csc_c11  = xfm->tf_mask->CM_ICSC_C11;
-	gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_ICSC_C12;
-	gam_regs.masks.csc_c12 = xfm->tf_mask->CM_ICSC_C12;
+	gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
+	gam_regs.masks.csc_c11  = dpp->tf_mask->CM_ICSC_C11;
+	gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
+	gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
 
 
 	if (select == INPUT_CSC_SELECT_ICSC) {
@@ -515,7 +515,7 @@ void ippn10_program_input_csc(
 		gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				regval,
 				&gam_regs);
 	} else {
@@ -524,21 +524,21 @@ void ippn10_program_input_csc(
 		gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
 
 		cm_helper_program_color_matrices(
-				xfm->base.ctx,
+				dpp->base.ctx,
 				regval,
 				&gam_regs);
 	}
 }
 
 /*program de gamma RAM B*/
-void ippn10_program_degamma_lutb_settings(
-		struct transform *xfm_base,
+void dpp1_program_degamma_lutb_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	struct xfer_func_reg gam_regs;
 
-	dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+	dpp1_cm_get_reg_field(dpp, &gam_regs);
 
 	gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B);
 	gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G);
@@ -556,18 +556,18 @@ void ippn10_program_degamma_lutb_settings(
 	gam_regs.region_end = REG(CM_DGAM_RAMB_REGION_14_15);
 
 
-	cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 }
 
 /*program de gamma RAM A*/
-void ippn10_program_degamma_luta_settings(
-		struct transform *xfm_base,
+void dpp1_program_degamma_luta_settings(
+		struct dpp *dpp_base,
 		const struct pwl_params *params)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	struct xfer_func_reg gam_regs;
 
-	dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+	dpp1_cm_get_reg_field(dpp, &gam_regs);
 
 	gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B);
 	gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G);
@@ -584,34 +584,35 @@ void ippn10_program_degamma_luta_settings(
 	gam_regs.region_start = REG(CM_DGAM_RAMA_REGION_0_1);
 	gam_regs.region_end = REG(CM_DGAM_RAMA_REGION_14_15);
 
-	cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 }
 
-void ippn10_power_on_degamma_lut(
-		struct transform *xfm_base,
+void dpp1_power_on_degamma_lut(
+		struct dpp *dpp_base,
 	bool power_on)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	REG_SET(CM_MEM_PWR_CTRL, 0,
 			SHARED_MEM_PWR_DIS, power_on == true ? 0:1);
 
 }
 
-static void ippn10_enable_cm_block(
-		struct transform *xfm_base)
+static void dpp1_enable_cm_block(
+		struct dpp *dpp_base)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
+	REG_UPDATE(CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, 8);
 	REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0);
 }
 
-void ippn10_set_degamma(
-		struct transform *xfm_base,
+void dpp1_set_degamma(
+		struct dpp *dpp_base,
 		enum ipp_degamma_mode mode)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
-	ippn10_enable_cm_block(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+	dpp1_enable_cm_block(dpp_base);
 
 	switch (mode) {
 	case IPP_DEGAMMA_MODE_BYPASS:
@@ -630,11 +631,11 @@ void ippn10_set_degamma(
 	}
 }
 
-void ippn10_degamma_ram_select(
-		struct transform *xfm_base,
+void dpp1_degamma_ram_select(
+		struct dpp *dpp_base,
 							bool use_ram_a)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	if (use_ram_a)
 		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
@@ -643,13 +644,13 @@ void ippn10_degamma_ram_select(
 
 }
 
-static bool ippn10_degamma_ram_inuse(
-		struct transform *xfm_base,
+static bool dpp1_degamma_ram_inuse(
+		struct dpp *dpp_base,
 							bool *ram_a_inuse)
 {
 	bool ret = false;
 	uint32_t status_reg = 0;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
 			&status_reg);
@@ -664,15 +665,15 @@ static bool ippn10_degamma_ram_inuse(
 	return ret;
 }
 
-void ippn10_program_degamma_lut(
-		struct transform *xfm_base,
+void dpp1_program_degamma_lut(
+		struct dpp *dpp_base,
 		const struct pwl_result_data *rgb,
 		uint32_t num,
 		bool is_ram_a)
 {
 	uint32_t i;
 
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0);
 	REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
 				   CM_DGAM_LUT_WRITE_EN_MASK, 7);
@@ -694,27 +695,27 @@ void ippn10_program_degamma_lut(
 	}
 }
 
-void ippn10_set_degamma_pwl(struct transform *xfm_base,
+void dpp1_set_degamma_pwl(struct dpp *dpp_base,
 								 const struct pwl_params *params)
 {
 	bool is_ram_a = true;
 
-	ippn10_power_on_degamma_lut(xfm_base, true);
-	ippn10_enable_cm_block(xfm_base);
-	ippn10_degamma_ram_inuse(xfm_base, &is_ram_a);
+	dpp1_power_on_degamma_lut(dpp_base, true);
+	dpp1_enable_cm_block(dpp_base);
+	dpp1_degamma_ram_inuse(dpp_base, &is_ram_a);
 	if (is_ram_a == true)
-		ippn10_program_degamma_lutb_settings(xfm_base, params);
+		dpp1_program_degamma_lutb_settings(dpp_base, params);
 	else
-		ippn10_program_degamma_luta_settings(xfm_base, params);
+		dpp1_program_degamma_luta_settings(dpp_base, params);
 
-	ippn10_program_degamma_lut(xfm_base, params->rgb_resulted,
+	dpp1_program_degamma_lut(dpp_base, params->rgb_resulted,
 							params->hw_points_num, !is_ram_a);
-	ippn10_degamma_ram_select(xfm_base, !is_ram_a);
+	dpp1_degamma_ram_select(dpp_base, !is_ram_a);
 }
 
-void ippn10_full_bypass(struct transform *xfm_base)
+void dpp1_full_bypass(struct dpp *dpp_base)
 {
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	/* Input pixel format: ARGB8888 */
 	REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
@@ -727,19 +728,19 @@ void ippn10_full_bypass(struct transform *xfm_base)
 			FORMAT_EXPANSION_MODE, 0);
 
 	/* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */
-	if (xfm->tf_mask->CM_BYPASS_EN)
+	if (dpp->tf_mask->CM_BYPASS_EN)
 		REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1);
 
 	/* Setting degamma bypass for now */
 	REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0);
 }
 
-static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
+static bool dpp1_ingamma_ram_inuse(struct dpp *dpp_base,
 							bool *ram_a_inuse)
 {
 	bool in_use = false;
 	uint32_t status_reg = 0;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 
 	REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
 				&status_reg);
@@ -765,19 +766,19 @@ static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
  * In the future, this function should support additional input gamma methods,
  * such as piecewise linear mapping, and input gamma bypass.
  */
-void ippn10_program_input_lut(
-		struct transform *xfm_base,
+void dpp1_program_input_lut(
+		struct dpp *dpp_base,
 		const struct dc_gamma *gamma)
 {
 	int i;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
 	bool rama_occupied = false;
 	uint32_t ram_num;
 	// Power on LUT memory.
 	REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1);
-	ippn10_enable_cm_block(xfm_base);
+	dpp1_enable_cm_block(dpp_base);
 	// Determine whether to use RAM A or RAM B
-	ippn10_ingamma_ram_inuse(xfm_base, &rama_occupied);
+	dpp1_ingamma_ram_inuse(dpp_base, &rama_occupied);
 	if (!rama_occupied)
 		REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0);
 	else

+ 121 - 129
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c

@@ -31,6 +31,7 @@
 #include "dcn10_dpp.h"
 #include "basics/conversion.h"
 
+
 #define NUM_PHASES    64
 #define HORZ_MAX_TAPS 8
 #define VERT_MAX_TAPS 8
@@ -39,14 +40,14 @@
 #define BLACK_OFFSET_CBCR  0x8000
 
 #define REG(reg)\
-	xfm->tf_regs->reg
+	dpp->tf_regs->reg
 
 #define CTX \
-	xfm->base.ctx
+	dpp->base.ctx
 
 #undef FN
 #define FN(reg_name, field_name) \
-	xfm->tf_shift->field_name, xfm->tf_mask->field_name
+	dpp->tf_shift->field_name, dpp->tf_mask->field_name
 
 enum dcn10_coef_filter_type_sel {
 	SCL_COEF_LUMA_VERT_FILTER = 0,
@@ -57,22 +58,6 @@ enum dcn10_coef_filter_type_sel {
 	SCL_COEF_ALPHA_HORZ_FILTER = 5
 };
 
-enum lb_memory_config {
-	/* Enable all 3 pieces of memory */
-	LB_MEMORY_CONFIG_0 = 0,
-
-	/* Enable only the first piece of memory */
-	LB_MEMORY_CONFIG_1 = 1,
-
-	/* Enable only the second piece of memory */
-	LB_MEMORY_CONFIG_2 = 2,
-
-	/* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
-	 * last piece of chroma memory used for the luma storage
-	 */
-	LB_MEMORY_CONFIG_3 = 3
-};
-
 enum dscl_autocal_mode {
 	AUTOCAL_MODE_OFF = 0,
 
@@ -100,8 +85,8 @@ enum dscl_mode_sel {
 	DSCL_MODE_DSCL_BYPASS = 6
 };
 
-static void dpp_set_overscan(
-	struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_overscan(
+	struct dcn10_dpp *dpp,
 	const struct scaler_data *data)
 {
 	uint32_t left = data->recout.x;
@@ -128,8 +113,8 @@ static void dpp_set_overscan(
 		EXT_OVERSCAN_TOP, top);
 }
 
-static void dpp_set_otg_blank(
-		struct dcn10_dpp *xfm, const struct scaler_data *data)
+static void dpp1_dscl_set_otg_blank(
+		struct dcn10_dpp *dpp, const struct scaler_data *data)
 {
 	uint32_t h_blank_start = data->h_active;
 	uint32_t h_blank_end = 0;
@@ -145,7 +130,7 @@ static void dpp_set_otg_blank(
 			OTG_V_BLANK_END, v_blank_end);
 }
 
-static int get_pixel_depth_val(enum lb_pixel_depth depth)
+static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)
 {
 	if (depth == LB_PIXEL_DEPTH_30BPP)
 		return 0; /* 10 bpc */
@@ -161,23 +146,36 @@ static int get_pixel_depth_val(enum lb_pixel_depth depth)
 	}
 }
 
-static enum dscl_mode_sel get_dscl_mode(
-		const struct scaler_data *data, bool dbg_always_scale)
+static bool dpp1_dscl_is_video_format(enum pixel_format format)
 {
-	const long long one = dal_fixed31_32_one.value;
-	bool ycbcr = false;
-	bool format420 = false;
+	if (format >= PIXEL_FORMAT_VIDEO_BEGIN
+			&& format <= PIXEL_FORMAT_VIDEO_END)
+		return true;
+	else
+		return false;
+}
 
-	if (data->format == PIXEL_FORMAT_FP16)
-		return DSCL_MODE_DSCL_BYPASS;
+static bool dpp1_dscl_is_420_format(enum pixel_format format)
+{
+	if (format == PIXEL_FORMAT_420BPP8 ||
+			format == PIXEL_FORMAT_420BPP10)
+		return true;
+	else
+		return false;
+}
 
-	if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN
-			&& data->format <= PIXEL_FORMAT_VIDEO_END)
-		ycbcr = true;
+static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
+		struct dpp *dpp_base,
+		const struct scaler_data *data,
+		bool dbg_always_scale)
+{
+	const long long one = dal_fixed31_32_one.value;
 
-	if (data->format == PIXEL_FORMAT_420BPP8 ||
-			data->format == PIXEL_FORMAT_420BPP10)
-		format420 = true;
+	if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
+		/* DSCL is processing data in fixed format */
+		if (data->format == PIXEL_FORMAT_FP16)
+			return DSCL_MODE_DSCL_BYPASS;
+	}
 
 	if (data->ratios.horz.value == one
 			&& data->ratios.vert.value == one
@@ -186,8 +184,8 @@ static enum dscl_mode_sel get_dscl_mode(
 			&& !dbg_always_scale)
 		return DSCL_MODE_SCALING_444_BYPASS;
 
-	if (!format420) {
-		if (ycbcr)
+	if (!dpp1_dscl_is_420_format(data->format)) {
+		if (dpp1_dscl_is_video_format(data->format))
 			return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
 		else
 			return DSCL_MODE_SCALING_444_RGB_ENABLE;
@@ -200,16 +198,17 @@ static enum dscl_mode_sel get_dscl_mode(
 	return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
 }
 
-static void dpp_set_lb(
-	struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_lb(
+	struct dcn10_dpp *dpp,
 	const struct line_buffer_params *lb_params,
 	enum lb_memory_config mem_size_config)
 {
-	uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth);
-	uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
-
 	/* LB */
-	if (xfm->tf_mask->PIXEL_DEPTH) {
+	if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
+		/* DSCL caps: pixel data processed in fixed format */
+		uint32_t pixel_depth = dpp1_dscl_get_pixel_depth_val(lb_params->depth);
+		uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
+
 		REG_SET_7(LB_DATA_FORMAT, 0,
 			PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */
 			PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */
@@ -225,7 +224,7 @@ static void dpp_set_lb(
 		LB_MAX_PARTITIONS, 63);
 }
 
-static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
+static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
 {
 	if (taps == 8)
 		return get_filter_8tap_64p(ratio);
@@ -250,8 +249,8 @@ static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
 	}
 }
 
-static void dpp_set_scaler_filter(
-		struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_scaler_filter(
+		struct dcn10_dpp *dpp,
 		uint32_t taps,
 		enum dcn10_coef_filter_type_sel filter_type,
 		const uint16_t *filter)
@@ -288,8 +287,8 @@ static void dpp_set_scaler_filter(
 
 }
 
-static void dpp_set_scl_filter(
-		struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_scl_filter(
+		struct dcn10_dpp *dpp,
 		const struct scaler_data *scl_data,
 		bool chroma_coef_mode)
 {
@@ -307,10 +306,10 @@ static void dpp_set_scl_filter(
 
 	h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3
 					&& scl_data->taps.h_taps_c < 3
-		&& (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1);
+		&& (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1);
 	v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3
 					&& scl_data->taps.v_taps_c < 3
-		&& (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1);
+		&& (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1);
 
 	h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0;
 	v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0;
@@ -326,56 +325,56 @@ static void dpp_set_scl_filter(
 	if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) {
 		bool filter_updated = false;
 
-		filter_h = get_filter_coeffs_64p(
+		filter_h = dpp1_dscl_get_filter_coeffs_64p(
 				scl_data->taps.h_taps, scl_data->ratios.horz);
-		filter_v = get_filter_coeffs_64p(
+		filter_v = dpp1_dscl_get_filter_coeffs_64p(
 				scl_data->taps.v_taps, scl_data->ratios.vert);
 
-		filter_updated = (filter_h && (filter_h != xfm->filter_h))
-				|| (filter_v && (filter_v != xfm->filter_v));
+		filter_updated = (filter_h && (filter_h != dpp->filter_h))
+				|| (filter_v && (filter_v != dpp->filter_v));
 
 		if (chroma_coef_mode) {
-			filter_h_c = get_filter_coeffs_64p(
+			filter_h_c = dpp1_dscl_get_filter_coeffs_64p(
 					scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
-			filter_v_c = get_filter_coeffs_64p(
+			filter_v_c = dpp1_dscl_get_filter_coeffs_64p(
 					scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
-			filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c))
-							|| (filter_v_c && (filter_v_c != xfm->filter_v_c));
+			filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c))
+							|| (filter_v_c && (filter_v_c != dpp->filter_v_c));
 		}
 
 		if (filter_updated) {
 			uint32_t scl_mode = REG_READ(SCL_MODE);
 
 			if (!h_2tap_hardcode_coef_en && filter_h) {
-				dpp_set_scaler_filter(
-					xfm, scl_data->taps.h_taps,
+				dpp1_dscl_set_scaler_filter(
+					dpp, scl_data->taps.h_taps,
 					SCL_COEF_LUMA_HORZ_FILTER, filter_h);
 			}
-			xfm->filter_h = filter_h;
+			dpp->filter_h = filter_h;
 			if (!v_2tap_hardcode_coef_en && filter_v) {
-				dpp_set_scaler_filter(
-					xfm, scl_data->taps.v_taps,
+				dpp1_dscl_set_scaler_filter(
+					dpp, scl_data->taps.v_taps,
 					SCL_COEF_LUMA_VERT_FILTER, filter_v);
 			}
-			xfm->filter_v = filter_v;
+			dpp->filter_v = filter_v;
 			if (chroma_coef_mode) {
 				if (!h_2tap_hardcode_coef_en && filter_h_c) {
-					dpp_set_scaler_filter(
-						xfm, scl_data->taps.h_taps_c,
+					dpp1_dscl_set_scaler_filter(
+						dpp, scl_data->taps.h_taps_c,
 						SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
 				}
 				if (!v_2tap_hardcode_coef_en && filter_v_c) {
-					dpp_set_scaler_filter(
-						xfm, scl_data->taps.v_taps_c,
+					dpp1_dscl_set_scaler_filter(
+						dpp, scl_data->taps.v_taps_c,
 						SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
 				}
 			}
-			xfm->filter_h_c = filter_h_c;
-			xfm->filter_v_c = filter_v_c;
+			dpp->filter_h_c = filter_h_c;
+			dpp->filter_v_c = filter_v_c;
 
 			coef_ram_current = get_reg_field_value_ex(
-				scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
-				xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
+				scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
+				dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
 
 			/* Swap coefficient RAM and set chroma coefficient mode */
 			REG_SET_2(SCL_MODE, scl_mode,
@@ -385,7 +384,7 @@ static void dpp_set_scl_filter(
 	}
 }
 
-static int get_lb_depth_bpc(enum lb_pixel_depth depth)
+static int dpp1_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth)
 {
 	if (depth == LB_PIXEL_DEPTH_30BPP)
 		return 10;
@@ -401,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth)
 	}
 }
 
-static void calc_lb_num_partitions(
+void dpp1_dscl_calc_lb_num_partitions(
 		const struct scaler_data *scl_data,
 		enum lb_memory_config lb_config,
 		int *num_part_y,
@@ -411,7 +410,7 @@ static void calc_lb_num_partitions(
 			scl_data->viewport.width : scl_data->recout.width;
 	int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
 			scl_data->viewport_c.width : scl_data->recout.width;
-	int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth);
+	int lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
 	int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
 	int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
 	int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
@@ -426,6 +425,7 @@ static void calc_lb_num_partitions(
 		lb_memory_size_c = 1088;
 		lb_memory_size_a = 1312;
 	} else if (lb_config == LB_MEMORY_CONFIG_3) {
+		/* 420 mode: using 3rd mem from Y, Cr and Cb */
 		lb_memory_size = 816 + 1088 + 848 + 848 + 848;
 		lb_memory_size_c = 816 + 1088;
 		lb_memory_size_a = 984 + 1312 + 456;
@@ -449,7 +449,7 @@ static void calc_lb_num_partitions(
 
 }
 
-static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
+bool dpp1_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
 {
 	if (ceil_vratio > 2)
 		return vtaps <= (num_partitions - ceil_vratio + 2);
@@ -458,7 +458,7 @@ static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
 }
 
 /*find first match configuration which meets the min required lb size*/
-static enum lb_memory_config dpp10_find_lb_memory_config(
+static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *dpp,
 		const struct scaler_data *scl_data)
 {
 	int num_part_y, num_part_c;
@@ -466,75 +466,67 @@ static enum lb_memory_config dpp10_find_lb_memory_config(
 	int vtaps_c = scl_data->taps.v_taps_c;
 	int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert);
 	int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c);
+	enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
+
+	if (dpp->base.ctx->dc->debug.use_max_lb)
+		return mem_cfg;
 
-	calc_lb_num_partitions(
+	dpp->base.caps->dscl_calc_lb_num_partitions(
 			scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
 
-	if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
-			&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
+	if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+			&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
 		return LB_MEMORY_CONFIG_1;
 
-	calc_lb_num_partitions(
+	dpp->base.caps->dscl_calc_lb_num_partitions(
 			scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c);
 
-	if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
-			&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
+	if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+			&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
 		return LB_MEMORY_CONFIG_2;
 
 	if (scl_data->format == PIXEL_FORMAT_420BPP8
 			|| scl_data->format == PIXEL_FORMAT_420BPP10) {
-		calc_lb_num_partitions(
+		dpp->base.caps->dscl_calc_lb_num_partitions(
 				scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c);
 
-		if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
-				&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
+		if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+				&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
 			return LB_MEMORY_CONFIG_3;
 	}
 
-	calc_lb_num_partitions(
+	dpp->base.caps->dscl_calc_lb_num_partitions(
 			scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c);
 
 	/*Ensure we can support the requested number of vtaps*/
-	ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
-			&& is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
+	ASSERT(dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+			&& dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
 
 	return LB_MEMORY_CONFIG_0;
 }
 
-/*find first match configuration which meets the min required lb size*/
-static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm,
-		const struct scaler_data *scl_data)
-{
-	enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
-
-	if (xfm->tf_mask->PIXEL_DEPTH) {
-		mem_cfg = dpp10_find_lb_memory_config(scl_data);
-	}
-	return mem_cfg;
-}
-
-void dpp_set_scaler_auto_scale(
-	struct transform *xfm_base,
+void dpp1_dscl_set_scaler_auto_scale(
+	struct dpp *dpp_base,
 	const struct scaler_data *scl_data)
 {
 	enum lb_memory_config lb_config;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
-	enum dscl_mode_sel dscl_mode = get_dscl_mode(
-			scl_data, xfm_base->ctx->dc->debug.always_scale);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+	enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
+			dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
 	bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
 				&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
 
-	dpp_set_overscan(xfm, scl_data);
+	dpp1_dscl_set_overscan(dpp, scl_data);
 
-	dpp_set_otg_blank(xfm, scl_data);
+	dpp1_dscl_set_otg_blank(dpp, scl_data);
 
 	REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
 
 	if (dscl_mode == DSCL_MODE_DSCL_BYPASS)
 		return;
 
-	lb_config =  find_lb_memory_config(xfm, scl_data);
-	dpp_set_lb(xfm, &scl_data->lb_params, lb_config);
+	lb_config =  dpp1_dscl_find_lb_memory_config(dpp, scl_data);
+	dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
 
 	if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
 		return;
@@ -562,12 +554,12 @@ void dpp_set_scaler_auto_scale(
 		SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
 		SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
 
-	dpp_set_scl_filter(xfm, scl_data, ycbcr);
+	dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
 }
 
 
-static void dpp_set_manual_ratio_init(
-		struct dcn10_dpp *xfm, const struct scaler_data *data)
+static void dpp1_dscl_set_manual_ratio_init(
+		struct dcn10_dpp *dpp, const struct scaler_data *data)
 {
 	uint32_t init_frac = 0;
 	uint32_t init_int = 0;
@@ -626,8 +618,8 @@ static void dpp_set_manual_ratio_init(
 
 
 
-static void dpp_set_recout(
-			struct dcn10_dpp *xfm, const struct rect *recout)
+static void dpp1_dscl_set_recout(
+			struct dcn10_dpp *dpp, const struct rect *recout)
 {
 	REG_SET_2(RECOUT_START, 0,
 		/* First pixel of RECOUT */
@@ -640,24 +632,24 @@ static void dpp_set_recout(
 			 RECOUT_WIDTH, recout->width,
 		/* Number of RECOUT vertical lines */
 			 RECOUT_HEIGHT, recout->height
-			 - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 *
-			 (xfm->base.inst + 1));
+			 - dpp->base.ctx->dc->debug.surface_visual_confirm * 4 *
+			 (dpp->base.inst + 1));
 }
 
 /* Main function to program scaler and line buffer in manual scaling mode */
-void dcn10_dpp_dscl_set_scaler_manual_scale(
-	struct transform *xfm_base,
+void dpp1_dscl_set_scaler_manual_scale(
+	struct dpp *dpp_base,
 	const struct scaler_data *scl_data)
 {
 	enum lb_memory_config lb_config;
-	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
-	enum dscl_mode_sel dscl_mode = get_dscl_mode(
-			scl_data, xfm_base->ctx->dc->debug.always_scale);
+	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+	enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
+			dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
 	bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
 				&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
 
 	/* Recout */
-	dpp_set_recout(xfm, &scl_data->recout);
+	dpp1_dscl_set_recout(dpp, &scl_data->recout);
 
 	/* MPC Size */
 	REG_SET_2(MPC_SIZE, 0,
@@ -673,8 +665,8 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
 		return;
 
 	/* LB */
-	lb_config =  find_lb_memory_config(xfm, scl_data);
-	dpp_set_lb(xfm, &scl_data->lb_params, lb_config);
+	lb_config =  dpp1_dscl_find_lb_memory_config(dpp, scl_data);
+	dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
 
 	if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
 		return;
@@ -697,7 +689,7 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
 				SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
 
 	/* Manually calculate scale ratio and init values */
-	dpp_set_manual_ratio_init(xfm, scl_data);
+	dpp1_dscl_set_manual_ratio_init(dpp, scl_data);
 
 	/* HTaps/VTaps */
 	REG_SET_4(SCL_TAP_CONTROL, 0,
@@ -706,5 +698,5 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
 		SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
 		SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
 
-	dpp_set_scl_filter(xfm, scl_data, ycbcr);
+	dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
 }

+ 249 - 95
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c → drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c

@@ -24,23 +24,23 @@
  */
 #include "dm_services.h"
 #include "dce_calcs.h"
-#include "dcn10_mem_input.h"
 #include "reg_helper.h"
 #include "basics/conversion.h"
+#include "dcn10_hubp.h"
 
 #define REG(reg)\
-	mi->mi_regs->reg
+	hubp1->mi_regs->reg
 
 #define CTX \
-	mi->base.ctx
+	hubp1->base.ctx
 
 #undef FN
 #define FN(reg_name, field_name) \
-	mi->mi_shift->field_name, mi->mi_mask->field_name
+	hubp1->mi_shift->field_name, hubp1->mi_mask->field_name
 
-static void min10_set_blank(struct mem_input *mem_input, bool blank)
+void hubp1_set_blank(struct hubp *hubp, bool blank)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	uint32_t blank_en = blank ? 1 : 0;
 
 	REG_UPDATE_2(DCHUBP_CNTL,
@@ -51,24 +51,24 @@ static void min10_set_blank(struct mem_input *mem_input, bool blank)
 		REG_WAIT(DCHUBP_CNTL,
 				HUBP_NO_OUTSTANDING_REQ, 1,
 				1, 200);
-		mem_input->mpcc_id = 0xf;
-		mem_input->opp_id = 0xf;
+		hubp->mpcc_id = 0xf;
+		hubp->opp_id = 0xf;
 	}
 }
 
-static void min10_set_hubp_blank_en(struct mem_input *mem_input, bool blank)
+static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	uint32_t blank_en = blank ? 1 : 0;
 
 	REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
 }
 
-static void min10_vready_workaround(struct mem_input *mem_input,
+static void hubp1_vready_workaround(struct hubp *hubp,
 		struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
 {
 	uint32_t value = 0;
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
 	/* set HBUBREQ_DEBUG_DB[12] = 1 */
 	value = REG_READ(HUBPREQ_DEBUG_DB);
@@ -87,8 +87,8 @@ static void min10_vready_workaround(struct mem_input *mem_input,
 	REG_WRITE(HUBPREQ_DEBUG_DB, value);
 }
 
-static void min10_program_tiling(
-	struct dcn10_mem_input *mi,
+void hubp1_program_tiling(
+	struct dcn10_hubp *hubp1,
 	const union dc_tiling_info *info,
 	const enum surface_pixel_format pixel_format)
 {
@@ -107,8 +107,8 @@ static void min10_program_tiling(
 			PIPE_ALIGNED, info->gfx9.pipe_aligned);
 }
 
-static void min10_program_size_and_rotation(
-	struct dcn10_mem_input *mi,
+void hubp1_program_size_and_rotation(
+	struct dcn10_hubp *hubp1,
 	enum dc_rotation_angle rotation,
 	enum surface_pixel_format format,
 	const union plane_size *plane_size,
@@ -169,8 +169,8 @@ static void min10_program_size_and_rotation(
 				H_MIRROR_EN, mirror);
 }
 
-static void min10_program_pixel_format(
-	struct dcn10_mem_input *mi,
+void hubp1_program_pixel_format(
+	struct dcn10_hubp *hubp1,
 	enum surface_pixel_format format)
 {
 	uint32_t red_bar = 3;
@@ -245,12 +245,12 @@ static void min10_program_pixel_format(
 	/* don't see the need of program the xbar in DCN 1.0 */
 }
 
-static bool min10_program_surface_flip_and_addr(
-	struct mem_input *mem_input,
+bool hubp1_program_surface_flip_and_addr(
+	struct hubp *hubp,
 	const struct dc_plane_address *address,
 	bool flip_immediate)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
 	/* program flip type */
 	REG_SET(DCSURF_FLIP_CONTROL, 0,
@@ -387,28 +387,28 @@ static bool min10_program_surface_flip_and_addr(
 		break;
 	}
 
-	mem_input->request_address = *address;
+	hubp->request_address = *address;
 
 	if (flip_immediate)
-		mem_input->current_address = *address;
+		hubp->current_address = *address;
 
 	return true;
 }
 
-static void min10_dcc_control(struct mem_input *mem_input, bool enable,
+void hubp1_dcc_control(struct hubp *hubp, bool enable,
 		bool independent_64b_blks)
 {
 	uint32_t dcc_en = enable ? 1 : 0;
 	uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
 	REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
 			PRIMARY_SURFACE_DCC_EN, dcc_en,
 			PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
 }
 
-static void min10_program_surface_config(
-	struct mem_input *mem_input,
+void hubp1_program_surface_config(
+	struct hubp *hubp,
 	enum surface_pixel_format format,
 	union dc_tiling_info *tiling_info,
 	union plane_size *plane_size,
@@ -416,20 +416,20 @@ static void min10_program_surface_config(
 	struct dc_plane_dcc_param *dcc,
 	bool horizontal_mirror)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
-	min10_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks);
-	min10_program_tiling(mi, tiling_info, format);
-	min10_program_size_and_rotation(
-		mi, rotation, format, plane_size, dcc, horizontal_mirror);
-	min10_program_pixel_format(mi, format);
+	hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
+	hubp1_program_tiling(hubp1, tiling_info, format);
+	hubp1_program_size_and_rotation(
+			hubp1, rotation, format, plane_size, dcc, horizontal_mirror);
+	hubp1_program_pixel_format(hubp1, format);
 }
 
-static void min10_program_requestor(
-		struct mem_input *mem_input,
+void hubp1_program_requestor(
+		struct hubp *hubp,
 		struct _vcs_dpi_display_rq_regs_st *rq_regs)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
 	REG_UPDATE(HUBPRET_CONTROL,
 			DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
@@ -459,12 +459,12 @@ static void min10_program_requestor(
 }
 
 
-static void min10_program_deadline(
-		struct mem_input *mem_input,
+void hubp1_program_deadline(
+		struct hubp *hubp,
 		struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
 		struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
 	/* DLG - Per hubp */
 	REG_SET_2(BLANK_OFFSET_0, 0,
@@ -580,8 +580,8 @@ static void min10_program_deadline(
 		ttu_attr->refcyc_per_req_delivery_pre_c);
 }
 
-static void min10_setup(
-		struct mem_input *mem_input,
+static void hubp1_setup(
+		struct hubp *hubp,
 		struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
 		struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
 		struct _vcs_dpi_display_rq_regs_st *rq_regs,
@@ -590,27 +590,15 @@ static void min10_setup(
 	/* otg is locked when this func is called. Register are double buffered.
 	 * disable the requestors is not needed
 	 */
-	min10_program_requestor(mem_input, rq_regs);
-	min10_program_deadline(mem_input, dlg_attr, ttu_attr);
-	min10_vready_workaround(mem_input, pipe_dest);
+	hubp1_program_requestor(hubp, rq_regs);
+	hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
+	hubp1_vready_workaround(hubp, pipe_dest);
 }
 
-static void min10_program_display_marks(
-	struct mem_input *mem_input,
-	struct dce_watermarks nbp,
-	struct dce_watermarks stutter,
-	struct dce_watermarks urgent,
-	uint32_t total_dest_line_time_ns)
-{
-	/* only for dce
-	 * dcn use only program_watermarks
-	 */
-}
-
-static bool min10_is_flip_pending(struct mem_input *mem_input)
+bool hubp1_is_flip_pending(struct hubp *hubp)
 {
 	uint32_t flip_pending = 0;
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	struct dc_plane_address earliest_inuse_address;
 
 	REG_GET(DCSURF_FLIP_CONTROL,
@@ -625,17 +613,20 @@ static bool min10_is_flip_pending(struct mem_input *mem_input)
 	if (flip_pending)
 		return true;
 
-	if (earliest_inuse_address.grph.addr.quad_part != mem_input->request_address.grph.addr.quad_part)
+	if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
 		return true;
 
-	mem_input->current_address = mem_input->request_address;
+	hubp->current_address = hubp->request_address;
 	return false;
 }
 
-static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
+uint32_t aperture_default_system = 1;
+uint32_t context0_default_system; /* = 0;*/
+
+static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
 		struct vm_system_aperture_param *apt)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
 	PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
 	PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
@@ -645,7 +636,7 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
 	mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
 
 	REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
-		MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, 1, /* 1 = system physical memory */
+		MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */
 		MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
 	REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
 		MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part);
@@ -661,10 +652,10 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
 			MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
 }
 
-static void min10_set_vm_context0_settings(struct mem_input *mem_input,
+static void hubp1_set_vm_context0_settings(struct hubp *hubp,
 		const struct vm_context0_param *vm0)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	/* pte base */
 	REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
 			VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part);
@@ -684,9 +675,9 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
 			VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
 
 	/* fault handling */
-	REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
-			VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->fault_default.high_part);
-	/* VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, 0 */
+	REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
+			VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
+			VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
 	REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
 			VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
 
@@ -696,12 +687,12 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
 			SYSTEM_ACCESS_MODE, 3);
 }
 
-static void min_set_viewport(
-	struct mem_input *mem_input,
+void min_set_viewport(
+	struct hubp *hubp,
 	const struct rect *viewport,
 	const struct rect *viewport_c)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 
 	REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
 		  PRI_VIEWPORT_WIDTH, viewport->width,
@@ -730,7 +721,7 @@ static void min_set_viewport(
 		  PRI_VIEWPORT_Y_START_C, viewport_c->y);
 }
 
-void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
+void hubp1_read_state(struct dcn10_hubp *hubp1,
 		struct dcn_hubp_state *s)
 {
 	REG_GET(DCSURF_SURFACE_CONFIG,
@@ -766,41 +757,204 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
 			QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
 }
 
-static struct mem_input_funcs dcn10_mem_input_funcs = {
-	.mem_input_program_display_marks = min10_program_display_marks,
-	.mem_input_program_surface_flip_and_addr =
-			min10_program_surface_flip_and_addr,
-	.mem_input_program_surface_config =
-			min10_program_surface_config,
-	.mem_input_is_flip_pending = min10_is_flip_pending,
-	.mem_input_setup = min10_setup,
-	.mem_input_set_vm_system_aperture_settings = min10_set_vm_system_aperture_settings,
-	.mem_input_set_vm_context0_settings = min10_set_vm_context0_settings,
-	.set_blank = min10_set_blank,
-	.dcc_control = min10_dcc_control,
+enum cursor_pitch {
+	CURSOR_PITCH_64_PIXELS = 0,
+	CURSOR_PITCH_128_PIXELS,
+	CURSOR_PITCH_256_PIXELS
+};
+
+enum cursor_lines_per_chunk {
+	CURSOR_LINE_PER_CHUNK_2 = 1,
+	CURSOR_LINE_PER_CHUNK_4,
+	CURSOR_LINE_PER_CHUNK_8,
+	CURSOR_LINE_PER_CHUNK_16
+};
+
+static bool ippn10_cursor_program_control(
+		struct dcn10_hubp *hubp1,
+		bool pixel_data_invert,
+		enum dc_cursor_color_format color_format)
+{
+	if (REG(CURSOR_SETTINS))
+		REG_SET_2(CURSOR_SETTINS, 0,
+				/* no shift of the cursor HDL schedule */
+				CURSOR0_DST_Y_OFFSET, 0,
+				 /* used to shift the cursor chunk request deadline */
+				CURSOR0_CHUNK_HDL_ADJUST, 3);
+	else
+		REG_SET_2(CURSOR_SETTINGS, 0,
+				/* no shift of the cursor HDL schedule */
+				CURSOR0_DST_Y_OFFSET, 0,
+				 /* used to shift the cursor chunk request deadline */
+				CURSOR0_CHUNK_HDL_ADJUST, 3);
+
+	return true;
+}
+
+static enum cursor_pitch ippn10_get_cursor_pitch(
+		unsigned int pitch)
+{
+	enum cursor_pitch hw_pitch;
+
+	switch (pitch) {
+	case 64:
+		hw_pitch = CURSOR_PITCH_64_PIXELS;
+		break;
+	case 128:
+		hw_pitch = CURSOR_PITCH_128_PIXELS;
+		break;
+	case 256:
+		hw_pitch = CURSOR_PITCH_256_PIXELS;
+		break;
+	default:
+		DC_ERR("Invalid cursor pitch of %d. "
+				"Only 64/128/256 is supported on DCN.\n", pitch);
+		hw_pitch = CURSOR_PITCH_64_PIXELS;
+		break;
+	}
+	return hw_pitch;
+}
+
+static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
+		unsigned int cur_width,
+		enum dc_cursor_color_format format)
+{
+	enum cursor_lines_per_chunk line_per_chunk;
+
+	if (format == CURSOR_MODE_MONO)
+		/* impl B. expansion in CUR Buffer reader */
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
+	else if (cur_width <= 32)
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
+	else if (cur_width <= 64)
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
+	else if (cur_width <= 128)
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
+	else
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
+
+	return line_per_chunk;
+}
+
+void hubp1_cursor_set_attributes(
+		struct hubp *hubp,
+		const struct dc_cursor_attributes *attr)
+{
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+	enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
+	enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
+			attr->width, attr->color_format);
+
+	hubp->curs_attr = *attr;
+
+	REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
+			CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
+	REG_UPDATE(CURSOR_SURFACE_ADDRESS,
+			CURSOR_SURFACE_ADDRESS, attr->address.low_part);
+
+	REG_UPDATE_2(CURSOR_SIZE,
+			CURSOR_WIDTH, attr->width,
+			CURSOR_HEIGHT, attr->height);
+	REG_UPDATE_3(CURSOR_CONTROL,
+			CURSOR_MODE, attr->color_format,
+			CURSOR_PITCH, hw_pitch,
+			CURSOR_LINES_PER_CHUNK, lpc);
+	ippn10_cursor_program_control(hubp1,
+			attr->attribute_flags.bits.INVERT_PIXEL_DATA,
+			attr->color_format);
+}
+
+void hubp1_cursor_set_position(
+		struct hubp *hubp,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param)
+{
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+	int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
+	uint32_t cur_en = pos->enable ? 1 : 0;
+	uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
+
+	/*
+	 * Guard aganst cursor_set_position() from being called with invalid
+	 * attributes
+	 *
+	 * TODO: Look at combining cursor_set_position() and
+	 * cursor_set_attributes() into cursor_update()
+	 */
+	if (hubp->curs_attr.address.quad_part == 0)
+		return;
+
+	dst_x_offset *= param->ref_clk_khz;
+	dst_x_offset /= param->pixel_clk_khz;
+
+	ASSERT(param->h_scale_ratio.value);
+
+	if (param->h_scale_ratio.value)
+		dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
+				dal_fixed31_32_from_int(dst_x_offset),
+				param->h_scale_ratio));
+
+	if (src_x_offset >= (int)param->viewport_width)
+		cur_en = 0;  /* not visible beyond right edge*/
+
+	if (src_x_offset + (int)hubp->curs_attr.width < 0)
+		cur_en = 0;  /* not visible beyond left edge*/
+
+	if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+		hubp1_cursor_set_attributes(hubp, &hubp->curs_attr);
+	REG_UPDATE(CURSOR_CONTROL,
+			CURSOR_ENABLE, cur_en);
+
+	REG_SET_2(CURSOR_POSITION, 0,
+			CURSOR_X_POSITION, pos->x,
+			CURSOR_Y_POSITION, pos->y);
+
+	REG_SET_2(CURSOR_HOT_SPOT, 0,
+			CURSOR_HOT_SPOT_X, pos->x_hotspot,
+			CURSOR_HOT_SPOT_Y, pos->y_hotspot);
+
+	REG_SET(CURSOR_DST_OFFSET, 0,
+			CURSOR_DST_X_OFFSET, dst_x_offset);
+	/* TODO Handle surface pixel formats other than 4:4:4 */
+}
+
+static struct hubp_funcs dcn10_hubp_funcs = {
+	.hubp_program_surface_flip_and_addr =
+			hubp1_program_surface_flip_and_addr,
+	.hubp_program_surface_config =
+			hubp1_program_surface_config,
+	.hubp_is_flip_pending = hubp1_is_flip_pending,
+	.hubp_setup = hubp1_setup,
+	.hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
+	.hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
+	.set_blank = hubp1_set_blank,
+	.dcc_control = hubp1_dcc_control,
 	.mem_program_viewport = min_set_viewport,
-	.set_hubp_blank_en = min10_set_hubp_blank_en,
+	.set_hubp_blank_en = hubp1_set_hubp_blank_en,
+	.set_cursor_attributes	= hubp1_cursor_set_attributes,
+	.set_cursor_position	= hubp1_cursor_set_position,
 };
 
 /*****************************************/
 /* Constructor, Destructor               */
 /*****************************************/
 
-void dcn10_mem_input_construct(
-	struct dcn10_mem_input *mi,
+void dcn10_hubp_construct(
+	struct dcn10_hubp *hubp1,
 	struct dc_context *ctx,
 	uint32_t inst,
 	const struct dcn_mi_registers *mi_regs,
 	const struct dcn_mi_shift *mi_shift,
 	const struct dcn_mi_mask *mi_mask)
 {
-	mi->base.funcs = &dcn10_mem_input_funcs;
-	mi->base.ctx = ctx;
-	mi->mi_regs = mi_regs;
-	mi->mi_shift = mi_shift;
-	mi->mi_mask = mi_mask;
-	mi->base.inst = inst;
-	mi->base.opp_id = 0xf;
-	mi->base.mpcc_id = 0xf;
+	hubp1->base.funcs = &dcn10_hubp_funcs;
+	hubp1->base.ctx = ctx;
+	hubp1->mi_regs = mi_regs;
+	hubp1->mi_shift = mi_shift;
+	hubp1->mi_mask = mi_mask;
+	hubp1->base.inst = inst;
+	hubp1->base.opp_id = 0xf;
+	hubp1->base.mpcc_id = 0xf;
 }
 
+

+ 127 - 12
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h → drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h

@@ -25,11 +25,10 @@
 #ifndef __DC_MEM_INPUT_DCN10_H__
 #define __DC_MEM_INPUT_DCN10_H__
 
-#include "mem_input.h"
-
-#define TO_DCN10_MEM_INPUT(mi)\
-	container_of(mi, struct dcn10_mem_input, base)
+#include "hubp.h"
 
+#define TO_DCN10_HUBP(hubp)\
+	container_of(hubp, struct dcn10_hubp, base)
 
 #define MI_REG_LIST_DCN(id)\
 	SRI(DCHUBP_CNTL, HUBP, id),\
@@ -118,7 +117,17 @@
 	SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
 	SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
 	SR(DCHUBBUB_SDPIF_FB_BASE),\
-	SR(DCHUBBUB_SDPIF_FB_OFFSET)
+	SR(DCHUBBUB_SDPIF_FB_OFFSET),\
+	SRI(CURSOR_SETTINS, HUBPREQ, id), \
+	SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
+	SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
+	SRI(CURSOR_SIZE, CURSOR, id), \
+	SRI(CURSOR_CONTROL, CURSOR, id), \
+	SRI(CURSOR_POSITION, CURSOR, id), \
+	SRI(CURSOR_HOT_SPOT, CURSOR, id), \
+	SRI(CURSOR_DST_OFFSET, CURSOR, id)
+
+
 
 struct dcn_mi_registers {
 	uint32_t DCHUBP_CNTL;
@@ -215,6 +224,15 @@ struct dcn_mi_registers {
 	uint32_t DCN_VM_AGP_BASE;
 	uint32_t DCN_VM_AGP_BOT;
 	uint32_t DCN_VM_AGP_TOP;
+	uint32_t CURSOR_SETTINS;
+	uint32_t CURSOR_SETTINGS;
+	uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
+	uint32_t CURSOR_SURFACE_ADDRESS;
+	uint32_t CURSOR_SIZE;
+	uint32_t CURSOR_CONTROL;
+	uint32_t CURSOR_POSITION;
+	uint32_t CURSOR_HOT_SPOT;
+	uint32_t CURSOR_DST_OFFSET;
 };
 
 #define MI_SF(reg_name, field_name, post_fix)\
@@ -351,6 +369,7 @@ struct dcn_mi_registers {
 	MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\
+	MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\
@@ -360,7 +379,23 @@ struct dcn_mi_registers {
 	MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
-	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh)
+	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
+	MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
+	MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
 
 #define DCN_MI_REG_FIELD_LIST(type) \
 	type HUBP_BLANK_EN;\
@@ -488,6 +523,7 @@ struct dcn_mi_registers {
 	type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\
 	type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\
 	type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\
+	type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM;\
 	type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\
 	type ENABLE_L1_TLB;\
 	type SYSTEM_ACCESS_MODE;\
@@ -521,7 +557,24 @@ struct dcn_mi_registers {
 	type PHYSICAL_PAGE_ADDR_LO32;\
 	type PHYSICAL_PAGE_NUMBER_MSB;\
 	type PHYSICAL_PAGE_NUMBER_LSB;\
-	type LOGICAL_ADDR
+	type LOGICAL_ADDR;\
+	type CURSOR0_DST_Y_OFFSET; \
+	type CURSOR0_CHUNK_HDL_ADJUST; \
+	type CURSOR_SURFACE_ADDRESS_HIGH; \
+	type CURSOR_SURFACE_ADDRESS; \
+	type CURSOR_WIDTH; \
+	type CURSOR_HEIGHT; \
+	type CURSOR_MODE; \
+	type CURSOR_2X_MAGNIFY; \
+	type CURSOR_PITCH; \
+	type CURSOR_LINES_PER_CHUNK; \
+	type CURSOR_ENABLE; \
+	type CURSOR_X_POSITION; \
+	type CURSOR_Y_POSITION; \
+	type CURSOR_HOT_SPOT_X; \
+	type CURSOR_HOT_SPOT_Y; \
+	type CURSOR_DST_X_OFFSET; \
+	type OUTPUT_FP
 
 struct dcn_mi_shift {
 	DCN_MI_REG_FIELD_LIST(uint8_t);
@@ -531,21 +584,83 @@ struct dcn_mi_mask {
 	DCN_MI_REG_FIELD_LIST(uint32_t);
 };
 
-struct dcn10_mem_input {
-	struct mem_input base;
+struct dcn10_hubp {
+	struct hubp base;
 	const struct dcn_mi_registers *mi_regs;
 	const struct dcn_mi_shift *mi_shift;
 	const struct dcn_mi_mask *mi_mask;
 };
 
-void dcn10_mem_input_construct(
-	struct dcn10_mem_input *mi,
+void hubp1_program_surface_config(
+	struct hubp *hubp,
+	enum surface_pixel_format format,
+	union dc_tiling_info *tiling_info,
+	union plane_size *plane_size,
+	enum dc_rotation_angle rotation,
+	struct dc_plane_dcc_param *dcc,
+	bool horizontal_mirror);
+
+void hubp1_program_deadline(
+		struct hubp *hubp,
+		struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
+		struct _vcs_dpi_display_ttu_regs_st *ttu_attr);
+
+void hubp1_program_requestor(
+		struct hubp *hubp,
+		struct _vcs_dpi_display_rq_regs_st *rq_regs);
+
+void hubp1_program_pixel_format(
+	struct dcn10_hubp *hubp,
+	enum surface_pixel_format format);
+
+void hubp1_program_size_and_rotation(
+	struct dcn10_hubp *hubp,
+	enum dc_rotation_angle rotation,
+	enum surface_pixel_format format,
+	const union plane_size *plane_size,
+	struct dc_plane_dcc_param *dcc,
+	bool horizontal_mirror);
+
+void hubp1_program_tiling(
+	struct dcn10_hubp *hubp,
+	const union dc_tiling_info *info,
+	const enum surface_pixel_format pixel_format);
+
+void hubp1_dcc_control(struct hubp *hubp,
+		bool enable,
+		bool independent_64b_blks);
+
+bool hubp1_program_surface_flip_and_addr(
+	struct hubp *hubp,
+	const struct dc_plane_address *address,
+	bool flip_immediate);
+
+bool hubp1_is_flip_pending(struct hubp *hubp);
+
+void hubp1_cursor_set_attributes(
+		struct hubp *hubp,
+		const struct dc_cursor_attributes *attr);
+
+void hubp1_cursor_set_position(
+		struct hubp *hubp,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param);
+
+void hubp1_set_blank(struct hubp *hubp, bool blank);
+
+void min_set_viewport(struct hubp *hubp,
+		const struct rect *viewport,
+		const struct rect *viewport_c);
+
+void dcn10_hubp_construct(
+	struct dcn10_hubp *hubp1,
 	struct dc_context *ctx,
 	uint32_t inst,
 	const struct dcn_mi_registers *mi_regs,
 	const struct dcn_mi_shift *mi_shift,
 	const struct dcn_mi_mask *mi_mask);
 
+
 struct dcn_hubp_state {
 	uint32_t pixel_format;
 	uint32_t inuse_addr_hi;
@@ -562,7 +677,7 @@ struct dcn_hubp_state {
 	uint32_t qos_level_low_wm;
 	uint32_t qos_level_high_wm;
 };
-void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
+void hubp1_read_state(struct dcn10_hubp *hubp1,
 		struct dcn_hubp_state *s);
 
 #endif

+ 276 - 210
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

@@ -31,7 +31,6 @@
 #include "dce110/dce110_hw_sequencer.h"
 #include "dce/dce_hwseq.h"
 #include "abm.h"
-#include "dcn10/dcn10_mem_input.h"
 #include "dcn10/dcn10_timing_generator.h"
 #include "dcn10/dcn10_dpp.h"
 #include "dcn10/dcn10_mpc.h"
@@ -41,6 +40,7 @@
 #include "mpc.h"
 #include "reg_helper.h"
 #include "custom_float.h"
+#include "dcn10_hubp.h"
 
 #define CTX \
 	hws->ctx
@@ -172,10 +172,10 @@ static void dcn10_log_hw_state(struct dc *dc)
 			"min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
 
 	for (i = 0; i < pool->pipe_count; i++) {
-		struct mem_input *mi = pool->mis[i];
+		struct hubp *hubp = pool->hubps[i];
 		struct dcn_hubp_state s;
 
-		dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s);
+		hubp1_read_state(TO_DCN10_HUBP(hubp), &s);
 
 		DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t "
 				"%xh \t %xh \t %xh \t "
@@ -245,15 +245,19 @@ static void verify_allow_pstate_change_high(
 {
 	/* pstate latency is ~20us so if we wait over 40us and pstate allow
 	 * still not asserted, we are probably stuck and going to hang
+	 *
+	 * TODO: Figure out why it takes ~100us on linux
+	 * pstate takes around ~100us on linux. Unknown currently as to
+	 * why it takes that long on linux
 	 */
-	static unsigned int pstate_wait_timeout_us = 40;
+	static unsigned int pstate_wait_timeout_us = 200;
+	static unsigned int pstate_wait_expected_timeout_us = 40;
 	static unsigned int max_sampled_pstate_wait_us; /* data collection */
 	static bool forced_pstate_allow; /* help with revert wa */
 	static bool should_log_hw_state; /* prevent hw state log by default */
 
 	unsigned int debug_index = 0x7;
 	unsigned int debug_data;
-	unsigned int force_allow_pstate = 0x30;
 	unsigned int i;
 
 	if (forced_pstate_allow) {
@@ -261,7 +265,9 @@ static void verify_allow_pstate_change_high(
 		 * we verify_allow_pstate_change_high.  so disable force
 		 * here so we can check status
 		 */
-		REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0);
+		REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
+			     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
 		forced_pstate_allow = false;
 	}
 
@@ -292,9 +298,15 @@ static void verify_allow_pstate_change_high(
 	for (i = 0; i < pstate_wait_timeout_us; i++) {
 		debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
 
-		if (debug_data & (1 << 30))
-			return;
+		if (debug_data & (1 << 30)) {
+
+			if (i > pstate_wait_expected_timeout_us)
+				dm_logger_write(hws->ctx->logger, LOG_WARNING,
+						"pstate took longer than expected ~%dus\n",
+						i);
 
+			return;
+		}
 		if (max_sampled_pstate_wait_us < i)
 			max_sampled_pstate_wait_us = i;
 
@@ -304,13 +316,18 @@ static void verify_allow_pstate_change_high(
 	/* force pstate allow to prevent system hang
 	 * and break to debugger to investigate
 	 */
-	REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate);
+	REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
+		     DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
 	forced_pstate_allow = true;
 
 	if (should_log_hw_state) {
 		dcn10_log_hw_state(hws->ctx->dc);
 	}
 
+	dm_logger_write(hws->ctx->logger, LOG_WARNING,
+			"pstate TEST_DEBUG_DATA: 0x%X\n",
+			debug_data);
 	BREAK_TO_DEBUGGER();
 }
 
@@ -451,7 +468,7 @@ static void program_watermarks(
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
 
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"URGENCY_WATERMARK_A calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->a.urgent_ns, prog_wm_value);
@@ -459,38 +476,37 @@ static void program_watermarks(
 	prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->a.pte_meta_urgent_ns, prog_wm_value);
 
+	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
+		prog_wm_value = convert_and_clamp(
+				watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
-			refclk_mhz, 0x1fffff);
-
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
-
-
-	prog_wm_value = convert_and_clamp(
-			watermarks->a.cstate_pstate.cstate_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_EXIT_WATERMARK_A calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
 
+		prog_wm_value = convert_and_clamp(
+				watermarks->a.cstate_pstate.cstate_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_EXIT_WATERMARK_A calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
+	}
 
 	prog_wm_value = convert_and_clamp(
 			watermarks->a.cstate_pstate.pstate_change_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
 		"HW register value = 0x%x\n\n",
 		watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -500,7 +516,7 @@ static void program_watermarks(
 	prog_wm_value = convert_and_clamp(
 			watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"URGENCY_WATERMARK_B calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->b.urgent_ns, prog_wm_value);
@@ -510,36 +526,38 @@ static void program_watermarks(
 			watermarks->b.pte_meta_urgent_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->b.pte_meta_urgent_ns, prog_wm_value);
 
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_ENTER_WATERMARK_B calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
+		prog_wm_value = convert_and_clamp(
+				watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_ENTER_WATERMARK_B calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
 
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->b.cstate_pstate.cstate_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_EXIT_WATERMARK_B calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
+		prog_wm_value = convert_and_clamp(
+				watermarks->b.cstate_pstate.cstate_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_EXIT_WATERMARK_B calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
+	}
 
 	prog_wm_value = convert_and_clamp(
 			watermarks->b.cstate_pstate.pstate_change_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
 		"HW register value = 0x%x\n",
 		watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -548,7 +566,7 @@ static void program_watermarks(
 	prog_wm_value = convert_and_clamp(
 			watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"URGENCY_WATERMARK_C calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->c.urgent_ns, prog_wm_value);
@@ -558,37 +576,38 @@ static void program_watermarks(
 			watermarks->c.pte_meta_urgent_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->c.pte_meta_urgent_ns, prog_wm_value);
 
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_ENTER_WATERMARK_C calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
+		prog_wm_value = convert_and_clamp(
+				watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_ENTER_WATERMARK_C calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
 
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->c.cstate_pstate.cstate_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_EXIT_WATERMARK_C calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
-
+		prog_wm_value = convert_and_clamp(
+				watermarks->c.cstate_pstate.cstate_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_EXIT_WATERMARK_C calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
+	}
 
 	prog_wm_value = convert_and_clamp(
 			watermarks->c.cstate_pstate.pstate_change_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
 		"HW register value = 0x%x\n",
 		watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -597,7 +616,7 @@ static void program_watermarks(
 	prog_wm_value = convert_and_clamp(
 			watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"URGENCY_WATERMARK_D calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->d.urgent_ns, prog_wm_value);
@@ -606,37 +625,39 @@ static void program_watermarks(
 			watermarks->d.pte_meta_urgent_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
 		"HW register value = 0x%x\n",
 		watermarks->d.pte_meta_urgent_ns, prog_wm_value);
 
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_ENTER_WATERMARK_D calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+	if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
+		prog_wm_value = convert_and_clamp(
+				watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_ENTER_WATERMARK_D calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
 
 
-	prog_wm_value = convert_and_clamp(
-			watermarks->d.cstate_pstate.cstate_exit_ns,
-			refclk_mhz, 0x1fffff);
-	REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
-		"SR_EXIT_WATERMARK_D calculated =%d\n"
-		"HW register value = 0x%x\n",
-		watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
+		prog_wm_value = convert_and_clamp(
+				watermarks->d.cstate_pstate.cstate_exit_ns,
+				refclk_mhz, 0x1fffff);
+		REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
+		dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+			"SR_EXIT_WATERMARK_D calculated =%d\n"
+			"HW register value = 0x%x\n",
+			watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
+	}
 
 
 	prog_wm_value = convert_and_clamp(
 			watermarks->d.cstate_pstate.pstate_change_ns,
 			refclk_mhz, 0x1fffff);
 	REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
-	dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+	dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
 		"DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
 		"HW register value = 0x%x\n\n",
 		watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -771,20 +792,22 @@ static void power_on_plane(
 	struct dce_hwseq *hws,
 	int plane_id)
 {
-	REG_SET(DC_IP_REQUEST_CNTL, 0,
-			IP_REQUEST_EN, 1);
-	dpp_pg_control(hws, plane_id, true);
-	hubp_pg_control(hws, plane_id, true);
-	REG_SET(DC_IP_REQUEST_CNTL, 0,
-			IP_REQUEST_EN, 0);
-	dm_logger_write(hws->ctx->logger, LOG_DEBUG,
-			"Un-gated front end for pipe %d\n", plane_id);
+	if (REG(DC_IP_REQUEST_CNTL)) {
+		REG_SET(DC_IP_REQUEST_CNTL, 0,
+				IP_REQUEST_EN, 1);
+		dpp_pg_control(hws, plane_id, true);
+		hubp_pg_control(hws, plane_id, true);
+		REG_SET(DC_IP_REQUEST_CNTL, 0,
+				IP_REQUEST_EN, 0);
+		dm_logger_write(hws->ctx->logger, LOG_DEBUG,
+				"Un-gated front end for pipe %d\n", plane_id);
+	}
 }
 
 static void undo_DEGVIDCN10_253_wa(struct dc *dc)
 {
 	struct dce_hwseq *hws = dc->hwseq;
-	struct mem_input *mi = dc->res_pool->mis[0];
+	struct hubp *hubp = dc->res_pool->hubps[0];
 	int pwr_status = 0;
 
 	REG_GET(DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, &pwr_status);
@@ -792,7 +815,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
 	if (pwr_status == 2)
 		return;
 
-	mi->funcs->set_blank(mi, true);
+	hubp->funcs->set_blank(hubp, true);
 
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 1);
@@ -802,17 +825,13 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
 			IP_REQUEST_EN, 0);
 }
 
-static void ready_shared_resources(struct dc *dc)
-{
-	if (dc->current_state->stream_count == 0 &&
-			!dc->debug.disable_stutter)
-		undo_DEGVIDCN10_253_wa(dc);
-}
-
 static void apply_DEGVIDCN10_253_wa(struct dc *dc)
 {
 	struct dce_hwseq *hws = dc->hwseq;
-	struct mem_input *mi = dc->res_pool->mis[0];
+	struct hubp *hubp = dc->res_pool->hubps[0];
+
+	if (dc->debug.disable_stutter)
+		return;
 
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 1);
@@ -821,14 +840,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 0);
 
-	mi->funcs->set_hubp_blank_en(mi, false);
-}
-
-static void optimize_shared_resources(struct dc *dc)
-{
-	if (dc->current_state->stream_count == 0 &&
-			!dc->debug.disable_stutter)
-		apply_DEGVIDCN10_253_wa(dc);
+	hubp->funcs->set_hubp_blank_en(hubp, false);
 }
 
 static void bios_golden_init(struct dc *dc)
@@ -887,12 +899,13 @@ static void dcn10_init_hw(struct dc *dc)
 	}
 
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		struct transform *xfm = dc->res_pool->transforms[i];
+		struct dpp *dpp = dc->res_pool->dpps[i];
 		struct timing_generator *tg = dc->res_pool->timing_generators[i];
 
-		xfm->funcs->transform_reset(xfm);
+		dpp->funcs->dpp_reset(dpp);
 		dc->res_pool->mpc->funcs->remove(
-				dc->res_pool->mpc, dc->res_pool->opps[i], i);
+				dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree),
+				dc->res_pool->opps[i]->inst, i);
 
 		/* Blank controller using driver code instead of
 		 * command table.
@@ -1028,12 +1041,11 @@ static void reset_back_end_for_pipe(
 		return;
 	}
 
-	/* TODOFPGA break core_link_disable_stream into 2 functions:
-	 * disable_stream and disable_link. disable_link will disable PHYPLL
-	 * which is used by otg. Move disable_link after disable_crtc
-	 */
-	if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
-		core_link_disable_stream(pipe_ctx);
+	if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+		/* DPMS may already disable */
+		if (!pipe_ctx->stream->dpms_off)
+			core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+	}
 
 	/* by upper caller loop, parent pipe: pipe0, will be reset last.
 	 * back end share by all pipes and will be disable only when disable
@@ -1062,7 +1074,7 @@ static void reset_back_end_for_pipe(
 static void plane_atomic_disconnect(struct dc *dc,
 		int fe_idx)
 {
-	struct mem_input *mi = dc->res_pool->mis[fe_idx];
+	struct hubp *hubp = dc->res_pool->hubps[fe_idx];
 	struct mpc *mpc = dc->res_pool->mpc;
 	int opp_id, z_idx;
 	int mpcc_id = -1;
@@ -1086,11 +1098,12 @@ static void plane_atomic_disconnect(struct dc *dc,
 
 	if (dc->debug.sanity_checks)
 		verify_allow_pstate_change_high(dc->hwseq);
-	mi->funcs->dcc_control(mi, false, false);
+	hubp->funcs->dcc_control(hubp, false, false);
 	if (dc->debug.sanity_checks)
 		verify_allow_pstate_change_high(dc->hwseq);
 
-	mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx);
+	mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree),
+			dc->res_pool->opps[opp_id]->inst, fe_idx);
 }
 
 /* disable HW used by plane.
@@ -1099,20 +1112,20 @@ static void plane_atomic_disable(struct dc *dc,
 		int fe_idx)
 {
 	struct dce_hwseq *hws = dc->hwseq;
-	struct mem_input *mi = dc->res_pool->mis[fe_idx];
+	struct hubp *hubp = dc->res_pool->hubps[fe_idx];
 	struct mpc *mpc = dc->res_pool->mpc;
-	int opp_id = mi->opp_id;
+	int opp_id = hubp->opp_id;
 
 	if (opp_id == 0xf)
 		return;
 
-	mpc->funcs->wait_for_idle(mpc, mi->mpcc_id);
-	dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false;
+	mpc->funcs->wait_for_idle(mpc, hubp->mpcc_id);
+	dc->res_pool->opps[hubp->opp_id]->mpcc_disconnect_pending[hubp->mpcc_id] = false;
 	/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
 			"[debug_mpo: atomic disable finished on mpcc %d]\n",
 			fe_idx);*/
 
-	mi->funcs->set_blank(mi, true);
+	hubp->funcs->set_blank(hubp, true);
 
 	if (dc->debug.sanity_checks)
 		verify_allow_pstate_change_high(dc->hwseq);
@@ -1137,20 +1150,22 @@ static void plane_atomic_disable(struct dc *dc,
 static void plane_atomic_power_down(struct dc *dc, int fe_idx)
 {
 	struct dce_hwseq *hws = dc->hwseq;
-	struct transform *xfm = dc->res_pool->transforms[fe_idx];
-
-	REG_SET(DC_IP_REQUEST_CNTL, 0,
-			IP_REQUEST_EN, 1);
-	dpp_pg_control(hws, fe_idx, false);
-	hubp_pg_control(hws, fe_idx, false);
-	xfm->funcs->transform_reset(xfm);
-	REG_SET(DC_IP_REQUEST_CNTL, 0,
-			IP_REQUEST_EN, 0);
-	dm_logger_write(dc->ctx->logger, LOG_DEBUG,
-			"Power gated front end %d\n", fe_idx);
-
-	if (dc->debug.sanity_checks)
-		verify_allow_pstate_change_high(dc->hwseq);
+	struct dpp *dpp = dc->res_pool->dpps[fe_idx];
+
+	if (REG(DC_IP_REQUEST_CNTL)) {
+		REG_SET(DC_IP_REQUEST_CNTL, 0,
+				IP_REQUEST_EN, 1);
+		dpp_pg_control(hws, fe_idx, false);
+		hubp_pg_control(hws, fe_idx, false);
+		dpp->funcs->dpp_reset(dpp);
+		REG_SET(DC_IP_REQUEST_CNTL, 0,
+				IP_REQUEST_EN, 0);
+		dm_logger_write(dc->ctx->logger, LOG_DEBUG,
+				"Power gated front end %d\n", fe_idx);
+
+		if (dc->debug.sanity_checks)
+			verify_allow_pstate_change_high(dc->hwseq);
+	}
 }
 
 
@@ -1160,7 +1175,7 @@ static void reset_front_end(
 {
 	struct dce_hwseq *hws = dc->hwseq;
 	struct timing_generator *tg;
-	int opp_id = dc->res_pool->mis[fe_idx]->opp_id;
+	int opp_id = dc->res_pool->hubps[fe_idx]->opp_id;
 
 	/*Already reset*/
 	if (opp_id == 0xf)
@@ -1192,7 +1207,7 @@ static void reset_front_end(
 static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
 {
 	struct dce_hwseq *hws = dc->hwseq;
-	struct transform *xfm = dc->res_pool->transforms[fe_idx];
+	struct dpp *dpp = dc->res_pool->dpps[fe_idx];
 
 	reset_front_end(dc, fe_idx);
 
@@ -1200,7 +1215,7 @@ static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
 			IP_REQUEST_EN, 1);
 	dpp_pg_control(hws, fe_idx, false);
 	hubp_pg_control(hws, fe_idx, false);
-	xfm->funcs->transform_reset(xfm);
+	dpp->funcs->dpp_reset(dpp);
 	REG_SET(DC_IP_REQUEST_CNTL, 0,
 			IP_REQUEST_EN, 0);
 	dm_logger_write(dc->ctx->logger, LOG_DEBUG,
@@ -1275,6 +1290,9 @@ static void reset_hw_ctx_wrap(
 		if (!pipe_ctx_old->stream)
 			continue;
 
+		if (pipe_ctx_old->top_pipe)
+			continue;
+
 		if (!pipe_ctx->stream ||
 				pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
 			struct clock_source *old_clk = pipe_ctx_old->clock_source;
@@ -1339,8 +1357,8 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
 	if (plane_state == NULL)
 		return;
 	addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
-	pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
-			pipe_ctx->plane_res.mi,
+	pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
+			pipe_ctx->plane_res.hubp,
 			&plane_state->address,
 			plane_state->flip_immediate);
 	plane_state->status.requested_address = plane_state->address;
@@ -1351,34 +1369,34 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
 static bool dcn10_set_input_transfer_func(
 	struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
 {
-	struct transform *xfm_base = pipe_ctx->plane_res.xfm;
+	struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
 	const struct dc_transfer_func *tf = NULL;
 	bool result = true;
 
-	if (xfm_base == NULL)
+	if (dpp_base == NULL)
 		return false;
 
 	if (plane_state->in_transfer_func)
 		tf = plane_state->in_transfer_func;
 
 	if (plane_state->gamma_correction && dce_use_lut(plane_state))
-		xfm_base->funcs->ipp_program_input_lut(xfm_base,
+		dpp_base->funcs->ipp_program_input_lut(dpp_base,
 				plane_state->gamma_correction);
 
 	if (tf == NULL)
-		xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS);
+		dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
 	else if (tf->type == TF_TYPE_PREDEFINED) {
 		switch (tf->tf) {
 		case TRANSFER_FUNCTION_SRGB:
-			xfm_base->funcs->ipp_set_degamma(xfm_base,
+			dpp_base->funcs->ipp_set_degamma(dpp_base,
 					IPP_DEGAMMA_MODE_HW_sRGB);
 			break;
 		case TRANSFER_FUNCTION_BT709:
-			xfm_base->funcs->ipp_set_degamma(xfm_base,
+			dpp_base->funcs->ipp_set_degamma(dpp_base,
 					IPP_DEGAMMA_MODE_HW_xvYCC);
 			break;
 		case TRANSFER_FUNCTION_LINEAR:
-			xfm_base->funcs->ipp_set_degamma(xfm_base,
+			dpp_base->funcs->ipp_set_degamma(dpp_base,
 					IPP_DEGAMMA_MODE_BYPASS);
 			break;
 		case TRANSFER_FUNCTION_PQ:
@@ -1389,7 +1407,7 @@ static bool dcn10_set_input_transfer_func(
 			break;
 		}
 	} else if (tf->type == TF_TYPE_BYPASS) {
-		xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS);
+		dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
 	} else {
 		/*TF_TYPE_DISTRIBUTED_POINTS*/
 		result = false;
@@ -1716,25 +1734,25 @@ static bool dcn10_set_output_transfer_func(
 	struct pipe_ctx *pipe_ctx,
 	const struct dc_stream_state *stream)
 {
-	struct transform *xfm = pipe_ctx->plane_res.xfm;
+	struct dpp *dpp = pipe_ctx->plane_res.dpp;
 
-	if (xfm == NULL)
+	if (dpp == NULL)
 		return false;
 
-	xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
+	dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
 
 	if (stream->out_transfer_func &&
 		stream->out_transfer_func->type ==
 			TF_TYPE_PREDEFINED &&
 		stream->out_transfer_func->tf ==
 			TRANSFER_FUNCTION_SRGB) {
-		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
+		dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_SRGB);
 	} else if (dcn10_translate_regamma_to_hw_format(
-				stream->out_transfer_func, &xfm->regamma_params)) {
-			xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
-			xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
+				stream->out_transfer_func, &dpp->regamma_params)) {
+			dpp->funcs->opp_program_regamma_pwl(dpp, &dpp->regamma_params);
+			dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_USER);
 	} else {
-		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
+		dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_BYPASS);
 	}
 
 	return true;
@@ -1745,8 +1763,8 @@ static void dcn10_pipe_control_lock(
 	struct pipe_ctx *pipe,
 	bool lock)
 {
-	struct mem_input *mi = NULL;
-	mi = dc->res_pool->mis[pipe->pipe_idx];
+	struct hubp *hubp = NULL;
+	hubp = dc->res_pool->hubps[pipe->pipe_idx];
 	/* use TG master update lock to lock everything on the TG
 	 * therefore only top pipe need to lock
 	 */
@@ -1997,10 +2015,11 @@ static void dcn10_power_on_fe(
 				plane_state->dst_rect.height);
 
 		dm_logger_write(dc->ctx->logger, LOG_DC,
-				"Pipe %d: width, height, x, y\n"
+				"Pipe %d: width, height, x, y         format:%d\n"
 				"viewport:%d, %d, %d, %d\n"
 				"recout:  %d, %d, %d, %d\n",
 				pipe_ctx->pipe_idx,
+				plane_state->format,
 				pipe_ctx->plane_res.scl_data.viewport.width,
 				pipe_ctx->plane_res.scl_data.viewport.height,
 				pipe_ctx->plane_res.scl_data.viewport.x,
@@ -2019,7 +2038,7 @@ static void dcn10_power_on_fe(
 
 static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
 {
-	struct xfm_grph_csc_adjustment adjust;
+	struct dpp_grph_csc_adjustment adjust;
 	memset(&adjust, 0, sizeof(adjust));
 	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
 
@@ -2055,7 +2074,7 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
 				gamut_remap_matrix.matrix[10];
 	}
 
-	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
+	pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
 }
 
 
@@ -2077,7 +2096,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
 
 			tbl_entry.color_space = color_space;
 			//tbl_entry.regval = matrix;
-			pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry);
+			pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry);
 	}
 }
 static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
@@ -2167,7 +2186,7 @@ static void dcn10_get_surface_visual_confirm_color(
 	}
 }
 
-static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
+static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1,
 		struct vm_system_aperture_param *apt,
 		struct dce_hwseq *hws)
 {
@@ -2192,7 +2211,7 @@ static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
 }
 
 /* Temporary read settings, future will get values from kmd directly */
-static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
+static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
 		struct vm_context0_param *vm0,
 		struct dce_hwseq *hws)
 {
@@ -2236,22 +2255,22 @@ static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
 	vm0->pte_base.quad_part -= fb_offset.quad_part;
 }
 
-static void dcn10_program_pte_vm(struct mem_input *mem_input,
+static void dcn10_program_pte_vm(struct hubp *hubp,
 		enum surface_pixel_format format,
 		union dc_tiling_info *tiling_info,
 		enum dc_rotation_angle rotation,
 		struct dce_hwseq *hws)
 {
-	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
 	struct vm_system_aperture_param apt = { {{ 0 } } };
 	struct vm_context0_param vm0 = { { { 0 } } };
 
 
-	mmhub_read_vm_system_aperture_settings(mi, &apt, hws);
-	mmhub_read_vm_context0_settings(mi, &vm0, hws);
+	mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
+	mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
 
-	mem_input->funcs->mem_input_set_vm_system_aperture_settings(mem_input, &apt);
-	mem_input->funcs->mem_input_set_vm_context0_settings(mem_input, &vm0);
+	hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt);
+	hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0);
 }
 
 static void update_dchubp_dpp(
@@ -2260,11 +2279,10 @@ static void update_dchubp_dpp(
 	struct dc_state *context)
 {
 	struct dce_hwseq *hws = dc->hwseq;
-	struct mem_input *mi = pipe_ctx->plane_res.mi;
-	struct transform *xfm = pipe_ctx->plane_res.xfm;
+	struct hubp *hubp = pipe_ctx->plane_res.hubp;
+	struct dpp *dpp = pipe_ctx->plane_res.dpp;
 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 	union plane_size size = plane_state->plane_size;
-	struct default_adjustment ocsc = {0};
 	struct mpcc_cfg mpcc_cfg = {0};
 	struct pipe_ctx *top_pipe;
 	bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
@@ -2286,10 +2304,8 @@ static void update_dchubp_dpp(
 	 */
 	REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst);
 
-	dc->hwss.update_plane_addr(dc, pipe_ctx);
-
-	mi->funcs->mem_input_setup(
-		mi,
+	hubp->funcs->hubp_setup(
+		hubp,
 		&pipe_ctx->dlg_regs,
 		&pipe_ctx->ttu_regs,
 		&pipe_ctx->rq_regs,
@@ -2299,19 +2315,20 @@ static void update_dchubp_dpp(
 
 	if (dc->config.gpu_vm_support)
 		dcn10_program_pte_vm(
-				pipe_ctx->plane_res.mi,
+				pipe_ctx->plane_res.hubp,
 				plane_state->format,
 				&plane_state->tiling_info,
 				plane_state->rotation,
 				hws
 				);
 
-	xfm->funcs->ipp_setup(xfm,
+	dpp->funcs->ipp_setup(dpp,
 			plane_state->format,
 			EXPANSION_MODE_ZERO);
 
-	mpcc_cfg.mi = mi;
-	mpcc_cfg.opp = pipe_ctx->stream_res.opp;
+	mpcc_cfg.dpp_id = hubp->inst;
+	mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst;
+	mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree);
 	for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
 		mpcc_cfg.z_index++;
 	if (dc->debug.surface_visual_confirm)
@@ -2328,25 +2345,27 @@ static void update_dchubp_dpp(
 	mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
 			pipe_ctx->stream->output_color_space)
 					&& per_pixel_alpha;
-	dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
+	hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
+	hubp->opp_id = mpcc_cfg.opp_id;
 
 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
 	pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
 	/* scaler configuration */
-	pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(
-			pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data);
-	mi->funcs->mem_program_viewport(mi,
+	pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
+			pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
+
+	hubp->funcs->mem_program_viewport(hubp,
 			&pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c);
 
 	/*gamut remap*/
 	program_gamut_remap(pipe_ctx);
 
-	/*TODO add adjustments parameters*/
-	ocsc.out_color_space = pipe_ctx->stream->output_color_space;
-	pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(pipe_ctx->plane_res.xfm, &ocsc);
+	program_csc_matrix(pipe_ctx,
+			pipe_ctx->stream->output_color_space,
+			pipe_ctx->stream->csc_color_matrix.matrix);
 
-	mi->funcs->mem_input_program_surface_config(
-		mi,
+	hubp->funcs->hubp_program_surface_config(
+		hubp,
 		plane_state->format,
 		&plane_state->tiling_info,
 		&size,
@@ -2354,8 +2373,10 @@ static void update_dchubp_dpp(
 		&plane_state->dcc,
 		plane_state->horizontal_mirror);
 
+	dc->hwss.update_plane_addr(dc, pipe_ctx);
+
 	if (is_pipe_tree_visible(pipe_ctx))
-		mi->funcs->set_blank(mi, false);
+		hubp->funcs->set_blank(hubp, false);
 }
 
 
@@ -2393,6 +2414,10 @@ static void program_all_pipe_in_tree(
 	}
 
 	if (pipe_ctx->plane_state != NULL) {
+		struct dc_cursor_position position = { 0 };
+		struct pipe_ctx *cur_pipe_ctx =
+				&dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
+
 		dcn10_power_on_fe(dc, pipe_ctx, context);
 
 		/* temporary dcn1 wa:
@@ -2407,6 +2432,19 @@ static void program_all_pipe_in_tree(
 		toggle_watermark_change_req(dc->hwseq);
 
 		update_dchubp_dpp(dc, pipe_ctx, context);
+
+		/* TODO: this is a hack w/a for switching from mpo to pipe split */
+		dc_stream_set_cursor_position(pipe_ctx->stream, &position);
+
+		dc_stream_set_cursor_attributes(pipe_ctx->stream,
+				&pipe_ctx->stream->cursor_attributes);
+
+		if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
+			dc->hwss.set_input_transfer_func(
+					pipe_ctx, pipe_ctx->plane_state);
+			dc->hwss.set_output_transfer_func(
+					pipe_ctx, pipe_ctx->stream);
+		}
 	}
 
 	if (dc->debug.sanity_checks) {
@@ -2445,6 +2483,30 @@ static void dcn10_pplib_apply_display_requirements(
 	dc->prev_display_config = *pp_display_cfg;
 }
 
+static void optimize_shared_resources(struct dc *dc)
+{
+	if (dc->current_state->stream_count == 0) {
+		apply_DEGVIDCN10_253_wa(dc);
+		/* S0i2 message */
+		dcn10_pplib_apply_display_requirements(dc, dc->current_state);
+	}
+
+	if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
+		dcn_bw_notify_pplib_of_wm_ranges(dc);
+}
+
+static void ready_shared_resources(struct dc *dc, struct dc_state *context)
+{
+	if (dc->current_state->stream_count == 0 &&
+			!dc->debug.disable_stutter)
+		undo_DEGVIDCN10_253_wa(dc);
+
+	/* S0i2 message */
+	if (dc->current_state->stream_count == 0 &&
+			context->stream_count != 0)
+		dcn10_pplib_apply_display_requirements(dc, context);
+}
+
 static void dcn10_apply_ctx_for_surface(
 		struct dc *dc,
 		const struct dc_stream_state *stream,
@@ -2494,7 +2556,7 @@ static void dcn10_apply_ctx_for_surface(
 		 */
 
 		if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
-			if (pipe_ctx->plane_res.mi->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
+			if (pipe_ctx->plane_res.hubp->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
 				dcn10_power_down_fe(dc, pipe_ctx->pipe_idx);
 				/*
 				 * power down fe will unlock when calling reset, need
@@ -2518,9 +2580,10 @@ static void dcn10_apply_ctx_for_surface(
 			/* reset mpc */
 			dc->res_pool->mpc->funcs->remove(
 					dc->res_pool->mpc,
-					old_pipe_ctx->stream_res.opp,
+					&(old_pipe_ctx->stream_res.opp->mpc_tree),
+					old_pipe_ctx->stream_res.opp->inst,
 					old_pipe_ctx->pipe_idx);
-			old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true;
+			old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.hubp->mpcc_id] = true;
 
 			/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
 					"[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n",
@@ -2532,6 +2595,7 @@ static void dcn10_apply_ctx_for_surface(
 			old_pipe_ctx->top_pipe = NULL;
 			old_pipe_ctx->bottom_pipe = NULL;
 			old_pipe_ctx->plane_state = NULL;
+			old_pipe_ctx->stream = NULL;
 
 			dm_logger_write(dc->ctx->logger, LOG_DC,
 					"Reset mpcc for pipe %d\n",
@@ -2803,7 +2867,7 @@ static void dcn10_wait_for_mpcc_disconnect(
 		if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
 			res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
 			pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
-			res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true);
+			res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
 			/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
 					"[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
 					i);*/
@@ -2834,11 +2898,11 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
 		return;
 
 	plane_state->status.is_flip_pending =
-			pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
-					pipe_ctx->plane_res.mi);
+			pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending(
+					pipe_ctx->plane_res.hubp);
 
-	plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
-	if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+	plane_state->status.current_address = pipe_ctx->plane_res.hubp->current_address;
+	if (pipe_ctx->plane_res.hubp->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
 			tg->funcs->is_stereo_left_eye) {
 		plane_state->status.is_right_eye =
 				!tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
@@ -2882,6 +2946,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
 	.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
 	.ready_shared_resources = ready_shared_resources,
 	.optimize_shared_resources = optimize_shared_resources,
+	.edp_backlight_control = hwss_edp_backlight_control,
+	.edp_power_control = hwss_edp_power_control
 };
 
 

+ 0 - 189
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c

@@ -37,188 +37,6 @@
 #define CTX \
 	ippn10->base.ctx
 
-static bool ippn10_cursor_program_control(
-		struct dcn10_ipp *ippn10,
-		bool pixel_data_invert,
-		enum dc_cursor_color_format color_format)
-{
-	if (REG(CURSOR_SETTINS))
-		REG_SET_2(CURSOR_SETTINS, 0,
-				/* no shift of the cursor HDL schedule */
-				CURSOR0_DST_Y_OFFSET, 0,
-				 /* used to shift the cursor chunk request deadline */
-				CURSOR0_CHUNK_HDL_ADJUST, 3);
-	else
-		REG_SET_2(CURSOR_SETTINGS, 0,
-				/* no shift of the cursor HDL schedule */
-				CURSOR0_DST_Y_OFFSET, 0,
-				 /* used to shift the cursor chunk request deadline */
-				CURSOR0_CHUNK_HDL_ADJUST, 3);
-
-	REG_UPDATE_2(CURSOR0_CONTROL,
-			CUR0_MODE, color_format,
-			CUR0_EXPANSION_MODE, 0);
-
-	if (color_format == CURSOR_MODE_MONO) {
-		/* todo: clarify what to program these to */
-		REG_UPDATE(CURSOR0_COLOR0,
-				CUR0_COLOR0, 0x00000000);
-		REG_UPDATE(CURSOR0_COLOR1,
-				CUR0_COLOR1, 0xFFFFFFFF);
-	}
-
-	/* TODO: Fixed vs float */
-
-	REG_UPDATE_3(FORMAT_CONTROL,
-				CNVC_BYPASS, 0,
-				ALPHA_EN, 1,
-				FORMAT_EXPANSION_MODE, 0);
-
-	return true;
-}
-
-enum cursor_pitch {
-	CURSOR_PITCH_64_PIXELS = 0,
-	CURSOR_PITCH_128_PIXELS,
-	CURSOR_PITCH_256_PIXELS
-};
-
-enum cursor_lines_per_chunk {
-	CURSOR_LINE_PER_CHUNK_2 = 1,
-	CURSOR_LINE_PER_CHUNK_4,
-	CURSOR_LINE_PER_CHUNK_8,
-	CURSOR_LINE_PER_CHUNK_16
-};
-
-static enum cursor_pitch ippn10_get_cursor_pitch(
-		unsigned int pitch)
-{
-	enum cursor_pitch hw_pitch;
-
-	switch (pitch) {
-	case 64:
-		hw_pitch = CURSOR_PITCH_64_PIXELS;
-		break;
-	case 128:
-		hw_pitch = CURSOR_PITCH_128_PIXELS;
-		break;
-	case 256:
-		hw_pitch = CURSOR_PITCH_256_PIXELS;
-		break;
-	default:
-		DC_ERR("Invalid cursor pitch of %d. "
-				"Only 64/128/256 is supported on DCN.\n", pitch);
-		hw_pitch = CURSOR_PITCH_64_PIXELS;
-		break;
-	}
-	return hw_pitch;
-}
-
-static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
-		unsigned int cur_width,
-		enum dc_cursor_color_format format)
-{
-	enum cursor_lines_per_chunk line_per_chunk;
-
-	if (format == CURSOR_MODE_MONO)
-		/* impl B. expansion in CUR Buffer reader */
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
-	else if (cur_width <= 32)
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
-	else if (cur_width <= 64)
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
-	else if (cur_width <= 128)
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
-	else
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
-
-	return line_per_chunk;
-}
-
-static void ippn10_cursor_set_attributes(
-		struct input_pixel_processor *ipp,
-		const struct dc_cursor_attributes *attr)
-{
-	struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
-	enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
-	enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
-			attr->width, attr->color_format);
-
-	ippn10->curs_attr = *attr;
-
-	REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
-			CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
-	REG_UPDATE(CURSOR_SURFACE_ADDRESS,
-			CURSOR_SURFACE_ADDRESS, attr->address.low_part);
-
-	REG_UPDATE_2(CURSOR_SIZE,
-			CURSOR_WIDTH, attr->width,
-			CURSOR_HEIGHT, attr->height);
-	REG_UPDATE_3(CURSOR_CONTROL,
-			CURSOR_MODE, attr->color_format,
-			CURSOR_PITCH, hw_pitch,
-			CURSOR_LINES_PER_CHUNK, lpc);
-	ippn10_cursor_program_control(ippn10,
-			attr->attribute_flags.bits.INVERT_PIXEL_DATA,
-			attr->color_format);
-}
-
-static void ippn10_cursor_set_position(
-		struct input_pixel_processor *ipp,
-		const struct dc_cursor_position *pos,
-		const struct dc_cursor_mi_param *param)
-{
-	struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
-	int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
-	uint32_t cur_en = pos->enable ? 1 : 0;
-	uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
-
-	/*
-	 * Guard aganst cursor_set_position() from being called with invalid
-	 * attributes
-	 *
-	 * TODO: Look at combining cursor_set_position() and
-	 * cursor_set_attributes() into cursor_update()
-	 */
-	if (ippn10->curs_attr.address.quad_part == 0)
-		return;
-
-	dst_x_offset *= param->ref_clk_khz;
-	dst_x_offset /= param->pixel_clk_khz;
-
-	ASSERT(param->h_scale_ratio.value);
-
-	if (param->h_scale_ratio.value)
-		dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
-				dal_fixed31_32_from_int(dst_x_offset),
-				param->h_scale_ratio));
-
-	if (src_x_offset >= (int)param->viewport_width)
-		cur_en = 0;  /* not visible beyond right edge*/
-
-	if (src_x_offset + (int)ippn10->curs_attr.width < 0)
-		cur_en = 0;  /* not visible beyond left edge*/
-
-	if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
-		ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
-	REG_UPDATE(CURSOR_CONTROL,
-			CURSOR_ENABLE, cur_en);
-	REG_UPDATE(CURSOR0_CONTROL,
-			CUR0_ENABLE, cur_en);
-
-	REG_SET_2(CURSOR_POSITION, 0,
-			CURSOR_X_POSITION, pos->x,
-			CURSOR_Y_POSITION, pos->y);
-
-	REG_SET_2(CURSOR_HOT_SPOT, 0,
-			CURSOR_HOT_SPOT_X, pos->x_hotspot,
-			CURSOR_HOT_SPOT_Y, pos->y_hotspot);
-
-	REG_SET(CURSOR_DST_OFFSET, 0,
-			CURSOR_DST_X_OFFSET, dst_x_offset);
-	/* TODO Handle surface pixel formats other than 4:4:4 */
-}
-
 /*****************************************/
 /* Constructor, Destructor               */
 /*****************************************/
@@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
 }
 
 static const struct ipp_funcs dcn10_ipp_funcs = {
-	.ipp_cursor_set_attributes	= ippn10_cursor_set_attributes,
-	.ipp_cursor_set_position	= ippn10_cursor_set_position,
-	.ipp_set_degamma		= NULL,
-	.ipp_program_input_lut		= NULL,
-	.ipp_full_bypass		= NULL,
-	.ipp_setup			= NULL,
-	.ipp_program_degamma_pwl	= NULL,
 	.ipp_destroy			= dcn10_ipp_destroy
 };
 

+ 152 - 63
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c

@@ -65,7 +65,7 @@ static void mpc10_set_bg_color(
 			MPCC_BG_B_CB, bg_b_cb);
 }
 
-static void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
+void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
 {
 	struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 
@@ -116,19 +116,21 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i
 	}
 }
 
-static void mpc10_mpcc_remove(
+void mpc10_mpcc_remove(
 		struct mpc *mpc,
-		struct output_pixel_processor *opp,
+		struct mpc_tree_cfg *tree_cfg,
+		int opp_id,
 		int dpp_id)
 {
 	struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
 	int mpcc_id, z_idx;
 
-	for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++)
-		if (opp->mpc_tree.dpp[z_idx] == dpp_id)
+	/* find z_idx for the dpp to be removed */
+	for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++)
+		if (tree_cfg->dpp[z_idx] == dpp_id)
 			break;
 
-	if (z_idx == opp->mpc_tree.num_pipes) {
+	if (z_idx == tree_cfg->num_pipes) {
 		/* In case of resume from S3/S4, remove mpcc from bios left over */
 		REG_SET(MPCC_OPP_ID[dpp_id], 0,
 				MPCC_OPP_ID, 0xf);
@@ -139,7 +141,7 @@ static void mpc10_mpcc_remove(
 		return;
 	}
 
-	mpcc_id = opp->mpc_tree.mpcc[z_idx];
+	mpcc_id = tree_cfg->mpcc[z_idx];
 
 	REG_SET(MPCC_OPP_ID[mpcc_id], 0,
 			MPCC_OPP_ID, 0xf);
@@ -149,82 +151,101 @@ static void mpc10_mpcc_remove(
 			MPCC_BOT_SEL, 0xf);
 
 	if (z_idx > 0) {
-		int top_mpcc_id = opp->mpc_tree.mpcc[z_idx - 1];
+		int top_mpcc_id = tree_cfg->mpcc[z_idx - 1];
 
-		if (z_idx + 1 < opp->mpc_tree.num_pipes)
+		if (z_idx + 1 < tree_cfg->num_pipes)
+			/* mpcc to be removed is in the middle of the tree */
 			REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
-					MPCC_BOT_SEL, opp->mpc_tree.mpcc[z_idx + 1]);
+					MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]);
 		else {
+			/* mpcc to be removed is at the bottom of the tree */
 			REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
 					MPCC_BOT_SEL, 0xf);
 			REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
 					MPCC_MODE, MODE_TOP_ONLY);
 		}
-	} else if (opp->mpc_tree.num_pipes > 1)
-		REG_SET(MUX[opp->inst], 0,
-				MPC_OUT_MUX, opp->mpc_tree.mpcc[z_idx + 1]);
+	} else if (tree_cfg->num_pipes > 1)
+		/* mpcc to be removed is at the top of the tree */
+		REG_SET(MUX[opp_id], 0,
+				MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]);
 	else
-		REG_SET(MUX[opp->inst], 0, MPC_OUT_MUX, 0xf);
+		/* mpcc to be removed is the only one in the tree */
+		REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf);
 
+	/* mark this mpcc as not in use */
 	mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
-	opp->mpc_tree.num_pipes--;
-	for (; z_idx < opp->mpc_tree.num_pipes; z_idx++) {
-		opp->mpc_tree.dpp[z_idx] = opp->mpc_tree.dpp[z_idx + 1];
-		opp->mpc_tree.mpcc[z_idx] = opp->mpc_tree.mpcc[z_idx + 1];
+	tree_cfg->num_pipes--;
+	for (; z_idx < tree_cfg->num_pipes; z_idx++) {
+		tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1];
+		tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1];
 	}
-	opp->mpc_tree.dpp[opp->mpc_tree.num_pipes] = 0xdeadbeef;
-	opp->mpc_tree.mpcc[opp->mpc_tree.num_pipes] = 0xdeadbeef;
+	tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef;
+	tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef;
 }
 
-static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
+static void mpc10_add_to_tree_cfg(
+	struct mpc *mpc,
+	struct mpcc_cfg *cfg,
+	int mpcc_id)
 {
 	struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+	int mpcc_mode = MODE_TOP_ONLY;
+	int position = cfg->z_index;
+	struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg;
 	int alpha_blnd_mode = cfg->per_pixel_alpha ?
 			BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
-	int mpcc_mode = MODE_TOP_ONLY;
-	int mpcc_id, z_idx;
+	int z_idx;
 
-	ASSERT(cfg->z_index < mpc10->num_mpcc);
+	REG_SET(MPCC_OPP_ID[mpcc_id], 0,
+			MPCC_OPP_ID, cfg->opp_id);
 
-	for (z_idx = 0; z_idx < cfg->opp->mpc_tree.num_pipes; z_idx++)
-		if (cfg->opp->mpc_tree.dpp[z_idx] == cfg->mi->inst)
-			break;
-	if (z_idx == cfg->opp->mpc_tree.num_pipes) {
-		ASSERT(cfg->z_index <= cfg->opp->mpc_tree.num_pipes);
-		mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
-		/*todo: remove hack*/
-		mpcc_id = cfg->mi->inst;
-		ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
+	REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
+			MPCC_TOP_SEL, cfg->dpp_id);
 
-		if (mpc->ctx->dc->debug.sanity_checks)
-			mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
-	} else {
-		ASSERT(cfg->z_index < cfg->opp->mpc_tree.num_pipes);
-		mpcc_id = cfg->opp->mpc_tree.mpcc[z_idx];
-		mpc10_mpcc_remove(mpc, cfg->opp, cfg->mi->inst);
-	}
+	if (position == 0) {
+		/* idle dpp/mpcc is added to the top layer of tree */
 
-	REG_SET(MPCC_OPP_ID[mpcc_id], 0,
-			MPCC_OPP_ID, cfg->opp->inst);
+		if (tree_cfg->num_pipes > 0) {
+			/* get instance of previous top mpcc */
+			int prev_top_mpcc_id = tree_cfg->mpcc[0];
 
-	REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
-			MPCC_TOP_SEL, cfg->mi->inst);
+			REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
+					MPCC_BOT_SEL, prev_top_mpcc_id);
+			mpcc_mode = MODE_BLEND;
+		}
 
-	if (cfg->z_index > 0) {
-		int top_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index - 1];
+		/* opp will get new output. from new added mpcc */
+		REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id);
 
-		REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
+	} else if (position == tree_cfg->num_pipes) {
+		/* idle dpp/mpcc is added to the bottom layer of tree */
+
+		/* get instance of previous bottom mpcc, set to middle layer */
+		int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1];
+
+		REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0,
 				MPCC_BOT_SEL, mpcc_id);
-		REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
+		REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id],
 				MPCC_MODE, MODE_BLEND);
-	} else
-		REG_SET(MUX[cfg->opp->inst], 0, MPC_OUT_MUX, mpcc_id);
 
-	if (cfg->z_index < cfg->opp->mpc_tree.num_pipes) {
-		int bot_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index];
+		/* mpcc_id become new bottom mpcc*/
+		REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
+				MPCC_BOT_SEL, 0xf);
+
+	} else {
+		/* idle dpp/mpcc is added to middle of tree */
+		int above_mpcc_id = tree_cfg->mpcc[position - 1];
+		int below_mpcc_id = tree_cfg->mpcc[position];
 
+		/* mpcc above new mpcc_id has new bottom mux*/
+		REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0,
+				MPCC_BOT_SEL, mpcc_id);
+		REG_UPDATE(MPCC_CONTROL[above_mpcc_id],
+				MPCC_MODE, MODE_BLEND);
+
+		/* mpcc_id bottom mux is from below mpcc*/
 		REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
-				MPCC_BOT_SEL, bot_mpcc_id);
+				MPCC_BOT_SEL, below_mpcc_id);
 		mpcc_mode = MODE_BLEND;
 	}
 
@@ -234,24 +255,91 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
 		MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
 		MPCC_BLND_ACTIVE_OVERLAP_ONLY, false);
 
+	/* update mpc_tree_cfg with new mpcc */
+	for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) {
+		tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1];
+		tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1];
+	}
+	tree_cfg->dpp[position] = cfg->dpp_id;
+	tree_cfg->mpcc[position] = mpcc_id;
+	tree_cfg->num_pipes++;
+}
+
+int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
+{
+	struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+	int mpcc_id, z_idx;
+
+	ASSERT(cfg->z_index < mpc10->num_mpcc);
+
+	/* check in dpp already exists in mpc tree */
+	for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
+		if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
+			break;
+	if (z_idx == cfg->tree_cfg->num_pipes) {
+		ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes);
+		mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
+
+		/*
+		 * TODO: remove hack
+		 * Note: currently there is a bug in init_hw such that
+		 * on resume from hibernate, BIOS sets up MPCC0, and
+		 * we do mpcc_remove but the mpcc cannot go to idle
+		 * after remove. This cause us to pick mpcc1 here,
+		 * which causes a pstate hang for yet unknown reason.
+		 */
+		mpcc_id = cfg->dpp_id;
+		/* end hack*/
+
+		ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
+
+		if (mpc->ctx->dc->debug.sanity_checks)
+			mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
+	} else {
+		ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes);
+		mpcc_id = cfg->tree_cfg->mpcc[z_idx];
+		mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id);
+	}
+
+	/* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */
+	mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id);
+
+	/* set background color */
 	mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id);
 
+	/* mark this mpcc as in use */
 	mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
-	for (z_idx = cfg->opp->mpc_tree.num_pipes; z_idx > cfg->z_index; z_idx--) {
-		cfg->opp->mpc_tree.dpp[z_idx] = cfg->opp->mpc_tree.dpp[z_idx - 1];
-		cfg->opp->mpc_tree.mpcc[z_idx] = cfg->opp->mpc_tree.mpcc[z_idx - 1];
-	}
-	cfg->opp->mpc_tree.dpp[cfg->z_index] = cfg->mi->inst;
-	cfg->opp->mpc_tree.mpcc[cfg->z_index] = mpcc_id;
-	cfg->opp->mpc_tree.num_pipes++;
-	cfg->mi->opp_id = cfg->opp->inst;
-	cfg->mi->mpcc_id = mpcc_id;
+
+	return mpcc_id;
+}
+
+void mpc10_update_blend_mode(
+		struct mpc *mpc,
+		struct mpcc_cfg *cfg)
+{
+	struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+	int mpcc_id, z_idx;
+	int alpha_blnd_mode = cfg->per_pixel_alpha ?
+			BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
+
+	/* find z_idx for the dpp that requires blending mode update*/
+	for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
+		if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
+			break;
+
+	ASSERT(z_idx < cfg->tree_cfg->num_pipes);
+	mpcc_id = cfg->tree_cfg->mpcc[z_idx];
+
+	REG_UPDATE_2(MPCC_CONTROL[mpcc_id],
+			MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
+			MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha);
 }
 
 const struct mpc_funcs dcn10_mpc_funcs = {
 		.add = mpc10_mpcc_add,
 		.remove = mpc10_mpcc_remove,
-		.wait_for_idle = mpc10_assert_idle_mpcc
+		.wait_for_idle = mpc10_assert_idle_mpcc,
+		.update_blend_mode = mpc10_update_blend_mode,
 };
 
 void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
@@ -272,3 +360,4 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
 	mpc10->mpcc_in_use_mask = 0;
 	mpc10->num_mpcc = num_mpcc;
 }
+

+ 34 - 11
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h

@@ -34,7 +34,6 @@
 #define MAX_OPP 6
 
 #define MPC_COMMON_REG_LIST_DCN1_0(inst) \
-	SRII(MUX, MPC_OUT, inst),\
 	SRII(MPCC_TOP_SEL, MPCC, inst),\
 	SRII(MPCC_BOT_SEL, MPCC, inst),\
 	SRII(MPCC_CONTROL, MPCC, inst),\
@@ -45,17 +44,19 @@
 	SRII(MPCC_BG_B_CB, MPCC, inst),\
 	SRII(MPCC_BG_B_CB, MPCC, inst)
 
-struct dcn_mpc_registers {
-	uint32_t MPCC_TOP_SEL[MAX_MPCC];
-	uint32_t MPCC_BOT_SEL[MAX_MPCC];
-	uint32_t MPCC_CONTROL[MAX_MPCC];
-	uint32_t MPCC_STATUS[MAX_MPCC];
-	uint32_t MPCC_OPP_ID[MAX_MPCC];
-	uint32_t MPCC_BG_G_Y[MAX_MPCC];
-	uint32_t MPCC_BG_R_CR[MAX_MPCC];
-	uint32_t MPCC_BG_B_CB[MAX_MPCC];
+#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
+	SRII(MUX, MPC_OUT, inst)
+
+#define MPC_COMMON_REG_VARIABLE_LIST \
+	uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
+	uint32_t MPCC_BOT_SEL[MAX_MPCC]; \
+	uint32_t MPCC_CONTROL[MAX_MPCC]; \
+	uint32_t MPCC_STATUS[MAX_MPCC]; \
+	uint32_t MPCC_OPP_ID[MAX_MPCC]; \
+	uint32_t MPCC_BG_G_Y[MAX_MPCC]; \
+	uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
+	uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
 	uint32_t MUX[MAX_OPP];
-};
 
 #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
 	SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
@@ -87,6 +88,10 @@ struct dcn_mpc_registers {
 	type MPCC_BG_B_CB;\
 	type MPC_OUT_MUX;
 
+struct dcn_mpc_registers {
+	MPC_COMMON_REG_VARIABLE_LIST
+};
+
 struct dcn_mpc_shift {
 	MPC_REG_FIELD_LIST(uint8_t)
 };
@@ -112,4 +117,22 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10,
 	const struct dcn_mpc_mask *mpc_mask,
 	int num_mpcc);
 
+int mpc10_mpcc_add(
+		struct mpc *mpc,
+		struct mpcc_cfg *cfg);
+
+void mpc10_mpcc_remove(
+		struct mpc *mpc,
+		struct mpc_tree_cfg *tree_cfg,
+		int opp_id,
+		int dpp_id);
+
+void mpc10_assert_idle_mpcc(
+		struct mpc *mpc,
+		int id);
+
+void mpc10_update_blend_mode(
+		struct mpc *mpc,
+		struct mpcc_cfg *cfg);
+
 #endif

+ 59 - 41
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c

@@ -42,12 +42,12 @@
 #include "dce/dce_stream_encoder.h"
 #include "dce/dce_clocks.h"
 #include "dce/dce_clock_source.h"
-#include "dcn10/dcn10_mem_input.h"
 #include "dce/dce_audio.h"
 #include "dce/dce_hwseq.h"
 #include "../virtual/virtual_stream_encoder.h"
 #include "dce110/dce110_resource.h"
 #include "dce112/dce112_resource.h"
+#include "dcn10_hubp.h"
 
 #include "vega10/soc15ip.h"
 
@@ -329,7 +329,11 @@ static const struct dcn_mpc_registers mpc_regs = {
 		MPC_COMMON_REG_LIST_DCN1_0(0),
 		MPC_COMMON_REG_LIST_DCN1_0(1),
 		MPC_COMMON_REG_LIST_DCN1_0(2),
-		MPC_COMMON_REG_LIST_DCN1_0(3)
+		MPC_COMMON_REG_LIST_DCN1_0(3),
+		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
+		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
+		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
+		MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
 };
 
 static const struct dcn_mpc_shift mpc_shift = {
@@ -414,22 +418,24 @@ static const struct resource_caps res_cap = {
 };
 
 static const struct dc_debug debug_defaults_drv = {
-		.disable_dcc = false,
 		.sanity_checks = true,
 		.disable_dmcu = true,
 		.force_abm_enable = false,
 		.timing_trace = false,
 		.clock_trace = true,
-		/* spread sheet doesn't handle taps_c is one properly,
-		 * need to enable scaler for video surface to pass
-		 * bandwidth validation.*/
-		.always_scale = true,
+
+		.min_disp_clk_khz = 300000,
+
 		.disable_pplib_clock_request = true,
 		.disable_pplib_wm_range = false,
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
-		.use_dml_wm = false,
-		.disable_pipe_split = true
-#endif
+		.pplib_wm_report_mode = WM_REPORT_DEFAULT,
+		.pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
+		.force_single_disp_pipe_split = true,
+		.disable_dcc = DCC_ENABLE,
+		.voltage_align_fclk = true,
+		.disable_stereo_support = true,
+		.vsr_support = true,
+		.performance_trace = false,
 };
 
 static const struct dc_debug debug_defaults_diags = {
@@ -438,21 +444,17 @@ static const struct dc_debug debug_defaults_diags = {
 		.timing_trace = true,
 		.clock_trace = true,
 		.disable_stutter = true,
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 		.disable_pplib_clock_request = true,
-		.disable_pplib_wm_range = true,
-		.use_dml_wm = false,
-		.disable_pipe_split = false
-#endif
+		.disable_pplib_wm_range = true
 };
 
-static void dcn10_dpp_destroy(struct transform **xfm)
+static void dcn10_dpp_destroy(struct dpp **dpp)
 {
-	kfree(TO_DCN10_DPP(*xfm));
-	*xfm = NULL;
+	kfree(TO_DCN10_DPP(*dpp));
+	*dpp = NULL;
 }
 
-static struct transform *dcn10_dpp_create(
+static struct dpp *dcn10_dpp_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -462,8 +464,8 @@ static struct transform *dcn10_dpp_create(
 	if (!dpp)
 		return NULL;
 
-	dcn10_dpp_construct(dpp, ctx, inst,
-			    &tf_regs[inst], &tf_shift, &tf_mask);
+	dpp1_construct(dpp, ctx, inst,
+		       &tf_regs[inst], &tf_shift, &tf_mask);
 	return &dpp->base;
 }
 
@@ -702,15 +704,15 @@ static void destruct(struct dcn10_resource_pool *pool)
 		if (pool->base.opps[i] != NULL)
 			pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
 
-		if (pool->base.transforms[i] != NULL)
-			dcn10_dpp_destroy(&pool->base.transforms[i]);
+		if (pool->base.dpps[i] != NULL)
+			dcn10_dpp_destroy(&pool->base.dpps[i]);
 
 		if (pool->base.ipps[i] != NULL)
 			pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
 
-		if (pool->base.mis[i] != NULL) {
-			kfree(TO_DCN10_MEM_INPUT(pool->base.mis[i]));
-			pool->base.mis[i] = NULL;
+		if (pool->base.hubps[i] != NULL) {
+			kfree(TO_DCN10_HUBP(pool->base.hubps[i]));
+			pool->base.hubps[i] = NULL;
 		}
 
 		if (pool->base.irqs != NULL) {
@@ -757,19 +759,19 @@ static void destruct(struct dcn10_resource_pool *pool)
 	kfree(pool->base.pp_smu);
 }
 
-static struct mem_input *dcn10_mem_input_create(
+static struct hubp *dcn10_hubp_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
-	struct dcn10_mem_input *mem_inputn10 =
-		kzalloc(sizeof(struct dcn10_mem_input), GFP_KERNEL);
+	struct dcn10_hubp *hubp1 =
+		kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL);
 
-	if (!mem_inputn10)
+	if (!hubp1)
 		return NULL;
 
-	dcn10_mem_input_construct(mem_inputn10, ctx, inst,
-				  &mi_regs[inst], &mi_shift, &mi_mask);
-	return &mem_inputn10->base;
+	dcn10_hubp_construct(hubp1, ctx, inst,
+			     &mi_regs[inst], &mi_shift, &mi_mask);
+	return &hubp1->base;
 }
 
 static void get_pixel_clock_parameters(
@@ -922,9 +924,9 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
 	idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
 	idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
 
-	idle_pipe->plane_res.mi = pool->mis[idle_pipe->pipe_idx];
+	idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
 	idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
-	idle_pipe->plane_res.xfm = pool->transforms[idle_pipe->pipe_idx];
+	idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
 
 	return idle_pipe;
 }
@@ -1085,7 +1087,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
 
 	memset(output, 0, sizeof(*output));
 
-	if (dc->debug.disable_dcc)
+	if (dc->debug.disable_dcc == DCC_DISABLE)
 		return false;
 
 	if (!dcc_support_pixel_format(input->format,
@@ -1129,6 +1131,10 @@ static bool get_dcc_compression_cap(const struct dc *dc,
 			dcc_control = dcc_control__128_128_xxx;
 	}
 
+	if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
+		dcc_control != dcc_control__256_256_xxx)
+		return false;
+
 	switch (dcc_control) {
 	case dcc_control__256_256_xxx:
 		output->grph.rgb.max_uncompressed_blk_size = 256;
@@ -1146,6 +1152,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
 		output->grph.rgb.independent_64b_blks = true;
 		break;
 	}
+
 	output->capable = true;
 	output->const_color_support = false;
 
@@ -1162,6 +1169,15 @@ static void dcn10_destroy_resource_pool(struct resource_pool **pool)
 	*pool = NULL;
 }
 
+static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
+{
+	if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
+			&& caps->max_video_width != 0
+			&& plane_state->src_rect.width > caps->max_video_width)
+		return DC_FAIL_SURFACE_VALIDATE;
+
+	return DC_OK;
+}
 
 static struct dc_cap_funcs cap_funcs = {
 	.get_dcc_compression_cap = get_dcc_compression_cap
@@ -1173,6 +1189,7 @@ static struct resource_funcs dcn10_res_pool_funcs = {
 	.validate_guaranteed = dcn10_validate_guaranteed,
 	.validate_bandwidth = dcn_validate_bandwidth,
 	.acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
+	.validate_plane = dcn10_validate_plane,
 	.add_stream_to_ctx = dcn10_add_stream_to_ctx
 };
 
@@ -1212,6 +1229,7 @@ static bool construct(
 	/* max pipe num for ASIC before check pipe fuses */
 	pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
 
+	dc->caps.max_video_width = 3840;
 	dc->caps.max_downscale_ratio = 200;
 	dc->caps.i2c_speed_in_khz = 100;
 	dc->caps.max_cursor_size = 256;
@@ -1345,8 +1363,8 @@ static bool construct(
 		if ((pipe_fuses & (1 << i)) != 0)
 			continue;
 
-		pool->base.mis[j] = dcn10_mem_input_create(ctx, i);
-		if (pool->base.mis[j] == NULL) {
+		pool->base.hubps[j] = dcn10_hubp_create(ctx, i);
+		if (pool->base.hubps[j] == NULL) {
 			BREAK_TO_DEBUGGER();
 			dm_error(
 				"DC: failed to create memory input!\n");
@@ -1361,8 +1379,8 @@ static bool construct(
 			goto ipp_create_fail;
 		}
 
-		pool->base.transforms[j] = dcn10_dpp_create(ctx, i);
-		if (pool->base.transforms[j] == NULL) {
+		pool->base.dpps[j] = dcn10_dpp_create(ctx, i);
+		if (pool->base.dpps[j] == NULL) {
 			BREAK_TO_DEBUGGER();
 			dm_error(
 				"DC: failed to create dpp!\n");

+ 15 - 0
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c

@@ -25,6 +25,7 @@
 
 #include "reg_helper.h"
 #include "dcn10_timing_generator.h"
+#include "dc.h"
 
 #define REG(reg)\
 	tgn10->tg_regs->reg
@@ -299,6 +300,17 @@ static void tgn10_program_timing(
 static void tgn10_unblank_crtc(struct timing_generator *tg)
 {
 	struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+	uint32_t vertical_interrupt_enable = 0;
+
+	REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
+			OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
+
+	/* temporary work around for vertical interrupt, once vertical interrupt enabled,
+	 * this check will be removed.
+	 */
+	if (vertical_interrupt_enable)
+		REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
+				OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 1);
 
 	REG_UPDATE_2(OTG_BLANK_CONTROL,
 			OTG_BLANK_DATA_EN, 0,
@@ -487,6 +499,9 @@ static bool tgn10_validate_timing(
 		timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
 		return false;
 
+	if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
+		tg->ctx->dc->debug.disable_stereo_support)
+		return false;
 	/* Temporarily blocking interlacing mode until it's supported */
 	if (timing->flags.INTERLACE == 1)
 		return false;

+ 5 - 10
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h

@@ -65,17 +65,14 @@
 	SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
 	SRI(OTG_BLACK_COLOR, OTG, inst),\
 	SRI(OTG_CLOCK_CONTROL, OTG, inst),\
+	SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
 	SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
 	SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
 	SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
 	SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
 	SRI(OPPBUF_CONTROL, OPPBUF, inst),\
 	SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\
-	SRI(CONTROL, VTG, inst),\
-	SR(D1VGA_CONTROL),\
-	SR(D2VGA_CONTROL),\
-	SR(D3VGA_CONTROL),\
-	SR(D4VGA_CONTROL)
+	SRI(CONTROL, VTG, inst)
 
 #define TG_COMMON_REG_LIST_DCN1_0(inst) \
 	TG_COMMON_REG_LIST_DCN(inst),\
@@ -121,6 +118,7 @@ struct dcn_tg_registers {
 	uint32_t OTG_TEST_PATTERN_CONTROL;
 	uint32_t OTG_TEST_PATTERN_COLOR;
 	uint32_t OTG_CLOCK_CONTROL;
+	uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
 	uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
 	uint32_t OPTC_INPUT_CLOCK_CONTROL;
 	uint32_t OPTC_DATA_SOURCE_SELECT;
@@ -128,11 +126,6 @@ struct dcn_tg_registers {
 	uint32_t OPPBUF_CONTROL;
 	uint32_t OPPBUF_3D_PARAMETERS_0;
 	uint32_t CONTROL;
-	/*todo: move VGA to HWSS */
-	uint32_t D1VGA_CONTROL;
-	uint32_t D2VGA_CONTROL;
-	uint32_t D3VGA_CONTROL;
-	uint32_t D4VGA_CONTROL;
 };
 
 #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -205,6 +198,7 @@ struct dcn_tg_registers {
 	SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
 	SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
 	SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
+	SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
 	SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
 	SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
 	SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
@@ -311,6 +305,7 @@ struct dcn_tg_registers {
 	type OTG_CLOCK_EN;\
 	type OTG_CLOCK_ON;\
 	type OTG_CLOCK_GATE_DIS;\
+	type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
 	type OTG_VERTICAL_INTERRUPT2_LINE_START;\
 	type OPTC_INPUT_CLK_EN;\
 	type OPTC_INPUT_CLK_ON;\

+ 2 - 45
drivers/gpu/drm/amd/display/dc/dm_services.h

@@ -38,51 +38,6 @@
 
 #undef DEPRECATED
 
-/*
- *
- * general debug capabilities
- *
- */
-#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
-
-#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
-#define ASSERT_CRITICAL(expr) do {	\
-	if (WARN_ON(!(expr))) { \
-		kgdb_breakpoint(); \
-	} \
-} while (0)
-#else
-#define ASSERT_CRITICAL(expr) do {	\
-	if (WARN_ON(!(expr))) { \
-		; \
-	} \
-} while (0)
-#endif
-
-#if defined(CONFIG_DEBUG_KERNEL_DC)
-#define ASSERT(expr) ASSERT_CRITICAL(expr)
-
-#else
-#define ASSERT(expr) WARN_ON(!(expr))
-#endif
-
-#define BREAK_TO_DEBUGGER() ASSERT(0)
-
-#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
-
-#define DC_ERR(...)  do { \
-	dm_error(__VA_ARGS__); \
-	BREAK_TO_DEBUGGER(); \
-} while (0)
-
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
-#include <asm/fpu/api.h>
-#endif
-
-#define dm_alloc(size) kzalloc(size, GFP_KERNEL)
-#define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
-#define dm_free(ptr) kfree(ptr)
-
 irq_handler_idx dm_register_interrupt(
 	struct dc_context *ctx,
 	struct dc_interrupt_params *int_params,
@@ -418,6 +373,8 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
 #define dm_log_to_buffer(buffer, size, fmt, args)\
 	vsnprintf(buffer, size, fmt, args)
 
+unsigned long long dm_get_timestamp(struct dc_context *ctx);
+
 /*
  * Debug and verification hooks
  */

+ 5 - 3
drivers/gpu/drm/amd/display/dc/dml/Makefile

@@ -3,17 +3,19 @@
 # It provides the general basic services required by other DAL
 # subcomponents.
 
+CFLAGS_display_mode_vba.o := -mhard-float -msse -mpreferred-stack-boundary=4
 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_dml1_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
 
+
 DML = display_mode_lib.o display_rq_dlg_calc.o \
-	  display_rq_dlg_helpers.o display_watermark.o \
-	  soc_bounding_box.o dml_common_defs.o
+	  display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
+	  soc_bounding_box.o dml_common_defs.o display_mode_vba.o
 
 AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
 

+ 2 - 0
drivers/gpu/drm/amd/display/dc/dml/dc_features.h

@@ -25,9 +25,11 @@
 #ifndef __DC_FEATURES_H__
 #define __DC_FEATURES_H__
 
+// local features
 #define DC__PRESENT 1
 #define DC__PRESENT__1 1
 #define DC__NUM_DPP 4
+#define DC__VOLTAGE_STATES 7
 #define DC__NUM_DPP__4 1
 #define DC__NUM_DPP__0_PRESENT 1
 #define DC__NUM_DPP__1_PRESENT 1

+ 28 - 28
drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h

@@ -24,14 +24,12 @@
  */
 #ifndef __DISPLAY_MODE_ENUMS_H__
 #define __DISPLAY_MODE_ENUMS_H__
+
 enum output_encoder_class {
-	dm_dp = 0,
-	dm_hdmi = 1,
-	dm_wb = 2
+	dm_dp = 0, dm_hdmi = 1, dm_wb = 2, dm_edp
 };
 enum output_format_class {
-	dm_444 = 0,
-	dm_420 = 1
+	dm_444 = 0, dm_420 = 1, dm_n422, dm_s422
 };
 enum source_format_class {
 	dm_444_16 = 0,
@@ -40,18 +38,16 @@ enum source_format_class {
 	dm_420_8 = 3,
 	dm_420_10 = 4,
 	dm_422_8 = 5,
-	dm_422_10 = 6
+	dm_422_10 = 6,
+	dm_444_8 = 7,
+	dm_mono_8,
+	dm_mono_16
 };
 enum output_bpc_class {
-	dm_out_6 = 0,
-	dm_out_8 = 1,
-	dm_out_10 = 2,
-	dm_out_12 = 3,
-	dm_out_16 = 4
+	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
+	dm_horz = 0, dm_vert = 1
 };
 enum dm_swizzle_mode {
 	dm_sw_linear = 0,
@@ -84,28 +80,32 @@ enum dm_swizzle_mode {
 	dm_sw_SPARE_14 = 27,
 	dm_sw_SPARE_15 = 28,
 	dm_sw_var_s_x = 29,
-	dm_sw_var_d_x = 30
+	dm_sw_var_d_x = 30,
+	dm_sw_64kb_r_x,
+	dm_sw_gfx7_2d_thin_lvp,
+	dm_sw_gfx7_2d_thin_gl
 };
 enum lb_depth {
-	dm_lb_10 = 30,
-	dm_lb_8 = 24,
-	dm_lb_6 = 18,
-	dm_lb_12 = 36
+	dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16
 };
 enum voltage_state {
-	dm_vmin = 0,
-	dm_vmid = 1,
-	dm_vnom = 2,
-	dm_vmax = 3,
-	dm_vmax_exceeded = 4
+	dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3
 };
 enum source_macro_tile_size {
-	dm_4k_tile = 0,
-	dm_64k_tile = 1,
-	dm_256k_tile = 2
+	dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2
 };
 enum cursor_bpp {
-	dm_cur_2bit = 0,
-	dm_cur_32bit = 1
+	dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2
 };
+enum clock_change_support {
+	dm_dram_clock_change_uninitialized = 0,
+	dm_dram_clock_change_vactive,
+	dm_dram_clock_change_vblank,
+	dm_dram_clock_change_unsupported
+};
+
+enum output_standard {
+	dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt
+};
+
 #endif

+ 1 - 10
drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c

@@ -24,6 +24,7 @@
  */
 
 #include "display_mode_lib.h"
+#include "dc_features.h"
 
 static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project)
 {
@@ -126,21 +127,11 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro
 	}
 }
 
-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;
 	}
 }

+ 4 - 5
drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h

@@ -25,11 +25,12 @@
 #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_mode_vba.h"
 #include "display_rq_dlg_calc.h"
-#include "display_mode_support.h"
+#include "dml1_display_rq_dlg_calc.h"
 
 enum dml_project {
 	DML_PROJECT_UNDEFINED,
@@ -39,10 +40,8 @@ enum dml_project {
 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 vba_vars_st vba;
 	struct dal_logger *logger;
 };
 

+ 514 - 386
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h

@@ -25,405 +25,533 @@
 #ifndef __DISPLAY_MODE_STRUCTS_H__
 #define __DISPLAY_MODE_STRUCTS_H__
 
+typedef struct _vcs_dpi_voltage_scaling_st	voltage_scaling_st;
+typedef struct _vcs_dpi_soc_bounding_box_st	soc_bounding_box_st;
+typedef struct _vcs_dpi_ip_params_st	ip_params_st;
+typedef struct _vcs_dpi_display_pipe_source_params_st	display_pipe_source_params_st;
+typedef struct _vcs_dpi_display_output_params_st	display_output_params_st;
+typedef struct _vcs_dpi_display_bandwidth_st	display_bandwidth_st;
+typedef struct _vcs_dpi_scaler_ratio_depth_st	scaler_ratio_depth_st;
+typedef struct _vcs_dpi_scaler_taps_st	scaler_taps_st;
+typedef struct _vcs_dpi_display_pipe_dest_params_st	display_pipe_dest_params_st;
+typedef struct _vcs_dpi_display_pipe_params_st	display_pipe_params_st;
+typedef struct _vcs_dpi_display_clocks_and_cfg_st	display_clocks_and_cfg_st;
+typedef struct _vcs_dpi_display_e2e_pipe_params_st	display_e2e_pipe_params_st;
+typedef struct _vcs_dpi_dchub_buffer_sizing_st	dchub_buffer_sizing_st;
+typedef struct _vcs_dpi_watermarks_perf_st	watermarks_perf_st;
+typedef struct _vcs_dpi_cstate_pstate_watermarks_st	cstate_pstate_watermarks_st;
+typedef struct _vcs_dpi_wm_calc_pipe_params_st	wm_calc_pipe_params_st;
+typedef struct _vcs_dpi_vratio_pre_st	vratio_pre_st;
+typedef struct _vcs_dpi_display_data_rq_misc_params_st	display_data_rq_misc_params_st;
+typedef struct _vcs_dpi_display_data_rq_sizing_params_st	display_data_rq_sizing_params_st;
+typedef struct _vcs_dpi_display_data_rq_dlg_params_st	display_data_rq_dlg_params_st;
+typedef struct _vcs_dpi_display_cur_rq_dlg_params_st	display_cur_rq_dlg_params_st;
+typedef struct _vcs_dpi_display_rq_dlg_params_st	display_rq_dlg_params_st;
+typedef struct _vcs_dpi_display_rq_sizing_params_st	display_rq_sizing_params_st;
+typedef struct _vcs_dpi_display_rq_misc_params_st	display_rq_misc_params_st;
+typedef struct _vcs_dpi_display_rq_params_st	display_rq_params_st;
+typedef struct _vcs_dpi_display_dlg_regs_st	display_dlg_regs_st;
+typedef struct _vcs_dpi_display_ttu_regs_st	display_ttu_regs_st;
+typedef struct _vcs_dpi_display_data_rq_regs_st	display_data_rq_regs_st;
+typedef struct _vcs_dpi_display_rq_regs_st	display_rq_regs_st;
+typedef struct _vcs_dpi_display_dlg_sys_params_st	display_dlg_sys_params_st;
+typedef struct _vcs_dpi_display_dlg_prefetch_param_st	display_dlg_prefetch_param_st;
+typedef struct _vcs_dpi_display_pipe_clock_st	display_pipe_clock_st;
+typedef struct _vcs_dpi_display_arb_params_st	display_arb_params_st;
+
 struct _vcs_dpi_voltage_scaling_st {
+	int state;
+	double dscclk_mhz;
 	double dcfclk_mhz;
+	double socclk_mhz;
+	double dram_speed_mhz;
+	double fabricclk_mhz;
 	double dispclk_mhz;
-	double dppclk_mhz;
 	double dram_bw_per_chan_gbps;
 	double phyclk_mhz;
-	double socclk_mhz;
+	double dppclk_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;
+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;
+	double	dram_channel_width_bytes;
+	double fabric_datapath_to_dcn_data_return_bytes;
+	double dcn_downspread_percent;
+	double dispclk_dppclk_vco_speed_mhz;
+	double dfs_vco_period_ps;
+	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;
+	unsigned int	voltage_override;
+	double	xfc_bus_transport_time_us;
+	double	xfc_xbuf_latency_tolerance_us;
+	struct _vcs_dpi_voltage_scaling_st clock_limits[7];
+};
+
+struct	_vcs_dpi_ip_params_st	{
+	unsigned int	max_inter_dcn_tile_repeaters;
+	unsigned int	num_dsc;
+	unsigned int	odm_capable;
+	unsigned int	rob_buffer_size_kbytes;
+	unsigned int	det_buffer_size_kbytes;
+	unsigned int	dpte_buffer_size_in_pte_reqs;
+	unsigned int	pde_proc_buffer_size_64k_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	writeback_luma_buffer_size_kbytes;
+	unsigned int	writeback_chroma_buffer_size_kbytes;
+	unsigned int	writeback_chroma_line_buffer_width_pixels;
+	unsigned int	max_page_table_levels;
+	unsigned int	max_num_dpp;
+	unsigned int	max_num_otg;
+	unsigned int	cursor_chunk_size;
+	unsigned int	cursor_buffer_size;
+	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;
+	unsigned int	xfc_supported;
+	unsigned int	ptoi_supported;
+	unsigned int	xfc_fill_constant_bytes;
+	double	dispclk_ramp_margin_percent;
+	double	xfc_fill_bw_overhead_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	dppclk_delay_scl;
+	unsigned int	dppclk_delay_scl_lb_only;
+	unsigned int	dppclk_delay_cnvc_formatter;
+	unsigned int	dppclk_delay_cnvc_cursor;
+	unsigned int	is_line_buffer_bpp_fixed;
+	unsigned int	line_buffer_fixed_bpp;
+	unsigned int	dcc_supported;
+
 	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;
+struct _vcs_dpi_display_xfc_params_st {
+	double xfc_tslv_vready_offset_us;
+	double xfc_tslv_vupdate_width_us;
+	double xfc_tslv_vupdate_offset_us;
+	int xfc_slv_chunk_size_bytes;
+};
+
+struct	_vcs_dpi_display_pipe_source_params_st	{
+	int	source_format;
+	unsigned char	dcc;
+	unsigned int	dcc_override;
+	unsigned int	dcc_rate;
+	unsigned char	dcc_use_global;
+	unsigned char	vm;
+	unsigned char	vm_levels_force_en;
+	unsigned int	vm_levels_force;
+	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_y_y;
+	unsigned int	viewport_y_c;
+	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 int	cur1_src_width;
+	int	cur1_bpp;
+	int	num_cursors;
+	unsigned char	is_hsplit;
+	unsigned char	dynamic_metadata_enable;
+	unsigned int	dynamic_metadata_lines_before_active;
+	unsigned int	dynamic_metadata_xmit_bytes;
+	unsigned int	hsplit_grp;
+	unsigned char	xfc_enable;
+	unsigned char	xfc_slave;
+	struct _vcs_dpi_display_xfc_params_st xfc_params;
+};
+struct writeback_st {
+	int wb_src_height;
+	int wb_dst_width;
+	int wb_dst_height;
+	int wb_pixel_format;
+	int wb_htaps_luma;
+	int wb_vtaps_luma;
+	int wb_htaps_chroma;
+	int wb_vtaps_chroma;
+	int wb_hratio;
+	int wb_vratio;
+};
+
+struct	_vcs_dpi_display_output_params_st	{
+	int	dp_lanes;
+	int	output_bpp;
+	int	dsc_enable;
+	int	wb_enable;
+	int	output_bpc;
+	int	output_type;
+	int	output_format;
+	int	output_standard;
+	int	dsc_slices;
+	struct writeback_st wb;
+};
+
+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;
+	int	scl_enable;
+};
+
+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	hactive;
+	unsigned int	vstartup_start;
+	unsigned int	vupdate_offset;
+	unsigned int	vupdate_width;
+	unsigned int	vready_offset;
+	unsigned char	interlaced;
+	unsigned char	underscan;
+	double	pixel_rate_mhz;
+	unsigned char	synchronized_vblank_all_planes;
+	unsigned char	otg_inst;
+	unsigned char	odm_split_cnt;
+	unsigned char	odm_combine;
+};
+
+struct	_vcs_dpi_display_pipe_params_st	{
+	display_pipe_source_params_st	src;
+	display_pipe_dest_params_st	dest;
+	scaler_ratio_depth_st	scale_ratio_depth;
+	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	{
+	display_pipe_params_st	pipe;
+	display_output_params_st	dout;
+	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	{
+	display_data_rq_dlg_params_st	rq_l;
+	display_data_rq_dlg_params_st	rq_c;
+	display_cur_rq_dlg_params_st	rq_cur0;
+};
+
+struct	_vcs_dpi_display_rq_sizing_params_st	{
+	display_data_rq_sizing_params_st	rq_l;
+	display_data_rq_sizing_params_st	rq_c;
+};
+
+struct	_vcs_dpi_display_rq_misc_params_st	{
+	display_data_rq_misc_params_st	rq_l;
+	display_data_rq_misc_params_st	rq_c;
+};
+
+struct	_vcs_dpi_display_rq_params_st	{
+	unsigned char	yuv420;
+	unsigned char	yuv420_10bpc;
+	display_rq_misc_params_st	misc;
+	display_rq_sizing_params_st	sizing;
+	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	dst_y_per_vm_flip;
+	unsigned int	dst_y_per_row_flip;
+	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	refcyc_per_pte_group_flip_l;
+	unsigned int	refcyc_per_pte_group_flip_c;
+	unsigned int	refcyc_per_meta_chunk_flip_l;
+	unsigned int	refcyc_per_meta_chunk_flip_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;
+	unsigned int	chunk_hdl_adjust_cur1;
+	unsigned int	vready_after_vcount0;
+	unsigned int	dst_y_offset_cur0;
+	unsigned int	dst_y_offset_cur1;
+	unsigned int	xfc_reg_transfer_delay;
+	unsigned int	xfc_reg_precharge_delay;
+	unsigned int	xfc_reg_remote_surface_flip_latency;
+	unsigned int	xfc_reg_prefetch_margin;
+	unsigned int	dst_y_delta_drq_limit;
+};
+
+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_cur1;
+	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	refcyc_per_req_delivery_pre_cur1;
+	unsigned int	qos_level_fixed_l;
+	unsigned int	qos_level_fixed_c;
+	unsigned int	qos_level_fixed_cur0;
+	unsigned int	qos_level_fixed_cur1;
+	unsigned int	qos_ramp_disable_l;
+	unsigned int	qos_ramp_disable_c;
+	unsigned int	qos_ramp_disable_cur0;
+	unsigned int	qos_ramp_disable_cur1;
+};
+
+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	{
+	display_data_rq_regs_st	rq_regs_l;
+	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	mem_trip_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	socclk_mhz;
+	double	dscclk_mhz[6];
+	double	dppclk_mhz[6];
+};
+
+struct	_vcs_dpi_display_arb_params_st	{
+	int	max_req_outstanding;
+	int	min_req_outstanding;
+	int	sat_level_us;
 };
 
 #endif /*__DISPLAY_MODE_STRUCTS_H__*/

+ 0 - 194
drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h

@@ -1,194 +0,0 @@
-/*
- * 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];
-};
-
-#endif

+ 6124 - 0
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c

@@ -0,0 +1,6124 @@
+/*
+ * 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"
+#include "display_mode_vba.h"
+
+#include "dml_inline_defs.h"
+
+static const unsigned int NumberOfStates = DC__VOLTAGE_STATES;
+
+static void fetch_socbb_params(struct display_mode_lib *mode_lib);
+static void fetch_ip_params(struct display_mode_lib *mode_lib);
+static void fetch_pipe_params(struct display_mode_lib *mode_lib);
+static void recalculate_params(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes);
+static void recalculate(struct display_mode_lib *mode_lib);
+static double adjust_ReturnBW(
+		struct display_mode_lib *mode_lib,
+		double ReturnBW,
+		bool DCCEnabledAnyPlane,
+		double ReturnBandwidthToDCN);
+static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
+static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
+static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+		struct display_mode_lib *mode_lib);
+static unsigned int dscceComputeDelay(
+		unsigned int bpc,
+		double bpp,
+		unsigned int sliceWidth,
+		unsigned int numSlices,
+		enum output_format_class pixelFormat);
+static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
+// Super monster function with some 45 argument
+static bool CalculatePrefetchSchedule(
+		struct display_mode_lib *mode_lib,
+		double DPPCLK,
+		double DISPCLK,
+		double PixelClock,
+		double DCFClkDeepSleep,
+		unsigned int DSCDelay,
+		unsigned int DPPPerPlane,
+		bool ScalerEnabled,
+		unsigned int NumberOfCursors,
+		double DPPCLKDelaySubtotal,
+		double DPPCLKDelaySCL,
+		double DPPCLKDelaySCLLBOnly,
+		double DPPCLKDelayCNVCFormater,
+		double DPPCLKDelayCNVCCursor,
+		double DISPCLKDelaySubtotal,
+		unsigned int ScalerRecoutWidth,
+		enum output_format_class OutputFormat,
+		unsigned int VBlank,
+		unsigned int HTotal,
+		unsigned int MaxInterDCNTileRepeaters,
+		unsigned int VStartup,
+		unsigned int PageTableLevels,
+		bool VirtualMemoryEnable,
+		bool DynamicMetadataEnable,
+		unsigned int DynamicMetadataLinesBeforeActiveRequired,
+		unsigned int DynamicMetadataTransmittedBytes,
+		bool DCCEnable,
+		double UrgentLatency,
+		double UrgentExtraLatency,
+		double TCalc,
+		unsigned int PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		double PrefetchSourceLinesY,
+		unsigned int SwathWidthY,
+		double BytePerPixelDETY,
+		double VInitPreFillY,
+		unsigned int MaxNumSwathY,
+		double PrefetchSourceLinesC,
+		double BytePerPixelDETC,
+		double VInitPreFillC,
+		unsigned int MaxNumSwathC,
+		unsigned int SwathHeightY,
+		unsigned int SwathHeightC,
+		double TWait,
+		bool XFCEnabled,
+		double XFCRemoteSurfaceFlipDelay,
+		bool InterlaceEnable,
+		bool ProgressiveToInterlaceUnitInOPP,
+		double *DSTXAfterScaler,
+		double *DSTYAfterScaler,
+		double *DestinationLinesForPrefetch,
+		double *PrefetchBandwidth,
+		double *DestinationLinesToRequestVMInVBlank,
+		double *DestinationLinesToRequestRowInVBlank,
+		double *VRatioPrefetchY,
+		double *VRatioPrefetchC,
+		double *RequiredPrefetchPixDataBW,
+		unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+		double *Tno_bw,
+		unsigned int *VUpdateOffsetPix,
+		unsigned int *VUpdateWidthPix,
+		unsigned int *VReadyOffsetPix);
+static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
+static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
+static double CalculatePrefetchSourceLines(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double vtaps,
+		bool Interlace,
+		bool ProgressiveToInterlaceUnitInOPP,
+		unsigned int SwathHeight,
+		unsigned int ViewportYStart,
+		double *VInitPreFill,
+		unsigned int *MaxNumSwath);
+static unsigned int CalculateVMAndRowBytes(
+		struct display_mode_lib *mode_lib,
+		bool DCCEnable,
+		unsigned int BlockHeight256Bytes,
+		unsigned int BlockWidth256Bytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int SurfaceTiling,
+		unsigned int BytePerPixel,
+		enum scan_direction_class ScanDirection,
+		unsigned int ViewportWidth,
+		unsigned int ViewportHeight,
+		unsigned int SwathWidthY,
+		bool VirtualMemoryEnable,
+		unsigned int VMMPageSize,
+		unsigned int PTEBufferSizeInRequests,
+		unsigned int PDEProcessingBufIn64KBReqs,
+		unsigned int Pitch,
+		unsigned int DCCMetaPitch,
+		unsigned int *MacroTileWidth,
+		unsigned int *MetaRowByte,
+		unsigned int *PixelPTEBytesPerRow,
+		bool *PTEBufferSizeNotExceeded,
+		unsigned int *dpte_row_height,
+		unsigned int *meta_row_height);
+static double CalculateTWait(
+		unsigned int PrefetchMode,
+		double DRAMClockChangeLatency,
+		double UrgentLatency,
+		double SREnterPlusExitTime);
+static double CalculateRemoteSurfaceFlipDelay(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double SwathWidth,
+		double Bpp,
+		double LineTime,
+		double XFCTSlvVupdateOffset,
+		double XFCTSlvVupdateWidth,
+		double XFCTSlvVreadyOffset,
+		double XFCXBUFLatencyTolerance,
+		double XFCFillBWOverhead,
+		double XFCSlvChunkSize,
+		double XFCBusTransportTime,
+		double TCalc,
+		double TWait,
+		double *SrcActiveDrainRate,
+		double *TInitXFill,
+		double *TslvChk);
+static double CalculateWriteBackDISPCLK(
+		enum source_format_class WritebackPixelFormat,
+		double PixelClock,
+		double WritebackHRatio,
+		double WritebackVRatio,
+		unsigned int WritebackLumaHTaps,
+		unsigned int WritebackLumaVTaps,
+		unsigned int WritebackChromaHTaps,
+		unsigned int WritebackChromaVTaps,
+		double WritebackDestinationWidth,
+		unsigned int HTotal,
+		unsigned int WritebackChromaLineBufferWidth);
+static void CalculateActiveRowBandwidth(
+		bool VirtualMemoryEnable,
+		enum source_format_class SourcePixelFormat,
+		double VRatio,
+		bool DCCEnable,
+		double LineTime,
+		unsigned int MetaRowByteLuma,
+		unsigned int MetaRowByteChroma,
+		unsigned int meta_row_height_luma,
+		unsigned int meta_row_height_chroma,
+		unsigned int PixelPTEBytesPerRowLuma,
+		unsigned int PixelPTEBytesPerRowChroma,
+		unsigned int dpte_row_height_luma,
+		unsigned int dpte_row_height_chroma,
+		double *meta_row_bw,
+		double *dpte_row_bw,
+		double *qual_row_bw);
+static void CalculateFlipSchedule(
+		struct display_mode_lib *mode_lib,
+		double UrgentExtraLatency,
+		double UrgentLatency,
+		unsigned int MaxPageTableLevels,
+		bool VirtualMemoryEnable,
+		double BandwidthAvailableForImmediateFlip,
+		unsigned int TotImmediateFlipBytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int ImmediateFlipBytes,
+		double LineTime,
+		double Tno_bw,
+		double VRatio,
+		double PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		bool DCCEnable,
+		unsigned int dpte_row_height,
+		unsigned int meta_row_height,
+		double qual_row_bw,
+		double *DestinationLinesToRequestVMInImmediateFlip,
+		double *DestinationLinesToRequestRowInImmediateFlip,
+		double *final_flip_bw,
+		bool *ImmediateFlipSupportedForPipe);
+static double CalculateWriteBackDelay(
+		enum source_format_class WritebackPixelFormat,
+		double WritebackHRatio,
+		double WritebackVRatio,
+		unsigned int WritebackLumaHTaps,
+		unsigned int WritebackLumaVTaps,
+		unsigned int WritebackChromaHTaps,
+		unsigned int WritebackChromaVTaps,
+		unsigned int WritebackDestinationWidth);
+static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib);
+static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
+static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
+
+void set_prefetch_mode(
+		struct display_mode_lib *mode_lib,
+		bool cstate_en,
+		bool pstate_en,
+		bool ignore_viewport_pos,
+		bool immediate_flip_support)
+{
+	unsigned int prefetch_mode;
+
+	if (cstate_en && pstate_en)
+		prefetch_mode = 0;
+	else if (cstate_en)
+		prefetch_mode = 1;
+	else
+		prefetch_mode = 2;
+	if (prefetch_mode != mode_lib->vba.PrefetchMode
+			|| ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning
+			|| immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) {
+		DTRACE(
+				"   Prefetch mode has changed from %i to %i. Recalculating.",
+				prefetch_mode,
+				mode_lib->vba.PrefetchMode);
+		mode_lib->vba.PrefetchMode = prefetch_mode;
+		mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos;
+		mode_lib->vba.ImmediateFlipSupport = immediate_flip_support;
+		recalculate(mode_lib);
+	}
+}
+
+unsigned int dml_get_voltage_level(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes)
+{
+	bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
+			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
+			|| num_pipes != mode_lib->vba.cache_num_pipes
+			|| memcmp(pipes, mode_lib->vba.cache_pipes,
+					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
+
+	mode_lib->vba.soc = mode_lib->soc;
+	mode_lib->vba.ip = mode_lib->ip;
+	memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
+	mode_lib->vba.cache_num_pipes = num_pipes;
+
+	if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
+		recalculate(mode_lib);
+	else {
+		fetch_socbb_params(mode_lib);
+		fetch_ip_params(mode_lib);
+		fetch_pipe_params(mode_lib);
+	}
+	ModeSupportAndSystemConfigurationFull(mode_lib);
+
+	return mode_lib->vba.VoltageLevel;
+}
+
+#define dml_get_attr_func(attr, var)  double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \
+{ \
+	recalculate_params(mode_lib, pipes, num_pipes); \
+	return var; \
+}
+
+dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep);
+dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
+dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark);
+dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
+dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
+dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
+dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
+dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
+dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent
+dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
+dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
+dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs);
+dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
+dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
+dml_get_attr_func(
+		dram_clock_change_latency,
+		mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
+dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
+dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
+dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
+dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
+
+#define dml_get_pipe_attr_func(attr, var)  double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) \
+{\
+	unsigned int which_plane; \
+	recalculate_params(mode_lib, pipes, num_pipes); \
+	which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
+	return var[which_plane]; \
+}
+
+dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
+dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
+dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
+dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
+dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
+dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
+dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
+dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
+dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
+dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
+dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
+dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
+dml_get_pipe_attr_func(
+		dst_y_per_row_flip,
+		mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
+
+dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay);
+dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay);
+dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency);
+dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin);
+
+unsigned int get_vstartup_calculated(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes,
+		unsigned int which_pipe)
+{
+	unsigned int which_plane;
+
+	recalculate_params(mode_lib, pipes, num_pipes);
+	which_plane = mode_lib->vba.pipe_plane[which_pipe];
+	return mode_lib->vba.VStartup[which_plane];
+}
+
+double get_total_immediate_flip_bytes(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes)
+{
+	recalculate_params(mode_lib, pipes, num_pipes);
+	return mode_lib->vba.TotImmediateFlipBytes;
+}
+
+double get_total_immediate_flip_bw(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes)
+{
+	recalculate_params(mode_lib, pipes, num_pipes);
+	return mode_lib->vba.ImmediateFlipBW;
+}
+
+double get_total_prefetch_bw(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes)
+{
+	unsigned int k;
+	double total_prefetch_bw = 0.0;
+
+	recalculate_params(mode_lib, pipes, num_pipes);
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
+	return total_prefetch_bw;
+}
+
+static void fetch_socbb_params(struct display_mode_lib *mode_lib)
+{
+	soc_bounding_box_st *soc = &mode_lib->vba.soc;
+	unsigned int i;
+
+	// SOC Bounding Box Parameters
+	mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
+	mode_lib->vba.NumberOfChannels = soc->num_chans;
+	mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency =
+			soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment!
+	mode_lib->vba.UrgentLatency = soc->urgent_latency_us;
+	mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
+	mode_lib->vba.UrgentOutOfOrderReturnPerChannel =
+			soc->urgent_out_of_order_return_per_channel_bytes;
+	mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
+	mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
+	mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
+	mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
+	mode_lib->vba.Downspreading = soc->downspread_percent;
+	mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes;   // new!
+	mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
+	mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent;   // new
+	mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz;   // new
+	mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
+	// Set the voltage scaling clocks as the defaults. Most of these will
+	// be set to different values by the test
+	for (i = 0; i < DC__VOLTAGE_STATES; i++)
+		if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
+			break;
+
+	mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
+	mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
+	mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz;
+	mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
+
+	mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
+	mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
+
+	mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
+	mode_lib->vba.MaxHSCLRatio = 4;
+	mode_lib->vba.MaxVSCLRatio = 4;
+	mode_lib->vba.MaxNumWriteback = 0; /*TODO*/
+	mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
+	mode_lib->vba.Cursor64BppSupport = true;
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
+		mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
+		mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
+		mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
+		mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
+		mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
+		mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
+		mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
+	}
+}
+
+static void fetch_ip_params(struct display_mode_lib *mode_lib)
+{
+	ip_params_st *ip = &mode_lib->vba.ip;
+
+	// IP Parameters
+	mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
+	mode_lib->vba.MaxNumOTG = ip->max_num_otg;
+	mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
+	mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
+
+	mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
+	mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
+	mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
+	mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
+	mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
+	mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
+	mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes;
+	mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
+	mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
+	mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
+	mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs;
+	mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
+	mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
+	mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes;
+	mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes;
+	mode_lib->vba.WritebackChromaLineBufferWidth =
+			ip->writeback_chroma_line_buffer_width_pixels;
+	mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels;
+	mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
+	mode_lib->vba.NumberOfDSC = ip->num_dsc;
+	mode_lib->vba.ODMCapability = ip->odm_capable;
+	mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
+
+	mode_lib->vba.XFCSupported = ip->xfc_supported;
+	mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
+	mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
+	mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
+	mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
+	mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
+	mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
+	mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
+	mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
+
+	mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
+
+	mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
+}
+
+static void fetch_pipe_params(struct display_mode_lib *mode_lib)
+{
+	display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
+	ip_params_st *ip = &mode_lib->vba.ip;
+
+	unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
+	unsigned int j, k;
+	bool PlaneVisited[DC__NUM_DPP__MAX];
+	bool visited[DC__NUM_DPP__MAX];
+
+	// Convert Pipes to Planes
+	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
+		visited[k] = false;
+
+	mode_lib->vba.NumberOfActivePlanes = 0;
+	for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
+		display_pipe_source_params_st *src = &pipes[j].pipe.src;
+		display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
+		scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
+		scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
+		display_output_params_st *dout = &pipes[j].dout;
+		display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
+
+		if (visited[j])
+			continue;
+		visited[j] = true;
+
+		mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
+
+		mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
+		mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
+				(enum scan_direction_class) (src->source_scan);
+		mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
+				src->viewport_width;
+		mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
+				src->viewport_height;
+		mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
+				src->viewport_y_y;
+		mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
+				src->viewport_y_c;
+		mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
+		mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
+		mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
+		mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
+		mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
+		mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
+		mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
+		if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes])
+			mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
+		mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
+		mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
+		mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
+		mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
+		mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
+		mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
+		mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
+				src->dcc_use_global ?
+						ip->dcc_supported : src->dcc && ip->dcc_supported;
+		mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
+		mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] =
+				(enum source_format_class) (src->source_format);
+		mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
+		mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
+		mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
+				(enum dm_swizzle_mode) (src->sw_mode);
+		mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
+				dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
+		mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
+				dst->odm_combine;
+		mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
+				(enum output_format_class) (dout->output_format);
+		mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
+				(enum output_encoder_class) (dout->output_type);
+		mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
+		mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
+				dout->dp_lanes;
+		mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
+		mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
+				dout->dsc_slices;
+		mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
+				dout->output_bpc == 0 ? 12 : dout->output_bpc;
+		mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
+		mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_src_height;
+		mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_dst_width;
+		mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_dst_height;
+		mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
+				(enum source_format_class) (dout->wb.wb_pixel_format);
+		mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_htaps_luma;
+		mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_vtaps_luma;
+		mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_htaps_chroma;
+		mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_vtaps_chroma;
+		mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_hratio;
+		mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
+				dout->wb.wb_vratio;
+
+		mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
+				src->dynamic_metadata_enable;
+		mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
+				src->dynamic_metadata_lines_before_active;
+		mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
+				src->dynamic_metadata_xmit_bytes;
+
+		mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
+				&& ip->xfc_supported;
+		mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
+		mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
+		mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
+		mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
+		mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
+		mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
+		if (ip->is_line_buffer_bpp_fixed)
+			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
+					ip->line_buffer_fixed_bpp;
+		else {
+			unsigned int lb_depth;
+
+			switch (scl->lb_depth) {
+			case dm_lb_6:
+				lb_depth = 18;
+				break;
+			case dm_lb_8:
+				lb_depth = 24;
+				break;
+			case dm_lb_10:
+				lb_depth = 30;
+				break;
+			case dm_lb_12:
+				lb_depth = 36;
+				break;
+			case dm_lb_16:
+				lb_depth = 48;
+				break;
+			default:
+				lb_depth = 36;
+			}
+			mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
+		}
+		mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
+		// The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
+		// calculate things a little more accurately
+		for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
+			switch (k) {
+			case 0:
+				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
+						CursorBppEnumToBits(
+								(enum cursor_bpp) (src->cur0_bpp));
+				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
+						src->cur0_src_width;
+				if (src->cur0_src_width > 0)
+					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
+				break;
+			case 1:
+				mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
+						CursorBppEnumToBits(
+								(enum cursor_bpp) (src->cur1_bpp));
+				mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
+						src->cur1_src_width;
+				if (src->cur1_src_width > 0)
+					mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
+				break;
+			default:
+				dml_print(
+						"ERROR: Number of cursors specified exceeds supported maximum\n")
+				;
+			}
+		}
+
+		OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
+
+		if (dst->odm_combine && !src->is_hsplit)
+			dml_print(
+					"ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
+					j);
+
+		if (src->is_hsplit) {
+			for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
+				display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
+				display_output_params_st *dout_k = &pipes[k].dout;
+
+				if (src_k->is_hsplit && !visited[k]
+						&& src->hsplit_grp == src_k->hsplit_grp) {
+					mode_lib->vba.pipe_plane[k] =
+							mode_lib->vba.NumberOfActivePlanes;
+					mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
+					if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
+							== dm_horz)
+						mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
+								src_k->viewport_width;
+					else
+						mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
+								src_k->viewport_height;
+
+					mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] +=
+							dout_k->dsc_slices;
+					visited[k] = true;
+				}
+			}
+		}
+
+		mode_lib->vba.NumberOfActivePlanes++;
+	}
+
+	// handle overlays through dml_ml->vba.BlendingAndTiming
+	// dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
+
+	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+		PlaneVisited[j] = false;
+
+	for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+		for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+			if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
+				// doesn't matter, so choose the smaller one
+				mode_lib->vba.BlendingAndTiming[j] = j;
+				PlaneVisited[j] = true;
+				mode_lib->vba.BlendingAndTiming[k] = j;
+				PlaneVisited[k] = true;
+			}
+		}
+
+		if (!PlaneVisited[j]) {
+			mode_lib->vba.BlendingAndTiming[j] = j;
+			PlaneVisited[j] = true;
+		}
+	}
+
+	// TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified
+	// Do we want the dscclk to automatically be halved? Guess not since the value is specified
+
+	mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
+	for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k)
+		ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
+
+	mode_lib->vba.VirtualMemoryEnable = false;
+	mode_lib->vba.OverridePageTableLevels = 0;
+
+	for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
+		mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable
+				|| !!pipes[k].pipe.src.vm;
+		mode_lib->vba.OverridePageTableLevels =
+				(pipes[k].pipe.src.vm_levels_force_en
+						&& mode_lib->vba.OverridePageTableLevels
+								< pipes[k].pipe.src.vm_levels_force) ?
+						pipes[k].pipe.src.vm_levels_force :
+						mode_lib->vba.OverridePageTableLevels;
+	}
+
+	if (mode_lib->vba.OverridePageTableLevels)
+		mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels;
+
+	mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable && !!ip->pte_enable;
+
+	mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
+			mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels
+					* mode_lib->vba.DRAMChannelWidth,
+			mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn)
+			/ 1000.0;
+
+	// TODO: Must be consistent across all pipes
+	// DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown;
+}
+
+static void recalculate(struct display_mode_lib *mode_lib)
+{
+	ModeSupportAndSystemConfiguration(mode_lib);
+	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
+	DisplayPipeConfiguration(mode_lib);
+	DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
+}
+
+// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
+// rather than working them out as in recalculate_ms
+static void recalculate_params(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes)
+{
+	// This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
+	if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
+			|| memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
+			|| num_pipes != mode_lib->vba.cache_num_pipes
+			|| memcmp(
+					pipes,
+					mode_lib->vba.cache_pipes,
+					sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
+		mode_lib->vba.soc = mode_lib->soc;
+		mode_lib->vba.ip = mode_lib->ip;
+		memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
+		mode_lib->vba.cache_num_pipes = num_pipes;
+		recalculate(mode_lib);
+	}
+}
+
+static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
+{
+	soc_bounding_box_st *soc = &mode_lib->vba.soc;
+	unsigned int i, k;
+	unsigned int total_pipes = 0;
+
+	mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
+	for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i)
+		ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage);
+
+	mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
+	mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
+
+	if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
+		mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
+	else
+		mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
+
+	fetch_socbb_params(mode_lib);
+	fetch_ip_params(mode_lib);
+	fetch_pipe_params(mode_lib);
+
+	// Total Available Pipes Support Check
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		total_pipes += mode_lib->vba.DPPPerPlane[k];
+	ASSERT(total_pipes <= DC__NUM_DPP__MAX);
+}
+
+static double adjust_ReturnBW(
+		struct display_mode_lib *mode_lib,
+		double ReturnBW,
+		bool DCCEnabledAnyPlane,
+		double ReturnBandwidthToDCN)
+{
+	double CriticalCompression;
+
+	if (DCCEnabledAnyPlane
+			&& ReturnBandwidthToDCN
+					> mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
+		ReturnBW =
+				dml_min(
+						ReturnBW,
+						ReturnBandwidthToDCN * 4
+								* (1.0
+										- mode_lib->vba.UrgentLatency
+												/ ((mode_lib->vba.ROBBufferSizeInKByte
+														- mode_lib->vba.PixelChunkSizeInKByte)
+														* 1024
+														/ ReturnBandwidthToDCN
+														- mode_lib->vba.DCFCLK
+																* mode_lib->vba.ReturnBusWidth
+																/ 4)
+										+ mode_lib->vba.UrgentLatency));
+
+	CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
+			* mode_lib->vba.UrgentLatency
+			/ (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency
+					+ (mode_lib->vba.ROBBufferSizeInKByte
+							- mode_lib->vba.PixelChunkSizeInKByte)
+							* 1024);
+
+	if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
+		ReturnBW =
+				dml_min(
+						ReturnBW,
+						4.0 * ReturnBandwidthToDCN
+								* (mode_lib->vba.ROBBufferSizeInKByte
+										- mode_lib->vba.PixelChunkSizeInKByte)
+								* 1024
+								* mode_lib->vba.ReturnBusWidth
+								* mode_lib->vba.DCFCLK
+								* mode_lib->vba.UrgentLatency
+								/ dml_pow(
+										(ReturnBandwidthToDCN
+												* mode_lib->vba.UrgentLatency
+												+ (mode_lib->vba.ROBBufferSizeInKByte
+														- mode_lib->vba.PixelChunkSizeInKByte)
+														* 1024),
+										2));
+
+	return ReturnBW;
+}
+
+static unsigned int dscceComputeDelay(
+		unsigned int bpc,
+		double bpp,
+		unsigned int sliceWidth,
+		unsigned int numSlices,
+		enum output_format_class pixelFormat)
+{
+	// valid bpc         = source bits per component in the set of {8, 10, 12}
+	// valid bpp         = increments of 1/16 of a bit
+	//                    min = 6/7/8 in N420/N422/444, respectively
+	//                    max = such that compression is 1:1
+	//valid sliceWidth  = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
+	//valid numSlices   = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
+	//valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
+
+	// fixed value
+	unsigned int rcModelSize = 8192;
+
+	// N422/N420 operate at 2 pixels per clock
+	unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
+			Delay, pixels;
+
+	if (pixelFormat == dm_n422 || pixelFormat == dm_420)
+		pixelsPerClock = 2;
+	// #all other modes operate at 1 pixel per clock
+	else
+		pixelsPerClock = 1;
+
+	//initial transmit delay as per PPS
+	initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
+
+	//compute ssm delay
+	if (bpc == 8)
+		D = 81;
+	else if (bpc == 10)
+		D = 89;
+	else
+		D = 113;
+
+	//divide by pixel per cycle to compute slice width as seen by DSC
+	w = sliceWidth / pixelsPerClock;
+
+	//422 mode has an additional cycle of delay
+	if (pixelFormat == dm_s422)
+		s = 1;
+	else
+		s = 0;
+
+	//main calculation for the dscce
+	ix = initalXmitDelay + 45;
+	wx = (w + 2) / 3;
+	p = 3 * wx - w;
+	l0 = ix / w;
+	a = ix + p * l0;
+	ax = (a + 2) / 3 + D + 6 + 1;
+	l = (ax + wx - 1) / wx;
+	if ((ix % w) == 0 && p != 0)
+		lstall = 1;
+	else
+		lstall = 0;
+	Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
+
+	//dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
+	pixels = Delay * 3 * pixelsPerClock;
+	return pixels;
+}
+
+static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
+{
+	unsigned int Delay = 0;
+
+	if (pixelFormat == dm_420) {
+		//   sfr
+		Delay = Delay + 2;
+		//   dsccif
+		Delay = Delay + 0;
+		//   dscc - input deserializer
+		Delay = Delay + 3;
+		//   dscc gets pixels every other cycle
+		Delay = Delay + 2;
+		//   dscc - input cdc fifo
+		Delay = Delay + 12;
+		//   dscc gets pixels every other cycle
+		Delay = Delay + 13;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output cdc fifo
+		Delay = Delay + 7;
+		//   dscc gets pixels every other cycle
+		Delay = Delay + 3;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output serializer
+		Delay = Delay + 1;
+		//   sft
+		Delay = Delay + 1;
+	} else if (pixelFormat == dm_n422) {
+		//   sfr
+		Delay = Delay + 2;
+		//   dsccif
+		Delay = Delay + 1;
+		//   dscc - input deserializer
+		Delay = Delay + 5;
+		//  dscc - input cdc fifo
+		Delay = Delay + 25;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output cdc fifo
+		Delay = Delay + 10;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output serializer
+		Delay = Delay + 1;
+		//   sft
+		Delay = Delay + 1;
+	} else {
+		//   sfr
+		Delay = Delay + 2;
+		//   dsccif
+		Delay = Delay + 0;
+		//   dscc - input deserializer
+		Delay = Delay + 3;
+		//   dscc - input cdc fifo
+		Delay = Delay + 12;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   dscc - output cdc fifo
+		Delay = Delay + 7;
+		//   dscc - output serializer
+		Delay = Delay + 1;
+		//   dscc - cdc uncertainty
+		Delay = Delay + 2;
+		//   sft
+		Delay = Delay + 1;
+	}
+
+	return Delay;
+}
+
+static bool CalculatePrefetchSchedule(
+		struct display_mode_lib *mode_lib,
+		double DPPCLK,
+		double DISPCLK,
+		double PixelClock,
+		double DCFClkDeepSleep,
+		unsigned int DSCDelay,
+		unsigned int DPPPerPlane,
+		bool ScalerEnabled,
+		unsigned int NumberOfCursors,
+		double DPPCLKDelaySubtotal,
+		double DPPCLKDelaySCL,
+		double DPPCLKDelaySCLLBOnly,
+		double DPPCLKDelayCNVCFormater,
+		double DPPCLKDelayCNVCCursor,
+		double DISPCLKDelaySubtotal,
+		unsigned int ScalerRecoutWidth,
+		enum output_format_class OutputFormat,
+		unsigned int VBlank,
+		unsigned int HTotal,
+		unsigned int MaxInterDCNTileRepeaters,
+		unsigned int VStartup,
+		unsigned int PageTableLevels,
+		bool VirtualMemoryEnable,
+		bool DynamicMetadataEnable,
+		unsigned int DynamicMetadataLinesBeforeActiveRequired,
+		unsigned int DynamicMetadataTransmittedBytes,
+		bool DCCEnable,
+		double UrgentLatency,
+		double UrgentExtraLatency,
+		double TCalc,
+		unsigned int PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		double PrefetchSourceLinesY,
+		unsigned int SwathWidthY,
+		double BytePerPixelDETY,
+		double VInitPreFillY,
+		unsigned int MaxNumSwathY,
+		double PrefetchSourceLinesC,
+		double BytePerPixelDETC,
+		double VInitPreFillC,
+		unsigned int MaxNumSwathC,
+		unsigned int SwathHeightY,
+		unsigned int SwathHeightC,
+		double TWait,
+		bool XFCEnabled,
+		double XFCRemoteSurfaceFlipDelay,
+		bool InterlaceEnable,
+		bool ProgressiveToInterlaceUnitInOPP,
+		double *DSTXAfterScaler,
+		double *DSTYAfterScaler,
+		double *DestinationLinesForPrefetch,
+		double *PrefetchBandwidth,
+		double *DestinationLinesToRequestVMInVBlank,
+		double *DestinationLinesToRequestRowInVBlank,
+		double *VRatioPrefetchY,
+		double *VRatioPrefetchC,
+		double *RequiredPrefetchPixDataBW,
+		unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+		double *Tno_bw,
+		unsigned int *VUpdateOffsetPix,
+		unsigned int *VUpdateWidthPix,
+		unsigned int *VReadyOffsetPix)
+{
+	bool MyError = false;
+	unsigned int DPPCycles, DISPCLKCycles;
+	double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
+	double Tdm, LineTime, Tsetup;
+	double dst_y_prefetch_equ;
+	double Tsw_oto;
+	double prefetch_bw_oto;
+	double Tvm_oto;
+	double Tr0_oto;
+	double Tpre_oto;
+	double dst_y_prefetch_oto;
+	double TimeForFetchingMetaPTE = 0;
+	double TimeForFetchingRowInVBlank = 0;
+	double LinesToRequestPrefetchPixelData = 0;
+
+	if (ScalerEnabled)
+		DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
+	else
+		DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
+
+	DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
+
+	DISPCLKCycles = DISPCLKDelaySubtotal;
+
+	if (DPPCLK == 0.0 || DISPCLK == 0.0)
+		return true;
+
+	*DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
+			+ DSCDelay;
+
+	if (DPPPerPlane > 1)
+		*DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
+
+	if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
+		*DSTYAfterScaler = 1;
+	else
+		*DSTYAfterScaler = 0;
+
+	DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
+	*DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
+	*DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
+
+	*VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
+	TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
+	*VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
+			* PixelClock;
+
+	*VReadyOffsetPix = dml_max(
+			150.0 / DPPCLK,
+			TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK)
+			* PixelClock;
+
+	Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
+
+	LineTime = (double) HTotal / PixelClock;
+
+	if (DynamicMetadataEnable) {
+		double Tdmbf, Tdmec, Tdmsks;
+
+		Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
+		Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
+		Tdmec = LineTime;
+		if (DynamicMetadataLinesBeforeActiveRequired == 0)
+			Tdmsks = VBlank * LineTime / 2.0;
+		else
+			Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
+		if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
+			Tdmsks = Tdmsks / 2;
+		if (VStartup * LineTime
+				< Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
+			MyError = true;
+			*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
+					+ UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
+		} else
+			*VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
+	} else
+		Tdm = 0;
+
+	if (VirtualMemoryEnable) {
+		if (PageTableLevels == 4)
+			*Tno_bw = UrgentExtraLatency + UrgentLatency;
+		else if (PageTableLevels == 3)
+			*Tno_bw = UrgentExtraLatency;
+		else
+			*Tno_bw = 0;
+	} else if (DCCEnable)
+		*Tno_bw = LineTime;
+	else
+		*Tno_bw = LineTime / 4;
+
+	dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
+			- (Tsetup + Tdm) / LineTime
+			- (*DSTYAfterScaler + *DSTXAfterScaler / HTotal);
+
+	Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
+
+	prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
+			+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+			+ PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
+			/ Tsw_oto;
+
+	if (VirtualMemoryEnable == true) {
+		Tvm_oto =
+				dml_max(
+						*Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
+						dml_max(
+								UrgentExtraLatency
+										+ UrgentLatency
+												* (PageTableLevels
+														- 1),
+								LineTime / 4.0));
+	} else
+		Tvm_oto = LineTime / 4.0;
+
+	if ((VirtualMemoryEnable == true || DCCEnable == true)) {
+		Tr0_oto = dml_max(
+				(MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
+				dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4)));
+	} else
+		Tr0_oto = LineTime - Tvm_oto;
+
+	Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
+
+	dst_y_prefetch_oto = Tpre_oto / LineTime;
+
+	if (dst_y_prefetch_oto < dst_y_prefetch_equ)
+		*DestinationLinesForPrefetch = dst_y_prefetch_oto;
+	else
+		*DestinationLinesForPrefetch = dst_y_prefetch_equ;
+
+	*DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
+			/ 4;
+
+	dml_print("DML: VStartup: %d\n", VStartup);
+	dml_print("DML: TCalc: %f\n", TCalc);
+	dml_print("DML: TWait: %f\n", TWait);
+	dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
+	dml_print("DML: LineTime: %f\n", LineTime);
+	dml_print("DML: Tsetup: %f\n", Tsetup);
+	dml_print("DML: Tdm: %f\n", Tdm);
+	dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler);
+	dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler);
+	dml_print("DML: HTotal: %d\n", HTotal);
+
+	*PrefetchBandwidth = 0;
+	*DestinationLinesToRequestVMInVBlank = 0;
+	*DestinationLinesToRequestRowInVBlank = 0;
+	*VRatioPrefetchY = 0;
+	*VRatioPrefetchC = 0;
+	*RequiredPrefetchPixDataBW = 0;
+	if (*DestinationLinesForPrefetch > 1) {
+		*PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
+				+ 2 * PixelPTEBytesPerRow
+				+ PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+				+ PrefetchSourceLinesC * SwathWidthY / 2
+						* dml_ceil(BytePerPixelDETC, 2))
+				/ (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
+		if (VirtualMemoryEnable) {
+			TimeForFetchingMetaPTE =
+					dml_max(
+							*Tno_bw
+									+ (double) PDEAndMetaPTEBytesFrame
+											/ *PrefetchBandwidth,
+							dml_max(
+									UrgentExtraLatency
+											+ UrgentLatency
+													* (PageTableLevels
+															- 1),
+									LineTime / 4));
+		} else {
+			if (NumberOfCursors > 0 || XFCEnabled)
+				TimeForFetchingMetaPTE = LineTime / 4;
+			else
+				TimeForFetchingMetaPTE = 0.0;
+		}
+
+		if ((VirtualMemoryEnable == true || DCCEnable == true)) {
+			TimeForFetchingRowInVBlank =
+					dml_max(
+							(MetaRowByte + PixelPTEBytesPerRow)
+									/ *PrefetchBandwidth,
+							dml_max(
+									UrgentLatency,
+									dml_max(
+											LineTime
+													- TimeForFetchingMetaPTE,
+											LineTime
+													/ 4.0)));
+		} else {
+			if (NumberOfCursors > 0 || XFCEnabled)
+				TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
+			else
+				TimeForFetchingRowInVBlank = 0.0;
+		}
+
+		*DestinationLinesToRequestVMInVBlank = dml_floor(
+				4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
+				1) / 4.0;
+
+		*DestinationLinesToRequestRowInVBlank = dml_floor(
+				4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
+				1) / 4.0;
+
+		LinesToRequestPrefetchPixelData =
+				*DestinationLinesForPrefetch
+						- ((NumberOfCursors > 0 || VirtualMemoryEnable
+								|| DCCEnable) ?
+								(*DestinationLinesToRequestVMInVBlank
+										+ *DestinationLinesToRequestRowInVBlank) :
+								0.0);
+
+		if (LinesToRequestPrefetchPixelData > 0) {
+
+			*VRatioPrefetchY = (double) PrefetchSourceLinesY
+					/ LinesToRequestPrefetchPixelData;
+			*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
+			if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
+				if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
+					*VRatioPrefetchY =
+							dml_max(
+									(double) PrefetchSourceLinesY
+											/ LinesToRequestPrefetchPixelData,
+									(double) MaxNumSwathY
+											* SwathHeightY
+											/ (LinesToRequestPrefetchPixelData
+													- (VInitPreFillY
+															- 3.0)
+															/ 2.0));
+					*VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
+				} else {
+					MyError = true;
+					*VRatioPrefetchY = 0;
+				}
+			}
+
+			*VRatioPrefetchC = (double) PrefetchSourceLinesC
+					/ LinesToRequestPrefetchPixelData;
+			*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
+
+			if ((SwathHeightC > 4)) {
+				if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
+					*VRatioPrefetchC =
+							dml_max(
+									*VRatioPrefetchC,
+									(double) MaxNumSwathC
+											* SwathHeightC
+											/ (LinesToRequestPrefetchPixelData
+													- (VInitPreFillC
+															- 3.0)
+															/ 2.0));
+					*VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
+				} else {
+					MyError = true;
+					*VRatioPrefetchC = 0;
+				}
+			}
+
+			*RequiredPrefetchPixDataBW =
+					DPPPerPlane
+							* ((double) PrefetchSourceLinesY
+									/ LinesToRequestPrefetchPixelData
+									* dml_ceil(
+											BytePerPixelDETY,
+											1)
+									+ (double) PrefetchSourceLinesC
+											/ LinesToRequestPrefetchPixelData
+											* dml_ceil(
+													BytePerPixelDETC,
+													2)
+											/ 2)
+							* SwathWidthY / LineTime;
+		} else {
+			MyError = true;
+			*VRatioPrefetchY = 0;
+			*VRatioPrefetchC = 0;
+			*RequiredPrefetchPixDataBW = 0;
+		}
+
+	} else {
+		MyError = true;
+	}
+
+	if (MyError) {
+		*PrefetchBandwidth = 0;
+		TimeForFetchingMetaPTE = 0;
+		TimeForFetchingRowInVBlank = 0;
+		*DestinationLinesToRequestVMInVBlank = 0;
+		*DestinationLinesToRequestRowInVBlank = 0;
+		*DestinationLinesForPrefetch = 0;
+		LinesToRequestPrefetchPixelData = 0;
+		*VRatioPrefetchY = 0;
+		*VRatioPrefetchC = 0;
+		*RequiredPrefetchPixDataBW = 0;
+	}
+
+	return MyError;
+}
+
+static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
+{
+	return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
+}
+
+static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
+{
+	return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
+}
+
+static double CalculatePrefetchSourceLines(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double vtaps,
+		bool Interlace,
+		bool ProgressiveToInterlaceUnitInOPP,
+		unsigned int SwathHeight,
+		unsigned int ViewportYStart,
+		double *VInitPreFill,
+		unsigned int *MaxNumSwath)
+{
+	unsigned int MaxPartialSwath;
+
+	if (ProgressiveToInterlaceUnitInOPP)
+		*VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
+	else
+		*VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
+
+	if (!mode_lib->vba.IgnoreViewportPositioning) {
+
+		*MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
+
+		if (*VInitPreFill > 1.0)
+			MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
+		else
+			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
+					% SwathHeight;
+		MaxPartialSwath = dml_max(1U, MaxPartialSwath);
+
+	} else {
+
+		if (ViewportYStart != 0)
+			dml_print(
+					"WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
+
+		*MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
+
+		if (*VInitPreFill > 1.0)
+			MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
+		else
+			MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
+					% SwathHeight;
+	}
+
+	return *MaxNumSwath * SwathHeight + MaxPartialSwath;
+}
+
+static unsigned int CalculateVMAndRowBytes(
+		struct display_mode_lib *mode_lib,
+		bool DCCEnable,
+		unsigned int BlockHeight256Bytes,
+		unsigned int BlockWidth256Bytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int SurfaceTiling,
+		unsigned int BytePerPixel,
+		enum scan_direction_class ScanDirection,
+		unsigned int ViewportWidth,
+		unsigned int ViewportHeight,
+		unsigned int SwathWidth,
+		bool VirtualMemoryEnable,
+		unsigned int VMMPageSize,
+		unsigned int PTEBufferSizeInRequests,
+		unsigned int PDEProcessingBufIn64KBReqs,
+		unsigned int Pitch,
+		unsigned int DCCMetaPitch,
+		unsigned int *MacroTileWidth,
+		unsigned int *MetaRowByte,
+		unsigned int *PixelPTEBytesPerRow,
+		bool *PTEBufferSizeNotExceeded,
+		unsigned int *dpte_row_height,
+		unsigned int *meta_row_height)
+{
+	unsigned int MetaRequestHeight;
+	unsigned int MetaRequestWidth;
+	unsigned int MetaSurfWidth;
+	unsigned int MetaSurfHeight;
+	unsigned int MPDEBytesFrame;
+	unsigned int MetaPTEBytesFrame;
+	unsigned int DCCMetaSurfaceBytes;
+
+	unsigned int MacroTileSizeBytes;
+	unsigned int MacroTileHeight;
+	unsigned int DPDE0BytesFrame;
+	unsigned int ExtraDPDEBytesFrame;
+	unsigned int PDEAndMetaPTEBytesFrame;
+
+	if (DCCEnable == true) {
+		MetaRequestHeight = 8 * BlockHeight256Bytes;
+		MetaRequestWidth = 8 * BlockWidth256Bytes;
+		if (ScanDirection == dm_horz) {
+			*meta_row_height = MetaRequestHeight;
+			MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
+					+ MetaRequestWidth;
+			*MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
+		} else {
+			*meta_row_height = MetaRequestWidth;
+			MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
+					+ MetaRequestHeight;
+			*MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
+		}
+		if (ScanDirection == dm_horz) {
+			DCCMetaSurfaceBytes = DCCMetaPitch
+					* (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
+							+ 64 * BlockHeight256Bytes) * BytePerPixel
+					/ 256;
+		} else {
+			DCCMetaSurfaceBytes = DCCMetaPitch
+					* (dml_ceil(
+							(double) ViewportHeight - 1,
+							64 * BlockHeight256Bytes)
+							+ 64 * BlockHeight256Bytes) * BytePerPixel
+					/ 256;
+		}
+		if (VirtualMemoryEnable == true) {
+			MetaPTEBytesFrame = (dml_ceil(
+					(double) (DCCMetaSurfaceBytes - VMMPageSize)
+							/ (8 * VMMPageSize),
+					1) + 1) * 64;
+			MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1);
+		} else {
+			MetaPTEBytesFrame = 0;
+			MPDEBytesFrame = 0;
+		}
+	} else {
+		MetaPTEBytesFrame = 0;
+		MPDEBytesFrame = 0;
+		*MetaRowByte = 0;
+	}
+
+	if (SurfaceTiling == dm_sw_linear) {
+		MacroTileSizeBytes = 256;
+		MacroTileHeight = 1;
+	} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
+			|| SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
+		MacroTileSizeBytes = 4096;
+		MacroTileHeight = 4 * BlockHeight256Bytes;
+	} else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
+			|| SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
+			|| SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
+			|| SurfaceTiling == dm_sw_64kb_r_x) {
+		MacroTileSizeBytes = 65536;
+		MacroTileHeight = 16 * BlockHeight256Bytes;
+	} else {
+		MacroTileSizeBytes = 262144;
+		MacroTileHeight = 32 * BlockHeight256Bytes;
+	}
+	*MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
+
+	if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) {
+		if (ScanDirection == dm_horz) {
+			DPDE0BytesFrame =
+					64
+							* (dml_ceil(
+									((Pitch
+											* (dml_ceil(
+													ViewportHeight
+															- 1,
+													MacroTileHeight)
+													+ MacroTileHeight)
+											* BytePerPixel)
+											- MacroTileSizeBytes)
+											/ (8
+													* 2097152),
+									1) + 1);
+		} else {
+			DPDE0BytesFrame =
+					64
+							* (dml_ceil(
+									((Pitch
+											* (dml_ceil(
+													(double) SwathWidth
+															- 1,
+													MacroTileHeight)
+													+ MacroTileHeight)
+											* BytePerPixel)
+											- MacroTileSizeBytes)
+											/ (8
+													* 2097152),
+									1) + 1);
+		}
+		ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2);
+	} else {
+		DPDE0BytesFrame = 0;
+		ExtraDPDEBytesFrame = 0;
+	}
+
+	PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
+			+ ExtraDPDEBytesFrame;
+
+	if (VirtualMemoryEnable == true) {
+		unsigned int PTERequestSize;
+		unsigned int PixelPTEReqHeight;
+		unsigned int PixelPTEReqWidth;
+		double FractionOfPTEReturnDrop;
+		unsigned int EffectivePDEProcessingBufIn64KBReqs;
+
+		if (SurfaceTiling == dm_sw_linear) {
+			PixelPTEReqHeight = 1;
+			PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
+			PTERequestSize = 64;
+			FractionOfPTEReturnDrop = 0;
+		} else if (MacroTileSizeBytes == 4096) {
+			PixelPTEReqHeight = MacroTileHeight;
+			PixelPTEReqWidth = 8 * *MacroTileWidth;
+			PTERequestSize = 64;
+			if (ScanDirection == dm_horz)
+				FractionOfPTEReturnDrop = 0;
+			else
+				FractionOfPTEReturnDrop = 7 / 8;
+		} else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
+			PixelPTEReqHeight = 16 * BlockHeight256Bytes;
+			PixelPTEReqWidth = 16 * BlockWidth256Bytes;
+			PTERequestSize = 128;
+			FractionOfPTEReturnDrop = 0;
+		} else {
+			PixelPTEReqHeight = MacroTileHeight;
+			PixelPTEReqWidth = 8 * *MacroTileWidth;
+			PTERequestSize = 64;
+			FractionOfPTEReturnDrop = 0;
+		}
+
+		if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
+			EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
+		else
+			EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
+
+		if (SurfaceTiling == dm_sw_linear) {
+			*dpte_row_height =
+					dml_min(
+							128,
+							1
+									<< (unsigned int) dml_floor(
+											dml_log2(
+													dml_min(
+															(double) PTEBufferSizeInRequests
+																	* PixelPTEReqWidth,
+															EffectivePDEProcessingBufIn64KBReqs
+																	* 65536.0
+																	/ BytePerPixel)
+															/ Pitch),
+											1));
+			*PixelPTEBytesPerRow = PTERequestSize
+					* (dml_ceil(
+							(double) (Pitch * *dpte_row_height - 1)
+									/ PixelPTEReqWidth,
+							1) + 1);
+		} else if (ScanDirection == dm_horz) {
+			*dpte_row_height = PixelPTEReqHeight;
+			*PixelPTEBytesPerRow = PTERequestSize
+					* (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
+							+ 1);
+		} else {
+			*dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
+			*PixelPTEBytesPerRow = PTERequestSize
+					* (dml_ceil(
+							((double) SwathWidth - 1)
+									/ PixelPTEReqHeight,
+							1) + 1);
+		}
+		if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
+				<= 64 * PTEBufferSizeInRequests) {
+			*PTEBufferSizeNotExceeded = true;
+		} else {
+			*PTEBufferSizeNotExceeded = false;
+		}
+	} else {
+		*PixelPTEBytesPerRow = 0;
+		*PTEBufferSizeNotExceeded = true;
+	}
+
+	return PDEAndMetaPTEBytesFrame;
+}
+
+static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+		struct display_mode_lib *mode_lib)
+{
+	unsigned int j, k;
+
+	mode_lib->vba.WritebackDISPCLK = 0.0;
+	mode_lib->vba.DISPCLKWithRamping = 0;
+	mode_lib->vba.DISPCLKWithoutRamping = 0;
+	mode_lib->vba.GlobalDPPCLK = 0.0;
+
+	// dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
+	//
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.WritebackEnable[k]) {
+			mode_lib->vba.WritebackDISPCLK =
+					dml_max(
+							mode_lib->vba.WritebackDISPCLK,
+							CalculateWriteBackDISPCLK(
+									mode_lib->vba.WritebackPixelFormat[k],
+									mode_lib->vba.PixelClock[k],
+									mode_lib->vba.WritebackHRatio[k],
+									mode_lib->vba.WritebackVRatio[k],
+									mode_lib->vba.WritebackLumaHTaps[k],
+									mode_lib->vba.WritebackLumaVTaps[k],
+									mode_lib->vba.WritebackChromaHTaps[k],
+									mode_lib->vba.WritebackChromaVTaps[k],
+									mode_lib->vba.WritebackDestinationWidth[k],
+									mode_lib->vba.HTotal[k],
+									mode_lib->vba.WritebackChromaLineBufferWidth));
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.HRatio[k] > 1) {
+			mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput
+							* mode_lib->vba.HRatio[k]
+							/ dml_ceil(
+									mode_lib->vba.htaps[k]
+											/ 6.0,
+									1));
+		} else {
+			mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput);
+		}
+
+		mode_lib->vba.DPPCLKUsingSingleDPPLuma =
+				mode_lib->vba.PixelClock[k]
+						* dml_max(
+								mode_lib->vba.vtaps[k] / 6.0
+										* dml_min(
+												1.0,
+												mode_lib->vba.HRatio[k]),
+								dml_max(
+										mode_lib->vba.HRatio[k]
+												* mode_lib->vba.VRatio[k]
+												/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
+										1.0));
+
+		if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
+				&& mode_lib->vba.DPPCLKUsingSingleDPPLuma
+						< 2 * mode_lib->vba.PixelClock[k]) {
+			mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
+		}
+
+		if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+			mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
+			mode_lib->vba.DPPCLKUsingSingleDPP[k] =
+					mode_lib->vba.DPPCLKUsingSingleDPPLuma;
+		} else {
+			if (mode_lib->vba.HRatio[k] > 1) {
+				mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
+						dml_min(
+								mode_lib->vba.MaxDCHUBToPSCLThroughput,
+								mode_lib->vba.MaxPSCLToLBThroughput
+										* mode_lib->vba.HRatio[k]
+										/ 2
+										/ dml_ceil(
+												mode_lib->vba.HTAPsChroma[k]
+														/ 6.0,
+												1.0));
+			} else {
+				mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
+						mode_lib->vba.MaxDCHUBToPSCLThroughput,
+						mode_lib->vba.MaxPSCLToLBThroughput);
+			}
+			mode_lib->vba.DPPCLKUsingSingleDPPChroma =
+					mode_lib->vba.PixelClock[k]
+							* dml_max(
+									mode_lib->vba.VTAPsChroma[k]
+											/ 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]
+															/ 2),
+									dml_max(
+											mode_lib->vba.HRatio[k]
+													* mode_lib->vba.VRatio[k]
+													/ 4
+													/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
+											1.0));
+
+			if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
+					&& mode_lib->vba.DPPCLKUsingSingleDPPChroma
+							< 2 * mode_lib->vba.PixelClock[k]) {
+				mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
+						* mode_lib->vba.PixelClock[k];
+			}
+
+			mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
+					mode_lib->vba.DPPCLKUsingSingleDPPLuma,
+					mode_lib->vba.DPPCLKUsingSingleDPPChroma);
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.BlendingAndTiming[k] != k)
+			continue;
+		if (mode_lib->vba.ODMCombineEnabled[k]) {
+			mode_lib->vba.DISPCLKWithRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithRamping,
+							mode_lib->vba.PixelClock[k] / 2
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100)
+									* (1
+											+ mode_lib->vba.DISPCLKRampingMargin
+													/ 100));
+			mode_lib->vba.DISPCLKWithoutRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithoutRamping,
+							mode_lib->vba.PixelClock[k] / 2
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100));
+		} else if (!mode_lib->vba.ODMCombineEnabled[k]) {
+			mode_lib->vba.DISPCLKWithRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithRamping,
+							mode_lib->vba.PixelClock[k]
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100)
+									* (1
+											+ mode_lib->vba.DISPCLKRampingMargin
+													/ 100));
+			mode_lib->vba.DISPCLKWithoutRamping =
+					dml_max(
+							mode_lib->vba.DISPCLKWithoutRamping,
+							mode_lib->vba.PixelClock[k]
+									* (1
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100));
+		}
+	}
+
+	mode_lib->vba.DISPCLKWithRamping = dml_max(
+			mode_lib->vba.DISPCLKWithRamping,
+			mode_lib->vba.WritebackDISPCLK);
+	mode_lib->vba.DISPCLKWithoutRamping = dml_max(
+			mode_lib->vba.DISPCLKWithoutRamping,
+			mode_lib->vba.WritebackDISPCLK);
+
+	ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
+	mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
+			mode_lib->vba.DISPCLKWithRamping,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
+			mode_lib->vba.DISPCLKWithoutRamping,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
+			mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
+			> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
+		mode_lib->vba.DISPCLK_calculated =
+				mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
+	} else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
+			> mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
+		mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
+	} else {
+		mode_lib->vba.DISPCLK_calculated =
+				mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
+	}
+	DTRACE("   dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
+				/ mode_lib->vba.DPPPerPlane[k]
+				* (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
+		mode_lib->vba.GlobalDPPCLK = dml_max(
+				mode_lib->vba.GlobalDPPCLK,
+				mode_lib->vba.DPPCLK_calculated[k]);
+	}
+	mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
+			mode_lib->vba.GlobalDPPCLK,
+			mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
+				* dml_ceil(
+						mode_lib->vba.DPPCLK_calculated[k] * 255
+								/ mode_lib->vba.GlobalDPPCLK,
+						1);
+		DTRACE("   dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
+	}
+
+	// Urgent Watermark
+	mode_lib->vba.DCCEnabledAnyPlane = false;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		if (mode_lib->vba.DCCEnable[k])
+			mode_lib->vba.DCCEnabledAnyPlane = true;
+
+	mode_lib->vba.ReturnBandwidthToDCN = dml_min(
+			mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
+			mode_lib->vba.FabricAndDRAMBandwidth * 1000)
+			* mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100;
+
+	mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
+	mode_lib->vba.ReturnBW = adjust_ReturnBW(
+			mode_lib,
+			mode_lib->vba.ReturnBW,
+			mode_lib->vba.DCCEnabledAnyPlane,
+			mode_lib->vba.ReturnBandwidthToDCN);
+
+	// Let's do this calculation again??
+	mode_lib->vba.ReturnBandwidthToDCN = dml_min(
+			mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
+			mode_lib->vba.FabricAndDRAMBandwidth * 1000);
+	mode_lib->vba.ReturnBW = adjust_ReturnBW(
+			mode_lib,
+			mode_lib->vba.ReturnBW,
+			mode_lib->vba.DCCEnabledAnyPlane,
+			mode_lib->vba.ReturnBandwidthToDCN);
+
+	DTRACE("   dcfclk_mhz         = %f", mode_lib->vba.DCFCLK);
+	DTRACE("   return_bw_to_dcn   = %f", mode_lib->vba.ReturnBandwidthToDCN);
+	DTRACE("   return_bus_bw      = %f", mode_lib->vba.ReturnBW);
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		bool MainPlaneDoesODMCombine = false;
+
+		if (mode_lib->vba.SourceScan[k] == dm_horz)
+			mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
+		else
+			mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
+
+		if (mode_lib->vba.ODMCombineEnabled[k] == true)
+			MainPlaneDoesODMCombine = true;
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+			if (mode_lib->vba.BlendingAndTiming[k] == j
+					&& mode_lib->vba.ODMCombineEnabled[j] == true)
+				MainPlaneDoesODMCombine = true;
+
+		if (MainPlaneDoesODMCombine == true)
+			mode_lib->vba.SwathWidthY[k] = dml_min(
+					(double) mode_lib->vba.SwathWidthSingleDPPY[k],
+					dml_round(
+							mode_lib->vba.HActive[k] / 2.0
+									* mode_lib->vba.HRatio[k]));
+		else
+			mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+					/ mode_lib->vba.DPPPerPlane[k];
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+			mode_lib->vba.BytePerPixelDETY[k] = 8;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+			mode_lib->vba.BytePerPixelDETY[k] = 4;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+			mode_lib->vba.BytePerPixelDETY[k] = 2;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
+			mode_lib->vba.BytePerPixelDETY[k] = 1;
+			mode_lib->vba.BytePerPixelDETC[k] = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+			mode_lib->vba.BytePerPixelDETY[k] = 1;
+			mode_lib->vba.BytePerPixelDETC[k] = 2;
+		} else { // dm_420_10
+			mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
+			mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
+		}
+	}
+
+	mode_lib->vba.TotalDataReadBandwidth = 0.0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+				* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				* mode_lib->vba.VRatio[k];
+		mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+				/ 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				* mode_lib->vba.VRatio[k] / 2;
+		DTRACE(
+				"   read_bw[%i] = %fBps",
+				k,
+				mode_lib->vba.ReadBandwidthPlaneLuma[k]
+						+ mode_lib->vba.ReadBandwidthPlaneChroma[k]);
+		mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
+				+ mode_lib->vba.ReadBandwidthPlaneChroma[k];
+	}
+
+	mode_lib->vba.TotalDCCActiveDPP = 0;
+	mode_lib->vba.TotalActiveDPP = 0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
+				+ mode_lib->vba.DPPPerPlane[k];
+		if (mode_lib->vba.DCCEnable[k])
+			mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
+					+ mode_lib->vba.DPPPerPlane[k];
+	}
+
+	mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
+			(mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
+					+ mode_lib->vba.UrgentOutOfOrderReturnPerChannel
+							* mode_lib->vba.NumberOfChannels
+							/ mode_lib->vba.ReturnBW;
+
+	mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma;
+
+		if (mode_lib->vba.VRatio[k] <= 1.0)
+			mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
+					(double) mode_lib->vba.SwathWidthY[k]
+							* mode_lib->vba.DPPPerPlane[k]
+							/ mode_lib->vba.HRatio[k]
+							/ mode_lib->vba.PixelClock[k];
+		else
+			mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
+					(double) mode_lib->vba.SwathWidthY[k]
+							/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+							/ mode_lib->vba.DPPCLK[k];
+
+		DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k]
+				* mode_lib->vba.SwathHeightY[k]
+				* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
+				/ (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k]
+						/ mode_lib->vba.TotalDataReadBandwidth);
+		mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(
+				mode_lib->vba.LastPixelOfLineExtraWatermark,
+				DataFabricLineDeliveryTimeLuma
+						- mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]);
+
+		if (mode_lib->vba.BytePerPixelDETC[k] == 0)
+			mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0;
+		else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0)
+			mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
+					mode_lib->vba.SwathWidthY[k] / 2.0
+							* mode_lib->vba.DPPPerPlane[k]
+							/ (mode_lib->vba.HRatio[k] / 2.0)
+							/ mode_lib->vba.PixelClock[k];
+		else
+			mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
+					mode_lib->vba.SwathWidthY[k] / 2.0
+							/ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
+							/ mode_lib->vba.DPPCLK[k];
+
+		DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0
+				* mode_lib->vba.SwathHeightC[k]
+				* dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
+				/ (mode_lib->vba.ReturnBW
+						* mode_lib->vba.ReadBandwidthPlaneChroma[k]
+						/ mode_lib->vba.TotalDataReadBandwidth);
+		mode_lib->vba.LastPixelOfLineExtraWatermark =
+				dml_max(
+						mode_lib->vba.LastPixelOfLineExtraWatermark,
+						DataFabricLineDeliveryTimeChroma
+								- mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
+	}
+
+	mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
+			+ (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
+					+ mode_lib->vba.TotalDCCActiveDPP
+							* mode_lib->vba.MetaChunkSize) * 1024.0
+					/ mode_lib->vba.ReturnBW;
+
+	if (mode_lib->vba.VirtualMemoryEnable)
+		mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
+				* mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW;
+
+	mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency
+			+ mode_lib->vba.LastPixelOfLineExtraWatermark
+			+ mode_lib->vba.UrgentExtraLatency;
+
+	DTRACE("   urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
+	DTRACE("   wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
+
+	mode_lib->vba.MemoryTripWatermark = mode_lib->vba.UrgentLatency;
+
+	mode_lib->vba.TotalActiveWriteback = 0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.WritebackEnable[k])
+			mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
+	}
+
+	if (mode_lib->vba.TotalActiveWriteback <= 1)
+		mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
+	else
+		mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
+				+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
+						/ mode_lib->vba.SOCCLK;
+
+	DTRACE("   wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
+
+	// NB P-State/DRAM Clock Change Watermark
+	mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
+			+ mode_lib->vba.UrgentWatermark;
+
+	DTRACE("   wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
+
+	DTRACE("   calculating wb pstate watermark");
+	DTRACE("      total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
+	DTRACE("      socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
+
+	if (mode_lib->vba.TotalActiveWriteback <= 1)
+		mode_lib->vba.WritebackDRAMClockChangeWatermark =
+				mode_lib->vba.DRAMClockChangeLatency
+						+ mode_lib->vba.WritebackLatency;
+	else
+		mode_lib->vba.WritebackDRAMClockChangeWatermark =
+				mode_lib->vba.DRAMClockChangeLatency
+						+ mode_lib->vba.WritebackLatency
+						+ mode_lib->vba.WritebackChunkSize * 1024.0 / 32
+								/ mode_lib->vba.SOCCLK;
+
+	DTRACE("   wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
+
+	// Stutter Efficiency
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
+				/ mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
+		mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
+				mode_lib->vba.LinesInDETY[k],
+				mode_lib->vba.SwathHeightY[k]);
+		mode_lib->vba.FullDETBufferingTimeY[k] =
+				mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
+						* (mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k])
+						/ mode_lib->vba.VRatio[k];
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k]
+					/ mode_lib->vba.BytePerPixelDETC[k]
+					/ (mode_lib->vba.SwathWidthY[k] / 2);
+			mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(
+					mode_lib->vba.LinesInDETC[k],
+					mode_lib->vba.SwathHeightC[k]);
+			mode_lib->vba.FullDETBufferingTimeC[k] =
+					mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
+							* (mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k])
+							/ (mode_lib->vba.VRatio[k] / 2);
+		} else {
+			mode_lib->vba.LinesInDETC[k] = 0;
+			mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
+			mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
+		}
+	}
+
+	mode_lib->vba.MinFullDETBufferingTime = 999999.0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.FullDETBufferingTimeY[k]
+				< mode_lib->vba.MinFullDETBufferingTime) {
+			mode_lib->vba.MinFullDETBufferingTime =
+					mode_lib->vba.FullDETBufferingTimeY[k];
+			mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
+					(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k];
+		}
+		if (mode_lib->vba.FullDETBufferingTimeC[k]
+				< mode_lib->vba.MinFullDETBufferingTime) {
+			mode_lib->vba.MinFullDETBufferingTime =
+					mode_lib->vba.FullDETBufferingTimeC[k];
+			mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
+					(double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k];
+		}
+	}
+
+	mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.DCCEnable[k]) {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ mode_lib->vba.DCCRate[k]
+									/ 1000
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ mode_lib->vba.DCCRate[k]
+									/ 1000;
+		} else {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ 1000
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ 1000;
+		}
+		if (mode_lib->vba.DCCEnable[k]) {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ 1000 / 256
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ 1000 / 256;
+		}
+		if (mode_lib->vba.VirtualMemoryEnable) {
+			mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+					mode_lib->vba.AverageReadBandwidthGBytePerSecond
+							+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+									/ 1000 / 512
+							+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+									/ 1000 / 512;
+		}
+	}
+
+	mode_lib->vba.PartOfBurstThatFitsInROB =
+			dml_min(
+					mode_lib->vba.MinFullDETBufferingTime
+							* mode_lib->vba.TotalDataReadBandwidth,
+					mode_lib->vba.ROBBufferSizeInKByte * 1024
+							* mode_lib->vba.TotalDataReadBandwidth
+							/ (mode_lib->vba.AverageReadBandwidthGBytePerSecond
+									* 1000));
+	mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
+			* (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
+			/ mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
+			+ (mode_lib->vba.MinFullDETBufferingTime
+					* mode_lib->vba.TotalDataReadBandwidth
+					- mode_lib->vba.PartOfBurstThatFitsInROB)
+					/ (mode_lib->vba.DCFCLK * 64);
+	if (mode_lib->vba.TotalActiveWriteback == 0) {
+		mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
+				- (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
+						/ mode_lib->vba.MinFullDETBufferingTime) * 100;
+	} else {
+		mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
+	}
+
+	mode_lib->vba.SmallestVBlank = 999999;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
+			mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
+					- mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
+					/ mode_lib->vba.PixelClock[k];
+		} else {
+			mode_lib->vba.VBlankTime = 0;
+		}
+		mode_lib->vba.SmallestVBlank = dml_min(
+				mode_lib->vba.SmallestVBlank,
+				mode_lib->vba.VBlankTime);
+	}
+
+	mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
+			* (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
+					- mode_lib->vba.SmallestVBlank)
+			+ mode_lib->vba.SmallestVBlank)
+			/ mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
+
+	// dml_ml->vba.DCFCLK Deep Sleep
+	mode_lib->vba.DCFClkDeepSleep = 8.0;
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			mode_lib->vba.DCFCLKDeepSleepPerPlane =
+					dml_max(
+							1.1 * mode_lib->vba.SwathWidthY[k]
+									* dml_ceil(
+											mode_lib->vba.BytePerPixelDETY[k],
+											1) / 32
+									/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
+							1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
+									* dml_ceil(
+											mode_lib->vba.BytePerPixelDETC[k],
+											2) / 32
+									/ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
+		} else
+			mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k]
+					* dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
+					/ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
+		mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(
+				mode_lib->vba.DCFCLKDeepSleepPerPlane,
+				mode_lib->vba.PixelClock[k] / 16.0);
+		mode_lib->vba.DCFClkDeepSleep = dml_max(
+				mode_lib->vba.DCFClkDeepSleep,
+				mode_lib->vba.DCFCLKDeepSleepPerPlane);
+
+		DTRACE(
+				"   dcfclk_deepsleep_per_plane[%i] = %fMHz",
+				k,
+				mode_lib->vba.DCFCLKDeepSleepPerPlane);
+	}
+
+	DTRACE("   dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep);
+
+	// Stutter Watermark
+	mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
+			+ mode_lib->vba.LastPixelOfLineExtraWatermark
+			+ mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFClkDeepSleep;
+	mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
+			+ mode_lib->vba.LastPixelOfLineExtraWatermark
+			+ mode_lib->vba.UrgentExtraLatency;
+
+	DTRACE("   wm_cstate_exit       = %fus", mode_lib->vba.StutterExitWatermark);
+	DTRACE("   wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
+
+	// Urgent Latency Supported
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.EffectiveDETPlusLBLinesLuma =
+				dml_floor(
+						mode_lib->vba.LinesInDETY[k]
+								+ dml_min(
+										mode_lib->vba.LinesInDETY[k]
+												* mode_lib->vba.DPPCLK[k]
+												* mode_lib->vba.BytePerPixelDETY[k]
+												* mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+												/ (mode_lib->vba.ReturnBW
+														/ mode_lib->vba.DPPPerPlane[k]),
+										(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
+						mode_lib->vba.SwathHeightY[k]);
+
+		mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
+				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				/ mode_lib->vba.VRatio[k]
+				- mode_lib->vba.EffectiveDETPlusLBLinesLuma
+						* mode_lib->vba.SwathWidthY[k]
+						* mode_lib->vba.BytePerPixelDETY[k]
+						/ (mode_lib->vba.ReturnBW
+								/ mode_lib->vba.DPPPerPlane[k]);
+
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			mode_lib->vba.EffectiveDETPlusLBLinesChroma =
+					dml_floor(
+							mode_lib->vba.LinesInDETC[k]
+									+ dml_min(
+											mode_lib->vba.LinesInDETC[k]
+													* mode_lib->vba.DPPCLK[k]
+													* mode_lib->vba.BytePerPixelDETC[k]
+													* mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
+													/ (mode_lib->vba.ReturnBW
+															/ mode_lib->vba.DPPPerPlane[k]),
+											(double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
+							mode_lib->vba.SwathHeightC[k]);
+			mode_lib->vba.UrgentLatencySupportUsChroma =
+					mode_lib->vba.EffectiveDETPlusLBLinesChroma
+							* (mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k])
+							/ (mode_lib->vba.VRatio[k] / 2)
+							- mode_lib->vba.EffectiveDETPlusLBLinesChroma
+									* (mode_lib->vba.SwathWidthY[k]
+											/ 2)
+									* mode_lib->vba.BytePerPixelDETC[k]
+									/ (mode_lib->vba.ReturnBW
+											/ mode_lib->vba.DPPPerPlane[k]);
+			mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
+					mode_lib->vba.UrgentLatencySupportUsLuma,
+					mode_lib->vba.UrgentLatencySupportUsChroma);
+		} else {
+			mode_lib->vba.UrgentLatencySupportUs[k] =
+					mode_lib->vba.UrgentLatencySupportUsLuma;
+		}
+	}
+
+	mode_lib->vba.MinUrgentLatencySupportUs = 999999;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
+				mode_lib->vba.MinUrgentLatencySupportUs,
+				mode_lib->vba.UrgentLatencySupportUs[k]);
+	}
+
+	// Non-Urgent Latency Tolerance
+	mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
+			- mode_lib->vba.UrgentWatermark;
+
+	// DSCCLK
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
+			mode_lib->vba.DSCCLK_calculated[k] = 0.0;
+		} else {
+			if (mode_lib->vba.OutputFormat[k] == dm_420
+					|| mode_lib->vba.OutputFormat[k] == dm_n422)
+				mode_lib->vba.DSCFormatFactor = 2;
+			else
+				mode_lib->vba.DSCFormatFactor = 1;
+			if (mode_lib->vba.ODMCombineEnabled[k])
+				mode_lib->vba.DSCCLK_calculated[k] =
+						mode_lib->vba.PixelClockBackEnd[k] / 6
+								/ mode_lib->vba.DSCFormatFactor
+								/ (1
+										- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100);
+			else
+				mode_lib->vba.DSCCLK_calculated[k] =
+						mode_lib->vba.PixelClockBackEnd[k] / 3
+								/ mode_lib->vba.DSCFormatFactor
+								/ (1
+										- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100);
+		}
+	}
+
+	// DSC Delay
+	// TODO
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		double bpp = mode_lib->vba.OutputBpp[k];
+		unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
+
+		if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
+			if (!mode_lib->vba.ODMCombineEnabled[k]) {
+				mode_lib->vba.DSCDelay[k] =
+						dscceComputeDelay(
+								mode_lib->vba.DSCInputBitPerComponent[k],
+								bpp,
+								dml_ceil(
+										(double) mode_lib->vba.HActive[k]
+												/ mode_lib->vba.NumberOfDSCSlices[k],
+										1),
+								slices,
+								mode_lib->vba.OutputFormat[k])
+								+ dscComputeDelay(
+										mode_lib->vba.OutputFormat[k]);
+			} else {
+				mode_lib->vba.DSCDelay[k] =
+						2
+								* (dscceComputeDelay(
+										mode_lib->vba.DSCInputBitPerComponent[k],
+										bpp,
+										dml_ceil(
+												(double) mode_lib->vba.HActive[k]
+														/ mode_lib->vba.NumberOfDSCSlices[k],
+												1),
+										slices / 2.0,
+										mode_lib->vba.OutputFormat[k])
+										+ dscComputeDelay(
+												mode_lib->vba.OutputFormat[k]));
+			}
+			mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k]
+					* mode_lib->vba.PixelClock[k]
+					/ mode_lib->vba.PixelClockBackEnd[k];
+		} else {
+			mode_lib->vba.DSCDelay[k] = 0;
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes
+			if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
+					&& mode_lib->vba.DSCEnabled[j])
+				mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
+
+	// Prefetch
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		unsigned int PDEAndMetaPTEBytesFrameY;
+		unsigned int PixelPTEBytesPerRowY;
+		unsigned int MetaRowByteY;
+		unsigned int MetaRowByteC;
+		unsigned int PDEAndMetaPTEBytesFrameC;
+		unsigned int PixelPTEBytesPerRowC;
+
+		Calculate256BBlockSizes(
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.SurfaceTiling[k],
+				dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+				dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
+				&mode_lib->vba.BlockHeight256BytesY[k],
+				&mode_lib->vba.BlockHeight256BytesC[k],
+				&mode_lib->vba.BlockWidth256BytesY[k],
+				&mode_lib->vba.BlockWidth256BytesC[k]);
+		PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
+				mode_lib,
+				mode_lib->vba.DCCEnable[k],
+				mode_lib->vba.BlockHeight256BytesY[k],
+				mode_lib->vba.BlockWidth256BytesY[k],
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.SurfaceTiling[k],
+				dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+				mode_lib->vba.SourceScan[k],
+				mode_lib->vba.ViewportWidth[k],
+				mode_lib->vba.ViewportHeight[k],
+				mode_lib->vba.SwathWidthY[k],
+				mode_lib->vba.VirtualMemoryEnable,
+				mode_lib->vba.VMMPageSize,
+				mode_lib->vba.PTEBufferSizeInRequests,
+				mode_lib->vba.PDEProcessingBufIn64KBReqs,
+				mode_lib->vba.PitchY[k],
+				mode_lib->vba.DCCMetaPitchY[k],
+				&mode_lib->vba.MacroTileWidthY[k],
+				&MetaRowByteY,
+				&PixelPTEBytesPerRowY,
+				&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
+				&mode_lib->vba.dpte_row_height[k],
+				&mode_lib->vba.meta_row_height[k]);
+		mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
+				mode_lib,
+				mode_lib->vba.VRatio[k],
+				mode_lib->vba.vtaps[k],
+				mode_lib->vba.Interlace[k],
+				mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+				mode_lib->vba.SwathHeightY[k],
+				mode_lib->vba.ViewportYStartY[k],
+				&mode_lib->vba.VInitPreFillY[k],
+				&mode_lib->vba.MaxNumSwathY[k]);
+
+		if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
+			PDEAndMetaPTEBytesFrameC =
+					CalculateVMAndRowBytes(
+							mode_lib,
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.BlockHeight256BytesC[k],
+							mode_lib->vba.BlockWidth256BytesC[k],
+							mode_lib->vba.SourcePixelFormat[k],
+							mode_lib->vba.SurfaceTiling[k],
+							dml_ceil(
+									mode_lib->vba.BytePerPixelDETC[k],
+									2),
+							mode_lib->vba.SourceScan[k],
+							mode_lib->vba.ViewportWidth[k] / 2,
+							mode_lib->vba.ViewportHeight[k] / 2,
+							mode_lib->vba.SwathWidthY[k] / 2,
+							mode_lib->vba.VirtualMemoryEnable,
+							mode_lib->vba.VMMPageSize,
+							mode_lib->vba.PTEBufferSizeInRequests,
+							mode_lib->vba.PDEProcessingBufIn64KBReqs,
+							mode_lib->vba.PitchC[k],
+							0,
+							&mode_lib->vba.MacroTileWidthC[k],
+							&MetaRowByteC,
+							&PixelPTEBytesPerRowC,
+							&mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
+							&mode_lib->vba.dpte_row_height_chroma[k],
+							&mode_lib->vba.meta_row_height_chroma[k]);
+			mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
+					mode_lib,
+					mode_lib->vba.VRatio[k] / 2,
+					mode_lib->vba.VTAPsChroma[k],
+					mode_lib->vba.Interlace[k],
+					mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+					mode_lib->vba.SwathHeightC[k],
+					mode_lib->vba.ViewportYStartC[k],
+					&mode_lib->vba.VInitPreFillC[k],
+					&mode_lib->vba.MaxNumSwathC[k]);
+		} else {
+			PixelPTEBytesPerRowC = 0;
+			PDEAndMetaPTEBytesFrameC = 0;
+			MetaRowByteC = 0;
+			mode_lib->vba.MaxNumSwathC[k] = 0;
+			mode_lib->vba.PrefetchSourceLinesC[k] = 0;
+		}
+
+		mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
+		mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
+				+ PDEAndMetaPTEBytesFrameC;
+		mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
+
+		CalculateActiveRowBandwidth(
+				mode_lib->vba.VirtualMemoryEnable,
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.VRatio[k],
+				mode_lib->vba.DCCEnable[k],
+				mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+				MetaRowByteY,
+				MetaRowByteC,
+				mode_lib->vba.meta_row_height[k],
+				mode_lib->vba.meta_row_height_chroma[k],
+				PixelPTEBytesPerRowY,
+				PixelPTEBytesPerRowC,
+				mode_lib->vba.dpte_row_height[k],
+				mode_lib->vba.dpte_row_height_chroma[k],
+				&mode_lib->vba.meta_row_bw[k],
+				&mode_lib->vba.dpte_row_bw[k],
+				&mode_lib->vba.qual_row_bw[k]);
+	}
+
+	mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep;
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.BlendingAndTiming[k] == k) {
+			if (mode_lib->vba.WritebackEnable[k] == true) {
+				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+						mode_lib->vba.WritebackLatency
+								+ CalculateWriteBackDelay(
+										mode_lib->vba.WritebackPixelFormat[k],
+										mode_lib->vba.WritebackHRatio[k],
+										mode_lib->vba.WritebackVRatio[k],
+										mode_lib->vba.WritebackLumaHTaps[k],
+										mode_lib->vba.WritebackLumaVTaps[k],
+										mode_lib->vba.WritebackChromaHTaps[k],
+										mode_lib->vba.WritebackChromaVTaps[k],
+										mode_lib->vba.WritebackDestinationWidth[k])
+										/ mode_lib->vba.DISPCLK;
+			} else
+				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
+			for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+				if (mode_lib->vba.BlendingAndTiming[j] == k
+						&& mode_lib->vba.WritebackEnable[j] == true) {
+					mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+							dml_max(
+									mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
+									mode_lib->vba.WritebackLatency
+											+ CalculateWriteBackDelay(
+													mode_lib->vba.WritebackPixelFormat[j],
+													mode_lib->vba.WritebackHRatio[j],
+													mode_lib->vba.WritebackVRatio[j],
+													mode_lib->vba.WritebackLumaHTaps[j],
+													mode_lib->vba.WritebackLumaVTaps[j],
+													mode_lib->vba.WritebackChromaHTaps[j],
+													mode_lib->vba.WritebackChromaVTaps[j],
+													mode_lib->vba.WritebackDestinationWidth[j])
+													/ mode_lib->vba.DISPCLK);
+				}
+			}
+		}
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+			if (mode_lib->vba.BlendingAndTiming[k] == j)
+				mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+						mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
+
+	mode_lib->vba.VStartupLines = 13;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.MaxVStartupLines[k] =
+				mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
+						- dml_max(
+								1.0,
+								dml_ceil(
+										mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
+												/ (mode_lib->vba.HTotal[k]
+														/ mode_lib->vba.PixelClock[k]),
+										1));
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+		mode_lib->vba.MaximumMaxVStartupLines = dml_max(
+				mode_lib->vba.MaximumMaxVStartupLines,
+				mode_lib->vba.MaxVStartupLines[k]);
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.cursor_bw[k] = 0.0;
+		for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
+			mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
+					* mode_lib->vba.CursorBPP[k][j] / 8.0
+					/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+					* mode_lib->vba.VRatio[k];
+	}
+
+	do {
+		double MaxTotalRDBandwidth = 0;
+		bool DestinationLineTimesForPrefetchLessThan2 = false;
+		bool VRatioPrefetchMoreThan4 = false;
+		bool prefetch_vm_bw_valid = true;
+		bool prefetch_row_bw_valid = true;
+		double TWait = CalculateTWait(
+				mode_lib->vba.PrefetchMode,
+				mode_lib->vba.DRAMClockChangeLatency,
+				mode_lib->vba.UrgentLatency,
+				mode_lib->vba.SREnterPlusExitTime);
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+			if (mode_lib->vba.XFCEnabled[k] == true) {
+				mode_lib->vba.XFCRemoteSurfaceFlipDelay =
+						CalculateRemoteSurfaceFlipDelay(
+								mode_lib,
+								mode_lib->vba.VRatio[k],
+								mode_lib->vba.SwathWidthY[k],
+								dml_ceil(
+										mode_lib->vba.BytePerPixelDETY[k],
+										1),
+								mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k],
+								mode_lib->vba.XFCTSlvVupdateOffset,
+								mode_lib->vba.XFCTSlvVupdateWidth,
+								mode_lib->vba.XFCTSlvVreadyOffset,
+								mode_lib->vba.XFCXBUFLatencyTolerance,
+								mode_lib->vba.XFCFillBWOverhead,
+								mode_lib->vba.XFCSlvChunkSize,
+								mode_lib->vba.XFCBusTransportTime,
+								mode_lib->vba.TCalc,
+								TWait,
+								&mode_lib->vba.SrcActiveDrainRate,
+								&mode_lib->vba.TInitXFill,
+								&mode_lib->vba.TslvChk);
+			} else {
+				mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
+			}
+			mode_lib->vba.ErrorResult[k] =
+					CalculatePrefetchSchedule(
+							mode_lib,
+							mode_lib->vba.DPPCLK[k],
+							mode_lib->vba.DISPCLK,
+							mode_lib->vba.PixelClock[k],
+							mode_lib->vba.DCFClkDeepSleep,
+							mode_lib->vba.DSCDelay[k],
+							mode_lib->vba.DPPPerPlane[k],
+							mode_lib->vba.ScalerEnabled[k],
+							mode_lib->vba.NumberOfCursors[k],
+							mode_lib->vba.DPPCLKDelaySubtotal,
+							mode_lib->vba.DPPCLKDelaySCL,
+							mode_lib->vba.DPPCLKDelaySCLLBOnly,
+							mode_lib->vba.DPPCLKDelayCNVCFormater,
+							mode_lib->vba.DPPCLKDelayCNVCCursor,
+							mode_lib->vba.DISPCLKDelaySubtotal,
+							(unsigned int) (mode_lib->vba.SwathWidthY[k]
+									/ mode_lib->vba.HRatio[k]),
+							mode_lib->vba.OutputFormat[k],
+							mode_lib->vba.VTotal[k]
+									- mode_lib->vba.VActive[k],
+							mode_lib->vba.HTotal[k],
+							mode_lib->vba.MaxInterDCNTileRepeaters,
+							dml_min(
+									mode_lib->vba.VStartupLines,
+									mode_lib->vba.MaxVStartupLines[k]),
+							mode_lib->vba.MaxPageTableLevels,
+							mode_lib->vba.VirtualMemoryEnable,
+							mode_lib->vba.DynamicMetadataEnable[k],
+							mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
+							mode_lib->vba.DynamicMetadataTransmittedBytes[k],
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.UrgentLatency,
+							mode_lib->vba.UrgentExtraLatency,
+							mode_lib->vba.TCalc,
+							mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
+							mode_lib->vba.MetaRowByte[k],
+							mode_lib->vba.PixelPTEBytesPerRow[k],
+							mode_lib->vba.PrefetchSourceLinesY[k],
+							mode_lib->vba.SwathWidthY[k],
+							mode_lib->vba.BytePerPixelDETY[k],
+							mode_lib->vba.VInitPreFillY[k],
+							mode_lib->vba.MaxNumSwathY[k],
+							mode_lib->vba.PrefetchSourceLinesC[k],
+							mode_lib->vba.BytePerPixelDETC[k],
+							mode_lib->vba.VInitPreFillC[k],
+							mode_lib->vba.MaxNumSwathC[k],
+							mode_lib->vba.SwathHeightY[k],
+							mode_lib->vba.SwathHeightC[k],
+							TWait,
+							mode_lib->vba.XFCEnabled[k],
+							mode_lib->vba.XFCRemoteSurfaceFlipDelay,
+							mode_lib->vba.Interlace[k],
+							mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+							&mode_lib->vba.DSTXAfterScaler[k],
+							&mode_lib->vba.DSTYAfterScaler[k],
+							&mode_lib->vba.DestinationLinesForPrefetch[k],
+							&mode_lib->vba.PrefetchBandwidth[k],
+							&mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
+							&mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
+							&mode_lib->vba.VRatioPrefetchY[k],
+							&mode_lib->vba.VRatioPrefetchC[k],
+							&mode_lib->vba.RequiredPrefetchPixDataBW[k],
+							&mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+							&mode_lib->vba.Tno_bw[k],
+							&mode_lib->vba.VUpdateOffsetPix[k],
+							&mode_lib->vba.VUpdateWidthPix[k],
+							&mode_lib->vba.VReadyOffsetPix[k]);
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				mode_lib->vba.VStartup[k] = dml_min(
+						mode_lib->vba.VStartupLines,
+						mode_lib->vba.MaxVStartupLines[k]);
+				if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
+						!= 0) {
+					mode_lib->vba.VStartup[k] =
+							mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
+				}
+			} else {
+				mode_lib->vba.VStartup[k] =
+						dml_min(
+								mode_lib->vba.VStartupLines,
+								mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
+			}
+		}
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+
+			if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
+				mode_lib->vba.prefetch_vm_bw[k] = 0;
+			else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
+				mode_lib->vba.prefetch_vm_bw[k] =
+						(double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+								/ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+										* mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k]);
+			} else {
+				mode_lib->vba.prefetch_vm_bw[k] = 0;
+				prefetch_vm_bw_valid = false;
+			}
+			if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
+					== 0)
+				mode_lib->vba.prefetch_row_bw[k] = 0;
+			else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
+				mode_lib->vba.prefetch_row_bw[k] =
+						(double) (mode_lib->vba.MetaRowByte[k]
+								+ mode_lib->vba.PixelPTEBytesPerRow[k])
+								/ (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
+										* mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k]);
+			} else {
+				mode_lib->vba.prefetch_row_bw[k] = 0;
+				prefetch_row_bw_valid = false;
+			}
+
+			MaxTotalRDBandwidth =
+					MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
+							+ dml_max(
+									mode_lib->vba.prefetch_vm_bw[k],
+									dml_max(
+											mode_lib->vba.prefetch_row_bw[k],
+											dml_max(
+													mode_lib->vba.ReadBandwidthPlaneLuma[k]
+															+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
+													mode_lib->vba.RequiredPrefetchPixDataBW[k])
+													+ mode_lib->vba.meta_row_bw[k]
+													+ mode_lib->vba.dpte_row_bw[k]));
+
+			if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
+				DestinationLineTimesForPrefetchLessThan2 = true;
+			if (mode_lib->vba.VRatioPrefetchY[k] > 4
+					|| mode_lib->vba.VRatioPrefetchC[k] > 4)
+				VRatioPrefetchMoreThan4 = true;
+		}
+
+		if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
+				&& prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
+				&& !DestinationLineTimesForPrefetchLessThan2)
+			mode_lib->vba.PrefetchModeSupported = true;
+		else {
+			mode_lib->vba.PrefetchModeSupported = false;
+			dml_print(
+					"DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
+		}
+
+		if (mode_lib->vba.PrefetchModeSupported == true) {
+			double final_flip_bw[DC__NUM_DPP__MAX];
+			unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
+			double total_dcn_read_bw_with_flip = 0;
+
+			mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				mode_lib->vba.BandwidthAvailableForImmediateFlip =
+						mode_lib->vba.BandwidthAvailableForImmediateFlip
+								- mode_lib->vba.cursor_bw[k]
+								- dml_max(
+										mode_lib->vba.ReadBandwidthPlaneLuma[k]
+												+ mode_lib->vba.ReadBandwidthPlaneChroma[k]
+												+ mode_lib->vba.qual_row_bw[k],
+										mode_lib->vba.PrefetchBandwidth[k]);
+			}
+
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				ImmediateFlipBytes[k] = 0;
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+					ImmediateFlipBytes[k] =
+							mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+									+ mode_lib->vba.MetaRowByte[k]
+									+ mode_lib->vba.PixelPTEBytesPerRow[k];
+				}
+			}
+			mode_lib->vba.TotImmediateFlipBytes = 0;
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+					mode_lib->vba.TotImmediateFlipBytes =
+							mode_lib->vba.TotImmediateFlipBytes
+									+ ImmediateFlipBytes[k];
+				}
+			}
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				CalculateFlipSchedule(
+						mode_lib,
+						mode_lib->vba.UrgentExtraLatency,
+						mode_lib->vba.UrgentLatency,
+						mode_lib->vba.MaxPageTableLevels,
+						mode_lib->vba.VirtualMemoryEnable,
+						mode_lib->vba.BandwidthAvailableForImmediateFlip,
+						mode_lib->vba.TotImmediateFlipBytes,
+						mode_lib->vba.SourcePixelFormat[k],
+						ImmediateFlipBytes[k],
+						mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k],
+						mode_lib->vba.VRatio[k],
+						mode_lib->vba.Tno_bw[k],
+						mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
+						mode_lib->vba.MetaRowByte[k],
+						mode_lib->vba.PixelPTEBytesPerRow[k],
+						mode_lib->vba.DCCEnable[k],
+						mode_lib->vba.dpte_row_height[k],
+						mode_lib->vba.meta_row_height[k],
+						mode_lib->vba.qual_row_bw[k],
+						&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
+						&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
+						&final_flip_bw[k],
+						&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
+			}
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				total_dcn_read_bw_with_flip =
+						total_dcn_read_bw_with_flip
+								+ mode_lib->vba.cursor_bw[k]
+								+ dml_max(
+										mode_lib->vba.prefetch_vm_bw[k],
+										dml_max(
+												mode_lib->vba.prefetch_row_bw[k],
+												final_flip_bw[k]
+														+ dml_max(
+																mode_lib->vba.ReadBandwidthPlaneLuma[k]
+																		+ mode_lib->vba.ReadBandwidthPlaneChroma[k],
+																mode_lib->vba.RequiredPrefetchPixDataBW[k])));
+			}
+			mode_lib->vba.ImmediateFlipSupported = true;
+			if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
+				mode_lib->vba.ImmediateFlipSupported = false;
+			}
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
+					mode_lib->vba.ImmediateFlipSupported = false;
+				}
+			}
+		} else {
+			mode_lib->vba.ImmediateFlipSupported = false;
+		}
+
+		for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+			if (mode_lib->vba.ErrorResult[k]) {
+				mode_lib->vba.PrefetchModeSupported = false;
+				dml_print(
+						"DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
+			}
+		}
+
+		mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
+	} while (!((mode_lib->vba.PrefetchModeSupported
+			&& (!mode_lib->vba.ImmediateFlipSupport
+					|| mode_lib->vba.ImmediateFlipSupported))
+			|| mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
+
+	//Display Pipeline Delivery Time in Prefetch
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
+			mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
+					mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
+							/ mode_lib->vba.HRatio[k]
+							/ mode_lib->vba.PixelClock[k];
+		} else {
+			mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
+					mode_lib->vba.SwathWidthY[k]
+							/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+							/ mode_lib->vba.DPPCLK[k];
+		}
+		if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
+			mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
+		} else {
+			if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
+				mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
+						mode_lib->vba.SwathWidthY[k]
+								* mode_lib->vba.DPPPerPlane[k]
+								/ mode_lib->vba.HRatio[k]
+								/ mode_lib->vba.PixelClock[k];
+			} else {
+				mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
+						mode_lib->vba.SwathWidthY[k]
+								/ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+								/ mode_lib->vba.DPPCLK[k];
+			}
+		}
+	}
+
+	// Min TTUVBlank
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.PrefetchMode == 0) {
+			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
+			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
+			mode_lib->vba.MinTTUVBlank[k] = dml_max(
+					mode_lib->vba.DRAMClockChangeWatermark,
+					dml_max(
+							mode_lib->vba.StutterEnterPlusExitWatermark,
+							mode_lib->vba.UrgentWatermark));
+		} else if (mode_lib->vba.PrefetchMode == 1) {
+			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
+			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
+			mode_lib->vba.MinTTUVBlank[k] = dml_max(
+					mode_lib->vba.StutterEnterPlusExitWatermark,
+					mode_lib->vba.UrgentWatermark);
+		} else {
+			mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
+			mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
+			mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
+		}
+		if (!mode_lib->vba.DynamicMetadataEnable[k])
+			mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
+					+ mode_lib->vba.MinTTUVBlank[k];
+	}
+
+	// DCC Configuration
+	mode_lib->vba.ActiveDPPs = 0;
+	// NB P-State/DRAM Clock Change Support
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
+	}
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		double EffectiveLBLatencyHidingY;
+		double EffectiveLBLatencyHidingC;
+		double DPPOutputBufferLinesY;
+		double DPPOutputBufferLinesC;
+		double DPPOPPBufferingY;
+		double MaxDETBufferingTimeY;
+		double ActiveDRAMClockChangeLatencyMarginY;
+
+		mode_lib->vba.LBLatencyHidingSourceLinesY =
+				dml_min(
+						mode_lib->vba.MaxLineBufferLines,
+						(unsigned int) dml_floor(
+								(double) mode_lib->vba.LineBufferSize
+										/ mode_lib->vba.LBBitPerPixel[k]
+										/ (mode_lib->vba.SwathWidthY[k]
+												/ dml_max(
+														mode_lib->vba.HRatio[k],
+														1.0)),
+								1)) - (mode_lib->vba.vtaps[k] - 1);
+
+		mode_lib->vba.LBLatencyHidingSourceLinesC =
+				dml_min(
+						mode_lib->vba.MaxLineBufferLines,
+						(unsigned int) dml_floor(
+								(double) mode_lib->vba.LineBufferSize
+										/ mode_lib->vba.LBBitPerPixel[k]
+										/ (mode_lib->vba.SwathWidthY[k]
+												/ 2.0
+												/ dml_max(
+														mode_lib->vba.HRatio[k]
+																/ 2,
+														1.0)),
+								1))
+						- (mode_lib->vba.VTAPsChroma[k] - 1);
+
+		EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
+				/ mode_lib->vba.VRatio[k]
+				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+
+		EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
+				/ (mode_lib->vba.VRatio[k] / 2)
+				* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+
+		if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
+					/ mode_lib->vba.SwathWidthY[k];
+		} else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesY = 0.5;
+		} else {
+			DPPOutputBufferLinesY = 1;
+		}
+
+		if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
+					/ (mode_lib->vba.SwathWidthY[k] / 2);
+		} else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
+			DPPOutputBufferLinesC = 0.5;
+		} else {
+			DPPOutputBufferLinesC = 1;
+		}
+
+		DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+				* (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
+		MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
+				+ (mode_lib->vba.LinesInDETY[k]
+						- mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
+						/ mode_lib->vba.SwathHeightY[k]
+						* (mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k]);
+
+		ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
+				+ MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
+
+		if (mode_lib->vba.ActiveDPPs > 1) {
+			ActiveDRAMClockChangeLatencyMarginY =
+					ActiveDRAMClockChangeLatencyMarginY
+							- (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
+									* mode_lib->vba.SwathHeightY[k]
+									* (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]);
+		}
+
+		if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+			double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
+					/ mode_lib->vba.PixelClock[k])
+					* (DPPOutputBufferLinesC
+							+ mode_lib->vba.OPPOutputBufferLines);
+			double MaxDETBufferingTimeC =
+					mode_lib->vba.FullDETBufferingTimeC[k]
+							+ (mode_lib->vba.LinesInDETC[k]
+									- mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
+									/ mode_lib->vba.SwathHeightC[k]
+									* (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]);
+			double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
+					+ EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
+					- mode_lib->vba.DRAMClockChangeWatermark;
+
+			if (mode_lib->vba.ActiveDPPs > 1) {
+				ActiveDRAMClockChangeLatencyMarginC =
+						ActiveDRAMClockChangeLatencyMarginC
+								- (1
+										- 1
+												/ (mode_lib->vba.ActiveDPPs
+														- 1))
+										* mode_lib->vba.SwathHeightC[k]
+										* (mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k]);
+			}
+			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
+					ActiveDRAMClockChangeLatencyMarginY,
+					ActiveDRAMClockChangeLatencyMarginC);
+		} else {
+			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
+					ActiveDRAMClockChangeLatencyMarginY;
+		}
+
+		if (mode_lib->vba.WritebackEnable[k]) {
+			double WritebackDRAMClockChangeLatencyMargin;
+
+			if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+				WritebackDRAMClockChangeLatencyMargin =
+						(double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
+								+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ (mode_lib->vba.WritebackDestinationWidth[k]
+										* mode_lib->vba.WritebackDestinationHeight[k]
+										/ (mode_lib->vba.WritebackSourceHeight[k]
+												* mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k])
+										* 4)
+								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
+			} else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+				WritebackDRAMClockChangeLatencyMargin =
+						dml_min(
+								(double) mode_lib->vba.WritebackInterfaceLumaBufferSize
+										* 8.0 / 10,
+								2.0
+										* mode_lib->vba.WritebackInterfaceChromaBufferSize
+										* 8 / 10)
+								/ (mode_lib->vba.WritebackDestinationWidth[k]
+										* mode_lib->vba.WritebackDestinationHeight[k]
+										/ (mode_lib->vba.WritebackSourceHeight[k]
+												* mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k]))
+								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
+			} else {
+				WritebackDRAMClockChangeLatencyMargin =
+						dml_min(
+								(double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
+								2.0
+										* mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ (mode_lib->vba.WritebackDestinationWidth[k]
+										* mode_lib->vba.WritebackDestinationHeight[k]
+										/ (mode_lib->vba.WritebackSourceHeight[k]
+												* mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k]))
+								- mode_lib->vba.WritebackDRAMClockChangeWatermark;
+			}
+			mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
+					mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
+					WritebackDRAMClockChangeLatencyMargin);
+		}
+	}
+
+	mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
+				< mode_lib->vba.MinActiveDRAMClockChangeMargin) {
+			mode_lib->vba.MinActiveDRAMClockChangeMargin =
+					mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
+		}
+	}
+
+	mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
+			mode_lib->vba.MinActiveDRAMClockChangeMargin
+					+ mode_lib->vba.DRAMClockChangeLatency;
+
+	if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
+		mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive;
+	} else {
+		if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
+			mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank;
+			for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+				if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
+					mode_lib->vba.DRAMClockChangeSupport =
+							dm_dram_clock_change_unsupported;
+				}
+			}
+		} else {
+			mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
+		}
+	}
+
+	//XFC Parameters:
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		if (mode_lib->vba.XFCEnabled[k] == true) {
+			double TWait;
+
+			mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
+			mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
+			mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
+			TWait = CalculateTWait(
+					mode_lib->vba.PrefetchMode,
+					mode_lib->vba.DRAMClockChangeLatency,
+					mode_lib->vba.UrgentLatency,
+					mode_lib->vba.SREnterPlusExitTime);
+			mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
+					mode_lib,
+					mode_lib->vba.VRatio[k],
+					mode_lib->vba.SwathWidthY[k],
+					dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+					mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+					mode_lib->vba.XFCTSlvVupdateOffset,
+					mode_lib->vba.XFCTSlvVupdateWidth,
+					mode_lib->vba.XFCTSlvVreadyOffset,
+					mode_lib->vba.XFCXBUFLatencyTolerance,
+					mode_lib->vba.XFCFillBWOverhead,
+					mode_lib->vba.XFCSlvChunkSize,
+					mode_lib->vba.XFCBusTransportTime,
+					mode_lib->vba.TCalc,
+					TWait,
+					&mode_lib->vba.SrcActiveDrainRate,
+					&mode_lib->vba.TInitXFill,
+					&mode_lib->vba.TslvChk);
+			mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
+					dml_floor(
+							mode_lib->vba.XFCRemoteSurfaceFlipDelay
+									/ (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]),
+							1);
+			mode_lib->vba.XFCTransferDelay[k] =
+					dml_ceil(
+							mode_lib->vba.XFCBusTransportTime
+									/ (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]),
+							1);
+			mode_lib->vba.XFCPrechargeDelay[k] =
+					dml_ceil(
+							(mode_lib->vba.XFCBusTransportTime
+									+ mode_lib->vba.TInitXFill
+									+ mode_lib->vba.TslvChk)
+									/ (mode_lib->vba.HTotal[k]
+											/ mode_lib->vba.PixelClock[k]),
+							1);
+			mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
+					* mode_lib->vba.SrcActiveDrainRate;
+			mode_lib->vba.FinalFillMargin =
+					(mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+							+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]
+							* mode_lib->vba.SrcActiveDrainRate
+							+ mode_lib->vba.XFCFillConstant;
+			mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
+					* mode_lib->vba.SrcActiveDrainRate
+					+ mode_lib->vba.FinalFillMargin;
+			mode_lib->vba.RemainingFillLevel = dml_max(
+					0.0,
+					mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
+			mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
+					/ (mode_lib->vba.SrcActiveDrainRate
+							* mode_lib->vba.XFCFillBWOverhead / 100);
+			mode_lib->vba.XFCPrefetchMargin[k] =
+					mode_lib->vba.XFCRemoteSurfaceFlipDelay
+							+ mode_lib->vba.TFinalxFill
+							+ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+									+ mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
+									* mode_lib->vba.HTotal[k]
+									/ mode_lib->vba.PixelClock[k];
+		} else {
+			mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
+			mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
+			mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
+			mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
+			mode_lib->vba.XFCPrechargeDelay[k] = 0;
+			mode_lib->vba.XFCTransferDelay[k] = 0;
+			mode_lib->vba.XFCPrefetchMargin[k] = 0;
+		}
+	}
+}
+
+static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
+{
+	double BytePerPixDETY;
+	double BytePerPixDETC;
+	double Read256BytesBlockHeightY;
+	double Read256BytesBlockHeightC;
+	double Read256BytesBlockWidthY;
+	double Read256BytesBlockWidthC;
+	double MaximumSwathHeightY;
+	double MaximumSwathHeightC;
+	double MinimumSwathHeightY;
+	double MinimumSwathHeightC;
+	double SwathWidth;
+	double SwathWidthGranularityY;
+	double SwathWidthGranularityC;
+	double RoundedUpMaxSwathSizeBytesY;
+	double RoundedUpMaxSwathSizeBytesC;
+	unsigned int j, k;
+
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		bool MainPlaneDoesODMCombine = false;
+
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+			BytePerPixDETY = 8;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+			BytePerPixDETY = 4;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+			BytePerPixDETY = 2;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
+			BytePerPixDETY = 1;
+			BytePerPixDETC = 0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+			BytePerPixDETY = 1;
+			BytePerPixDETC = 2;
+		} else {
+			BytePerPixDETY = 4.0 / 3.0;
+			BytePerPixDETC = 8.0 / 3.0;
+		}
+
+		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				Read256BytesBlockHeightY = 1;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+				Read256BytesBlockHeightY = 4;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+					|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+				Read256BytesBlockHeightY = 8;
+			} else {
+				Read256BytesBlockHeightY = 16;
+			}
+			Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
+					/ Read256BytesBlockHeightY;
+			Read256BytesBlockHeightC = 0;
+			Read256BytesBlockWidthC = 0;
+		} else {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				Read256BytesBlockHeightY = 1;
+				Read256BytesBlockHeightC = 1;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+				Read256BytesBlockHeightY = 16;
+				Read256BytesBlockHeightC = 8;
+			} else {
+				Read256BytesBlockHeightY = 8;
+				Read256BytesBlockHeightC = 8;
+			}
+			Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
+					/ Read256BytesBlockHeightY;
+			Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
+					/ Read256BytesBlockHeightC;
+		}
+
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			MaximumSwathHeightY = Read256BytesBlockHeightY;
+			MaximumSwathHeightC = Read256BytesBlockHeightC;
+		} else {
+			MaximumSwathHeightY = Read256BytesBlockWidthY;
+			MaximumSwathHeightC = Read256BytesBlockWidthC;
+		}
+
+		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+					|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+							&& (mode_lib->vba.SurfaceTiling[k]
+									== dm_sw_4kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_4kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_t
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s_x)
+							&& mode_lib->vba.SourceScan[k] == dm_horz)) {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
+					&& mode_lib->vba.SourceScan[k] != dm_horz) {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+			} else {
+				MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
+			}
+			MinimumSwathHeightC = MaximumSwathHeightC;
+		} else {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+				MinimumSwathHeightC = MaximumSwathHeightC;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
+				MinimumSwathHeightC = MaximumSwathHeightC;
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
+				MinimumSwathHeightY = MaximumSwathHeightY;
+			} else {
+				MinimumSwathHeightY = MaximumSwathHeightY;
+				MinimumSwathHeightC = MaximumSwathHeightC;
+			}
+		}
+
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			SwathWidth = mode_lib->vba.ViewportWidth[k];
+		} else {
+			SwathWidth = mode_lib->vba.ViewportHeight[k];
+		}
+
+		if (mode_lib->vba.ODMCombineEnabled[k] == true) {
+			MainPlaneDoesODMCombine = true;
+		}
+		for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+			if (mode_lib->vba.BlendingAndTiming[k] == j
+					&& mode_lib->vba.ODMCombineEnabled[j] == true) {
+				MainPlaneDoesODMCombine = true;
+			}
+		}
+
+		if (MainPlaneDoesODMCombine == true) {
+			SwathWidth = dml_min(
+					SwathWidth,
+					mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
+		} else {
+			SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
+		}
+
+		SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
+		RoundedUpMaxSwathSizeBytesY = (dml_ceil(
+				(double) (SwathWidth - 1),
+				SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
+				* MaximumSwathHeightY;
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+			RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
+					+ 256;
+		}
+		if (MaximumSwathHeightC > 0) {
+			SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
+					/ MaximumSwathHeightC;
+			RoundedUpMaxSwathSizeBytesC = (dml_ceil(
+					(double) (SwathWidth / 2.0 - 1),
+					SwathWidthGranularityC) + SwathWidthGranularityC)
+					* BytePerPixDETC * MaximumSwathHeightC;
+			if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+				RoundedUpMaxSwathSizeBytesC = dml_ceil(
+						RoundedUpMaxSwathSizeBytesC,
+						256) + 256;
+			}
+		} else
+			RoundedUpMaxSwathSizeBytesC = 0.0;
+
+		if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
+				<= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
+			mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
+			mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
+		} else {
+			mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
+			mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
+		}
+
+		if (mode_lib->vba.SwathHeightC[k] == 0) {
+			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
+			mode_lib->vba.DETBufferSizeC[k] = 0;
+		} else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
+			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 / 2;
+			mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 / 2;
+		} else {
+			mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 * 2 / 3;
+			mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
+					* 1024.0 / 3;
+		}
+	}
+}
+
+bool Calculate256BBlockSizes(
+		enum source_format_class SourcePixelFormat,
+		enum dm_swizzle_mode SurfaceTiling,
+		unsigned int BytePerPixelY,
+		unsigned int BytePerPixelC,
+		unsigned int *BlockHeight256BytesY,
+		unsigned int *BlockHeight256BytesC,
+		unsigned int *BlockWidth256BytesY,
+		unsigned int *BlockWidth256BytesC)
+{
+	if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
+			|| SourcePixelFormat == dm_444_16
+			|| SourcePixelFormat == dm_444_8)) {
+		if (SurfaceTiling == dm_sw_linear) {
+			*BlockHeight256BytesY = 1;
+		} else if (SourcePixelFormat == dm_444_64) {
+			*BlockHeight256BytesY = 4;
+		} else if (SourcePixelFormat == dm_444_8) {
+			*BlockHeight256BytesY = 16;
+		} else {
+			*BlockHeight256BytesY = 8;
+		}
+		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
+		*BlockHeight256BytesC = 0;
+		*BlockWidth256BytesC = 0;
+	} else {
+		if (SurfaceTiling == dm_sw_linear) {
+			*BlockHeight256BytesY = 1;
+			*BlockHeight256BytesC = 1;
+		} else if (SourcePixelFormat == dm_420_8) {
+			*BlockHeight256BytesY = 16;
+			*BlockHeight256BytesC = 8;
+		} else {
+			*BlockHeight256BytesY = 8;
+			*BlockHeight256BytesC = 8;
+		}
+		*BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
+		*BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
+	}
+	return true;
+}
+
+static double CalculateTWait(
+		unsigned int PrefetchMode,
+		double DRAMClockChangeLatency,
+		double UrgentLatency,
+		double SREnterPlusExitTime)
+{
+	if (PrefetchMode == 0) {
+		return dml_max(
+				DRAMClockChangeLatency + UrgentLatency,
+				dml_max(SREnterPlusExitTime, UrgentLatency));
+	} else if (PrefetchMode == 1) {
+		return dml_max(SREnterPlusExitTime, UrgentLatency);
+	} else {
+		return UrgentLatency;
+	}
+}
+
+static double CalculateRemoteSurfaceFlipDelay(
+		struct display_mode_lib *mode_lib,
+		double VRatio,
+		double SwathWidth,
+		double Bpp,
+		double LineTime,
+		double XFCTSlvVupdateOffset,
+		double XFCTSlvVupdateWidth,
+		double XFCTSlvVreadyOffset,
+		double XFCXBUFLatencyTolerance,
+		double XFCFillBWOverhead,
+		double XFCSlvChunkSize,
+		double XFCBusTransportTime,
+		double TCalc,
+		double TWait,
+		double *SrcActiveDrainRate,
+		double *TInitXFill,
+		double *TslvChk)
+{
+	double TSlvSetup, AvgfillRate, result;
+
+	*SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
+	TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
+	*TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
+	AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
+	*TslvChk = XFCSlvChunkSize / AvgfillRate;
+	dml_print(
+			"DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
+			*SrcActiveDrainRate);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
+	result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
+	dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
+	return result;
+}
+
+static double CalculateWriteBackDISPCLK(
+		enum source_format_class WritebackPixelFormat,
+		double PixelClock,
+		double WritebackHRatio,
+		double WritebackVRatio,
+		unsigned int WritebackLumaHTaps,
+		unsigned int WritebackLumaVTaps,
+		unsigned int WritebackChromaHTaps,
+		unsigned int WritebackChromaVTaps,
+		double WritebackDestinationWidth,
+		unsigned int HTotal,
+		unsigned int WritebackChromaLineBufferWidth)
+{
+	double CalculateWriteBackDISPCLK =
+			1.01 * PixelClock
+					* dml_max(
+							dml_ceil(WritebackLumaHTaps / 4.0, 1)
+									/ WritebackHRatio,
+							dml_max(
+									(WritebackLumaVTaps
+											* dml_ceil(
+													1.0
+															/ WritebackVRatio,
+													1)
+											* dml_ceil(
+													WritebackDestinationWidth
+															/ 4.0,
+													1)
+											+ dml_ceil(
+													WritebackDestinationWidth
+															/ 4.0,
+													1))
+											/ (double) HTotal
+											+ dml_ceil(
+													1.0
+															/ WritebackVRatio,
+													1)
+													* (dml_ceil(
+															WritebackLumaVTaps
+																	/ 4.0,
+															1)
+															+ 4.0)
+													/ (double) HTotal,
+									dml_ceil(
+											1.0
+													/ WritebackVRatio,
+											1)
+											* WritebackDestinationWidth
+											/ (double) HTotal));
+	if (WritebackPixelFormat != dm_444_32) {
+		CalculateWriteBackDISPCLK =
+				dml_max(
+						CalculateWriteBackDISPCLK,
+						1.01 * PixelClock
+								* dml_max(
+										dml_ceil(
+												WritebackChromaHTaps
+														/ 2.0,
+												1)
+												/ (2
+														* WritebackHRatio),
+										dml_max(
+												(WritebackChromaVTaps
+														* dml_ceil(
+																1
+																		/ (2
+																				* WritebackVRatio),
+																1)
+														* dml_ceil(
+																WritebackDestinationWidth
+																		/ 2.0
+																		/ 2.0,
+																1)
+														+ dml_ceil(
+																WritebackDestinationWidth
+																		/ 2.0
+																		/ WritebackChromaLineBufferWidth,
+																1))
+														/ HTotal
+														+ dml_ceil(
+																1
+																		/ (2
+																				* WritebackVRatio),
+																1)
+																* (dml_ceil(
+																		WritebackChromaVTaps
+																				/ 4.0,
+																		1)
+																		+ 4)
+																/ HTotal,
+												dml_ceil(
+														1.0
+																/ (2
+																		* WritebackVRatio),
+														1)
+														* WritebackDestinationWidth
+														/ 2.0
+														/ HTotal)));
+	}
+	return CalculateWriteBackDISPCLK;
+}
+
+static double CalculateWriteBackDelay(
+		enum source_format_class WritebackPixelFormat,
+		double WritebackHRatio,
+		double WritebackVRatio,
+		unsigned int WritebackLumaHTaps,
+		unsigned int WritebackLumaVTaps,
+		unsigned int WritebackChromaHTaps,
+		unsigned int WritebackChromaVTaps,
+		unsigned int WritebackDestinationWidth)
+{
+	double CalculateWriteBackDelay =
+			dml_max(
+					dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
+					WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
+							* dml_ceil(
+									WritebackDestinationWidth
+											/ 4.0,
+									1)
+							+ dml_ceil(1.0 / WritebackVRatio, 1)
+									* (dml_ceil(
+											WritebackLumaVTaps
+													/ 4.0,
+											1) + 4));
+
+	if (WritebackPixelFormat != dm_444_32) {
+		CalculateWriteBackDelay =
+				dml_max(
+						CalculateWriteBackDelay,
+						dml_max(
+								dml_ceil(
+										WritebackChromaHTaps
+												/ 2.0,
+										1)
+										/ (2
+												* WritebackHRatio),
+								WritebackChromaVTaps
+										* dml_ceil(
+												1
+														/ (2
+																* WritebackVRatio),
+												1)
+										* dml_ceil(
+												WritebackDestinationWidth
+														/ 2.0
+														/ 2.0,
+												1)
+										+ dml_ceil(
+												1
+														/ (2
+																* WritebackVRatio),
+												1)
+												* (dml_ceil(
+														WritebackChromaVTaps
+																/ 4.0,
+														1)
+														+ 4)));
+	}
+	return CalculateWriteBackDelay;
+}
+
+static void CalculateActiveRowBandwidth(
+		bool VirtualMemoryEnable,
+		enum source_format_class SourcePixelFormat,
+		double VRatio,
+		bool DCCEnable,
+		double LineTime,
+		unsigned int MetaRowByteLuma,
+		unsigned int MetaRowByteChroma,
+		unsigned int meta_row_height_luma,
+		unsigned int meta_row_height_chroma,
+		unsigned int PixelPTEBytesPerRowLuma,
+		unsigned int PixelPTEBytesPerRowChroma,
+		unsigned int dpte_row_height_luma,
+		unsigned int dpte_row_height_chroma,
+		double *meta_row_bw,
+		double *dpte_row_bw,
+		double *qual_row_bw)
+{
+	if (DCCEnable != true) {
+		*meta_row_bw = 0;
+	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
+				+ VRatio / 2 * MetaRowByteChroma
+						/ (meta_row_height_chroma * LineTime);
+	} else {
+		*meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
+	}
+
+	if (VirtualMemoryEnable != true) {
+		*dpte_row_bw = 0;
+	} else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
+				+ VRatio / 2 * PixelPTEBytesPerRowChroma
+						/ (dpte_row_height_chroma * LineTime);
+	} else {
+		*dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
+	}
+
+	if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
+		*qual_row_bw = *meta_row_bw + *dpte_row_bw;
+	} else {
+		*qual_row_bw = 0;
+	}
+}
+
+static void CalculateFlipSchedule(
+		struct display_mode_lib *mode_lib,
+		double UrgentExtraLatency,
+		double UrgentLatency,
+		unsigned int MaxPageTableLevels,
+		bool VirtualMemoryEnable,
+		double BandwidthAvailableForImmediateFlip,
+		unsigned int TotImmediateFlipBytes,
+		enum source_format_class SourcePixelFormat,
+		unsigned int ImmediateFlipBytes,
+		double LineTime,
+		double Tno_bw,
+		double VRatio,
+		double PDEAndMetaPTEBytesFrame,
+		unsigned int MetaRowByte,
+		unsigned int PixelPTEBytesPerRow,
+		bool DCCEnable,
+		unsigned int dpte_row_height,
+		unsigned int meta_row_height,
+		double qual_row_bw,
+		double *DestinationLinesToRequestVMInImmediateFlip,
+		double *DestinationLinesToRequestRowInImmediateFlip,
+		double *final_flip_bw,
+		bool *ImmediateFlipSupportedForPipe)
+{
+	double min_row_time = 0.0;
+
+	if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+		*DestinationLinesToRequestVMInImmediateFlip = 0.0;
+		*DestinationLinesToRequestRowInImmediateFlip = 0.0;
+		*final_flip_bw = qual_row_bw;
+		*ImmediateFlipSupportedForPipe = true;
+	} else {
+		double TimeForFetchingMetaPTEImmediateFlip;
+		double TimeForFetchingRowInVBlankImmediateFlip;
+
+		if (VirtualMemoryEnable == true) {
+			mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
+					* ImmediateFlipBytes / TotImmediateFlipBytes;
+			TimeForFetchingMetaPTEImmediateFlip =
+					dml_max(
+							Tno_bw
+									+ PDEAndMetaPTEBytesFrame
+											/ mode_lib->vba.ImmediateFlipBW,
+							dml_max(
+									UrgentExtraLatency
+											+ UrgentLatency
+													* (MaxPageTableLevels
+															- 1),
+									LineTime / 4.0));
+		} else {
+			TimeForFetchingMetaPTEImmediateFlip = 0;
+		}
+
+		*DestinationLinesToRequestVMInImmediateFlip = dml_floor(
+				4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
+				1) / 4.0;
+
+		if ((VirtualMemoryEnable == true || DCCEnable == true)) {
+			mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
+					* ImmediateFlipBytes / TotImmediateFlipBytes;
+			TimeForFetchingRowInVBlankImmediateFlip = dml_max(
+					(MetaRowByte + PixelPTEBytesPerRow)
+							/ mode_lib->vba.ImmediateFlipBW,
+					dml_max(UrgentLatency, LineTime / 4.0));
+		} else {
+			TimeForFetchingRowInVBlankImmediateFlip = 0;
+		}
+
+		*DestinationLinesToRequestRowInImmediateFlip = dml_floor(
+				4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
+				1) / 4.0;
+
+		if (VirtualMemoryEnable == true) {
+			*final_flip_bw =
+					dml_max(
+							PDEAndMetaPTEBytesFrame
+									/ (*DestinationLinesToRequestVMInImmediateFlip
+											* LineTime),
+							(MetaRowByte + PixelPTEBytesPerRow)
+									/ (TimeForFetchingRowInVBlankImmediateFlip
+											* LineTime));
+		} else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
+			*final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
+					/ (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
+		} else {
+			*final_flip_bw = 0;
+		}
+
+		if (VirtualMemoryEnable && !DCCEnable)
+			min_row_time = dpte_row_height * LineTime / VRatio;
+		else if (!VirtualMemoryEnable && DCCEnable)
+			min_row_time = meta_row_height * LineTime / VRatio;
+		else
+			min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
+					/ VRatio;
+
+		if (*DestinationLinesToRequestVMInImmediateFlip >= 8
+				|| *DestinationLinesToRequestRowInImmediateFlip >= 16
+				|| TimeForFetchingMetaPTEImmediateFlip
+						+ 2 * TimeForFetchingRowInVBlankImmediateFlip
+						> min_row_time)
+			*ImmediateFlipSupportedForPipe = false;
+		else
+			*ImmediateFlipSupportedForPipe = true;
+	}
+}
+
+static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
+{
+	unsigned int k;
+
+	//Progressive To dml_ml->vba.Interlace Unit Effect
+	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+		mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
+		if (mode_lib->vba.Interlace[k] == 1
+				&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
+			mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
+		}
+	}
+}
+
+static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
+{
+	switch (ebpp) {
+	case dm_cur_2bit:
+		return 2;
+	case dm_cur_32bit:
+		return 32;
+	case dm_cur_64bit:
+		return 64;
+	default:
+		return 0;
+	}
+}
+
+static unsigned int TruncToValidBPP(
+		double DecimalBPP,
+		bool DSCEnabled,
+		enum output_encoder_class Output,
+		enum output_format_class Format,
+		unsigned int DSCInputBitPerComponent)
+{
+	if (Output == dm_hdmi) {
+		if (Format == dm_420) {
+			if (DecimalBPP >= 18)
+				return 18;
+			else if (DecimalBPP >= 15)
+				return 15;
+			else if (DecimalBPP >= 12)
+				return 12;
+			else
+				return 0;
+		} else if (Format == dm_444) {
+			if (DecimalBPP >= 36)
+				return 36;
+			else if (DecimalBPP >= 30)
+				return 30;
+			else if (DecimalBPP >= 24)
+				return 24;
+			else
+				return 0;
+		} else {
+			if (DecimalBPP / 1.5 >= 24)
+				return 24;
+			else if (DecimalBPP / 1.5 >= 20)
+				return 20;
+			else if (DecimalBPP / 1.5 >= 16)
+				return 16;
+			else
+				return 0;
+		}
+	} else {
+		if (DSCEnabled) {
+			if (Format == dm_420) {
+				if (DecimalBPP < 6)
+					return 0;
+				else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
+					return 1.5 * DSCInputBitPerComponent - 1 / 16;
+				else
+					return dml_floor(16 * DecimalBPP, 1) / 16;
+			} else if (Format == dm_n422) {
+				if (DecimalBPP < 7)
+					return 0;
+				else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
+					return 2 * DSCInputBitPerComponent - 1 / 16;
+				else
+					return dml_floor(16 * DecimalBPP, 1) / 16;
+			} else {
+				if (DecimalBPP < 8)
+					return 0;
+				else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
+					return 3 * DSCInputBitPerComponent - 1 / 16;
+				else
+					return dml_floor(16 * DecimalBPP, 1) / 16;
+			}
+		} else if (Format == dm_420) {
+			if (DecimalBPP >= 18)
+				return 18;
+			else if (DecimalBPP >= 15)
+				return 15;
+			else if (DecimalBPP >= 12)
+				return 12;
+			else
+				return 0;
+		} else if (Format == dm_s422 || Format == dm_n422) {
+			if (DecimalBPP >= 24)
+				return 24;
+			else if (DecimalBPP >= 20)
+				return 20;
+			else if (DecimalBPP >= 16)
+				return 16;
+			else
+				return 0;
+		} else {
+			if (DecimalBPP >= 36)
+				return 36;
+			else if (DecimalBPP >= 30)
+				return 30;
+			else if (DecimalBPP >= 24)
+				return 24;
+			else
+				return 0;
+		}
+	}
+}
+
+static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
+{
+	int i;
+	unsigned int j, k;
+	/*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
+
+	/*Scale Ratio, taps Support Check*/
+
+	mode_lib->vba.ScaleRatioAndTapsSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.ScalerEnabled[k] == false
+				&& ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
+						|| mode_lib->vba.HRatio[k] != 1.0
+						|| mode_lib->vba.htaps[k] != 1.0
+						|| mode_lib->vba.VRatio[k] != 1.0
+						|| mode_lib->vba.vtaps[k] != 1.0)) {
+			mode_lib->vba.ScaleRatioAndTapsSupport = false;
+		} else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
+				|| mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
+				|| (mode_lib->vba.htaps[k] > 1.0
+						&& (mode_lib->vba.htaps[k] % 2) == 1)
+				|| mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
+				|| mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
+				|| mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
+				|| mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
+				|| (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
+						&& (mode_lib->vba.HRatio[k] / 2.0
+								> mode_lib->vba.HTAPsChroma[k]
+								|| mode_lib->vba.VRatio[k] / 2.0
+										> mode_lib->vba.VTAPsChroma[k]))) {
+			mode_lib->vba.ScaleRatioAndTapsSupport = false;
+		}
+	}
+	/*Source Format, Pixel Format and Scan Support Check*/
+
+	mode_lib->vba.SourceFormatPixelAndScanSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+				&& mode_lib->vba.SourceScan[k] != dm_horz)
+				|| ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
+				|| (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
+						&& (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
+								|| mode_lib->vba.SourcePixelFormat[k]
+										== dm_420_8
+								|| mode_lib->vba.SourcePixelFormat[k]
+										== dm_420_10))
+				|| (((mode_lib->vba.SurfaceTiling[k]
+						== dm_sw_gfx7_2d_thin_gl
+						|| mode_lib->vba.SurfaceTiling[k]
+								== dm_sw_gfx7_2d_thin_lvp)
+						&& !((mode_lib->vba.SourcePixelFormat[k]
+								== dm_444_64
+								|| mode_lib->vba.SourcePixelFormat[k]
+										== dm_444_32)
+								&& mode_lib->vba.SourceScan[k]
+										== dm_horz
+								&& mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
+										== true
+								&& mode_lib->vba.DCCEnable[k]
+										== false))
+						|| (mode_lib->vba.DCCEnable[k] == true
+								&& (mode_lib->vba.SurfaceTiling[k]
+										== dm_sw_linear
+										|| mode_lib->vba.SourcePixelFormat[k]
+												== dm_420_8
+										|| mode_lib->vba.SourcePixelFormat[k]
+												== dm_420_10)))) {
+			mode_lib->vba.SourceFormatPixelAndScanSupport = false;
+		}
+	}
+	/*Bandwidth Support Check*/
+
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
+		} else {
+			mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
+		}
+		if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+			mode_lib->vba.BytePerPixelInDETY[k] = 8.0;
+			mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+			mode_lib->vba.BytePerPixelInDETY[k] = 4.0;
+			mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
+			mode_lib->vba.BytePerPixelInDETY[k] = 2.0;
+			mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
+			mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
+			mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+		} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+			mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
+			mode_lib->vba.BytePerPixelInDETC[k] = 2.0;
+		} else {
+			mode_lib->vba.BytePerPixelInDETY[k] = 4.0 / 3;
+			mode_lib->vba.BytePerPixelInDETC[k] = 8.0 / 3;
+		}
+	}
+	mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = 0.0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.SwathWidthYSingleDPP[k]
+				* (dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
+						* mode_lib->vba.VRatio[k]
+						+ dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
+								/ 2.0 * mode_lib->vba.VRatio[k] / 2)
+				/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+		if (mode_lib->vba.DCCEnable[k] == true) {
+			mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+					* (1 + 1 / 256);
+		}
+		if (mode_lib->vba.VirtualMemoryEnable == true
+				&& mode_lib->vba.SourceScan[k] != dm_horz
+				&& (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x)) {
+			mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+					* (1 + 1 / 64);
+		} else if (mode_lib->vba.VirtualMemoryEnable == true
+				&& mode_lib->vba.SourceScan[k] == dm_horz
+				&& (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+						|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32)
+				&& (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_t
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
+						|| mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x)) {
+			mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+					* (1 + 1 / 256);
+		} else if (mode_lib->vba.VirtualMemoryEnable == true) {
+			mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+					* (1 + 1 / 512);
+		}
+		mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond =
+				mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
+						+ mode_lib->vba.ReadBandwidth[k] / 1000.0;
+	}
+	mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = 0.0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true
+				&& mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+			mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+					* mode_lib->vba.WritebackDestinationHeight[k]
+					/ (mode_lib->vba.WritebackSourceHeight[k]
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]) * 4.0;
+		} else if (mode_lib->vba.WritebackEnable[k] == true
+				&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+			mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+					* mode_lib->vba.WritebackDestinationHeight[k]
+					/ (mode_lib->vba.WritebackSourceHeight[k]
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]) * 3.0;
+		} else if (mode_lib->vba.WritebackEnable[k] == true) {
+			mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+					* mode_lib->vba.WritebackDestinationHeight[k]
+					/ (mode_lib->vba.WritebackSourceHeight[k]
+							* mode_lib->vba.HTotal[k]
+							/ mode_lib->vba.PixelClock[k]) * 1.5;
+		} else {
+			mode_lib->vba.WriteBandwidth[k] = 0.0;
+		}
+		mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond =
+				mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond
+						+ mode_lib->vba.WriteBandwidth[k] / 1000.0;
+	}
+	mode_lib->vba.TotalBandwidthConsumedGBytePerSecond =
+			mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
+					+ mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond;
+	mode_lib->vba.DCCEnabledInAnyPlane = false;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.DCCEnable[k] == true) {
+			mode_lib->vba.DCCEnabledInAnyPlane = true;
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.FabricAndDRAMBandwidthPerState[i] = dml_min(
+				mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+						* mode_lib->vba.DRAMChannelWidth,
+				mode_lib->vba.FabricClockPerState[i]
+						* mode_lib->vba.FabricDatapathToDCNDataReturn)
+				/ 1000;
+		mode_lib->vba.ReturnBWToDCNPerState = dml_min(
+				mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
+				mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0)
+				* mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
+				/ 100;
+		mode_lib->vba.ReturnBWPerState[i] = mode_lib->vba.ReturnBWToDCNPerState;
+		if (mode_lib->vba.DCCEnabledInAnyPlane == true
+				&& mode_lib->vba.ReturnBWToDCNPerState
+						> mode_lib->vba.DCFCLKPerState[i]
+								* mode_lib->vba.ReturnBusWidth
+								/ 4.0) {
+			mode_lib->vba.ReturnBWPerState[i] =
+					dml_min(
+							mode_lib->vba.ReturnBWPerState[i],
+							mode_lib->vba.ReturnBWToDCNPerState * 4.0
+									* (1.0
+											- mode_lib->vba.UrgentLatency
+													/ ((mode_lib->vba.ROBBufferSizeInKByte
+															- mode_lib->vba.PixelChunkSizeInKByte)
+															* 1024.0
+															/ (mode_lib->vba.ReturnBWToDCNPerState
+																	- mode_lib->vba.DCFCLKPerState[i]
+																			* mode_lib->vba.ReturnBusWidth
+																			/ 4.0)
+															+ mode_lib->vba.UrgentLatency)));
+		}
+		mode_lib->vba.CriticalPoint =
+				2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
+						* mode_lib->vba.UrgentLatency
+						/ (mode_lib->vba.ReturnBWToDCNPerState
+								* mode_lib->vba.UrgentLatency
+								+ (mode_lib->vba.ROBBufferSizeInKByte
+										- mode_lib->vba.PixelChunkSizeInKByte)
+										* 1024.0);
+		if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
+				&& mode_lib->vba.CriticalPoint < 4.0) {
+			mode_lib->vba.ReturnBWPerState[i] =
+					dml_min(
+							mode_lib->vba.ReturnBWPerState[i],
+							dml_pow(
+									4.0
+											* mode_lib->vba.ReturnBWToDCNPerState
+											* (mode_lib->vba.ROBBufferSizeInKByte
+													- mode_lib->vba.PixelChunkSizeInKByte)
+											* 1024.0
+											* mode_lib->vba.ReturnBusWidth
+											* mode_lib->vba.DCFCLKPerState[i]
+											* mode_lib->vba.UrgentLatency
+											/ (mode_lib->vba.ReturnBWToDCNPerState
+													* mode_lib->vba.UrgentLatency
+													+ (mode_lib->vba.ROBBufferSizeInKByte
+															- mode_lib->vba.PixelChunkSizeInKByte)
+															* 1024.0),
+									2));
+		}
+		mode_lib->vba.ReturnBWToDCNPerState = dml_min(
+				mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
+				mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0);
+		if (mode_lib->vba.DCCEnabledInAnyPlane == true
+				&& mode_lib->vba.ReturnBWToDCNPerState
+						> mode_lib->vba.DCFCLKPerState[i]
+								* mode_lib->vba.ReturnBusWidth
+								/ 4.0) {
+			mode_lib->vba.ReturnBWPerState[i] =
+					dml_min(
+							mode_lib->vba.ReturnBWPerState[i],
+							mode_lib->vba.ReturnBWToDCNPerState * 4.0
+									* (1.0
+											- mode_lib->vba.UrgentLatency
+													/ ((mode_lib->vba.ROBBufferSizeInKByte
+															- mode_lib->vba.PixelChunkSizeInKByte)
+															* 1024.0
+															/ (mode_lib->vba.ReturnBWToDCNPerState
+																	- mode_lib->vba.DCFCLKPerState[i]
+																			* mode_lib->vba.ReturnBusWidth
+																			/ 4.0)
+															+ mode_lib->vba.UrgentLatency)));
+		}
+		mode_lib->vba.CriticalPoint =
+				2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
+						* mode_lib->vba.UrgentLatency
+						/ (mode_lib->vba.ReturnBWToDCNPerState
+								* mode_lib->vba.UrgentLatency
+								+ (mode_lib->vba.ROBBufferSizeInKByte
+										- mode_lib->vba.PixelChunkSizeInKByte)
+										* 1024.0);
+		if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
+				&& mode_lib->vba.CriticalPoint < 4.0) {
+			mode_lib->vba.ReturnBWPerState[i] =
+					dml_min(
+							mode_lib->vba.ReturnBWPerState[i],
+							dml_pow(
+									4.0
+											* mode_lib->vba.ReturnBWToDCNPerState
+											* (mode_lib->vba.ROBBufferSizeInKByte
+													- mode_lib->vba.PixelChunkSizeInKByte)
+											* 1024.0
+											* mode_lib->vba.ReturnBusWidth
+											* mode_lib->vba.DCFCLKPerState[i]
+											* mode_lib->vba.UrgentLatency
+											/ (mode_lib->vba.ReturnBWToDCNPerState
+													* mode_lib->vba.UrgentLatency
+													+ (mode_lib->vba.ROBBufferSizeInKByte
+															- mode_lib->vba.PixelChunkSizeInKByte)
+															* 1024.0),
+									2));
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		if ((mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond * 1000.0
+				<= mode_lib->vba.ReturnBWPerState[i])
+				&& (mode_lib->vba.TotalBandwidthConsumedGBytePerSecond * 1000.0
+						<= mode_lib->vba.FabricAndDRAMBandwidthPerState[i]
+								* 1000.0
+								* mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
+								/ 100.0)) {
+			mode_lib->vba.BandwidthSupport[i] = true;
+		} else {
+			mode_lib->vba.BandwidthSupport[i] = false;
+		}
+	}
+	/*Writeback Latency support check*/
+
+	mode_lib->vba.WritebackLatencySupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+				if (mode_lib->vba.WriteBandwidth[k]
+						> (mode_lib->vba.WritebackInterfaceLumaBufferSize
+								+ mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ mode_lib->vba.WritebackLatency) {
+					mode_lib->vba.WritebackLatencySupport = false;
+				}
+			} else {
+				if (mode_lib->vba.WriteBandwidth[k]
+						> 1.5
+								* dml_min(
+										mode_lib->vba.WritebackInterfaceLumaBufferSize,
+										2.0
+												* mode_lib->vba.WritebackInterfaceChromaBufferSize)
+								/ mode_lib->vba.WritebackLatency) {
+					mode_lib->vba.WritebackLatencySupport = false;
+				}
+			}
+		}
+	}
+	/*Re-ordering Buffer Support Check*/
+
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
+				(mode_lib->vba.RoundTripPingLatencyCycles + 32.0)
+						/ mode_lib->vba.DCFCLKPerState[i]
+						+ mode_lib->vba.UrgentOutOfOrderReturnPerChannel
+								* mode_lib->vba.NumberOfChannels
+								/ mode_lib->vba.ReturnBWPerState[i];
+		if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte)
+				* 1024.0 / mode_lib->vba.ReturnBWPerState[i]
+				> mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
+			mode_lib->vba.ROBSupport[i] = true;
+		} else {
+			mode_lib->vba.ROBSupport[i] = false;
+		}
+	}
+	/*Writeback Mode Support Check*/
+
+	mode_lib->vba.TotalNumberOfActiveWriteback = 0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			mode_lib->vba.TotalNumberOfActiveWriteback =
+					mode_lib->vba.TotalNumberOfActiveWriteback + 1;
+		}
+	}
+	mode_lib->vba.WritebackModeSupport = true;
+	if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
+		mode_lib->vba.WritebackModeSupport = false;
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true
+				&& mode_lib->vba.Writeback10bpc420Supported != true
+				&& mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+			mode_lib->vba.WritebackModeSupport = false;
+		}
+	}
+	/*Writeback Scale Ratio and Taps Support Check*/
+
+	mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
+					&& (mode_lib->vba.WritebackHRatio[k] != 1.0
+							|| mode_lib->vba.WritebackVRatio[k] != 1.0)) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+			if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
+					|| mode_lib->vba.WritebackVRatio[k]
+							> mode_lib->vba.WritebackMaxVSCLRatio
+					|| mode_lib->vba.WritebackHRatio[k]
+							< mode_lib->vba.WritebackMinHSCLRatio
+					|| mode_lib->vba.WritebackVRatio[k]
+							< mode_lib->vba.WritebackMinVSCLRatio
+					|| mode_lib->vba.WritebackLumaHTaps[k]
+							> mode_lib->vba.WritebackMaxHSCLTaps
+					|| mode_lib->vba.WritebackLumaVTaps[k]
+							> mode_lib->vba.WritebackMaxVSCLTaps
+					|| mode_lib->vba.WritebackHRatio[k]
+							> mode_lib->vba.WritebackLumaHTaps[k]
+					|| mode_lib->vba.WritebackVRatio[k]
+							> mode_lib->vba.WritebackLumaVTaps[k]
+					|| (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
+							&& ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
+									== 1))
+					|| (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
+							&& (mode_lib->vba.WritebackChromaHTaps[k]
+									> mode_lib->vba.WritebackMaxHSCLTaps
+									|| mode_lib->vba.WritebackChromaVTaps[k]
+											> mode_lib->vba.WritebackMaxVSCLTaps
+									|| 2.0
+											* mode_lib->vba.WritebackHRatio[k]
+											> mode_lib->vba.WritebackChromaHTaps[k]
+									|| 2.0
+											* mode_lib->vba.WritebackVRatio[k]
+											> mode_lib->vba.WritebackChromaVTaps[k]
+									|| (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
+										&& ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+			if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
+				mode_lib->vba.WritebackLumaVExtra =
+						dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
+			} else {
+				mode_lib->vba.WritebackLumaVExtra = -1;
+			}
+			if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
+					&& mode_lib->vba.WritebackLumaVTaps[k]
+							> (mode_lib->vba.WritebackLineBufferLumaBufferSize
+									+ mode_lib->vba.WritebackLineBufferChromaBufferSize)
+									/ 3.0
+									/ mode_lib->vba.WritebackDestinationWidth[k]
+									- mode_lib->vba.WritebackLumaVExtra)
+					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
+							&& mode_lib->vba.WritebackLumaVTaps[k]
+									> mode_lib->vba.WritebackLineBufferLumaBufferSize
+											/ mode_lib->vba.WritebackDestinationWidth[k]
+											- mode_lib->vba.WritebackLumaVExtra)
+					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
+							&& mode_lib->vba.WritebackLumaVTaps[k]
+									> mode_lib->vba.WritebackLineBufferLumaBufferSize
+											* 8.0 / 10.0
+											/ mode_lib->vba.WritebackDestinationWidth[k]
+											- mode_lib->vba.WritebackLumaVExtra)) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+			if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
+				mode_lib->vba.WritebackChromaVExtra = 0.0;
+			} else {
+				mode_lib->vba.WritebackChromaVExtra = -1;
+			}
+			if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
+					&& mode_lib->vba.WritebackChromaVTaps[k]
+							> mode_lib->vba.WritebackLineBufferChromaBufferSize
+									/ mode_lib->vba.WritebackDestinationWidth[k]
+									- mode_lib->vba.WritebackChromaVExtra)
+					|| (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
+							&& mode_lib->vba.WritebackChromaVTaps[k]
+									> mode_lib->vba.WritebackLineBufferChromaBufferSize
+											* 8.0 / 10.0
+											/ mode_lib->vba.WritebackDestinationWidth[k]
+											- mode_lib->vba.WritebackChromaVExtra)) {
+				mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+			}
+		}
+	}
+	/*Maximum DISPCLK/DPPCLK Support check*/
+
+	mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.WritebackEnable[k] == true) {
+			mode_lib->vba.WritebackRequiredDISPCLK =
+					dml_max(
+							mode_lib->vba.WritebackRequiredDISPCLK,
+							CalculateWriteBackDISPCLK(
+									mode_lib->vba.WritebackPixelFormat[k],
+									mode_lib->vba.PixelClock[k],
+									mode_lib->vba.WritebackHRatio[k],
+									mode_lib->vba.WritebackVRatio[k],
+									mode_lib->vba.WritebackLumaHTaps[k],
+									mode_lib->vba.WritebackLumaVTaps[k],
+									mode_lib->vba.WritebackChromaHTaps[k],
+									mode_lib->vba.WritebackChromaVTaps[k],
+									mode_lib->vba.WritebackDestinationWidth[k],
+									mode_lib->vba.HTotal[k],
+									mode_lib->vba.WritebackChromaLineBufferWidth));
+		}
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.HRatio[k] > 1.0) {
+			mode_lib->vba.PSCL_FACTOR[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput
+							* mode_lib->vba.HRatio[k]
+							/ dml_ceil(
+									mode_lib->vba.htaps[k]
+											/ 6.0,
+									1.0));
+		} else {
+			mode_lib->vba.PSCL_FACTOR[k] = dml_min(
+					mode_lib->vba.MaxDCHUBToPSCLThroughput,
+					mode_lib->vba.MaxPSCLToLBThroughput);
+		}
+		if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+			mode_lib->vba.PSCL_FACTOR_CHROMA[k] = 0.0;
+			mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
+					mode_lib->vba.PixelClock[k]
+							* dml_max3(
+									mode_lib->vba.vtaps[k] / 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]),
+									mode_lib->vba.HRatio[k]
+											* mode_lib->vba.VRatio[k]
+											/ mode_lib->vba.PSCL_FACTOR[k],
+									1.0);
+			if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
+					&& mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+							< 2.0 * mode_lib->vba.PixelClock[k]) {
+				mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
+						* mode_lib->vba.PixelClock[k];
+			}
+		} else {
+			if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
+				mode_lib->vba.PSCL_FACTOR_CHROMA[k] =
+						dml_min(
+								mode_lib->vba.MaxDCHUBToPSCLThroughput,
+								mode_lib->vba.MaxPSCLToLBThroughput
+										* mode_lib->vba.HRatio[k]
+										/ 2.0
+										/ dml_ceil(
+												mode_lib->vba.HTAPsChroma[k]
+														/ 6.0,
+												1.0));
+			} else {
+				mode_lib->vba.PSCL_FACTOR_CHROMA[k] = dml_min(
+						mode_lib->vba.MaxDCHUBToPSCLThroughput,
+						mode_lib->vba.MaxPSCLToLBThroughput);
+			}
+			mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
+					mode_lib->vba.PixelClock[k]
+							* dml_max5(
+									mode_lib->vba.vtaps[k] / 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]),
+									mode_lib->vba.HRatio[k]
+											* mode_lib->vba.VRatio[k]
+											/ mode_lib->vba.PSCL_FACTOR[k],
+									mode_lib->vba.VTAPsChroma[k]
+											/ 6.0
+											* dml_min(
+													1.0,
+													mode_lib->vba.HRatio[k]
+															/ 2.0),
+									mode_lib->vba.HRatio[k]
+											* mode_lib->vba.VRatio[k]
+											/ 4.0
+											/ mode_lib->vba.PSCL_FACTOR_CHROMA[k],
+									1.0);
+			if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
+					|| mode_lib->vba.HTAPsChroma[k] > 6.0
+					|| mode_lib->vba.VTAPsChroma[k] > 6.0)
+					&& mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+							< 2.0 * mode_lib->vba.PixelClock[k]) {
+				mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
+						* mode_lib->vba.PixelClock[k];
+			}
+		}
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		Calculate256BBlockSizes(
+				mode_lib->vba.SourcePixelFormat[k],
+				mode_lib->vba.SurfaceTiling[k],
+				dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
+				dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
+				&mode_lib->vba.Read256BlockHeightY[k],
+				&mode_lib->vba.Read256BlockHeightC[k],
+				&mode_lib->vba.Read256BlockWidthY[k],
+				&mode_lib->vba.Read256BlockWidthC[k]);
+		if (mode_lib->vba.SourceScan[k] == dm_horz) {
+			mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockHeightY[k];
+			mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockHeightC[k];
+		} else {
+			mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockWidthY[k];
+			mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockWidthC[k];
+		}
+		if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
+				|| mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+					|| (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+							&& (mode_lib->vba.SurfaceTiling[k]
+									== dm_sw_4kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_4kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_t
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_64kb_s_x
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s
+									|| mode_lib->vba.SurfaceTiling[k]
+											== dm_sw_var_s_x)
+							&& mode_lib->vba.SourceScan[k] == dm_horz)) {
+				mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+			} else {
+				mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
+						/ 2.0;
+			}
+			mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+		} else {
+			if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+				mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+				mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
+						/ 2.0;
+				mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+			} else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
+					&& mode_lib->vba.SourceScan[k] == dm_horz) {
+				mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]
+						/ 2.0;
+				mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+			} else {
+				mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+				mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+			}
+		}
+		if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+			mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
+		} else {
+			mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
+		}
+		mode_lib->vba.MaximumSwathWidthInDETBuffer =
+				dml_min(
+						mode_lib->vba.MaximumSwathWidthSupport,
+						mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
+								/ (mode_lib->vba.BytePerPixelInDETY[k]
+										* mode_lib->vba.MinSwathHeightY[k]
+										+ mode_lib->vba.BytePerPixelInDETC[k]
+												/ 2.0
+												* mode_lib->vba.MinSwathHeightC[k]));
+		if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+			mode_lib->vba.MaximumSwathWidthInLineBuffer =
+					mode_lib->vba.LineBufferSize
+							* dml_max(mode_lib->vba.HRatio[k], 1.0)
+							/ mode_lib->vba.LBBitPerPixel[k]
+							/ (mode_lib->vba.vtaps[k]
+									+ dml_max(
+											dml_ceil(
+													mode_lib->vba.VRatio[k],
+													1.0)
+													- 2,
+											0.0));
+		} else {
+			mode_lib->vba.MaximumSwathWidthInLineBuffer =
+					dml_min(
+							mode_lib->vba.LineBufferSize
+									* dml_max(
+											mode_lib->vba.HRatio[k],
+											1.0)
+									/ mode_lib->vba.LBBitPerPixel[k]
+									/ (mode_lib->vba.vtaps[k]
+											+ dml_max(
+													dml_ceil(
+															mode_lib->vba.VRatio[k],
+															1.0)
+															- 2,
+													0.0)),
+							2.0 * mode_lib->vba.LineBufferSize
+									* dml_max(
+											mode_lib->vba.HRatio[k]
+													/ 2.0,
+											1.0)
+									/ mode_lib->vba.LBBitPerPixel[k]
+									/ (mode_lib->vba.VTAPsChroma[k]
+											+ dml_max(
+													dml_ceil(
+															mode_lib->vba.VRatio[k]
+																	/ 2.0,
+															1.0)
+															- 2,
+													0.0)));
+		}
+		mode_lib->vba.MaximumSwathWidth[k] = dml_min(
+				mode_lib->vba.MaximumSwathWidthInDETBuffer,
+				mode_lib->vba.MaximumSwathWidthInLineBuffer);
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
+				mode_lib->vba.MaxDispclk[i],
+				mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+		mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
+				mode_lib->vba.MaxDppclk[i],
+				mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+		mode_lib->vba.RequiredDISPCLK[i] = 0.0;
+		mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
+					mode_lib->vba.PixelClock[k]
+							* (1.0
+									+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+											/ 100.0)
+							* (1.0
+									+ mode_lib->vba.DISPCLKRampingMargin
+											/ 100.0);
+			if (mode_lib->vba.ODMCapability == true
+					&& mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+							> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+				mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
+				mode_lib->vba.PlaneRequiredDISPCLK =
+						mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+								/ 2.0;
+			} else {
+				mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
+				mode_lib->vba.PlaneRequiredDISPCLK =
+						mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+			}
+			if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+					* (1.0
+							+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+									/ 100.0)
+					<= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
+					&& mode_lib->vba.SwathWidthYSingleDPP[k]
+							<= mode_lib->vba.MaximumSwathWidth[k]
+					&& mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
+				mode_lib->vba.NoOfDPP[i][k] = 1;
+				mode_lib->vba.RequiredDPPCLK[i][k] =
+						mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+								* (1.0
+										+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100.0);
+			} else {
+				mode_lib->vba.NoOfDPP[i][k] = 2;
+				mode_lib->vba.RequiredDPPCLK[i][k] =
+						mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+								* (1.0
+										+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100.0)
+								/ 2.0;
+			}
+			mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+					mode_lib->vba.RequiredDISPCLK[i],
+					mode_lib->vba.PlaneRequiredDISPCLK);
+			if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] / mode_lib->vba.NoOfDPP[i][k]
+					* (1.0
+							+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+									/ 100.0)
+					> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+					|| (mode_lib->vba.PlaneRequiredDISPCLK
+							> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+				mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+			}
+		}
+		mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.TotalNumberOfActiveDPP[i] =
+					mode_lib->vba.TotalNumberOfActiveDPP[i]
+							+ mode_lib->vba.NoOfDPP[i][k];
+		}
+		if ((mode_lib->vba.MaxDispclk[i] == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
+				&& mode_lib->vba.MaxDppclk[i]
+						== mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])
+				&& (mode_lib->vba.TotalNumberOfActiveDPP[i]
+						> mode_lib->vba.MaxNumDPP
+						|| mode_lib->vba.DISPCLK_DPPCLK_Support[i] == false)) {
+			mode_lib->vba.RequiredDISPCLK[i] = 0.0;
+			mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
+						mode_lib->vba.PixelClock[k]
+								* (1.0
+										+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+												/ 100.0);
+				if (mode_lib->vba.ODMCapability == true
+						&& mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+								> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+					mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
+					mode_lib->vba.PlaneRequiredDISPCLK =
+							mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+									/ 2.0;
+				} else {
+					mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
+					mode_lib->vba.PlaneRequiredDISPCLK =
+							mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+				}
+				if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+						* (1.0
+								+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+										/ 100.0)
+						<= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
+						&& mode_lib->vba.SwathWidthYSingleDPP[k]
+								<= mode_lib->vba.MaximumSwathWidth[k]
+						&& mode_lib->vba.ODMCombineEnablePerState[i][k]
+								== false) {
+					mode_lib->vba.NoOfDPP[i][k] = 1;
+					mode_lib->vba.RequiredDPPCLK[i][k] =
+							mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+									* (1.0
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0);
+				} else {
+					mode_lib->vba.NoOfDPP[i][k] = 2;
+					mode_lib->vba.RequiredDPPCLK[i][k] =
+							mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+									* (1.0
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0)
+									/ 2.0;
+				}
+				mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+						mode_lib->vba.RequiredDISPCLK[i],
+						mode_lib->vba.PlaneRequiredDISPCLK);
+				if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+						/ mode_lib->vba.NoOfDPP[i][k]
+						* (1.0
+								+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+										/ 100.0)
+						> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+						|| (mode_lib->vba.PlaneRequiredDISPCLK
+								> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+					mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+				}
+			}
+			mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.TotalNumberOfActiveDPP[i] =
+						mode_lib->vba.TotalNumberOfActiveDPP[i]
+								+ mode_lib->vba.NoOfDPP[i][k];
+			}
+		}
+		if (mode_lib->vba.TotalNumberOfActiveDPP[i] > mode_lib->vba.MaxNumDPP) {
+			mode_lib->vba.RequiredDISPCLK[i] = 0.0;
+			mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
+				if (mode_lib->vba.SwathWidthYSingleDPP[k]
+						<= mode_lib->vba.MaximumSwathWidth[k]) {
+					mode_lib->vba.NoOfDPP[i][k] = 1;
+					mode_lib->vba.RequiredDPPCLK[i][k] =
+							mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+									* (1.0
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0);
+				} else {
+					mode_lib->vba.NoOfDPP[i][k] = 2;
+					mode_lib->vba.RequiredDPPCLK[i][k] =
+							mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+									* (1.0
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0)
+									/ 2.0;
+				}
+				if (!(mode_lib->vba.MaxDispclk[i]
+						== mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
+						&& mode_lib->vba.MaxDppclk[i]
+								== mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])) {
+					mode_lib->vba.PlaneRequiredDISPCLK =
+							mode_lib->vba.PixelClock[k]
+									* (1.0
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0)
+									* (1.0
+											+ mode_lib->vba.DISPCLKRampingMargin
+													/ 100.0);
+				} else {
+					mode_lib->vba.PlaneRequiredDISPCLK =
+							mode_lib->vba.PixelClock[k]
+									* (1.0
+											+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0);
+				}
+				mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+						mode_lib->vba.RequiredDISPCLK[i],
+						mode_lib->vba.PlaneRequiredDISPCLK);
+				if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+						/ mode_lib->vba.NoOfDPP[i][k]
+						* (1.0
+								+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+										/ 100.0)
+						> mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+						|| (mode_lib->vba.PlaneRequiredDISPCLK
+								> mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+					mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+				}
+			}
+			mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.TotalNumberOfActiveDPP[i] =
+						mode_lib->vba.TotalNumberOfActiveDPP[i]
+								+ mode_lib->vba.NoOfDPP[i][k];
+			}
+		}
+		mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+				mode_lib->vba.RequiredDISPCLK[i],
+				mode_lib->vba.WritebackRequiredDISPCLK);
+		if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
+				< mode_lib->vba.WritebackRequiredDISPCLK) {
+			mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+		}
+	}
+	/*Viewport Size Check*/
+
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.ViewportSizeSupport[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
+				if (dml_min(
+						mode_lib->vba.SwathWidthYSingleDPP[k],
+						dml_round(
+								mode_lib->vba.HActive[k] / 2.0
+										* mode_lib->vba.HRatio[k]))
+						> mode_lib->vba.MaximumSwathWidth[k]) {
+					mode_lib->vba.ViewportSizeSupport[i] = false;
+				}
+			} else {
+				if (mode_lib->vba.SwathWidthYSingleDPP[k] / 2.0
+						> mode_lib->vba.MaximumSwathWidth[k]) {
+					mode_lib->vba.ViewportSizeSupport[i] = false;
+				}
+			}
+		}
+	}
+	/*Total Available Pipes Support Check*/
+
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		if (mode_lib->vba.TotalNumberOfActiveDPP[i] <= mode_lib->vba.MaxNumDPP) {
+			mode_lib->vba.TotalAvailablePipesSupport[i] = true;
+		} else {
+			mode_lib->vba.TotalAvailablePipesSupport[i] = false;
+		}
+	}
+	/*Total Available OTG Support Check*/
+
+	mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.BlendingAndTiming[k] == k) {
+			mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+					+ 1.0;
+		}
+	}
+	if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
+		mode_lib->vba.NumberOfOTGSupport = true;
+	} else {
+		mode_lib->vba.NumberOfOTGSupport = false;
+	}
+	/*Display IO and DSC Support Check*/
+
+	mode_lib->vba.NonsupportedDSCInputBPC = false;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
+				|| mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
+				|| mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
+			mode_lib->vba.NonsupportedDSCInputBPC = true;
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.RequiresDSC[i][k] = 0;
+			mode_lib->vba.RequiresFEC[i][k] = 0;
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				if (mode_lib->vba.Output[k] == dm_hdmi) {
+					mode_lib->vba.RequiresDSC[i][k] = 0;
+					mode_lib->vba.RequiresFEC[i][k] = 0;
+					mode_lib->vba.OutputBppPerState[i][k] =
+							TruncToValidBPP(
+									dml_min(
+											600.0,
+											mode_lib->vba.PHYCLKPerState[i])
+											/ mode_lib->vba.PixelClockBackEnd[k]
+											* 24,
+									false,
+									mode_lib->vba.Output[k],
+									mode_lib->vba.OutputFormat[k],
+									mode_lib->vba.DSCInputBitPerComponent[k]);
+				} else if (mode_lib->vba.Output[k] == dm_dp
+						|| mode_lib->vba.Output[k] == dm_edp) {
+					if (mode_lib->vba.Output[k] == dm_edp) {
+						mode_lib->vba.EffectiveFECOverhead = 0.0;
+					} else {
+						mode_lib->vba.EffectiveFECOverhead =
+								mode_lib->vba.FECOverhead;
+					}
+					if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
+						mode_lib->vba.Outbpp =
+								TruncToValidBPP(
+										(1.0
+												- mode_lib->vba.Downspreading
+														/ 100.0)
+												* 270.0
+												* mode_lib->vba.OutputLinkDPLanes[k]
+												/ mode_lib->vba.PixelClockBackEnd[k]
+												* 8.0,
+										false,
+										mode_lib->vba.Output[k],
+										mode_lib->vba.OutputFormat[k],
+										mode_lib->vba.DSCInputBitPerComponent[k]);
+						mode_lib->vba.OutbppDSC =
+								TruncToValidBPP(
+										(1.0
+												- mode_lib->vba.Downspreading
+														/ 100.0)
+												* (1.0
+														- mode_lib->vba.EffectiveFECOverhead
+																/ 100.0)
+												* 270.0
+												* mode_lib->vba.OutputLinkDPLanes[k]
+												/ mode_lib->vba.PixelClockBackEnd[k]
+												* 8.0,
+										true,
+										mode_lib->vba.Output[k],
+										mode_lib->vba.OutputFormat[k],
+										mode_lib->vba.DSCInputBitPerComponent[k]);
+						if (mode_lib->vba.DSCEnabled[k] == true) {
+							mode_lib->vba.RequiresDSC[i][k] = true;
+							if (mode_lib->vba.Output[k] == dm_dp) {
+								mode_lib->vba.RequiresFEC[i][k] =
+										true;
+							} else {
+								mode_lib->vba.RequiresFEC[i][k] =
+										false;
+							}
+							mode_lib->vba.Outbpp =
+									mode_lib->vba.OutbppDSC;
+						} else {
+							mode_lib->vba.RequiresDSC[i][k] = false;
+							mode_lib->vba.RequiresFEC[i][k] = false;
+						}
+						mode_lib->vba.OutputBppPerState[i][k] =
+								mode_lib->vba.Outbpp;
+					}
+					if (mode_lib->vba.Outbpp == 0) {
+						mode_lib->vba.Outbpp =
+								TruncToValidBPP(
+										(1.0
+												- mode_lib->vba.Downspreading
+														/ 100.0)
+												* 540.0
+												* mode_lib->vba.OutputLinkDPLanes[k]
+												/ mode_lib->vba.PixelClockBackEnd[k]
+												* 8.0,
+										false,
+										mode_lib->vba.Output[k],
+										mode_lib->vba.OutputFormat[k],
+										mode_lib->vba.DSCInputBitPerComponent[k]);
+						mode_lib->vba.OutbppDSC =
+								TruncToValidBPP(
+										(1.0
+												- mode_lib->vba.Downspreading
+														/ 100.0)
+												* (1.0
+														- mode_lib->vba.EffectiveFECOverhead
+																/ 100.0)
+												* 540.0
+												* mode_lib->vba.OutputLinkDPLanes[k]
+												/ mode_lib->vba.PixelClockBackEnd[k]
+												* 8.0,
+										true,
+										mode_lib->vba.Output[k],
+										mode_lib->vba.OutputFormat[k],
+										mode_lib->vba.DSCInputBitPerComponent[k]);
+						if (mode_lib->vba.DSCEnabled[k] == true) {
+							mode_lib->vba.RequiresDSC[i][k] = true;
+							if (mode_lib->vba.Output[k] == dm_dp) {
+								mode_lib->vba.RequiresFEC[i][k] =
+										true;
+							} else {
+								mode_lib->vba.RequiresFEC[i][k] =
+										false;
+							}
+							mode_lib->vba.Outbpp =
+									mode_lib->vba.OutbppDSC;
+						} else {
+							mode_lib->vba.RequiresDSC[i][k] = false;
+							mode_lib->vba.RequiresFEC[i][k] = false;
+						}
+						mode_lib->vba.OutputBppPerState[i][k] =
+								mode_lib->vba.Outbpp;
+					}
+					if (mode_lib->vba.Outbpp == 0
+							&& mode_lib->vba.PHYCLKPerState[i]
+									>= 810.0) {
+						mode_lib->vba.Outbpp =
+								TruncToValidBPP(
+										(1.0
+												- mode_lib->vba.Downspreading
+														/ 100.0)
+												* 810.0
+												* mode_lib->vba.OutputLinkDPLanes[k]
+												/ mode_lib->vba.PixelClockBackEnd[k]
+												* 8.0,
+										false,
+										mode_lib->vba.Output[k],
+										mode_lib->vba.OutputFormat[k],
+										mode_lib->vba.DSCInputBitPerComponent[k]);
+						mode_lib->vba.OutbppDSC =
+								TruncToValidBPP(
+										(1.0
+												- mode_lib->vba.Downspreading
+														/ 100.0)
+												* (1.0
+														- mode_lib->vba.EffectiveFECOverhead
+																/ 100.0)
+												* 810.0
+												* mode_lib->vba.OutputLinkDPLanes[k]
+												/ mode_lib->vba.PixelClockBackEnd[k]
+												* 8.0,
+										true,
+										mode_lib->vba.Output[k],
+										mode_lib->vba.OutputFormat[k],
+										mode_lib->vba.DSCInputBitPerComponent[k]);
+						if (mode_lib->vba.DSCEnabled[k] == true
+								|| mode_lib->vba.Outbpp == 0) {
+							mode_lib->vba.RequiresDSC[i][k] = true;
+							if (mode_lib->vba.Output[k] == dm_dp) {
+								mode_lib->vba.RequiresFEC[i][k] =
+										true;
+							} else {
+								mode_lib->vba.RequiresFEC[i][k] =
+										false;
+							}
+							mode_lib->vba.Outbpp =
+									mode_lib->vba.OutbppDSC;
+						} else {
+							mode_lib->vba.RequiresDSC[i][k] = false;
+							mode_lib->vba.RequiresFEC[i][k] = false;
+						}
+						mode_lib->vba.OutputBppPerState[i][k] =
+								mode_lib->vba.Outbpp;
+					}
+				}
+			} else {
+				mode_lib->vba.OutputBppPerState[i][k] = 0;
+			}
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.DIOSupport[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.OutputBppPerState[i][k] == 0
+					|| (mode_lib->vba.OutputFormat[k] == dm_420
+							&& mode_lib->vba.ProgressiveToInterlaceUnitInOPP
+									== true)) {
+				mode_lib->vba.DIOSupport[i] = false;
+			}
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = false;
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				if ((mode_lib->vba.Output[k] == dm_dp
+						|| mode_lib->vba.Output[k] == dm_edp)) {
+					if (mode_lib->vba.OutputFormat[k] == dm_420
+							|| mode_lib->vba.OutputFormat[k]
+									== dm_n422) {
+						mode_lib->vba.DSCFormatFactor = 2;
+					} else {
+						mode_lib->vba.DSCFormatFactor = 1;
+					}
+					if (mode_lib->vba.RequiresDSC[i][k] == true) {
+						if (mode_lib->vba.ODMCombineEnablePerState[i][k]
+								== true) {
+							if (mode_lib->vba.PixelClockBackEnd[k] / 6.0
+									/ mode_lib->vba.DSCFormatFactor
+									> (1.0
+											- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0)
+											* mode_lib->vba.MaxDSCCLK[i]) {
+								mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
+										true;
+							}
+						} else {
+							if (mode_lib->vba.PixelClockBackEnd[k] / 3.0
+									/ mode_lib->vba.DSCFormatFactor
+									> (1.0
+											- mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+													/ 100.0)
+											* mode_lib->vba.MaxDSCCLK[i]) {
+								mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
+										true;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.NotEnoughDSCUnits[i] = false;
+		mode_lib->vba.TotalDSCUnitsRequired = 0.0;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.RequiresDSC[i][k] == true) {
+				if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
+					mode_lib->vba.TotalDSCUnitsRequired =
+							mode_lib->vba.TotalDSCUnitsRequired + 2.0;
+				} else {
+					mode_lib->vba.TotalDSCUnitsRequired =
+							mode_lib->vba.TotalDSCUnitsRequired + 1.0;
+				}
+			}
+		}
+		if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
+			mode_lib->vba.NotEnoughDSCUnits[i] = true;
+		}
+	}
+	/*DSC Delay per state*/
+
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.BlendingAndTiming[k] != k) {
+				mode_lib->vba.slices = 0;
+			} else if (mode_lib->vba.RequiresDSC[i][k] == 0
+					|| mode_lib->vba.RequiresDSC[i][k] == false) {
+				mode_lib->vba.slices = 0;
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
+				mode_lib->vba.slices = dml_ceil(
+						mode_lib->vba.PixelClockBackEnd[k] / 400.0,
+						4.0);
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
+				mode_lib->vba.slices = 8.0;
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
+				mode_lib->vba.slices = 4.0;
+			} else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
+				mode_lib->vba.slices = 2.0;
+			} else {
+				mode_lib->vba.slices = 1.0;
+			}
+			if (mode_lib->vba.OutputBppPerState[i][k] == 0
+					|| mode_lib->vba.OutputBppPerState[i][k] == 0) {
+				mode_lib->vba.bpp = 0.0;
+			} else {
+				mode_lib->vba.bpp = mode_lib->vba.OutputBppPerState[i][k];
+			}
+			if (mode_lib->vba.RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
+				if (mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
+					mode_lib->vba.DSCDelayPerState[i][k] =
+							dscceComputeDelay(
+									mode_lib->vba.DSCInputBitPerComponent[k],
+									mode_lib->vba.bpp,
+									dml_ceil(
+											mode_lib->vba.HActive[k]
+													/ mode_lib->vba.slices,
+											1.0),
+									mode_lib->vba.slices,
+									mode_lib->vba.OutputFormat[k])
+									+ dscComputeDelay(
+											mode_lib->vba.OutputFormat[k]);
+				} else {
+					mode_lib->vba.DSCDelayPerState[i][k] =
+							2.0
+									* (dscceComputeDelay(
+											mode_lib->vba.DSCInputBitPerComponent[k],
+											mode_lib->vba.bpp,
+											dml_ceil(
+													mode_lib->vba.HActive[k]
+															/ mode_lib->vba.slices,
+													1.0),
+											mode_lib->vba.slices
+													/ 2,
+											mode_lib->vba.OutputFormat[k])
+											+ dscComputeDelay(
+													mode_lib->vba.OutputFormat[k]));
+				}
+				mode_lib->vba.DSCDelayPerState[i][k] =
+						mode_lib->vba.DSCDelayPerState[i][k]
+								* mode_lib->vba.PixelClock[k]
+								/ mode_lib->vba.PixelClockBackEnd[k];
+			} else {
+				mode_lib->vba.DSCDelayPerState[i][k] = 0.0;
+			}
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+				if (mode_lib->vba.BlendingAndTiming[k] == j
+						&& mode_lib->vba.RequiresDSC[i][j] == true) {
+					mode_lib->vba.DSCDelayPerState[i][k] =
+							mode_lib->vba.DSCDelayPerState[i][j];
+				}
+			}
+		}
+	}
+	/*Urgent Latency Support Check*/
+
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+			if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
+				mode_lib->vba.SwathWidthYPerState[i][k] =
+						dml_min(
+								mode_lib->vba.SwathWidthYSingleDPP[k],
+								dml_round(
+										mode_lib->vba.HActive[k]
+												/ 2.0
+												* mode_lib->vba.HRatio[k]));
+			} else {
+				mode_lib->vba.SwathWidthYPerState[i][k] =
+						mode_lib->vba.SwathWidthYSingleDPP[k]
+								/ mode_lib->vba.NoOfDPP[i][k];
+			}
+			mode_lib->vba.SwathWidthGranularityY = 256.0
+					/ dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
+					/ mode_lib->vba.MaxSwathHeightY[k];
+			mode_lib->vba.RoundedUpMaxSwathSizeBytesY = (dml_ceil(
+					mode_lib->vba.SwathWidthYPerState[i][k] - 1.0,
+					mode_lib->vba.SwathWidthGranularityY)
+					+ mode_lib->vba.SwathWidthGranularityY)
+					* mode_lib->vba.BytePerPixelInDETY[k]
+					* mode_lib->vba.MaxSwathHeightY[k];
+			if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+				mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil(
+						mode_lib->vba.RoundedUpMaxSwathSizeBytesY,
+						256.0) + 256;
+			}
+			if (mode_lib->vba.MaxSwathHeightC[k] > 0.0) {
+				mode_lib->vba.SwathWidthGranularityC = 256.0
+						/ dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
+						/ mode_lib->vba.MaxSwathHeightC[k];
+				mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil(
+						mode_lib->vba.SwathWidthYPerState[i][k] / 2.0 - 1.0,
+						mode_lib->vba.SwathWidthGranularityC)
+						+ mode_lib->vba.SwathWidthGranularityC)
+						* mode_lib->vba.BytePerPixelInDETC[k]
+						* mode_lib->vba.MaxSwathHeightC[k];
+				if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+					mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil(
+							mode_lib->vba.RoundedUpMaxSwathSizeBytesC,
+							256.0) + 256;
+				}
+			} else {
+				mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0;
+			}
+			if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY
+					+ mode_lib->vba.RoundedUpMaxSwathSizeBytesC
+					<= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
+				mode_lib->vba.SwathHeightYPerState[i][k] =
+						mode_lib->vba.MaxSwathHeightY[k];
+				mode_lib->vba.SwathHeightCPerState[i][k] =
+						mode_lib->vba.MaxSwathHeightC[k];
+			} else {
+				mode_lib->vba.SwathHeightYPerState[i][k] =
+						mode_lib->vba.MinSwathHeightY[k];
+				mode_lib->vba.SwathHeightCPerState[i][k] =
+						mode_lib->vba.MinSwathHeightC[k];
+			}
+			if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+				mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
+						* 1024.0 / mode_lib->vba.BytePerPixelInDETY[k]
+						/ mode_lib->vba.SwathWidthYPerState[i][k];
+				mode_lib->vba.LinesInDETChroma = 0.0;
+			} else if (mode_lib->vba.SwathHeightYPerState[i][k]
+					<= mode_lib->vba.SwathHeightCPerState[i][k]) {
+				mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
+						* 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETY[k]
+						/ mode_lib->vba.SwathWidthYPerState[i][k];
+				mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
+						* 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETC[k]
+						/ (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
+			} else {
+				mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
+						* 1024.0 * 2.0 / 3.0
+						/ mode_lib->vba.BytePerPixelInDETY[k]
+						/ mode_lib->vba.SwathWidthYPerState[i][k];
+				mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
+						* 1024.0 / 3.0 / mode_lib->vba.BytePerPixelInDETY[k]
+						/ (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
+			}
+			mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma =
+					dml_min(
+							mode_lib->vba.MaxLineBufferLines,
+							dml_floor(
+									mode_lib->vba.LineBufferSize
+											/ mode_lib->vba.LBBitPerPixel[k]
+											/ (mode_lib->vba.SwathWidthYPerState[i][k]
+													/ dml_max(
+															mode_lib->vba.HRatio[k],
+															1.0)),
+									1.0))
+							- (mode_lib->vba.vtaps[k] - 1.0);
+			mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma =
+					dml_min(
+							mode_lib->vba.MaxLineBufferLines,
+							dml_floor(
+									mode_lib->vba.LineBufferSize
+											/ mode_lib->vba.LBBitPerPixel[k]
+											/ (mode_lib->vba.SwathWidthYPerState[i][k]
+													/ 2.0
+													/ dml_max(
+															mode_lib->vba.HRatio[k]
+																	/ 2.0,
+															1.0)),
+									1.0))
+							- (mode_lib->vba.VTAPsChroma[k] - 1.0);
+			mode_lib->vba.EffectiveDETLBLinesLuma =
+					dml_floor(
+							mode_lib->vba.LinesInDETLuma
+									+ dml_min(
+											mode_lib->vba.LinesInDETLuma
+													* mode_lib->vba.RequiredDISPCLK[i]
+													* mode_lib->vba.BytePerPixelInDETY[k]
+													* mode_lib->vba.PSCL_FACTOR[k]
+													/ mode_lib->vba.ReturnBWPerState[i],
+											mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
+							mode_lib->vba.SwathHeightYPerState[i][k]);
+			mode_lib->vba.EffectiveDETLBLinesChroma =
+					dml_floor(
+							mode_lib->vba.LinesInDETChroma
+									+ dml_min(
+											mode_lib->vba.LinesInDETChroma
+													* mode_lib->vba.RequiredDISPCLK[i]
+													* mode_lib->vba.BytePerPixelInDETC[k]
+													* mode_lib->vba.PSCL_FACTOR_CHROMA[k]
+													/ mode_lib->vba.ReturnBWPerState[i],
+											mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
+							mode_lib->vba.SwathHeightCPerState[i][k]);
+			if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+				mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
+						mode_lib->vba.EffectiveDETLBLinesLuma
+								* (mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k])
+								/ mode_lib->vba.VRatio[k]
+								- mode_lib->vba.EffectiveDETLBLinesLuma
+										* mode_lib->vba.SwathWidthYPerState[i][k]
+										* dml_ceil(
+												mode_lib->vba.BytePerPixelInDETY[k],
+												1.0)
+										/ (mode_lib->vba.ReturnBWPerState[i]
+												/ mode_lib->vba.NoOfDPP[i][k]);
+			} else {
+				mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
+						dml_min(
+								mode_lib->vba.EffectiveDETLBLinesLuma
+										* (mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k])
+										/ mode_lib->vba.VRatio[k]
+										- mode_lib->vba.EffectiveDETLBLinesLuma
+												* mode_lib->vba.SwathWidthYPerState[i][k]
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETY[k],
+														1.0)
+												/ (mode_lib->vba.ReturnBWPerState[i]
+														/ mode_lib->vba.NoOfDPP[i][k]),
+								mode_lib->vba.EffectiveDETLBLinesChroma
+										* (mode_lib->vba.HTotal[k]
+												/ mode_lib->vba.PixelClock[k])
+										/ (mode_lib->vba.VRatio[k]
+												/ 2.0)
+										- mode_lib->vba.EffectiveDETLBLinesChroma
+												* mode_lib->vba.SwathWidthYPerState[i][k]
+												/ 2.0
+												* dml_ceil(
+														mode_lib->vba.BytePerPixelInDETC[k],
+														2.0)
+												/ (mode_lib->vba.ReturnBWPerState[i]
+														/ mode_lib->vba.NoOfDPP[i][k]));
+			}
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.UrgentLatencySupport[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.UrgentLatencySupportUsPerState[i][k]
+					< mode_lib->vba.UrgentLatency / 1.0) {
+				mode_lib->vba.UrgentLatencySupport[i] = false;
+			}
+		}
+	}
+	/*Prefetch Check*/
+
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = 0.0;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.DCCEnable[k] == true) {
+				mode_lib->vba.TotalNumberOfDCCActiveDPP[i] =
+						mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
+								+ mode_lib->vba.NoOfDPP[i][k];
+			}
+		}
+	}
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.ProjectedDCFCLKDeepSleep = 8.0;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
+					mode_lib->vba.ProjectedDCFCLKDeepSleep,
+					mode_lib->vba.PixelClock[k] / 16.0);
+			if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+				if (mode_lib->vba.VRatio[k] <= 1.0) {
+					mode_lib->vba.ProjectedDCFCLKDeepSleep =
+							dml_max(
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									1.1
+											* dml_ceil(
+													mode_lib->vba.BytePerPixelInDETY[k],
+													1.0)
+											/ 64.0
+											* mode_lib->vba.HRatio[k]
+											* mode_lib->vba.PixelClock[k]
+											/ mode_lib->vba.NoOfDPP[i][k]);
+				} else {
+					mode_lib->vba.ProjectedDCFCLKDeepSleep =
+							dml_max(
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									1.1
+											* dml_ceil(
+													mode_lib->vba.BytePerPixelInDETY[k],
+													1.0)
+											/ 64.0
+											* mode_lib->vba.PSCL_FACTOR[k]
+											* mode_lib->vba.RequiredDPPCLK[i][k]);
+				}
+			} else {
+				if (mode_lib->vba.VRatio[k] <= 1.0) {
+					mode_lib->vba.ProjectedDCFCLKDeepSleep =
+							dml_max(
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									1.1
+											* dml_ceil(
+													mode_lib->vba.BytePerPixelInDETY[k],
+													1.0)
+											/ 32.0
+											* mode_lib->vba.HRatio[k]
+											* mode_lib->vba.PixelClock[k]
+											/ mode_lib->vba.NoOfDPP[i][k]);
+				} else {
+					mode_lib->vba.ProjectedDCFCLKDeepSleep =
+							dml_max(
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									1.1
+											* dml_ceil(
+													mode_lib->vba.BytePerPixelInDETY[k],
+													1.0)
+											/ 32.0
+											* mode_lib->vba.PSCL_FACTOR[k]
+											* mode_lib->vba.RequiredDPPCLK[i][k]);
+				}
+				if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
+					mode_lib->vba.ProjectedDCFCLKDeepSleep =
+							dml_max(
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									1.1
+											* dml_ceil(
+													mode_lib->vba.BytePerPixelInDETC[k],
+													2.0)
+											/ 32.0
+											* mode_lib->vba.HRatio[k]
+											/ 2.0
+											* mode_lib->vba.PixelClock[k]
+											/ mode_lib->vba.NoOfDPP[i][k]);
+				} else {
+					mode_lib->vba.ProjectedDCFCLKDeepSleep =
+							dml_max(
+									mode_lib->vba.ProjectedDCFCLKDeepSleep,
+									1.1
+											* dml_ceil(
+													mode_lib->vba.BytePerPixelInDETC[k],
+													2.0)
+											/ 32.0
+											* mode_lib->vba.PSCL_FACTOR_CHROMA[k]
+											* mode_lib->vba.RequiredDPPCLK[i][k]);
+				}
+			}
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
+					mode_lib,
+					mode_lib->vba.DCCEnable[k],
+					mode_lib->vba.Read256BlockHeightY[k],
+					mode_lib->vba.Read256BlockWidthY[k],
+					mode_lib->vba.SourcePixelFormat[k],
+					mode_lib->vba.SurfaceTiling[k],
+					dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
+					mode_lib->vba.SourceScan[k],
+					mode_lib->vba.ViewportWidth[k],
+					mode_lib->vba.ViewportHeight[k],
+					mode_lib->vba.SwathWidthYPerState[i][k],
+					mode_lib->vba.VirtualMemoryEnable,
+					mode_lib->vba.VMMPageSize,
+					mode_lib->vba.PTEBufferSizeInRequests,
+					mode_lib->vba.PDEProcessingBufIn64KBReqs,
+					mode_lib->vba.PitchY[k],
+					mode_lib->vba.DCCMetaPitchY[k],
+					&mode_lib->vba.MacroTileWidthY[k],
+					&mode_lib->vba.MetaRowBytesY,
+					&mode_lib->vba.DPTEBytesPerRowY,
+					&mode_lib->vba.PTEBufferSizeNotExceededY[i][k],
+					&mode_lib->vba.dpte_row_height[k],
+					&mode_lib->vba.meta_row_height[k]);
+			mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
+					mode_lib,
+					mode_lib->vba.VRatio[k],
+					mode_lib->vba.vtaps[k],
+					mode_lib->vba.Interlace[k],
+					mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+					mode_lib->vba.SwathHeightYPerState[i][k],
+					mode_lib->vba.ViewportYStartY[k],
+					&mode_lib->vba.PrefillY[k],
+					&mode_lib->vba.MaxNumSwY[k]);
+			if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+					&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+					&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+					&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+					&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
+				mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
+						mode_lib,
+						mode_lib->vba.DCCEnable[k],
+						mode_lib->vba.Read256BlockHeightY[k],
+						mode_lib->vba.Read256BlockWidthY[k],
+						mode_lib->vba.SourcePixelFormat[k],
+						mode_lib->vba.SurfaceTiling[k],
+						dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
+						mode_lib->vba.SourceScan[k],
+						mode_lib->vba.ViewportWidth[k] / 2.0,
+						mode_lib->vba.ViewportHeight[k] / 2.0,
+						mode_lib->vba.SwathWidthYPerState[i][k] / 2.0,
+						mode_lib->vba.VirtualMemoryEnable,
+						mode_lib->vba.VMMPageSize,
+						mode_lib->vba.PTEBufferSizeInRequests,
+						mode_lib->vba.PDEProcessingBufIn64KBReqs,
+						mode_lib->vba.PitchC[k],
+						0.0,
+						&mode_lib->vba.MacroTileWidthC[k],
+						&mode_lib->vba.MetaRowBytesC,
+						&mode_lib->vba.DPTEBytesPerRowC,
+						&mode_lib->vba.PTEBufferSizeNotExceededC[i][k],
+						&mode_lib->vba.dpte_row_height_chroma[k],
+						&mode_lib->vba.meta_row_height_chroma[k]);
+				mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
+						mode_lib,
+						mode_lib->vba.VRatio[k] / 2.0,
+						mode_lib->vba.VTAPsChroma[k],
+						mode_lib->vba.Interlace[k],
+						mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+						mode_lib->vba.SwathHeightCPerState[i][k],
+						mode_lib->vba.ViewportYStartC[k],
+						&mode_lib->vba.PrefillC[k],
+						&mode_lib->vba.MaxNumSwC[k]);
+			} else {
+				mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
+				mode_lib->vba.MetaRowBytesC = 0.0;
+				mode_lib->vba.DPTEBytesPerRowC = 0.0;
+				mode_lib->vba.PrefetchLinesC[k] = 0.0;
+				mode_lib->vba.PTEBufferSizeNotExceededC[i][k] = true;
+			}
+			mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] =
+					mode_lib->vba.PDEAndMetaPTEBytesPerFrameY
+							+ mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
+			mode_lib->vba.MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY
+					+ mode_lib->vba.MetaRowBytesC;
+			mode_lib->vba.DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY
+					+ mode_lib->vba.DPTEBytesPerRowC;
+		}
+		mode_lib->vba.ExtraLatency =
+				mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
+						+ (mode_lib->vba.TotalNumberOfActiveDPP[i]
+								* mode_lib->vba.PixelChunkSizeInKByte
+								+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
+										* mode_lib->vba.MetaChunkSize)
+								* 1024.0
+								/ mode_lib->vba.ReturnBWPerState[i];
+		if (mode_lib->vba.VirtualMemoryEnable == true) {
+			mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
+					+ mode_lib->vba.TotalNumberOfActiveDPP[i]
+							* mode_lib->vba.PTEChunkSize * 1024.0
+							/ mode_lib->vba.ReturnBWPerState[i];
+		}
+		mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.BlendingAndTiming[k] == k) {
+				if (mode_lib->vba.WritebackEnable[k] == true) {
+					mode_lib->vba.WritebackDelay[i][k] =
+							mode_lib->vba.WritebackLatency
+									+ CalculateWriteBackDelay(
+											mode_lib->vba.WritebackPixelFormat[k],
+											mode_lib->vba.WritebackHRatio[k],
+											mode_lib->vba.WritebackVRatio[k],
+											mode_lib->vba.WritebackLumaHTaps[k],
+											mode_lib->vba.WritebackLumaVTaps[k],
+											mode_lib->vba.WritebackChromaHTaps[k],
+											mode_lib->vba.WritebackChromaVTaps[k],
+											mode_lib->vba.WritebackDestinationWidth[k])
+											/ mode_lib->vba.RequiredDISPCLK[i];
+				} else {
+					mode_lib->vba.WritebackDelay[i][k] = 0.0;
+				}
+				for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+					if (mode_lib->vba.BlendingAndTiming[j] == k
+							&& mode_lib->vba.WritebackEnable[j]
+									== true) {
+						mode_lib->vba.WritebackDelay[i][k] =
+								dml_max(
+										mode_lib->vba.WritebackDelay[i][k],
+										mode_lib->vba.WritebackLatency
+												+ CalculateWriteBackDelay(
+														mode_lib->vba.WritebackPixelFormat[j],
+														mode_lib->vba.WritebackHRatio[j],
+														mode_lib->vba.WritebackVRatio[j],
+														mode_lib->vba.WritebackLumaHTaps[j],
+														mode_lib->vba.WritebackLumaVTaps[j],
+														mode_lib->vba.WritebackChromaHTaps[j],
+														mode_lib->vba.WritebackChromaVTaps[j],
+														mode_lib->vba.WritebackDestinationWidth[j])
+														/ mode_lib->vba.RequiredDISPCLK[i]);
+					}
+				}
+			}
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+				if (mode_lib->vba.BlendingAndTiming[k] == j) {
+					mode_lib->vba.WritebackDelay[i][k] =
+							mode_lib->vba.WritebackDelay[i][j];
+				}
+			}
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.MaximumVStartup[k] =
+					mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
+							- dml_max(
+									1.0,
+									dml_ceil(
+											mode_lib->vba.WritebackDelay[i][k]
+													/ (mode_lib->vba.HTotal[k]
+															/ mode_lib->vba.PixelClock[k]),
+											1.0));
+		}
+		mode_lib->vba.TWait = CalculateTWait(
+				mode_lib->vba.PrefetchMode,
+				mode_lib->vba.DRAMClockChangeLatency,
+				mode_lib->vba.UrgentLatency,
+				mode_lib->vba.SREnterPlusExitTime);
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.XFCEnabled[k] == true) {
+				mode_lib->vba.XFCRemoteSurfaceFlipDelay =
+						CalculateRemoteSurfaceFlipDelay(
+								mode_lib,
+								mode_lib->vba.VRatio[k],
+								mode_lib->vba.SwathWidthYPerState[i][k],
+								dml_ceil(
+										mode_lib->vba.BytePerPixelInDETY[k],
+										1.0),
+								mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k],
+								mode_lib->vba.XFCTSlvVupdateOffset,
+								mode_lib->vba.XFCTSlvVupdateWidth,
+								mode_lib->vba.XFCTSlvVreadyOffset,
+								mode_lib->vba.XFCXBUFLatencyTolerance,
+								mode_lib->vba.XFCFillBWOverhead,
+								mode_lib->vba.XFCSlvChunkSize,
+								mode_lib->vba.XFCBusTransportTime,
+								mode_lib->vba.TimeCalc,
+								mode_lib->vba.TWait,
+								&mode_lib->vba.SrcActiveDrainRate,
+								&mode_lib->vba.TInitXFill,
+								&mode_lib->vba.TslvChk);
+			} else {
+				mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
+			}
+			mode_lib->vba.IsErrorResult[i][k] =
+					CalculatePrefetchSchedule(
+							mode_lib,
+							mode_lib->vba.RequiredDPPCLK[i][k],
+							mode_lib->vba.RequiredDISPCLK[i],
+							mode_lib->vba.PixelClock[k],
+							mode_lib->vba.ProjectedDCFCLKDeepSleep,
+							mode_lib->vba.DSCDelayPerState[i][k],
+							mode_lib->vba.NoOfDPP[i][k],
+							mode_lib->vba.ScalerEnabled[k],
+							mode_lib->vba.NumberOfCursors[k],
+							mode_lib->vba.DPPCLKDelaySubtotal,
+							mode_lib->vba.DPPCLKDelaySCL,
+							mode_lib->vba.DPPCLKDelaySCLLBOnly,
+							mode_lib->vba.DPPCLKDelayCNVCFormater,
+							mode_lib->vba.DPPCLKDelayCNVCCursor,
+							mode_lib->vba.DISPCLKDelaySubtotal,
+							mode_lib->vba.SwathWidthYPerState[i][k]
+									/ mode_lib->vba.HRatio[k],
+							mode_lib->vba.OutputFormat[k],
+							mode_lib->vba.VTotal[k]
+									- mode_lib->vba.VActive[k],
+							mode_lib->vba.HTotal[k],
+							mode_lib->vba.MaxInterDCNTileRepeaters,
+							mode_lib->vba.MaximumVStartup[k],
+							mode_lib->vba.MaxPageTableLevels,
+							mode_lib->vba.VirtualMemoryEnable,
+							mode_lib->vba.DynamicMetadataEnable[k],
+							mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
+							mode_lib->vba.DynamicMetadataTransmittedBytes[k],
+							mode_lib->vba.DCCEnable[k],
+							mode_lib->vba.UrgentLatency,
+							mode_lib->vba.ExtraLatency,
+							mode_lib->vba.TimeCalc,
+							mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
+							mode_lib->vba.MetaRowBytes[k],
+							mode_lib->vba.DPTEBytesPerRow[k],
+							mode_lib->vba.PrefetchLinesY[k],
+							mode_lib->vba.SwathWidthYPerState[i][k],
+							mode_lib->vba.BytePerPixelInDETY[k],
+							mode_lib->vba.PrefillY[k],
+							mode_lib->vba.MaxNumSwY[k],
+							mode_lib->vba.PrefetchLinesC[k],
+							mode_lib->vba.BytePerPixelInDETC[k],
+							mode_lib->vba.PrefillC[k],
+							mode_lib->vba.MaxNumSwC[k],
+							mode_lib->vba.SwathHeightYPerState[i][k],
+							mode_lib->vba.SwathHeightCPerState[i][k],
+							mode_lib->vba.TWait,
+							mode_lib->vba.XFCEnabled[k],
+							mode_lib->vba.XFCRemoteSurfaceFlipDelay,
+							mode_lib->vba.Interlace[k],
+							mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+							mode_lib->vba.DSTXAfterScaler,
+							mode_lib->vba.DSTYAfterScaler,
+							&mode_lib->vba.LineTimesForPrefetch[k],
+							&mode_lib->vba.PrefetchBW[k],
+							&mode_lib->vba.LinesForMetaPTE[k],
+							&mode_lib->vba.LinesForMetaAndDPTERow[k],
+							&mode_lib->vba.VRatioPreY[i][k],
+							&mode_lib->vba.VRatioPreC[i][k],
+							&mode_lib->vba.RequiredPrefetchPixelDataBW[i][k],
+							&mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+							&mode_lib->vba.Tno_bw[k],
+							&mode_lib->vba.VUpdateOffsetPix[k],
+							&mode_lib->vba.VUpdateWidthPix[k],
+							&mode_lib->vba.VReadyOffsetPix[k]);
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k]
+					* mode_lib->vba.CursorWidth[k][0]
+					* mode_lib->vba.CursorBPP[k][0] / 8.0
+					/ (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+					* mode_lib->vba.VRatio[k];
+		}
+		mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
+		mode_lib->vba.prefetch_vm_bw_valid = true;
+		mode_lib->vba.prefetch_row_bw_valid = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] == 0.0) {
+				mode_lib->vba.prefetch_vm_bw[k] = 0.0;
+			} else if (mode_lib->vba.LinesForMetaPTE[k] > 0.0) {
+				mode_lib->vba.prefetch_vm_bw[k] =
+						mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
+								/ (mode_lib->vba.LinesForMetaPTE[k]
+										* mode_lib->vba.HTotal[k]
+										/ mode_lib->vba.PixelClock[k]);
+			} else {
+				mode_lib->vba.prefetch_vm_bw[k] = 0.0;
+				mode_lib->vba.prefetch_vm_bw_valid = false;
+			}
+			if (mode_lib->vba.MetaRowBytes[k] + mode_lib->vba.DPTEBytesPerRow[k]
+					== 0.0) {
+				mode_lib->vba.prefetch_row_bw[k] = 0.0;
+			} else if (mode_lib->vba.LinesForMetaAndDPTERow[k] > 0.0) {
+				mode_lib->vba.prefetch_row_bw[k] = (mode_lib->vba.MetaRowBytes[k]
+						+ mode_lib->vba.DPTEBytesPerRow[k])
+						/ (mode_lib->vba.LinesForMetaAndDPTERow[k]
+								* mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k]);
+			} else {
+				mode_lib->vba.prefetch_row_bw[k] = 0.0;
+				mode_lib->vba.prefetch_row_bw_valid = false;
+			}
+			mode_lib->vba.MaximumReadBandwidthWithPrefetch =
+					mode_lib->vba.MaximumReadBandwidthWithPrefetch
+							+ mode_lib->vba.cursor_bw[k]
+							+ dml_max4(
+									mode_lib->vba.prefetch_vm_bw[k],
+									mode_lib->vba.prefetch_row_bw[k],
+									mode_lib->vba.ReadBandwidth[k],
+									mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]);
+		}
+		mode_lib->vba.PrefetchSupported[i] = true;
+		if (mode_lib->vba.MaximumReadBandwidthWithPrefetch
+				> mode_lib->vba.ReturnBWPerState[i]
+				|| mode_lib->vba.prefetch_vm_bw_valid == false
+				|| mode_lib->vba.prefetch_row_bw_valid == false) {
+			mode_lib->vba.PrefetchSupported[i] = false;
+		}
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.LineTimesForPrefetch[k] < 2.0
+					|| mode_lib->vba.LinesForMetaPTE[k] >= 8.0
+					|| mode_lib->vba.LinesForMetaAndDPTERow[k] >= 16.0
+					|| mode_lib->vba.IsErrorResult[i][k] == true) {
+				mode_lib->vba.PrefetchSupported[i] = false;
+			}
+		}
+		mode_lib->vba.VRatioInPrefetchSupported[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.VRatioPreY[i][k] > 4.0
+					|| mode_lib->vba.VRatioPreC[i][k] > 4.0
+					|| mode_lib->vba.IsErrorResult[i][k] == true) {
+				mode_lib->vba.VRatioInPrefetchSupported[i] = false;
+			}
+		}
+		if (mode_lib->vba.PrefetchSupported[i] == true
+				&& mode_lib->vba.VRatioInPrefetchSupported[i] == true) {
+			mode_lib->vba.BandwidthAvailableForImmediateFlip =
+					mode_lib->vba.ReturnBWPerState[i];
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.BandwidthAvailableForImmediateFlip =
+						mode_lib->vba.BandwidthAvailableForImmediateFlip
+								- mode_lib->vba.cursor_bw[k]
+								- dml_max(
+										mode_lib->vba.ReadBandwidth[k],
+										mode_lib->vba.PrefetchBW[k]);
+			}
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+					mode_lib->vba.ImmediateFlipBytes[k] =
+							mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
+									+ mode_lib->vba.MetaRowBytes[k]
+									+ mode_lib->vba.DPTEBytesPerRow[k];
+				}
+			}
+			mode_lib->vba.TotImmediateFlipBytes = 0.0;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+						&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+					mode_lib->vba.TotImmediateFlipBytes =
+							mode_lib->vba.TotImmediateFlipBytes
+									+ mode_lib->vba.ImmediateFlipBytes[k];
+				}
+			}
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				CalculateFlipSchedule(
+						mode_lib,
+						mode_lib->vba.ExtraLatency,
+						mode_lib->vba.UrgentLatency,
+						mode_lib->vba.MaxPageTableLevels,
+						mode_lib->vba.VirtualMemoryEnable,
+						mode_lib->vba.BandwidthAvailableForImmediateFlip,
+						mode_lib->vba.TotImmediateFlipBytes,
+						mode_lib->vba.SourcePixelFormat[k],
+						mode_lib->vba.ImmediateFlipBytes[k],
+						mode_lib->vba.HTotal[k]
+								/ mode_lib->vba.PixelClock[k],
+						mode_lib->vba.VRatio[k],
+						mode_lib->vba.Tno_bw[k],
+						mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
+						mode_lib->vba.MetaRowBytes[k],
+						mode_lib->vba.DPTEBytesPerRow[k],
+						mode_lib->vba.DCCEnable[k],
+						mode_lib->vba.dpte_row_height[k],
+						mode_lib->vba.meta_row_height[k],
+						mode_lib->vba.qual_row_bw[k],
+						&mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
+						&mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
+						&mode_lib->vba.final_flip_bw[k],
+						&mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
+			}
+			mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				mode_lib->vba.total_dcn_read_bw_with_flip =
+						mode_lib->vba.total_dcn_read_bw_with_flip
+								+ mode_lib->vba.cursor_bw[k]
+								+ dml_max3(
+										mode_lib->vba.prefetch_vm_bw[k],
+										mode_lib->vba.prefetch_row_bw[k],
+										mode_lib->vba.final_flip_bw[k]
+												+ dml_max(
+														mode_lib->vba.ReadBandwidth[k],
+														mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]));
+			}
+			mode_lib->vba.ImmediateFlipSupportedForState[i] = true;
+			if (mode_lib->vba.total_dcn_read_bw_with_flip
+					> mode_lib->vba.ReturnBWPerState[i]) {
+				mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
+			}
+			for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+				if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
+					mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
+				}
+			}
+		} else {
+			mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
+		}
+	}
+	/*PTE Buffer Size Check*/
+
+	for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+		mode_lib->vba.PTEBufferSizeNotExceeded[i] = true;
+		for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+			if (mode_lib->vba.PTEBufferSizeNotExceededY[i][k] == false
+					|| mode_lib->vba.PTEBufferSizeNotExceededC[i][k] == false) {
+				mode_lib->vba.PTEBufferSizeNotExceeded[i] = false;
+			}
+		}
+	}
+	/*Cursor Support Check*/
+
+	mode_lib->vba.CursorSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.CursorWidth[k][0] > 0.0) {
+			if (dml_floor(
+					dml_floor(
+							mode_lib->vba.CursorBufferSize
+									- mode_lib->vba.CursorChunkSize,
+							mode_lib->vba.CursorChunkSize) * 1024.0
+							/ (mode_lib->vba.CursorWidth[k][0]
+									* mode_lib->vba.CursorBPP[k][0]
+									/ 8.0),
+					1.0)
+					* (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+					/ mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatency
+					|| (mode_lib->vba.CursorBPP[k][0] == 64.0
+							&& mode_lib->vba.Cursor64BppSupport == false)) {
+				mode_lib->vba.CursorSupport = false;
+			}
+		}
+	}
+	/*Valid Pitch Check*/
+
+	mode_lib->vba.PitchSupport = true;
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		mode_lib->vba.AlignedYPitch[k] = dml_ceil(
+				dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
+				mode_lib->vba.MacroTileWidthY[k]);
+		if (mode_lib->vba.AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
+			mode_lib->vba.PitchSupport = false;
+		}
+		if (mode_lib->vba.DCCEnable[k] == true) {
+			mode_lib->vba.AlignedDCCMetaPitch[k] = dml_ceil(
+					dml_max(
+							mode_lib->vba.DCCMetaPitchY[k],
+							mode_lib->vba.ViewportWidth[k]),
+					64.0 * mode_lib->vba.Read256BlockWidthY[k]);
+		} else {
+			mode_lib->vba.AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
+		}
+		if (mode_lib->vba.AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
+			mode_lib->vba.PitchSupport = false;
+		}
+		if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+				&& mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
+			mode_lib->vba.AlignedCPitch[k] = dml_ceil(
+					dml_max(
+							mode_lib->vba.PitchC[k],
+							mode_lib->vba.ViewportWidth[k] / 2.0),
+					mode_lib->vba.MacroTileWidthC[k]);
+		} else {
+			mode_lib->vba.AlignedCPitch[k] = mode_lib->vba.PitchC[k];
+		}
+		if (mode_lib->vba.AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
+			mode_lib->vba.PitchSupport = false;
+		}
+	}
+	/*Mode Support, Voltage State and SOC Configuration*/
+
+	for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
+		if (mode_lib->vba.ScaleRatioAndTapsSupport == true
+				&& mode_lib->vba.SourceFormatPixelAndScanSupport == true
+				&& mode_lib->vba.ViewportSizeSupport[i] == true
+				&& mode_lib->vba.BandwidthSupport[i] == true
+				&& mode_lib->vba.DIOSupport[i] == true
+				&& mode_lib->vba.NotEnoughDSCUnits[i] == false
+				&& mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] == false
+				&& mode_lib->vba.UrgentLatencySupport[i] == true
+				&& mode_lib->vba.ROBSupport[i] == true
+				&& mode_lib->vba.DISPCLK_DPPCLK_Support[i] == true
+				&& mode_lib->vba.TotalAvailablePipesSupport[i] == true
+				&& mode_lib->vba.NumberOfOTGSupport == true
+				&& mode_lib->vba.WritebackModeSupport == true
+				&& mode_lib->vba.WritebackLatencySupport == true
+				&& mode_lib->vba.WritebackScaleRatioAndTapsSupport == true
+				&& mode_lib->vba.CursorSupport == true
+				&& mode_lib->vba.PitchSupport == true
+				&& mode_lib->vba.PrefetchSupported[i] == true
+				&& mode_lib->vba.VRatioInPrefetchSupported[i] == true
+				&& mode_lib->vba.PTEBufferSizeNotExceeded[i] == true
+				&& mode_lib->vba.NonsupportedDSCInputBPC == false) {
+			mode_lib->vba.ModeSupport[i] = true;
+		} else {
+			mode_lib->vba.ModeSupport[i] = false;
+		}
+	}
+	for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
+		if (i == DC__VOLTAGE_STATES || mode_lib->vba.ModeSupport[i] == true) {
+			mode_lib->vba.VoltageLevel = i;
+		}
+	}
+	mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.FabricAndDRAMBandwidth =
+			mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
+	mode_lib->vba.ImmediateFlipSupport =
+			mode_lib->vba.ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel];
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		mode_lib->vba.DPPPerPlane[k] = mode_lib->vba.NoOfDPP[mode_lib->vba.VoltageLevel][k];
+	}
+	for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+		if (mode_lib->vba.BlendingAndTiming[k] == k) {
+			mode_lib->vba.ODMCombineEnabled[k] =
+					mode_lib->vba.ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
+		} else {
+			mode_lib->vba.ODMCombineEnabled[k] = 0;
+		}
+		mode_lib->vba.DSCEnabled[k] =
+				mode_lib->vba.RequiresDSC[mode_lib->vba.VoltageLevel][k];
+		mode_lib->vba.OutputBpp[k] =
+				mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k];
+	}
+}

+ 598 - 0
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h

@@ -0,0 +1,598 @@
+/*
+ * 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 __DML2_DISPLAY_MODE_VBA_H__
+#define __DML2_DISPLAY_MODE_VBA_H__
+
+#include "dml_common_defs.h"
+
+struct display_mode_lib;
+
+void set_prefetch_mode(struct display_mode_lib *mode_lib,
+		bool cstate_en,
+		bool pstate_en,
+		bool ignore_viewport_pos,
+		bool immediate_flip_support);
+
+#define dml_get_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes)
+
+dml_get_attr_decl(clk_dcf_deepsleep);
+dml_get_attr_decl(wm_urgent);
+dml_get_attr_decl(wm_memory_trip);
+dml_get_attr_decl(wm_writeback_urgent);
+dml_get_attr_decl(wm_stutter_exit);
+dml_get_attr_decl(wm_stutter_enter_exit);
+dml_get_attr_decl(wm_dram_clock_change);
+dml_get_attr_decl(wm_writeback_dram_clock_change);
+dml_get_attr_decl(wm_xfc_underflow);
+dml_get_attr_decl(stutter_efficiency_no_vblank);
+dml_get_attr_decl(stutter_efficiency);
+dml_get_attr_decl(urgent_latency);
+dml_get_attr_decl(urgent_extra_latency);
+dml_get_attr_decl(nonurgent_latency);
+dml_get_attr_decl(dram_clock_change_latency);
+dml_get_attr_decl(dispclk_calculated);
+dml_get_attr_decl(total_data_read_bw);
+dml_get_attr_decl(return_bw);
+dml_get_attr_decl(tcalc);
+
+#define dml_get_pipe_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe)
+
+dml_get_pipe_attr_decl(dsc_delay);
+dml_get_pipe_attr_decl(dppclk_calculated);
+dml_get_pipe_attr_decl(dscclk_calculated);
+dml_get_pipe_attr_decl(min_ttu_vblank);
+dml_get_pipe_attr_decl(vratio_prefetch_l);
+dml_get_pipe_attr_decl(vratio_prefetch_c);
+dml_get_pipe_attr_decl(dst_x_after_scaler);
+dml_get_pipe_attr_decl(dst_y_after_scaler);
+dml_get_pipe_attr_decl(dst_y_per_vm_vblank);
+dml_get_pipe_attr_decl(dst_y_per_row_vblank);
+dml_get_pipe_attr_decl(dst_y_prefetch);
+dml_get_pipe_attr_decl(dst_y_per_vm_flip);
+dml_get_pipe_attr_decl(dst_y_per_row_flip);
+dml_get_pipe_attr_decl(xfc_transfer_delay);
+dml_get_pipe_attr_decl(xfc_precharge_delay);
+dml_get_pipe_attr_decl(xfc_remote_surface_flip_latency);
+dml_get_pipe_attr_decl(xfc_prefetch_margin);
+
+unsigned int get_vstartup_calculated(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes,
+		unsigned int which_pipe);
+
+double get_total_immediate_flip_bytes(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes);
+double get_total_immediate_flip_bw(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes);
+double get_total_prefetch_bw(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes);
+
+unsigned int dml_get_voltage_level(
+		struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *pipes,
+		unsigned int num_pipes);
+
+bool Calculate256BBlockSizes(
+		enum source_format_class SourcePixelFormat,
+		enum dm_swizzle_mode SurfaceTiling,
+		unsigned int BytePerPixelY,
+		unsigned int BytePerPixelC,
+		unsigned int *BlockHeight256BytesY,
+		unsigned int *BlockHeight256BytesC,
+		unsigned int *BlockWidth256BytesY,
+		unsigned int *BlockWidth256BytesC);
+
+
+struct vba_vars_st {
+	ip_params_st	ip;
+	soc_bounding_box_st	soc;
+
+	unsigned int MaximumMaxVStartupLines;
+	double cursor_bw[DC__NUM_DPP__MAX];
+	double meta_row_bw[DC__NUM_DPP__MAX];
+	double dpte_row_bw[DC__NUM_DPP__MAX];
+	double qual_row_bw[DC__NUM_DPP__MAX];
+	double WritebackDISPCLK;
+	double PSCL_THROUGHPUT_LUMA[DC__NUM_DPP__MAX];
+	double PSCL_THROUGHPUT_CHROMA[DC__NUM_DPP__MAX];
+	double DPPCLKUsingSingleDPPLuma;
+	double DPPCLKUsingSingleDPPChroma;
+	double DPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
+	double DISPCLKWithRamping;
+	double DISPCLKWithoutRamping;
+	double GlobalDPPCLK;
+	double DISPCLKWithRampingRoundedToDFSGranularity;
+	double DISPCLKWithoutRampingRoundedToDFSGranularity;
+	double MaxDispclkRoundedToDFSGranularity;
+	bool DCCEnabledAnyPlane;
+	double ReturnBandwidthToDCN;
+	unsigned int SwathWidthY[DC__NUM_DPP__MAX];
+	unsigned int SwathWidthSingleDPPY[DC__NUM_DPP__MAX];
+	double BytePerPixelDETY[DC__NUM_DPP__MAX];
+	double BytePerPixelDETC[DC__NUM_DPP__MAX];
+	double ReadBandwidthPlaneLuma[DC__NUM_DPP__MAX];
+	double ReadBandwidthPlaneChroma[DC__NUM_DPP__MAX];
+	unsigned int TotalActiveDPP;
+	unsigned int TotalDCCActiveDPP;
+	double UrgentRoundTripAndOutOfOrderLatency;
+	double DisplayPipeLineDeliveryTimeLuma[DC__NUM_DPP__MAX];                     // WM
+	double DisplayPipeLineDeliveryTimeChroma[DC__NUM_DPP__MAX];                     // WM
+	double LinesInDETY[DC__NUM_DPP__MAX];                     // WM
+	double LinesInDETC[DC__NUM_DPP__MAX];                     // WM
+	unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX];                     // WM
+	unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX];                     // WM
+	double FullDETBufferingTimeY[DC__NUM_DPP__MAX];                     // WM
+	double FullDETBufferingTimeC[DC__NUM_DPP__MAX];                     // WM
+	double MinFullDETBufferingTime;
+	double FrameTimeForMinFullDETBufferingTime;
+	double AverageReadBandwidthGBytePerSecond;
+	double PartOfBurstThatFitsInROB;
+	double StutterBurstTime;
+	//unsigned int     NextPrefetchMode;
+	double VBlankTime;
+	double SmallestVBlank;
+	double DCFCLKDeepSleepPerPlane;
+	double EffectiveDETPlusLBLinesLuma;
+	double EffectiveDETPlusLBLinesChroma;
+	double UrgentLatencySupportUsLuma;
+	double UrgentLatencySupportUsChroma;
+	double UrgentLatencySupportUs[DC__NUM_DPP__MAX];
+	unsigned int DSCFormatFactor;
+	unsigned int BlockHeight256BytesY[DC__NUM_DPP__MAX];
+	unsigned int BlockHeight256BytesC[DC__NUM_DPP__MAX];
+	unsigned int BlockWidth256BytesY[DC__NUM_DPP__MAX];
+	unsigned int BlockWidth256BytesC[DC__NUM_DPP__MAX];
+	double VInitPreFillY[DC__NUM_DPP__MAX];
+	double VInitPreFillC[DC__NUM_DPP__MAX];
+	unsigned int MaxNumSwathY[DC__NUM_DPP__MAX];
+	unsigned int MaxNumSwathC[DC__NUM_DPP__MAX];
+	double PrefetchSourceLinesY[DC__NUM_DPP__MAX];
+	double PrefetchSourceLinesC[DC__NUM_DPP__MAX];
+	double PixelPTEBytesPerRow[DC__NUM_DPP__MAX];
+	double MetaRowByte[DC__NUM_DPP__MAX];
+	unsigned int dpte_row_height[DC__NUM_DPP__MAX];
+	unsigned int dpte_row_height_chroma[DC__NUM_DPP__MAX];
+	unsigned int meta_row_height[DC__NUM_DPP__MAX];
+	unsigned int meta_row_height_chroma[DC__NUM_DPP__MAX];
+
+	unsigned int MacroTileWidthY[DC__NUM_DPP__MAX];
+	unsigned int MacroTileWidthC[DC__NUM_DPP__MAX];
+	unsigned int MaxVStartupLines[DC__NUM_DPP__MAX];
+	double WritebackDelay[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	bool PrefetchModeSupported;
+	bool AllowDRAMClockChangeDuringVBlank[DC__NUM_DPP__MAX];
+	bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_DPP__MAX];
+	double RequiredPrefetchPixDataBW[DC__NUM_DPP__MAX];
+	double XFCRemoteSurfaceFlipDelay;
+	double TInitXFill;
+	double TslvChk;
+	double SrcActiveDrainRate;
+	double Tno_bw[DC__NUM_DPP__MAX];
+	bool ImmediateFlipSupported;
+
+	double prefetch_vm_bw[DC__NUM_DPP__MAX];
+	double prefetch_row_bw[DC__NUM_DPP__MAX];
+	bool ImmediateFlipSupportedForPipe[DC__NUM_DPP__MAX];
+	unsigned int VStartupLines;
+	double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_DPP__MAX];
+	double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_DPP__MAX];
+	unsigned int ActiveDPPs;
+	unsigned int LBLatencyHidingSourceLinesY;
+	unsigned int LBLatencyHidingSourceLinesC;
+	double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX];
+	double MinActiveDRAMClockChangeMargin;
+	double XFCSlaveVUpdateOffset[DC__NUM_DPP__MAX];
+	double XFCSlaveVupdateWidth[DC__NUM_DPP__MAX];
+	double XFCSlaveVReadyOffset[DC__NUM_DPP__MAX];
+	double InitFillLevel;
+	double FinalFillMargin;
+	double FinalFillLevel;
+	double RemainingFillLevel;
+	double TFinalxFill;
+
+
+	//
+	// SOC Bounding Box Parameters
+	//
+	double SRExitTime;
+	double SREnterPlusExitTime;
+	double UrgentLatency;
+	double WritebackLatency;
+	double PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency;
+	double NumberOfChannels;
+	double DRAMChannelWidth;
+	double FabricDatapathToDCNDataReturn;
+	double ReturnBusWidth;
+	double Downspreading;
+	double DISPCLKDPPCLKDSCCLKDownSpreading;
+	double DISPCLKDPPCLKVCOSpeed;
+	double RoundTripPingLatencyCycles;
+	double UrgentOutOfOrderReturnPerChannel;
+	unsigned int VMMPageSize;
+	double DRAMClockChangeLatency;
+	double XFCBusTransportTime;
+	double XFCXBUFLatencyTolerance;
+
+	//
+	// IP Parameters
+	//
+	unsigned int ROBBufferSizeInKByte;
+	double DETBufferSizeInKByte;
+	unsigned int DPPOutputBufferPixels;
+	unsigned int OPPOutputBufferLines;
+	unsigned int PixelChunkSizeInKByte;
+	double ReturnBW;
+	bool VirtualMemoryEnable;
+	unsigned int MaxPageTableLevels;
+	unsigned int OverridePageTableLevels;
+	unsigned int PTEChunkSize;
+	unsigned int MetaChunkSize;
+	unsigned int WritebackChunkSize;
+	bool ODMCapability;
+	unsigned int NumberOfDSC;
+	unsigned int LineBufferSize;
+	unsigned int MaxLineBufferLines;
+	unsigned int WritebackInterfaceLumaBufferSize;
+	unsigned int WritebackInterfaceChromaBufferSize;
+	unsigned int WritebackChromaLineBufferWidth;
+	double MaxDCHUBToPSCLThroughput;
+	double MaxPSCLToLBThroughput;
+	unsigned int PTEBufferSizeInRequests;
+	double DISPCLKRampingMargin;
+	unsigned int MaxInterDCNTileRepeaters;
+	bool XFCSupported;
+	double XFCSlvChunkSize;
+	double XFCFillBWOverhead;
+	double XFCFillConstant;
+	double XFCTSlvVupdateOffset;
+	double XFCTSlvVupdateWidth;
+	double XFCTSlvVreadyOffset;
+	double DPPCLKDelaySubtotal;
+	double DPPCLKDelaySCL;
+	double DPPCLKDelaySCLLBOnly;
+	double DPPCLKDelayCNVCFormater;
+	double DPPCLKDelayCNVCCursor;
+	double DISPCLKDelaySubtotal;
+	bool ProgressiveToInterlaceUnitInOPP;
+	unsigned int PDEProcessingBufIn64KBReqs;
+
+	// Pipe/Plane Parameters
+	int VoltageLevel;
+	double FabricAndDRAMBandwidth;
+	double FabricClock;
+	double DRAMSpeed;
+	double DISPCLK;
+	double SOCCLK;
+	double DCFCLK;
+
+	unsigned int NumberOfActivePlanes;
+	unsigned int ViewportWidth[DC__NUM_DPP__MAX];
+	unsigned int ViewportHeight[DC__NUM_DPP__MAX];
+	unsigned int ViewportYStartY[DC__NUM_DPP__MAX];
+	unsigned int ViewportYStartC[DC__NUM_DPP__MAX];
+	unsigned int PitchY[DC__NUM_DPP__MAX];
+	unsigned int PitchC[DC__NUM_DPP__MAX];
+	double HRatio[DC__NUM_DPP__MAX];
+	double VRatio[DC__NUM_DPP__MAX];
+	unsigned int htaps[DC__NUM_DPP__MAX];
+	unsigned int vtaps[DC__NUM_DPP__MAX];
+	unsigned int HTAPsChroma[DC__NUM_DPP__MAX];
+	unsigned int VTAPsChroma[DC__NUM_DPP__MAX];
+	unsigned int HTotal[DC__NUM_DPP__MAX];
+	unsigned int VTotal[DC__NUM_DPP__MAX];
+	unsigned int DPPPerPlane[DC__NUM_DPP__MAX];
+	double PixelClock[DC__NUM_DPP__MAX];
+	double PixelClockBackEnd[DC__NUM_DPP__MAX];
+	double DPPCLK[DC__NUM_DPP__MAX];
+	bool DCCEnable[DC__NUM_DPP__MAX];
+	unsigned int DCCMetaPitchY[DC__NUM_DPP__MAX];
+	enum scan_direction_class SourceScan[DC__NUM_DPP__MAX];
+	enum source_format_class SourcePixelFormat[DC__NUM_DPP__MAX];
+	bool WritebackEnable[DC__NUM_DPP__MAX];
+	double WritebackDestinationWidth[DC__NUM_DPP__MAX];
+	double WritebackDestinationHeight[DC__NUM_DPP__MAX];
+	double WritebackSourceHeight[DC__NUM_DPP__MAX];
+	enum source_format_class WritebackPixelFormat[DC__NUM_DPP__MAX];
+	unsigned int WritebackLumaHTaps[DC__NUM_DPP__MAX];
+	unsigned int WritebackLumaVTaps[DC__NUM_DPP__MAX];
+	unsigned int WritebackChromaHTaps[DC__NUM_DPP__MAX];
+	unsigned int WritebackChromaVTaps[DC__NUM_DPP__MAX];
+	double WritebackHRatio[DC__NUM_DPP__MAX];
+	double WritebackVRatio[DC__NUM_DPP__MAX];
+	unsigned int HActive[DC__NUM_DPP__MAX];
+	unsigned int VActive[DC__NUM_DPP__MAX];
+	bool Interlace[DC__NUM_DPP__MAX];
+	enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP__MAX];
+	unsigned int ScalerRecoutWidth[DC__NUM_DPP__MAX];
+	bool DynamicMetadataEnable[DC__NUM_DPP__MAX];
+	unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP__MAX];
+	unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP__MAX];
+	double DCCRate[DC__NUM_DPP__MAX];
+	bool ODMCombineEnabled[DC__NUM_DPP__MAX];
+	double OutputBpp[DC__NUM_DPP__MAX];
+	unsigned int NumberOfDSCSlices[DC__NUM_DPP__MAX];
+	bool DSCEnabled[DC__NUM_DPP__MAX];
+	unsigned int DSCDelay[DC__NUM_DPP__MAX];
+	unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX];
+	enum output_format_class OutputFormat[DC__NUM_DPP__MAX];
+	enum output_encoder_class Output[DC__NUM_DPP__MAX];
+	unsigned int BlendingAndTiming[DC__NUM_DPP__MAX];
+	bool SynchronizedVBlank;
+	unsigned int NumberOfCursors[DC__NUM_DPP__MAX];
+	unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
+	unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
+	bool XFCEnabled[DC__NUM_DPP__MAX];
+	bool ScalerEnabled[DC__NUM_DPP__MAX];
+
+	// Intermediates/Informational
+	bool ImmediateFlipSupport;
+	unsigned int SwathHeightY[DC__NUM_DPP__MAX];
+	unsigned int SwathHeightC[DC__NUM_DPP__MAX];
+	unsigned int DETBufferSizeY[DC__NUM_DPP__MAX];
+	unsigned int DETBufferSizeC[DC__NUM_DPP__MAX];
+	unsigned int LBBitPerPixel[DC__NUM_DPP__MAX];
+	double LastPixelOfLineExtraWatermark;
+	double TotalDataReadBandwidth;
+	unsigned int TotalActiveWriteback;
+	unsigned int EffectiveLBLatencyHidingSourceLinesLuma;
+	unsigned int EffectiveLBLatencyHidingSourceLinesChroma;
+	double BandwidthAvailableForImmediateFlip;
+	unsigned int PrefetchMode;
+	bool IgnoreViewportPositioning;
+	double PrefetchBandwidth[DC__NUM_DPP__MAX];
+	bool ErrorResult[DC__NUM_DPP__MAX];
+	double PDEAndMetaPTEBytesFrame[DC__NUM_DPP__MAX];
+
+	//
+	// Calculated dml_ml->vba.Outputs
+	//
+	double DCFClkDeepSleep;
+	double UrgentWatermark;
+	double UrgentExtraLatency;
+	double MemoryTripWatermark;
+	double WritebackUrgentWatermark;
+	double StutterExitWatermark;
+	double StutterEnterPlusExitWatermark;
+	double DRAMClockChangeWatermark;
+	double WritebackDRAMClockChangeWatermark;
+	double StutterEfficiency;
+	double StutterEfficiencyNotIncludingVBlank;
+	double MinUrgentLatencySupportUs;
+	double NonUrgentLatencyTolerance;
+	double MinActiveDRAMClockChangeLatencySupported;
+	enum clock_change_support DRAMClockChangeSupport;
+
+	// These are the clocks calcuated by the library but they are not actually
+	// used explicitly. They are fetched by tests and then possibly used. The
+	// ultimate values to use are the ones specified by the parameters to DML
+	double DISPCLK_calculated;
+	double DSCCLK_calculated[DC__NUM_DPP__MAX];
+	double DPPCLK_calculated[DC__NUM_DPP__MAX];
+
+	unsigned int VStartup[DC__NUM_DPP__MAX];
+	unsigned int VUpdateOffsetPix[DC__NUM_DPP__MAX];
+	unsigned int VUpdateWidthPix[DC__NUM_DPP__MAX];
+	unsigned int VReadyOffsetPix[DC__NUM_DPP__MAX];
+	unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
+
+	double ImmediateFlipBW;
+	unsigned int TotImmediateFlipBytes;
+	double TCalc;
+	double MinTTUVBlank[DC__NUM_DPP__MAX];
+	double VRatioPrefetchY[DC__NUM_DPP__MAX];
+	double VRatioPrefetchC[DC__NUM_DPP__MAX];
+	double DSTXAfterScaler[DC__NUM_DPP__MAX];
+	double DSTYAfterScaler[DC__NUM_DPP__MAX];
+
+	double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP__MAX];
+	double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP__MAX];
+	double DestinationLinesForPrefetch[DC__NUM_DPP__MAX];
+	double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP__MAX];
+	double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP__MAX];
+
+	double XFCTransferDelay[DC__NUM_DPP__MAX];
+	double XFCPrechargeDelay[DC__NUM_DPP__MAX];
+	double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP__MAX];
+	double XFCPrefetchMargin[DC__NUM_DPP__MAX];
+
+	display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP__MAX];
+	unsigned int cache_num_pipes;
+	unsigned int pipe_plane[DC__NUM_DPP__MAX];
+
+	/* vba mode support */
+	/*inputs*/
+	bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
+	double MaxHSCLRatio;
+	double MaxVSCLRatio;
+	unsigned int  MaxNumWriteback;
+	bool WritebackLumaAndChromaScalingSupported;
+	bool Cursor64BppSupport;
+	double DCFCLKPerState[DC__VOLTAGE_STATES + 1];
+	double FabricClockPerState[DC__VOLTAGE_STATES + 1];
+	double SOCCLKPerState[DC__VOLTAGE_STATES + 1];
+	double PHYCLKPerState[DC__VOLTAGE_STATES + 1];
+	double MaxDppclk[DC__VOLTAGE_STATES + 1];
+	double MaxDSCCLK[DC__VOLTAGE_STATES + 1];
+	double DRAMSpeedPerState[DC__VOLTAGE_STATES + 1];
+	double MaxDispclk[DC__VOLTAGE_STATES + 1];
+
+	/*outputs*/
+	bool ScaleRatioAndTapsSupport;
+	bool SourceFormatPixelAndScanSupport;
+	unsigned int SwathWidthYSingleDPP[DC__NUM_DPP__MAX];
+	double BytePerPixelInDETY[DC__NUM_DPP__MAX];
+	double BytePerPixelInDETC[DC__NUM_DPP__MAX];
+	double TotalReadBandwidthConsumedGBytePerSecond;
+	double ReadBandwidth[DC__NUM_DPP__MAX];
+	double TotalWriteBandwidthConsumedGBytePerSecond;
+	double WriteBandwidth[DC__NUM_DPP__MAX];
+	double TotalBandwidthConsumedGBytePerSecond;
+	bool DCCEnabledInAnyPlane;
+	bool WritebackLatencySupport;
+	bool WritebackModeSupport;
+	bool Writeback10bpc420Supported;
+	bool BandwidthSupport[DC__VOLTAGE_STATES + 1];
+	unsigned int TotalNumberOfActiveWriteback;
+	double CriticalPoint;
+	double ReturnBWToDCNPerState;
+	double FabricAndDRAMBandwidthPerState[DC__VOLTAGE_STATES + 1];
+	double ReturnBWPerState[DC__VOLTAGE_STATES + 1];
+	double UrgentRoundTripAndOutOfOrderLatencyPerState[DC__VOLTAGE_STATES + 1];
+	bool ODMCombineEnablePerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	bool PTEBufferSizeNotExceededY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	bool PTEBufferSizeNotExceededC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	bool PrefetchSupported[DC__VOLTAGE_STATES + 1];
+	bool VRatioInPrefetchSupported[DC__VOLTAGE_STATES + 1];
+	bool DISPCLK_DPPCLK_Support[DC__VOLTAGE_STATES + 1];
+	bool TotalAvailablePipesSupport[DC__VOLTAGE_STATES + 1];
+	bool UrgentLatencySupport[DC__VOLTAGE_STATES + 1];
+	bool ModeSupport[DC__VOLTAGE_STATES + 1];
+	bool DIOSupport[DC__VOLTAGE_STATES + 1];
+	bool NotEnoughDSCUnits[DC__VOLTAGE_STATES + 1];
+	bool DSCCLKRequiredMoreThanSupported[DC__VOLTAGE_STATES + 1];
+	bool ROBSupport[DC__VOLTAGE_STATES + 1];
+	bool PTEBufferSizeNotExceeded[DC__VOLTAGE_STATES + 1];
+	bool RequiresDSC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	bool IsErrorResult[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	bool ViewportSizeSupport[DC__VOLTAGE_STATES + 1];
+	bool prefetch_vm_bw_valid;
+	bool prefetch_row_bw_valid;
+	bool NumberOfOTGSupport;
+	bool NonsupportedDSCInputBPC;
+	bool WritebackScaleRatioAndTapsSupport;
+	bool CursorSupport;
+	bool PitchSupport;
+
+	double WritebackLineBufferLumaBufferSize;
+	double WritebackLineBufferChromaBufferSize;
+	double WritebackMinHSCLRatio;
+	double WritebackMinVSCLRatio;
+	double WritebackMaxHSCLRatio;
+	double WritebackMaxVSCLRatio;
+	double WritebackMaxHSCLTaps;
+	double WritebackMaxVSCLTaps;
+	unsigned int MaxNumDPP;
+	unsigned int MaxNumOTG;
+	double CursorBufferSize;
+	double CursorChunkSize;
+	unsigned int Mode;
+	unsigned int NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double OutputLinkDPLanes[DC__NUM_DPP__MAX];
+	double SwathWidthYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double SwathHeightYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double SwathHeightCPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double UrgentLatencySupportUsPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double VRatioPreY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double VRatioPreC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double RequiredPrefetchPixelDataBW[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double RequiredDPPCLK[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double RequiredDISPCLK[DC__VOLTAGE_STATES + 1];
+	double TotalNumberOfActiveDPP[DC__VOLTAGE_STATES + 1];
+	double TotalNumberOfDCCActiveDPP[DC__VOLTAGE_STATES + 1];
+	double PrefetchBW[DC__NUM_DPP__MAX];
+	double PDEAndMetaPTEBytesPerFrame[DC__NUM_DPP__MAX];
+	double MetaRowBytes[DC__NUM_DPP__MAX];
+	double DPTEBytesPerRow[DC__NUM_DPP__MAX];
+	double PrefetchLinesY[DC__NUM_DPP__MAX];
+	double PrefetchLinesC[DC__NUM_DPP__MAX];
+	unsigned int MaxNumSwY[DC__NUM_DPP__MAX];
+	unsigned int MaxNumSwC[DC__NUM_DPP__MAX];
+	double PrefillY[DC__NUM_DPP__MAX];
+	double PrefillC[DC__NUM_DPP__MAX];
+	double LineTimesForPrefetch[DC__NUM_DPP__MAX];
+	double LinesForMetaPTE[DC__NUM_DPP__MAX];
+	double LinesForMetaAndDPTERow[DC__NUM_DPP__MAX];
+	double MinDPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
+	double RequiresFEC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	unsigned int OutputBppPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	double DSCDelayPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+	unsigned int Read256BlockHeightY[DC__NUM_DPP__MAX];
+	unsigned int Read256BlockWidthY[DC__NUM_DPP__MAX];
+	unsigned int Read256BlockHeightC[DC__NUM_DPP__MAX];
+	unsigned int Read256BlockWidthC[DC__NUM_DPP__MAX];
+	unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
+	double MaxSwathHeightY[DC__NUM_DPP__MAX];
+	double MaxSwathHeightC[DC__NUM_DPP__MAX];
+	double MinSwathHeightY[DC__NUM_DPP__MAX];
+	double MinSwathHeightC[DC__NUM_DPP__MAX];
+	double PSCL_FACTOR[DC__NUM_DPP__MAX];
+	double PSCL_FACTOR_CHROMA[DC__NUM_DPP__MAX];
+	double MaximumVStartup[DC__NUM_DPP__MAX];
+	double AlignedDCCMetaPitch[DC__NUM_DPP__MAX];
+	double AlignedYPitch[DC__NUM_DPP__MAX];
+	double AlignedCPitch[DC__NUM_DPP__MAX];
+	double MaximumSwathWidth[DC__NUM_DPP__MAX];
+	double final_flip_bw[DC__NUM_DPP__MAX];
+	double ImmediateFlipSupportedForState[DC__VOLTAGE_STATES + 1];
+
+	double WritebackLumaVExtra;
+	double WritebackChromaVExtra;
+	double WritebackRequiredDISPCLK;
+	double MaximumSwathWidthSupport;
+	double MaximumSwathWidthInDETBuffer;
+	double MaximumSwathWidthInLineBuffer;
+	double MaxDispclkRoundedDownToDFSGranularity;
+	double MaxDppclkRoundedDownToDFSGranularity;
+	double PlaneRequiredDISPCLKWithoutODMCombine;
+	double PlaneRequiredDISPCLK;
+	double TotalNumberOfActiveOTG;
+	double FECOverhead;
+	double EffectiveFECOverhead;
+	unsigned int Outbpp;
+	unsigned int OutbppDSC;
+	double TotalDSCUnitsRequired;
+	double bpp;
+	unsigned int slices;
+	double SwathWidthGranularityY;
+	double RoundedUpMaxSwathSizeBytesY;
+	double SwathWidthGranularityC;
+	double RoundedUpMaxSwathSizeBytesC;
+	double LinesInDETLuma;
+	double LinesInDETChroma;
+	double EffectiveDETLBLinesLuma;
+	double EffectiveDETLBLinesChroma;
+	double ProjectedDCFCLKDeepSleep;
+	double PDEAndMetaPTEBytesPerFrameY;
+	double PDEAndMetaPTEBytesPerFrameC;
+	unsigned int MetaRowBytesY;
+	unsigned int MetaRowBytesC;
+	unsigned int DPTEBytesPerRowC;
+	unsigned int DPTEBytesPerRowY;
+	double ExtraLatency;
+	double TimeCalc;
+	double TWait;
+	double MaximumReadBandwidthWithPrefetch;
+	double total_dcn_read_bw_with_flip;
+};
+
+#endif /* _DML2_DISPLAY_MODE_VBA_H_ */

+ 982 - 1475
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c

@@ -22,8 +22,22 @@
  * Authors: AMD
  *
  */
-#include "display_rq_dlg_calc.h"
+
 #include "display_mode_lib.h"
+#include "display_mode_vba.h"
+#include "display_rq_dlg_calc.h"
+
+static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+		double *refcyc_per_req_delivery_pre_cur,
+		double *refcyc_per_req_delivery_cur,
+		double refclk_freq_in_mhz,
+		double ref_freq_to_pix_freq,
+		double hscale_pixel_rate_l,
+		double hscl_ratio,
+		double vratio_pre_l,
+		double vratio_l,
+		unsigned int cur_width,
+		enum cursor_bpp cur_bpp);
 
 #include "dml_inline_defs.h"
 
@@ -50,6 +64,8 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format
 			ret_val = 4;
 		else
 			ret_val = 2;
+	} else if (source_format == dm_444_8) {
+		ret_val = 1;
 	}
 	return ret_val;
 }
@@ -64,123 +80,43 @@ static bool is_dual_plane(enum source_format_class source_format)
 	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,
+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,
+		bool odm_combine,
+		unsigned int recout_width,
+		unsigned int hactive,
 		double vratio,
 		double hscale_pixel_rate,
-		int unsigned delivery_width,
-		int unsigned req_per_swath_ub)
+		unsigned int delivery_width,
+		unsigned int 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;
+		if (odm_combine)
+			refcyc_per_delivery = (double) refclk_freq_in_mhz
+					* dml_min((double) recout_width, (double) hactive / 2.0)
+					/ pclk_freq_in_mhz / (double) req_per_swath_ub;
+		else
+			refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
+					/ pclk_freq_in_mhz / (double) req_per_swath_ub;
 	} else {
 		refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
 				/ (double) hscale_pixel_rate / (double) req_per_swath_ub;
 	}
 
-	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);
+	dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: pclk_freq_in_mhz   = %3.2f\n", __func__, pclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: recout_width       = %d\n", __func__, recout_width);
+	dml_print("DML_DLG: %s: vratio             = %3.2f\n", __func__, vratio);
+	dml_print("DML_DLG: %s: req_per_swath_ub   = %d\n", __func__, req_per_swath_ub);
+	dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery);
 
 	return refcyc_per_delivery;
 
 }
 
-static 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)
@@ -191,12 +127,11 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si
 		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)
+static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib,
+		display_data_rq_regs_st *rq_regs,
+		const display_data_rq_sizing_params_st rq_sizing)
 {
-	DTRACE("DLG: %s: rq_sizing param", __func__);
+	dml_print("DML_DLG: %s: rq_sizing param\n", __func__);
 	print__data_rq_sizing_params_st(mode_lib, rq_sizing);
 
 	rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
@@ -216,25 +151,30 @@ static void extract_rq_sizing_regs(
 	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)
+static void extract_rq_regs(struct display_mode_lib *mode_lib,
+		display_rq_regs_st *rq_regs,
+		const display_rq_params_st rq_param)
 {
 	unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
 	unsigned int detile_buf_plane1_addr = 0;
 
 	extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
-	if (rq_param.yuv420)
+
+	rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height),
+			1) - 3;
+
+	if (rq_param.yuv420) {
 		extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
+		rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height),
+				1) - 3;
+	}
 
 	rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
 	rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
 
-	/* FIXME: take the max between luma, chroma chunk size?
-	 * okay for now, as we are setting chunk_bytes to 8kb anyways
-	 */
-	if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */
+	// 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;
@@ -246,21 +186,19 @@ void extract_rq_regs(
 	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 */
+			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),
+			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 */
+					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)
+static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+		display_rq_params_st *rq_param,
+		const display_pipe_source_params_st pipe_src_param)
 {
 	unsigned int total_swath_bytes = 0;
 	unsigned int swath_bytes_l = 0;
@@ -279,12 +217,10 @@ static void handle_det_buf_split(
 	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,
+		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,
+		full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
 				256,
 				1) + 256;
 	}
@@ -292,29 +228,19 @@ static void handle_det_buf_split(
 	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 */
+		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) */
+		} 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.
-		 */
+		// Note: assumption, the config that pass in will fit into
+		//       the detiled buffer.
 	} else {
 		total_swath_bytes = 2 * full_swath_bytes_packed_l;
 
@@ -342,207 +268,47 @@ static void handle_det_buf_split(
 	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);
+	dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l);
+	dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c);
+	dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n",
+			__func__,
+			full_swath_bytes_packed_l);
+	dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n",
+			__func__,
+			full_swath_bytes_packed_c);
 }
 
-/* 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,
+static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
+		display_data_rq_dlg_params_st *rq_dlg_param,
+		display_data_rq_misc_params_st *rq_misc_param,
+		display_data_rq_sizing_params_st *rq_sizing_param,
 		unsigned int vp_width,
+		unsigned int vp_height,
 		unsigned int data_pitch,
-		int source_format,
-		int tiling,
-		int macro_tile_size,
-		int source_scan,
-		int is_chroma)
+		unsigned int meta_pitch,
+		unsigned int source_format,
+		unsigned int tiling,
+		unsigned int macro_tile_size,
+		unsigned int source_scan,
+		unsigned int is_chroma)
 {
 	bool surf_linear = (tiling == dm_sw_linear);
 	bool surf_vert = (source_scan == dm_vert);
 
-	unsigned int bytes_per_element = 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 bytes_per_element;
+	unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format),
+			false);
+	unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format),
+			true);
+
 	unsigned int blk256_width = 0;
 	unsigned int blk256_height = 0;
 
-	unsigned int 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 blk256_width_y = 0;
+	unsigned int blk256_height_y = 0;
+	unsigned int blk256_width_c = 0;
+	unsigned int blk256_height_c = 0;
 	unsigned int log2_bytes_per_element;
-	unsigned int blk256_width;
-	unsigned int blk256_height;
 	unsigned int log2_blk256_width;
 	unsigned int log2_blk256_height;
 	unsigned int blk_bytes;
@@ -558,6 +324,8 @@ static void get_surf_rq_param(
 	unsigned int meta_row_width_ub;
 	unsigned int log2_meta_chunk_bytes;
 	unsigned int log2_meta_chunk_height;
+
+	//full sized meta chunk width in unit of data elements
 	unsigned int log2_meta_chunk_width;
 	unsigned int log2_min_meta_chunk_bytes;
 	unsigned int min_meta_chunk_width;
@@ -572,93 +340,72 @@ static void get_surf_rq_param(
 	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;
+	const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+	const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
+	const unsigned int pde_proc_buffer_size_64k_reqs =
+			mode_lib->ip.pde_proc_buffer_size_64k_reqs;
+
+	unsigned int log2_vmpg_height = 0;
+	unsigned int log2_vmpg_width = 0;
+	unsigned int log2_dpte_req_height_ptes = 0;
+	unsigned int log2_dpte_req_height = 0;
+	unsigned int log2_dpte_req_width = 0;
+	unsigned int log2_dpte_row_height_linear = 0;
+	unsigned int log2_dpte_row_height = 0;
+	unsigned int log2_dpte_group_width = 0;
+	unsigned int dpte_row_width_ub = 0;
+	unsigned int dpte_req_height = 0;
+	unsigned int dpte_req_width = 0;
+	unsigned int dpte_group_width = 0;
+	unsigned int log2_dpte_group_bytes = 0;
+	unsigned int log2_dpte_group_length = 0;
+	unsigned int pde_buf_entries;
+	bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10);
+
+	Calculate256BBlockSizes((enum source_format_class)(source_format),
+			(enum dm_swizzle_mode)(tiling),
+			bytes_per_element_y,
+			bytes_per_element_c,
+			&blk256_height_y,
+			&blk256_height_c,
+			&blk256_width_y,
+			&blk256_width_c);
+
+	if (!is_chroma) {
+		blk256_width = blk256_width_y;
+		blk256_height = blk256_height_y;
+		bytes_per_element = bytes_per_element_y;
 	} else {
-		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;
+		blk256_width = blk256_width_c;
+		blk256_height = blk256_height_c;
+		bytes_per_element = bytes_per_element_c;
 	}
 
-	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);
+	dml_print("DML_DLG: %s: surf_linear        = %d\n", __func__, surf_linear);
+	dml_print("DML_DLG: %s: surf_vert          = %d\n", __func__, surf_vert);
+	dml_print("DML_DLG: %s: blk256_width       = %d\n", __func__, blk256_width);
+	dml_print("DML_DLG: %s: blk256_height      = %d\n", __func__, blk256_height);
 
 	log2_blk256_width = dml_log2((double) blk256_width);
 	log2_blk256_height = dml_log2((double) blk256_height);
-	blk_bytes =
-			surf_linear ? 256 : get_blk_size_bytes(
-							(enum source_macro_tile_size) pipe_src_param.macro_tile_size);
+	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 (pipe_src_param.sw_mode != dm_sw_linear)
+	// 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);
+				+ dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
 	else
-		log2_blk_height = 0; /* blk height of 1 */
+		log2_blk_height = 0;  // blk height of 1
 
 	log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
 
@@ -667,10 +414,8 @@ static void get_surf_rq_param(
 				+ 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->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;
 	}
 
@@ -684,15 +429,14 @@ static void get_surf_rq_param(
 	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 */
+	// -------
+	// 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 */
+	// 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;
@@ -700,9 +444,8 @@ static void get_surf_rq_param(
 	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
-	 */
+	// 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)
@@ -716,10 +459,12 @@ static void get_surf_rq_param(
 	}
 	rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
 
+	rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
+
 	log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
 	log2_meta_chunk_height = log2_meta_row_height;
 
-	/*full sized meta chunk width in unit of data elements */
+	//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);
@@ -734,21 +479,24 @@ static void get_surf_rq_param(
 	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;
+			* (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,
+	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 */
+	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);
+	dml_print("DML_DLG: %s: meta_blk_height             = %d\n", __func__, meta_blk_height);
+	dml_print("DML_DLG: %s: meta_blk_width              = %d\n", __func__, meta_blk_width);
+	dml_print("DML_DLG: %s: meta_surface_bytes          = %d\n", __func__, meta_surface_bytes);
+	dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub   = %d\n",
+			__func__,
+			meta_pte_req_per_frame_ub);
+	dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n",
+			__func__,
+			meta_pte_bytes_per_frame_ub);
 
 	if (!surf_vert)
 		meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
@@ -760,67 +508,58 @@ static void get_surf_rq_param(
 	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;
-
+	// ------
+	// dpte
+	// ------
 	if (surf_linear) {
-		log2_vmpg_height = 0; /* one line high */
+		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)
+	// only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4.
+	if (surf_linear) { //one 64B PTE request returns 8 PTEs
 		log2_dpte_req_height_ptes = 0;
-	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;
+		log2_dpte_req_width = log2_vmpg_width + 3;
+		log2_dpte_req_height = 0;
+	} else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size
+		//one 64B req gives 8x1 PTEs for 4KB tile
+		log2_dpte_req_height_ptes = 0;
+		log2_dpte_req_width = log2_blk_width + 3;
+		log2_dpte_req_height = log2_blk_height + 0;
+	} else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB
+		//two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB
+		log2_dpte_req_height_ptes = 4;
+		log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width
+		log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height
+	} else { //64KB page size and must 64KB tile block
+		 //one 64B req gives 8x1 PTEs for 64KB tile
+		log2_dpte_req_height_ptes = 0;
+		log2_dpte_req_width = log2_blk_width + 3;
+		log2_dpte_req_height = log2_blk_height + 0;
+	}
+
+	// The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
+	// log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
+	// That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
+	//log2_dpte_req_height    = log2_vmpg_height + log2_dpte_req_height_ptes;
+	//log2_dpte_req_width     = log2_vmpg_width + log2_dpte_req_width_ptes;
 	dpte_req_height = 1 << log2_dpte_req_height;
 	dpte_req_width = 1 << log2_dpte_req_width;
 
-	/* calculate pitch dpte row buffer can hold
-	 * round the result down to a power of two.
-	 */
+	// calculate pitch dpte row buffer can hold
+	// round the result down to a power of two.
+	pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs;
 	if (surf_linear) {
-		log2_dpte_row_height_linear = dml_floor(
-				dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch));
+		unsigned int dpte_row_height;
+
+		log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries
+										/ bytes_per_element,
+								dpte_buf_in_pte_reqs
+										* dpte_req_width)
+								/ data_pitch),
+				1);
 
 		ASSERT(log2_dpte_row_height_linear >= 3);
 
@@ -828,18 +567,16 @@ static void get_surf_rq_param(
 			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,
+		// For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
+		// the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
+		dpte_row_height = 1 << log2_dpte_row_height;
+		dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1,
 				dpte_req_width,
 				1) + dpte_req_width;
 		rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
 	} else {
-		/* for tiled mode, row height is the same as req height and row store up to vp size upper bound */
+		// the upper bound of the dpte_row_width without dependency on viewport position follows.
+		// for tiled mode, row height is the same as req height and row store up to vp size upper bound
 		if (!surf_vert) {
 			log2_dpte_row_height = log2_dpte_req_height;
 			dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1)
@@ -853,103 +590,117 @@ static void get_surf_rq_param(
 					+ 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;
 	}
+	if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB
+		rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request
+	else
+		rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request
 
-	/* 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_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 */
+		//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.  */
+	//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  */
+	log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests
 
-	/* full sized data pte group width in elements */
+	// full sized data pte group width in elements
 	if (!surf_vert)
 		log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
 	else
 		log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
 
+	//But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B
+	if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB
+		log2_dpte_group_width = log2_dpte_group_width - 1;
+
 	dpte_group_width = 1 << log2_dpte_group_width;
 
-	/* since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
-	 * the upper bound for the dpte groups per row is as follows.
-	 */
-	rq_dlg_param->dpte_groups_per_row_ub = dml_ceil(
-			(double) dpte_row_width_ub / dpte_group_width);
+	// since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
+	// the upper bound for the dpte groups per row is as follows.
+	rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width,
+			1);
+}
+
+static void get_surf_rq_param(struct display_mode_lib *mode_lib,
+		display_data_rq_sizing_params_st *rq_sizing_param,
+		display_data_rq_dlg_params_st *rq_dlg_param,
+		display_data_rq_misc_params_st *rq_misc_param,
+		const display_pipe_source_params_st pipe_src_param,
+		bool is_chroma)
+{
+	bool mode_422 = 0;
+	unsigned int vp_width = 0;
+	unsigned int vp_height = 0;
+	unsigned int data_pitch = 0;
+	unsigned int meta_pitch = 0;
+	unsigned int ppe = mode_422 ? 2 : 1;
+
+	// FIXME check if ppe apply for both luma and chroma in 422 case
+	if (is_chroma) {
+		vp_width = pipe_src_param.viewport_width_c / ppe;
+		vp_height = pipe_src_param.viewport_height_c;
+		data_pitch = pipe_src_param.data_pitch_c;
+		meta_pitch = pipe_src_param.meta_pitch_c;
+	} else {
+		vp_width = pipe_src_param.viewport_width / ppe;
+		vp_height = pipe_src_param.viewport_height;
+		data_pitch = pipe_src_param.data_pitch;
+		meta_pitch = pipe_src_param.meta_pitch;
+	}
+
+	rq_sizing_param->chunk_bytes = 8192;
+
+	if (rq_sizing_param->chunk_bytes == 64 * 1024)
+		rq_sizing_param->min_chunk_bytes = 0;
+	else
+		rq_sizing_param->min_chunk_bytes = 1024;
+
+	rq_sizing_param->meta_chunk_bytes = 2048;
+	rq_sizing_param->min_meta_chunk_bytes = 256;
+
+	rq_sizing_param->mpte_group_bytes = 2048;
 
-	dml_rq_dlg_get_row_heights(
-			mode_lib,
-			&func_dpte_row_height,
-			&func_meta_row_height,
+	get_meta_and_pte_attr(mode_lib,
+			rq_dlg_param,
+			rq_misc_param,
+			rq_sizing_param,
 			vp_width,
+			vp_height,
 			data_pitch,
+			meta_pitch,
 			pipe_src_param.source_format,
 			pipe_src_param.sw_mode,
 			pipe_src_param.macro_tile_size,
 			pipe_src_param.source_scan,
 			is_chroma);
-
-	/* 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)
+void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
+		display_rq_params_st *rq_param,
+		const display_pipe_source_params_st pipe_src_param)
 {
-	/* get param for luma surface */
+	// 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,
+	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,
+	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),
@@ -957,355 +708,126 @@ void dml_rq_dlg_get_rq_params(
 				1);
 	}
 
-	/* calculate how to split the det buffer space between luma and chroma */
+	// 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)
+void dml_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
+		display_rq_regs_st *rq_regs,
+		const display_pipe_source_params_st pipe_src_param)
 {
-	struct _vcs_dpi_display_rq_params_st rq_param = {0};
+	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,
+// 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,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
+		display_dlg_regs_st *disp_dlg_regs,
+		display_ttu_regs_st *disp_ttu_regs,
+		const display_rq_dlg_params_st rq_dlg_param,
+		const display_dlg_sys_params_st dlg_sys_param,
 		const bool cstate_en,
 		const bool pstate_en,
-		const bool vm_en)
+		const bool vm_en,
+		const bool ignore_viewport_pos,
+		const bool immediate_flip_support)
 {
-	/* Prefetch */
-	unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
-	bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
+	const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
+	const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
+	const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout;
+	const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
+	const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth;
+	const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps;
+
+	// -------------------------
+	// Section 1.15.2.1: OTG dependent Params
+	// -------------------------
+	// Timing
+	unsigned int htotal = dst->htotal;
+//    unsigned int hblank_start = dst.hblank_start; // TODO: Remove
+	unsigned int hblank_end = dst->hblank_end;
+	unsigned int vblank_start = dst->vblank_start;
+	unsigned int vblank_end = dst->vblank_end;
 	unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
-	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 dppclk_freq_in_mhz = clks->dppclk_mhz;
+	double dispclk_freq_in_mhz = clks->dispclk_mhz;
+	double refclk_freq_in_mhz = clks->refclk_mhz;
+	double pclk_freq_in_mhz = dst->pixel_rate_mhz;
+	bool interlaced = dst->interlaced;
 
-	double 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 ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
 
-	if (interlaced)
-		vstartup_start = vstartup_start / 2;
+	double min_dcfclk_mhz;
+	double t_calc_us;
+	double min_ttu_vblank;
 
-	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);
-	}
+	double min_dst_y_ttu_vblank;
+	unsigned int dlg_vblank_start;
+	bool dual_plane;
+	bool mode_422;
+	unsigned int access_dir;
+	unsigned int vp_height_l;
+	unsigned int vp_width_l;
+	unsigned int vp_height_c;
+	unsigned int vp_width_c;
 
-	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;
+	// Scaling
+	unsigned int htaps_l;
+	unsigned int htaps_c;
+	double hratio_l;
+	double hratio_c;
+	double vratio_l;
+	double vratio_c;
+	bool scl_enable;
 
-	if (e2e_pipe_param.dout.output_format == dm_420)
-		dst_y_after_scaler = 1;
-	else
-		dst_y_after_scaler = 0;
+	double line_time_in_us;
+	//    double vinit_l;
+	//    double vinit_c;
+	//    double vinit_bot_l;
+	//    double vinit_bot_c;
 
-	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_height_l;
 	unsigned int swath_width_ub_l;
-	unsigned int dpte_bytes_per_row_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 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_bytes_per_row_ub_c;
 	unsigned int dpte_groups_per_row_ub_c;
+
 	unsigned int meta_chunks_per_row_ub_l;
+	unsigned int meta_chunks_per_row_ub_c;
 	unsigned int vupdate_offset;
 	unsigned int vupdate_width;
 	unsigned int vready_offset;
+
 	unsigned int dppclk_delay_subtotal;
 	unsigned int dispclk_delay_subtotal;
 	unsigned int pixel_rate_delay_subtotal;
+
 	unsigned int vstartup_start;
 	unsigned int dst_x_after_scaler;
 	unsigned int dst_y_after_scaler;
 	double line_wait;
-	double 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 dst_y_per_vm_flip;
+	double dst_y_per_row_flip;
 	double min_dst_y_per_vm_vblank;
 	double min_dst_y_per_row_vblank;
 	double lsw;
@@ -1314,6 +836,7 @@ void dml_rq_dlg_get_dlg_params(
 	unsigned int req_per_swath_ub_l;
 	unsigned int req_per_swath_ub_c;
 	unsigned int meta_row_height_l;
+	unsigned int meta_row_height_c;
 	unsigned int swath_width_pixels_ub_l;
 	unsigned int swath_width_pixels_ub_c;
 	unsigned int scaler_rec_in_width_l;
@@ -1328,59 +851,52 @@ void dml_rq_dlg_get_dlg_params(
 	double refcyc_per_line_delivery_pre_c;
 	double refcyc_per_line_delivery_l;
 	double refcyc_per_line_delivery_c;
+
 	double refcyc_per_req_delivery_pre_l;
 	double refcyc_per_req_delivery_pre_c;
 	double refcyc_per_req_delivery_l;
 	double refcyc_per_req_delivery_c;
+
+	unsigned int full_recout_width;
+	double xfc_transfer_delay;
+	double xfc_precharge_delay;
+	double xfc_remote_surface_flip_latency;
+	double xfc_dst_y_delta_drq_limit;
+	double xfc_prefetch_margin;
 	double refcyc_per_req_delivery_pre_cur0;
 	double refcyc_per_req_delivery_cur0;
-	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;
+	double refcyc_per_req_delivery_pre_cur1;
+	double refcyc_per_req_delivery_cur1;
 
 	memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
 	memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
 
-	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;
+	dml_print("DML_DLG: %s:  cstate_en = %d\n", __func__, cstate_en);
+	dml_print("DML_DLG: %s:  pstate_en = %d\n", __func__, pstate_en);
+	dml_print("DML_DLG: %s:  vm_en     = %d\n", __func__, vm_en);
+	dml_print("DML_DLG: %s:  ignore_viewport_pos  = %d\n", __func__, ignore_viewport_pos);
+	dml_print("DML_DLG: %s:  immediate_flip_support  = %d\n", __func__, immediate_flip_support);
+
+	dml_print("DML_DLG: %s: dppclk_freq_in_mhz     = %3.2f\n", __func__, dppclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: dispclk_freq_in_mhz    = %3.2f\n", __func__, dispclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: refclk_freq_in_mhz     = %3.2f\n", __func__, refclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: pclk_freq_in_mhz       = %3.2f\n", __func__, pclk_freq_in_mhz);
+	dml_print("DML_DLG: %s: interlaced             = %d\n", __func__, interlaced);
 	ASSERT(ref_freq_to_pix_freq < 4.0);
+
 	disp_dlg_regs->ref_freq_to_pix_freq =
 			(unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
 	disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal
 			* dml_pow(2, 8));
+	disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits
 	disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end
 			* (double) ref_freq_to_pix_freq);
 	ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13));
-	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;
+	set_prefetch_mode(mode_lib, cstate_en, pstate_en, ignore_viewport_pos, immediate_flip_support);
+	t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes);
+	min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
 
 	min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal;
 	dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
@@ -1389,383 +905,202 @@ void dml_rq_dlg_get_dlg_params(
 			+ 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",
+	dml_print("DML_DLG: %s: min_dcfclk_mhz                         = %3.2f\n",
+			__func__,
+			min_dcfclk_mhz);
+	dml_print("DML_DLG: %s: min_ttu_vblank                         = %3.2f\n",
+			__func__,
+			min_ttu_vblank);
+	dml_print("DML_DLG: %s: min_dst_y_ttu_vblank                   = %3.2f\n",
 			__func__,
 			min_dst_y_ttu_vblank);
-	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",
+	dml_print("DML_DLG: %s: t_calc_us                              = %3.2f\n",
+			__func__,
+			t_calc_us);
+	dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start    = 0x%0x\n",
 			__func__,
 			disp_dlg_regs->min_dst_y_next_start);
-	DTRACE(
-			"DLG: %s: ref_freq_to_pix_freq                   = %3.2f",
+	dml_print("DML_DLG: %s: ref_freq_to_pix_freq                   = %3.2f\n",
 			__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;
+	// -------------------------
+	// Section 1.15.2.2: Prefetch, Active and TTU
+	// -------------------------
+	// Prefetch Calc
+	// Source
+//             dcc_en              = src.dcc;
+	dual_plane = is_dual_plane((enum source_format_class)(src->source_format));
+	mode_422 = 0; // FIXME
+	access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
+//      bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0);
+//      bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1);
+	vp_height_l = src->viewport_height;
+	vp_width_l = src->viewport_width;
+	vp_height_c = src->viewport_height_c;
+	vp_width_c = src->viewport_width_c;
+
+	// Scaling
+	htaps_l = taps->htaps;
+	htaps_c = taps->htaps_c;
+	hratio_l = scl->hscl_ratio;
+	hratio_c = scl->hscl_ratio_c;
+	vratio_l = scl->vscl_ratio;
+	vratio_c = scl->vscl_ratio_c;
+	scl_enable = scl->scl_enable;
 
 	line_time_in_us = (htotal / pclk_freq_in_mhz);
-	vinit_l = 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;
+//     vinit_l         = scl.vinit;
+//     vinit_c         = scl.vinit_c;
+//     vinit_bot_l     = scl.vinit_bot;
+//     vinit_bot_c     = scl.vinit_bot_c;
 
-	swath_height_l = rq_dlg_param.rq_l.swath_height;
+//    unsigned int 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;
+//    unsigned int dpte_bytes_per_row_ub_l        = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
 	dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
-	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;
+//    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;
 
-	swath_height_c = rq_dlg_param.rq_c.swath_height;
+//    unsigned int swath_height_c                 = rq_dlg_param.rq_c.swath_height;
 	swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
-	dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
+	//   dpte_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;
+	meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub;
+	vupdate_offset = dst->vupdate_offset;
+	vupdate_width = dst->vupdate_width;
+	vready_offset = dst->vready_offset;
 
 	dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
 	dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
+
+	if (scl_enable)
+		dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl;
+	else
+		dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only;
+
+	dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter
+			+ src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor;
+
+	if (dout->dsc_enable) {
+		double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+		dispclk_delay_subtotal += dsc_delay;
+	}
+
 	pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
 			+ dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
 
-	vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
+	vstartup_start = dst->vstartup_start;
+	if (interlaced) {
+		if (vstartup_start / 2.0
+				- (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
+				<= vblank_end / 2.0)
+			disp_dlg_regs->vready_after_vcount0 = 1;
+		else
+			disp_dlg_regs->vready_after_vcount0 = 0;
+	} else {
+		if (vstartup_start
+				- (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
+				<= vblank_end)
+			disp_dlg_regs->vready_after_vcount0 = 1;
+		else
+			disp_dlg_regs->vready_after_vcount0 = 0;
+	}
 
+	// TODO: Where is this coming from?
 	if (interlaced)
 		vstartup_start = vstartup_start / 2;
 
+	// TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp?
 	if (vstartup_start >= min_vblank) {
-		DTRACE(
-				"WARNING_DLG: %s:  vblank_start=%d vblank_end=%d",
+		dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n",
 				__func__,
 				vblank_start,
 				vblank_end);
-		DTRACE(
-				"WARNING_DLG: %s:  vstartup_start=%d should be less than min_vblank=%d",
+		dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
 				__func__,
 				vstartup_start,
 				min_vblank);
 		min_vblank = vstartup_start + 1;
-		DTRACE(
-				"WARNING_DLG: %s:  vstartup_start=%d should be less than min_vblank=%d",
+		dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
 				__func__,
 				vstartup_start,
 				min_vblank);
 	}
 
-	dst_x_after_scaler = 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;
-	}
+	dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
 
-	DTRACE("DLG: %s: htotal                                 = %d", __func__, htotal);
-	DTRACE(
-			"DLG: %s: pixel_rate_delay_subtotal              = %d",
+	dml_print("DML_DLG: %s: htotal                                 = %d\n", __func__, htotal);
+	dml_print("DML_DLG: %s: pixel_rate_delay_subtotal              = %d\n",
 			__func__,
 			pixel_rate_delay_subtotal);
-	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);
+	dml_print("DML_DLG: %s: dst_x_after_scaler                     = %d\n",
+			__func__,
+			dst_x_after_scaler);
+	dml_print("DML_DLG: %s: dst_y_after_scaler                     = %d\n",
+			__func__,
+			dst_y_after_scaler);
 
+	// Lwait
 	line_wait = mode_lib->soc.urgent_latency_us;
 	if (cstate_en)
 		line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
 	if (pstate_en)
-		line_wait = dml_max(
-				mode_lib->soc.dram_clock_change_latency_us
+		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;
+	dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
 
-	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);
+	dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
 
 	min_dst_y_per_vm_vblank = 8.0;
 	min_dst_y_per_row_vblank = 16.0;
+
+	// magic!
 	if (htotal <= 75) {
 		min_vblank = 300;
 		min_dst_y_per_vm_vblank = 100.0;
 		min_dst_y_per_row_vblank = 100.0;
 	}
 
+	dml_print("DML_DLG: %s: dst_y_per_vm_vblank    = %3.2f\n", __func__, dst_y_per_vm_vblank);
+	dml_print("DML_DLG: %s: dst_y_per_row_vblank   = %3.2f\n", __func__, dst_y_per_row_vblank);
+
 	ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
 	ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
 
 	ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
 	lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
 
-	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));
+	dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw);
 
-	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));
+	vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
 
-	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 */
+	dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l);
+	dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c);
 
-	/* Active */
+	// Active
 	req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
 	req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
 	meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
+	meta_row_height_c = rq_dlg_param.rq_c.meta_row_height;
 	swath_width_pixels_ub_l = 0;
 	swath_width_pixels_ub_c = 0;
 	scaler_rec_in_width_l = 0;
@@ -1773,40 +1108,8 @@ void dml_rq_dlg_get_dlg_params(
 	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_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;
@@ -1821,15 +1124,15 @@ void dml_rq_dlg_get_dlg_params(
 	if (htaps_l <= 1)
 		min_hratio_fact_l = 2.0;
 	else if (htaps_l <= 6) {
-		if ((hratios_l * 2.0) > 4.0)
+		if ((hratio_l * 2.0) > 4.0)
 			min_hratio_fact_l = 4.0;
 		else
-			min_hratio_fact_l = hratios_l * 2.0;
+			min_hratio_fact_l = hratio_l * 2.0;
 	} else {
-		if (hratios_l > 4.0)
+		if (hratio_l > 4.0)
 			min_hratio_fact_l = 4.0;
 		else
-			min_hratio_fact_l = hratios_l;
+			min_hratio_fact_l = hratio_l;
 	}
 
 	hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
@@ -1837,15 +1140,15 @@ void dml_rq_dlg_get_dlg_params(
 	if (htaps_c <= 1)
 		min_hratio_fact_c = 2.0;
 	else if (htaps_c <= 6) {
-		if ((hratios_c * 2.0) > 4.0)
+		if ((hratio_c * 2.0) > 4.0)
 			min_hratio_fact_c = 4.0;
 		else
-			min_hratio_fact_c = hratios_c * 2.0;
+			min_hratio_fact_c = hratio_c * 2.0;
 	} else {
-		if (hratios_c > 4.0)
+		if (hratio_c > 4.0)
 			min_hratio_fact_c = 4.0;
 		else
-			min_hratio_fact_c = hratios_c;
+			min_hratio_fact_c = hratio_c;
 	}
 
 	hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
@@ -1859,97 +1162,90 @@ void dml_rq_dlg_get_dlg_params(
 	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 */
+	// In ODM
+	if (src->is_hsplit) {
+		// This "hack"  is only allowed (and valid) for MPC combine. In ODM
+		// combine, you MUST specify the full_recout_width...according to Oswin
+		if (dst->full_recout_width == 0 && !dst->odm_combine) {
+			dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n",
+					__func__);
+			full_recout_width = dst->recout_width * 2; // assume half split for dcn1
 		} else
-			full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width;
+			full_recout_width = dst->full_recout_width;
 	} else
-		full_recout_width = e2e_pipe_param.pipe.dest.recout_width;
+		full_recout_width = dst->recout_width;
 
-	refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(
-			mode_lib,
+	// mpc_combine and odm_combine are mutually exclusive
+	refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
 			refclk_freq_in_mhz,
 			pclk_freq_in_mhz,
+			dst->odm_combine,
 			full_recout_width,
+			dst->hactive,
 			vratio_pre_l,
 			hscale_pixel_rate_l,
 			swath_width_pixels_ub_l,
-			1); /* per line */
+			1); // per line
 
-	refcyc_per_line_delivery_l = get_refcyc_per_delivery(
-			mode_lib,
+	refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib,
 			refclk_freq_in_mhz,
 			pclk_freq_in_mhz,
+			dst->odm_combine,
 			full_recout_width,
+			dst->hactive,
 			vratio_l,
 			hscale_pixel_rate_l,
 			swath_width_pixels_ub_l,
-			1); /* per line */
+			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",
+	dml_print("DML_DLG: %s: full_recout_width              = %d\n",
 			__func__,
-			refcyc_per_line_delivery_pre_l);
-	DTRACE(
-			"DLG: %s: refcyc_per_line_delivery_l     = %3.2f",
+			full_recout_width);
+	dml_print("DML_DLG: %s: hscale_pixel_rate_l            = %3.2f\n",
+			__func__,
+			hscale_pixel_rate_l);
+	dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n",
 			__func__,
-			refcyc_per_line_delivery_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(
+	dml_print("DML_DLG: %s: refcyc_per_line_delivery_l     = %3.2f\n",
+			__func__,
 			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,
+		refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
 				refclk_freq_in_mhz,
 				pclk_freq_in_mhz,
+				dst->odm_combine,
 				full_recout_width,
+				dst->hactive,
 				vratio_pre_c,
 				hscale_pixel_rate_c,
 				swath_width_pixels_ub_c,
-				1); /* per line */
+				1); // per line
 
-		refcyc_per_line_delivery_c = get_refcyc_per_delivery(
-				mode_lib,
+		refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib,
 				refclk_freq_in_mhz,
 				pclk_freq_in_mhz,
+				dst->odm_combine,
 				full_recout_width,
+				dst->hactive,
 				vratio_c,
 				hscale_pixel_rate_c,
 				swath_width_pixels_ub_c,
-				1); /* per line */
+				1);  // per line
 
-		DTRACE(
-				"DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
+		dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n",
 				__func__,
 				refcyc_per_line_delivery_pre_c);
-		DTRACE(
-				"DLG: %s: refcyc_per_line_delivery_c     = %3.2f",
+		dml_print("DML_DLG: %s: refcyc_per_line_delivery_c     = %3.2f\n",
 				__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 */
+	// 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 {
@@ -1957,167 +1253,264 @@ void dml_rq_dlg_get_dlg_params(
 		scaler_rec_in_width_c = vp_width_c;
 	}
 
-	refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(
-			mode_lib,
+	refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
 			refclk_freq_in_mhz,
 			pclk_freq_in_mhz,
+			dst->odm_combine,
 			full_recout_width,
+			dst->hactive,
 			vratio_pre_l,
 			hscale_pixel_rate_l,
 			scaler_rec_in_width_l,
-			req_per_swath_ub_l); /* per req */
-	refcyc_per_req_delivery_l = get_refcyc_per_delivery(
-			mode_lib,
+			req_per_swath_ub_l);  // per req
+	refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib,
 			refclk_freq_in_mhz,
 			pclk_freq_in_mhz,
+			dst->odm_combine,
 			full_recout_width,
+			dst->hactive,
 			vratio_l,
 			hscale_pixel_rate_l,
 			scaler_rec_in_width_l,
-			req_per_swath_ub_l); /* per req */
+			req_per_swath_ub_l);  // per req
 
-	DTRACE(
-			"DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
+	dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n",
 			__func__,
 			refcyc_per_req_delivery_pre_l);
-	DTRACE(
-			"DLG: %s: refcyc_per_req_delivery_l     = %3.2f",
+	dml_print("DML_DLG: %s: refcyc_per_req_delivery_l     = %3.2f\n",
 			__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,
+		refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
 				refclk_freq_in_mhz,
 				pclk_freq_in_mhz,
+				dst->odm_combine,
 				full_recout_width,
+				dst->hactive,
 				vratio_pre_c,
 				hscale_pixel_rate_c,
 				scaler_rec_in_width_c,
-				req_per_swath_ub_c); /* per req  */
-		refcyc_per_req_delivery_c = get_refcyc_per_delivery(
-				mode_lib,
+				req_per_swath_ub_c);  // per req
+		refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib,
 				refclk_freq_in_mhz,
 				pclk_freq_in_mhz,
+				dst->odm_combine,
 				full_recout_width,
+				dst->hactive,
 				vratio_c,
 				hscale_pixel_rate_c,
 				scaler_rec_in_width_c,
-				req_per_swath_ub_c); /* per req */
+				req_per_swath_ub_c);  // per req
 
-		DTRACE(
-				"DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n",
 				__func__,
 				refcyc_per_req_delivery_pre_c);
-		DTRACE(
-				"DLG: %s: refcyc_per_req_delivery_c     = %3.2f",
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_c     = %3.2f\n",
 				__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;
-		}
+	// XFC
+	xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+	xfc_precharge_delay = get_xfc_precharge_delay(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+	xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency;
+	xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx);
+
+	// TTU - Cursor
+	refcyc_per_req_delivery_pre_cur0 = 0.0;
+	refcyc_per_req_delivery_cur0 = 0.0;
+	if (src->num_cursors > 0) {
+		calculate_ttu_cursor(mode_lib,
+				&refcyc_per_req_delivery_pre_cur0,
+				&refcyc_per_req_delivery_cur0,
+				refclk_freq_in_mhz,
+				ref_freq_to_pix_freq,
+				hscale_pixel_rate_l,
+				scl->hscl_ratio,
+				vratio_pre_l,
+				vratio_l,
+				src->cur0_src_width,
+				(enum cursor_bpp)(src->cur0_bpp));
+	}
+
+	refcyc_per_req_delivery_pre_cur1 = 0.0;
+	refcyc_per_req_delivery_cur1 = 0.0;
+	if (src->num_cursors > 1) {
+		calculate_ttu_cursor(mode_lib,
+				&refcyc_per_req_delivery_pre_cur1,
+				&refcyc_per_req_delivery_cur1,
+				refclk_freq_in_mhz,
+				ref_freq_to_pix_freq,
+				hscale_pixel_rate_l,
+				scl->hscl_ratio,
+				vratio_pre_l,
+				vratio_l,
+				src->cur1_src_width,
+				(enum cursor_bpp)(src->cur1_bpp));
+	}
 
-		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 */
+	// TTU - Misc
+	// all hard-coded
 
-		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;
-		}
+	// Assignment to register structures
+	disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
+	disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk
+	ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
+	disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
+	disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
 
-		disp_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));
+	disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
+	disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
 
-		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;
+	disp_dlg_regs->refcyc_per_pte_group_vblank_l =
+			(unsigned int) (dst_y_per_row_vblank * (double) htotal
+					* ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
+	ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
+
+	if (dual_plane) {
+		disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank
+				* (double) htotal * ref_freq_to_pix_freq
+				/ (double) dpte_groups_per_row_ub_c);
+		ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c
+						< (unsigned int) dml_pow(2, 13));
+	}
+
+	disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
+			(unsigned int) (dst_y_per_row_vblank * (double) htotal
+					* ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
+	ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
+
+	disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
+			disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0.  assigned to be the same as _l for now
+
+	disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
+			* ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l;
+	disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
+			* ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l;
+
+	if (dual_plane) {
+		disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip
+				* htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c;
+		disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip
+				* htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c;
+	}
+
+	disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
+			/ (double) vratio_l * dml_pow(2, 2));
+	ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
+
+	if (dual_plane) {
+		disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
+				/ (double) vratio_c * dml_pow(2, 2));
+		if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
+			dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n",
+					__func__,
+					disp_dlg_regs->dst_y_per_pte_row_nom_c,
+					(unsigned int) dml_pow(2, 17) - 1);
 		}
+	}
 
-		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_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_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;
+	disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0.  assigned to be the same as _l for now
+
+	disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
+			/ (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+			/ (double) dpte_groups_per_row_ub_l);
+	if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
+		disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
+	disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
+			/ (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+			/ (double) meta_chunks_per_row_ub_l);
+	if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
+		disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
+
+	if (dual_plane) {
+		disp_dlg_regs->refcyc_per_pte_group_nom_c =
+				(unsigned int) ((double) dpte_row_height_c / (double) vratio_c
+						* (double) htotal * ref_freq_to_pix_freq
+						/ (double) dpte_groups_per_row_ub_c);
+		if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
+			disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
+
+		// TODO: Is this the right calculation? Does htotal need to be halved?
+		disp_dlg_regs->refcyc_per_meta_chunk_nom_c =
+				(unsigned int) ((double) meta_row_height_c / (double) vratio_c
+						* (double) htotal * ref_freq_to_pix_freq
+						/ (double) meta_chunks_per_row_ub_c);
+		if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
+			disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1;
 	}
 
-	/* TTU - Misc */
+	disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l,
+			1);
+	disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l,
+			1);
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
+
+	disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c,
+			1);
+	disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c,
+			1);
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
+
+	disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
+	disp_dlg_regs->dst_y_offset_cur0 = 0;
+	disp_dlg_regs->chunk_hdl_adjust_cur1 = 3;
+	disp_dlg_regs->dst_y_offset_cur1 = 0;
+
+	disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay;
+	disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay;
+	disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency;
+	disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz,
+			1);
+
+	// slave has to have this value also set to off
+	if (src->xfc_enable && !src->xfc_slave)
+		disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1);
+	else
+		disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
+
+	disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
+			(unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0
+			* dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 =
+			(unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10));
+	disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1
+			* dml_pow(2, 10));
 	disp_ttu_regs->qos_level_low_wm = 0;
 	ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
 	disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
@@ -2139,118 +1532,232 @@ void dml_rq_dlg_get_dlg_params(
 	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,
+void dml_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
+		display_dlg_regs_st *dlg_regs,
+		display_ttu_regs_st *ttu_regs,
+		display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
 		const bool cstate_en,
 		const bool pstate_en,
 		const bool vm_en,
-		const bool iflip_en)
+		const bool ignore_viewport_pos,
+		const bool immediate_flip_support)
 {
-	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,
+	display_rq_params_st rq_param = {0};
+	display_dlg_sys_params_st dlg_sys_param = {0};
+
+	// Get watermark and Tex.
+	dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib,
+			e2e_pipe_param,
+			num_pipes);
+	dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes);
+	dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib,
 			e2e_pipe_param,
 			num_pipes);
+	dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
+			e2e_pipe_param,
+			num_pipes);
+	dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
+			/ dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
 
 	print__dlg_sys_params_st(mode_lib, dlg_sys_param);
 
-	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;
+	// system parameter calculation done
 
-	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_print("DML_DLG: Calculation for pipe[%d] start\n\n", 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,
+	dml_rq_dlg_get_dlg_params(mode_lib,
+			e2e_pipe_param,
+			num_pipes,
+			pipe_idx,
 			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);
+			ignore_viewport_pos,
+			immediate_flip_support);
+	dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx);
 }
 
-void dml_rq_dlg_get_arb_params(
-		struct display_mode_lib *mode_lib,
-		struct _vcs_dpi_display_arb_params_st *arb_param)
+void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, 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;
 }
+
+void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+		double *refcyc_per_req_delivery_pre_cur,
+		double *refcyc_per_req_delivery_cur,
+		double refclk_freq_in_mhz,
+		double ref_freq_to_pix_freq,
+		double hscale_pixel_rate_l,
+		double hscl_ratio,
+		double vratio_pre_l,
+		double vratio_l,
+		unsigned int cur_width,
+		enum cursor_bpp cur_bpp)
+{
+	unsigned int cur_src_width = cur_width;
+	unsigned int cur_req_size = 0;
+	unsigned int cur_req_width = 0;
+	double cur_width_ub = 0.0;
+	double cur_req_per_width = 0.0;
+	double hactive_cur = 0.0;
+
+	ASSERT(cur_src_width <= 256);
+
+	*refcyc_per_req_delivery_pre_cur = 0.0;
+	*refcyc_per_req_delivery_cur = 0.0;
+	if (cur_src_width > 0) {
+		unsigned int cur_bit_per_pixel = 0;
+
+		if (cur_bpp == dm_cur_2bit) {
+			cur_req_size = 64; // byte
+			cur_bit_per_pixel = 2;
+		} else { // 32bit
+			cur_bit_per_pixel = 32;
+			if (cur_src_width >= 1 && cur_src_width <= 16)
+				cur_req_size = 64;
+			else if (cur_src_width >= 17 && cur_src_width <= 31)
+				cur_req_size = 128;
+			else
+				cur_req_size = 256;
+		}
+
+		cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0);
+		cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1)
+				* (double) cur_req_width;
+		cur_req_per_width = cur_width_ub / (double) cur_req_width;
+		hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor
+
+		if (vratio_pre_l <= 1.0) {
+			*refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq
+					/ (double) cur_req_per_width;
+		} else {
+			*refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz
+					* (double) cur_src_width / hscale_pixel_rate_l
+					/ (double) cur_req_per_width;
+		}
+
+		ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13));
+
+		if (vratio_l <= 1.0) {
+			*refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq
+					/ (double) cur_req_per_width;
+		} else {
+			*refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz
+					* (double) cur_src_width / hscale_pixel_rate_l
+					/ (double) cur_req_per_width;
+		}
+
+		dml_print("DML_DLG: %s: cur_req_width                     = %d\n",
+				__func__,
+				cur_req_width);
+		dml_print("DML_DLG: %s: cur_width_ub                      = %3.2f\n",
+				__func__,
+				cur_width_ub);
+		dml_print("DML_DLG: %s: cur_req_per_width                 = %3.2f\n",
+				__func__,
+				cur_req_per_width);
+		dml_print("DML_DLG: %s: hactive_cur                       = %3.2f\n",
+				__func__,
+				hactive_cur);
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur   = %3.2f\n",
+				__func__,
+				*refcyc_per_req_delivery_pre_cur);
+		dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur       = %3.2f\n",
+				__func__,
+				*refcyc_per_req_delivery_cur);
+
+		ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
+	}
+}
+
+unsigned int dml_rq_dlg_get_calculated_vstartup(struct display_mode_lib *mode_lib,
+		display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx)
+{
+	unsigned int vstartup_pipe[DC__NUM_PIPES__MAX];
+	bool visited[DC__NUM_PIPES__MAX];
+	unsigned int pipe_inst = 0;
+	unsigned int i, j, k;
+
+	for (k = 0; k < num_pipes; ++k)
+		visited[k] = false;
+
+	for (i = 0; i < num_pipes; i++) {
+		if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) {
+			unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp;
+
+			for (j = i; j < num_pipes; j++) {
+				if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp
+						&& e2e_pipe_param[j].pipe.src.is_hsplit
+						&& !visited[j]) {
+					vstartup_pipe[j] = get_vstartup_calculated(mode_lib,
+							e2e_pipe_param,
+							num_pipes,
+							pipe_inst);
+					visited[j] = true;
+				}
+			}
+
+			pipe_inst++;
+		}
+
+		if (!visited[i]) {
+			vstartup_pipe[i] = get_vstartup_calculated(mode_lib,
+					e2e_pipe_param,
+					num_pipes,
+					pipe_inst);
+			visited[i] = true;
+			pipe_inst++;
+		}
+	}
+
+	return vstartup_pipe[pipe_idx];
+
+}
+
+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)
+{
+	display_data_rq_dlg_params_st rq_dlg_param;
+	display_data_rq_misc_params_st rq_misc_param;
+	display_data_rq_sizing_params_st rq_sizing_param;
+
+	get_meta_and_pte_attr(mode_lib,
+			&rq_dlg_param,
+			&rq_misc_param,
+			&rq_sizing_param,
+			vp_width,
+			0, // dummy
+			data_pitch,
+			0, // dummy
+			source_format,
+			tiling,
+			macro_tile_size,
+			source_scan,
+			is_chroma);
+
+	*o_dpte_row_height = rq_dlg_param.dpte_row_height;
+	*o_meta_row_height = rq_dlg_param.meta_row_height;
+}

+ 80 - 71
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h

@@ -22,103 +22,114 @@
  * Authors: AMD
  *
  */
-#ifndef __DISPLAY_RQ_DLG_CALC_H__
-#define __DISPLAY_RQ_DLG_CALC_H__
+
+#ifndef __DML2_DISPLAY_RQ_DLG_CALC_H__
+#define __DML2_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.)
- */
+// 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 definition)
+// Input:
+//  pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+// Output:
+//  rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
+//
 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);
+		display_rq_params_st *rq_param,
+		const 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>
- */
+// 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);
+		display_rq_regs_st *rq_regs,
+		const 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,
+// Function: dml_rq_dlg_get_dlg_params
+//  Calculate deadline related parameters
+//
+void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
+		const display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx,
+		display_dlg_regs_st *disp_dlg_regs,
+		display_ttu_regs_st *disp_ttu_regs,
+		const display_rq_dlg_params_st rq_dlg_param,
+		const display_dlg_sys_params_st dlg_sys_param,
 		const bool cstate_en,
 		const bool pstate_en,
 		const bool vm_en,
-		const bool iflip_en);
+		const bool ignore_viewport_pos,
+		const bool immediate_flip_support);
 
-/* 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
- */
+// 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,
+		display_dlg_prefetch_param_st *prefetch_param,
+		display_rq_dlg_params_st rq_dlg_param,
+		display_dlg_sys_params_st dlg_sys_param,
+		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.
- */
+// 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,
+		display_dlg_regs_st *dlg_regs,
+		display_ttu_regs_st *ttu_regs,
+		display_e2e_pipe_params_st *e2e_pipe_param,
 		const unsigned int num_pipes,
 		const unsigned int pipe_idx,
 		const bool cstate_en,
 		const bool pstate_en,
 		const bool vm_en,
-		const bool iflip_en);
+		const bool ignore_viewport_pos,
+		const bool immediate_flip_support);
 
-/* Function: dml_rq_dlg_get_row_heights
- *  Calculate dpte and meta row heights
- */
+// Function: dml_rq_dlg_get_calculated_vstartup
+//   Calculate and return vstartup
+// Output:
+//  unsigned int vstartup
+// 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
+// NOTE: this MUST be called after setting the prefetch mode!
+unsigned int dml_rq_dlg_get_calculated_vstartup(
+		struct display_mode_lib *mode_lib,
+		display_e2e_pipe_params_st *e2e_pipe_param,
+		const unsigned int num_pipes,
+		const unsigned int pipe_idx);
+
+// 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,
@@ -131,9 +142,7 @@ void dml_rq_dlg_get_row_heights(
 		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);
+// Function: dml_rq_dlg_get_arb_params
+void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param);
 
 #endif

+ 277 - 205
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c

@@ -25,296 +25,368 @@
 
 #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)
+void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param)
 {
-	DTRACE("RQ_DLG_CALC: *************************** ");
-	DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST");
-	DTRACE("RQ_DLG_CALC:  <LUMA>");
+	dml_print("DML_RQ_DLG_CALC: ***************************\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n");
+	dml_print("DML_RQ_DLG_CALC:  <LUMA>\n");
 	print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l);
-	DTRACE("RQ_DLG_CALC:  <CHROMA> === ");
+	dml_print("DML_RQ_DLG_CALC:  <CHROMA> ===\n");
 	print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c);
 
-	DTRACE("RQ_DLG_CALC: <LUMA>");
+	dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
 	print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l);
-	DTRACE("RQ_DLG_CALC: <CHROMA>");
+	dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
 	print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c);
 
-	DTRACE("RQ_DLG_CALC: <LUMA>");
+	dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
 	print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l);
-	DTRACE("RQ_DLG_CALC: <CHROMA>");
+	dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
 	print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c);
-	DTRACE("RQ_DLG_CALC: *************************** ");
+	dml_print("DML_RQ_DLG_CALC: ***************************\n");
 }
 
-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_sizing_params_st(struct display_mode_lib *mode_lib, 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: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n");
+	dml_print("DML_RQ_DLG_CALC:    chunk_bytes           = %0d\n", rq_sizing.chunk_bytes);
+	dml_print("DML_RQ_DLG_CALC:    min_chunk_bytes       = %0d\n", rq_sizing.min_chunk_bytes);
+	dml_print("DML_RQ_DLG_CALC:    meta_chunk_bytes      = %0d\n", rq_sizing.meta_chunk_bytes);
+	dml_print(
+			"DML_RQ_DLG_CALC:    min_meta_chunk_bytes  = %0d\n",
+			rq_sizing.min_meta_chunk_bytes);
+	dml_print("DML_RQ_DLG_CALC:    mpte_group_bytes      = %0d\n", rq_sizing.mpte_group_bytes);
+	dml_print("DML_RQ_DLG_CALC:    dpte_group_bytes      = %0d\n", rq_sizing.dpte_group_bytes);
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-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_dlg_params_st(struct display_mode_lib *mode_lib, 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",
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n");
+	dml_print(
+			"DML_RQ_DLG_CALC:    swath_width_ub              = %0d\n",
+			rq_dlg_param.swath_width_ub);
+	dml_print(
+			"DML_RQ_DLG_CALC:    swath_height                = %0d\n",
+			rq_dlg_param.swath_height);
+	dml_print(
+			"DML_RQ_DLG_CALC:    req_per_swath_ub            = %0d\n",
+			rq_dlg_param.req_per_swath_ub);
+	dml_print(
+			"DML_RQ_DLG_CALC:    meta_pte_bytes_per_frame_ub = %0d\n",
 			rq_dlg_param.meta_pte_bytes_per_frame_ub);
-	DTRACE(
-			"RQ_DLG_CALC:    dpte_req_per_row_ub         = %0d",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dpte_req_per_row_ub         = %0d\n",
 			rq_dlg_param.dpte_req_per_row_ub);
-	DTRACE(
-			"RQ_DLG_CALC:    dpte_groups_per_row_ub      = %0d",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dpte_groups_per_row_ub      = %0d\n",
 			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",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dpte_row_height             = %0d\n",
+			rq_dlg_param.dpte_row_height);
+	dml_print(
+			"DML_RQ_DLG_CALC:    dpte_bytes_per_row_ub       = %0d\n",
 			rq_dlg_param.dpte_bytes_per_row_ub);
-	DTRACE(
-			"RQ_DLG_CALC:    meta_chunks_per_row_ub      = %0d",
+	dml_print(
+			"DML_RQ_DLG_CALC:    meta_chunks_per_row_ub      = %0d\n",
 			rq_dlg_param.meta_chunks_per_row_ub);
-	DTRACE(
-			"RQ_DLG_CALC:    meta_req_per_row_ub         = %0d",
+	dml_print(
+			"DML_RQ_DLG_CALC:    meta_req_per_row_ub         = %0d\n",
 			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",
+	dml_print(
+			"DML_RQ_DLG_CALC:    meta_row_height             = %0d\n",
+			rq_dlg_param.meta_row_height);
+	dml_print(
+			"DML_RQ_DLG_CALC:    meta_bytes_per_row_ub       = %0d\n",
 			rq_dlg_param.meta_bytes_per_row_ub);
-	DTRACE("RQ_DLG_CALC: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-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__data_rq_misc_params_st(struct display_mode_lib *mode_lib, 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: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n");
+	dml_print(
+			"DML_RQ_DLG_CALC:     full_swath_bytes   = %0d\n",
+			rq_misc_param.full_swath_bytes);
+	dml_print(
+			"DML_RQ_DLG_CALC:     stored_swath_bytes = %0d\n",
+			rq_misc_param.stored_swath_bytes);
+	dml_print("DML_RQ_DLG_CALC:     blk256_width       = %0d\n", rq_misc_param.blk256_width);
+	dml_print("DML_RQ_DLG_CALC:     blk256_height      = %0d\n", rq_misc_param.blk256_height);
+	dml_print("DML_RQ_DLG_CALC:     req_width          = %0d\n", rq_misc_param.req_width);
+	dml_print("DML_RQ_DLG_CALC:     req_height         = %0d\n", rq_misc_param.req_height);
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-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__rq_dlg_params_st(struct display_mode_lib *mode_lib, 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> ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
+	dml_print("DML_RQ_DLG_CALC:  <LUMA>\n");
 	print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l);
-	DTRACE("RQ_DLG_CALC:  <CHROMA> ");
+	dml_print("DML_RQ_DLG_CALC:  <CHROMA>\n");
 	print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c);
-	DTRACE("RQ_DLG_CALC: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-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__dlg_sys_params_st(struct display_mode_lib *mode_lib, 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: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
+	dml_print("DML_RQ_DLG_CALC:    t_mclk_wm_us         = %3.2f\n", dlg_sys_param.t_mclk_wm_us);
+	dml_print("DML_RQ_DLG_CALC:    t_urg_wm_us          = %3.2f\n", dlg_sys_param.t_urg_wm_us);
+	dml_print("DML_RQ_DLG_CALC:    t_sr_wm_us           = %3.2f\n", dlg_sys_param.t_sr_wm_us);
+	dml_print("DML_RQ_DLG_CALC:    t_extra_us           = %3.2f\n", dlg_sys_param.t_extra_us);
+	dml_print(
+			"DML_RQ_DLG_CALC:    t_srx_delay_us       = %3.2f\n",
+			dlg_sys_param.t_srx_delay_us);
+	dml_print(
+			"DML_RQ_DLG_CALC:    deepsleep_dcfclk_mhz = %3.2f\n",
+			dlg_sys_param.deepsleep_dcfclk_mhz);
+	dml_print(
+			"DML_RQ_DLG_CALC:    total_flip_bw        = %3.2f\n",
+			dlg_sys_param.total_flip_bw);
+	dml_print(
+			"DML_RQ_DLG_CALC:    total_flip_bytes     = %i\n",
+			dlg_sys_param.total_flip_bytes);
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-void print__data_rq_regs_st(
-		struct display_mode_lib *mode_lib,
-		struct _vcs_dpi_display_data_rq_regs_st rq_regs)
+void print__data_rq_regs_st(struct display_mode_lib *mode_lib, 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: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n");
+	dml_print("DML_RQ_DLG_CALC:    chunk_size              = 0x%0x\n", rq_regs.chunk_size);
+	dml_print("DML_RQ_DLG_CALC:    min_chunk_size          = 0x%0x\n", rq_regs.min_chunk_size);
+	dml_print("DML_RQ_DLG_CALC:    meta_chunk_size         = 0x%0x\n", rq_regs.meta_chunk_size);
+	dml_print(
+			"DML_RQ_DLG_CALC:    min_meta_chunk_size     = 0x%0x\n",
+			rq_regs.min_meta_chunk_size);
+	dml_print("DML_RQ_DLG_CALC:    dpte_group_size         = 0x%0x\n", rq_regs.dpte_group_size);
+	dml_print("DML_RQ_DLG_CALC:    mpte_group_size         = 0x%0x\n", rq_regs.mpte_group_size);
+	dml_print("DML_RQ_DLG_CALC:    swath_height            = 0x%0x\n", rq_regs.swath_height);
+	dml_print(
+			"DML_RQ_DLG_CALC:    pte_row_height_linear   = 0x%0x\n",
+			rq_regs.pte_row_height_linear);
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-void print__rq_regs_st(
-		struct display_mode_lib *mode_lib,
-		struct _vcs_dpi_display_rq_regs_st rq_regs)
+void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs)
 {
-	DTRACE("RQ_DLG_CALC: ===================================== ");
-	DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST");
-	DTRACE("RQ_DLG_CALC:  <LUMA> ");
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n");
+	dml_print("DML_RQ_DLG_CALC:  <LUMA>\n");
 	print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l);
-	DTRACE("RQ_DLG_CALC:  <CHROMA> ");
+	dml_print("DML_RQ_DLG_CALC:  <CHROMA>\n");
 	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: ===================================== ");
+	dml_print("DML_RQ_DLG_CALC:    drq_expansion_mode  = 0x%0x\n", rq_regs.drq_expansion_mode);
+	dml_print("DML_RQ_DLG_CALC:    prq_expansion_mode  = 0x%0x\n", rq_regs.prq_expansion_mode);
+	dml_print("DML_RQ_DLG_CALC:    mrq_expansion_mode  = 0x%0x\n", rq_regs.mrq_expansion_mode);
+	dml_print("DML_RQ_DLG_CALC:    crq_expansion_mode  = 0x%0x\n", rq_regs.crq_expansion_mode);
+	dml_print("DML_RQ_DLG_CALC:    plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address);
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-void print__dlg_regs_st(
-		struct display_mode_lib *mode_lib,
-		struct _vcs_dpi_display_dlg_regs_st dlg_regs)
+void print__dlg_regs_st(struct display_mode_lib *mode_lib, 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",
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n");
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_h_blank_end              = 0x%0x\n",
 			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",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dlg_vblank_end                  = 0x%0x\n",
+			dlg_regs.dlg_vblank_end);
+	dml_print(
+			"DML_RQ_DLG_CALC:    min_dst_y_next_start            = 0x%0x\n",
 			dlg_regs.min_dst_y_next_start);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_htotal               = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_htotal               = 0x%0x\n",
 			dlg_regs.refcyc_per_htotal);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_x_after_scaler           = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_x_after_scaler           = 0x%0x\n",
 			dlg_regs.refcyc_x_after_scaler);
-	DTRACE(
-			"RQ_DLG_CALC:    dst_y_after_scaler              = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_after_scaler              = 0x%0x\n",
 			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",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_prefetch                  = 0x%0x\n",
+			dlg_regs.dst_y_prefetch);
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_vm_vblank             = 0x%0x\n",
 			dlg_regs.dst_y_per_vm_vblank);
-	DTRACE(
-			"RQ_DLG_CALC:    dst_y_per_row_vblank            = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_row_vblank            = 0x%0x\n",
 			dlg_regs.dst_y_per_row_vblank);
-	DTRACE(
-			"RQ_DLG_CALC:    ref_freq_to_pix_freq            = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_vm_flip               = 0x%0x\n",
+			dlg_regs.dst_y_per_vm_flip);
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_row_flip              = 0x%0x\n",
+			dlg_regs.dst_y_per_row_flip);
+	dml_print(
+			"DML_RQ_DLG_CALC:    ref_freq_to_pix_freq            = 0x%0x\n",
 			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",
+	dml_print(
+			"DML_RQ_DLG_CALC:    vratio_prefetch                 = 0x%0x\n",
+			dlg_regs.vratio_prefetch);
+	dml_print(
+			"DML_RQ_DLG_CALC:    vratio_prefetch_c               = 0x%0x\n",
 			dlg_regs.vratio_prefetch_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_pte_group_vblank_l   = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_pte_group_vblank_l   = 0x%0x\n",
 			dlg_regs.refcyc_per_pte_group_vblank_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_pte_group_vblank_c   = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_pte_group_vblank_c   = 0x%0x\n",
 			dlg_regs.refcyc_per_pte_group_vblank_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_meta_chunk_vblank_l  = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_meta_chunk_vblank_l  = 0x%0x\n",
 			dlg_regs.refcyc_per_meta_chunk_vblank_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_meta_chunk_vblank_c  = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_meta_chunk_vblank_c  = 0x%0x\n",
 			dlg_regs.refcyc_per_meta_chunk_vblank_c);
-	DTRACE(
-			"RQ_DLG_CALC:    dst_y_per_pte_row_nom_l         = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_pte_group_flip_l     = 0x%0x\n",
+			dlg_regs.refcyc_per_pte_group_flip_l);
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_pte_group_flip_c     = 0x%0x\n",
+			dlg_regs.refcyc_per_pte_group_flip_c);
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_meta_chunk_flip_l    = 0x%0x\n",
+			dlg_regs.refcyc_per_meta_chunk_flip_l);
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_meta_chunk_flip_c    = 0x%0x\n",
+			dlg_regs.refcyc_per_meta_chunk_flip_c);
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_pte_row_nom_l         = 0x%0x\n",
 			dlg_regs.dst_y_per_pte_row_nom_l);
-	DTRACE(
-			"RQ_DLG_CALC:    dst_y_per_pte_row_nom_c         = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_pte_row_nom_c         = 0x%0x\n",
 			dlg_regs.dst_y_per_pte_row_nom_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_pte_group_nom_l      = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_pte_group_nom_l      = 0x%0x\n",
 			dlg_regs.refcyc_per_pte_group_nom_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_pte_group_nom_c      = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_pte_group_nom_c      = 0x%0x\n",
 			dlg_regs.refcyc_per_pte_group_nom_c);
-	DTRACE(
-			"RQ_DLG_CALC:    dst_y_per_meta_row_nom_l        = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_meta_row_nom_l        = 0x%0x\n",
 			dlg_regs.dst_y_per_meta_row_nom_l);
-	DTRACE(
-			"RQ_DLG_CALC:    dst_y_per_meta_row_nom_c        = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_per_meta_row_nom_c        = 0x%0x\n",
 			dlg_regs.dst_y_per_meta_row_nom_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_meta_chunk_nom_l     = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_meta_chunk_nom_l     = 0x%0x\n",
 			dlg_regs.refcyc_per_meta_chunk_nom_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_meta_chunk_nom_c     = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_meta_chunk_nom_c     = 0x%0x\n",
 			dlg_regs.refcyc_per_meta_chunk_nom_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_line_delivery_pre_l  = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_line_delivery_pre_l  = 0x%0x\n",
 			dlg_regs.refcyc_per_line_delivery_pre_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_line_delivery_pre_c  = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_line_delivery_pre_c  = 0x%0x\n",
 			dlg_regs.refcyc_per_line_delivery_pre_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_line_delivery_l      = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_line_delivery_l      = 0x%0x\n",
 			dlg_regs.refcyc_per_line_delivery_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_line_delivery_c      = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_line_delivery_c      = 0x%0x\n",
 			dlg_regs.refcyc_per_line_delivery_c);
-	DTRACE(
-			"RQ_DLG_CALC:    chunk_hdl_adjust_cur0           = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    chunk_hdl_adjust_cur0           = 0x%0x\n",
 			dlg_regs.chunk_hdl_adjust_cur0);
-	DTRACE("RQ_DLG_CALC: ===================================== ");
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_offset_cur1               = 0x%0x\n",
+			dlg_regs.dst_y_offset_cur1);
+	dml_print(
+			"DML_RQ_DLG_CALC:    chunk_hdl_adjust_cur1           = 0x%0x\n",
+			dlg_regs.chunk_hdl_adjust_cur1);
+	dml_print(
+			"DML_RQ_DLG_CALC:    vready_after_vcount0            = 0x%0x\n",
+			dlg_regs.vready_after_vcount0);
+	dml_print(
+			"DML_RQ_DLG_CALC:    dst_y_delta_drq_limit           = 0x%0x\n",
+			dlg_regs.dst_y_delta_drq_limit);
+	dml_print(
+			"DML_RQ_DLG_CALC:    xfc_reg_transfer_delay          = 0x%0x\n",
+			dlg_regs.xfc_reg_transfer_delay);
+	dml_print(
+			"DML_RQ_DLG_CALC:    xfc_reg_precharge_delay         = 0x%0x\n",
+			dlg_regs.xfc_reg_precharge_delay);
+	dml_print(
+			"DML_RQ_DLG_CALC:    xfc_reg_remote_surface_flip_latency = 0x%0x\n",
+			dlg_regs.xfc_reg_remote_surface_flip_latency);
+
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }
 
-void print__ttu_regs_st(
-		struct display_mode_lib *mode_lib,
-		struct _vcs_dpi_display_ttu_regs_st ttu_regs)
+void print__ttu_regs_st(struct display_mode_lib *mode_lib, 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",
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
+	dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n");
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_low_wm                  = 0x%0x\n",
 			ttu_regs.qos_level_low_wm);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_level_high_wm                 = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_high_wm                 = 0x%0x\n",
 			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",
+	dml_print(
+			"DML_RQ_DLG_CALC:    min_ttu_vblank                    = 0x%0x\n",
+			ttu_regs.min_ttu_vblank);
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_flip                    = 0x%0x\n",
+			ttu_regs.qos_level_flip);
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_pre_l     = 0x%0x\n",
 			ttu_regs.refcyc_per_req_delivery_pre_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_req_delivery_l         = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_l         = 0x%0x\n",
 			ttu_regs.refcyc_per_req_delivery_l);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_req_delivery_pre_c     = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_pre_c     = 0x%0x\n",
 			ttu_regs.refcyc_per_req_delivery_pre_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_req_delivery_c         = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_c         = 0x%0x\n",
 			ttu_regs.refcyc_per_req_delivery_c);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_req_delivery_cur0      = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_cur0      = 0x%0x\n",
 			ttu_regs.refcyc_per_req_delivery_cur0);
-	DTRACE(
-			"RQ_DLG_CALC:    refcyc_per_req_delivery_pre_cur0  = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_pre_cur0  = 0x%0x\n",
 			ttu_regs.refcyc_per_req_delivery_pre_cur0);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_level_fixed_l                 = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_cur1      = 0x%0x\n",
+			ttu_regs.refcyc_per_req_delivery_cur1);
+	dml_print(
+			"DML_RQ_DLG_CALC:    refcyc_per_req_delivery_pre_cur1  = 0x%0x\n",
+			ttu_regs.refcyc_per_req_delivery_pre_cur1);
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_fixed_l                 = 0x%0x\n",
 			ttu_regs.qos_level_fixed_l);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_ramp_disable_l                = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_ramp_disable_l                = 0x%0x\n",
 			ttu_regs.qos_ramp_disable_l);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_level_fixed_c                 = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_fixed_c                 = 0x%0x\n",
 			ttu_regs.qos_level_fixed_c);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_ramp_disable_c                = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_ramp_disable_c                = 0x%0x\n",
 			ttu_regs.qos_ramp_disable_c);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_level_fixed_cur0              = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_fixed_cur0              = 0x%0x\n",
 			ttu_regs.qos_level_fixed_cur0);
-	DTRACE(
-			"RQ_DLG_CALC:    qos_ramp_disable_cur0             = 0x%0x",
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_ramp_disable_cur0             = 0x%0x\n",
 			ttu_regs.qos_ramp_disable_cur0);
-	DTRACE("RQ_DLG_CALC: ===================================== ");
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_level_fixed_cur1              = 0x%0x\n",
+			ttu_regs.qos_level_fixed_cur1);
+	dml_print(
+			"DML_RQ_DLG_CALC:    qos_ramp_disable_cur1             = 0x%0x\n",
+			ttu_regs.qos_ramp_disable_cur1);
+	dml_print("DML_RQ_DLG_CALC: =====================================\n");
 }

+ 11 - 30
drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h

@@ -22,6 +22,7 @@
  * Authors: AMD
  *
  */
+
 #ifndef __DISPLAY_RQ_DLG_HELPERS_H__
 #define __DISPLAY_RQ_DLG_HELPERS_H__
 
@@ -31,36 +32,16 @@
 /* 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__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param);
+void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing);
+void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param);
+void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param);
+void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param);
+void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, 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);
+void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs);
+void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs);
+void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs);
+void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs);
 
 #endif

+ 0 - 1282
drivers/gpu/drm/amd/display/dc/dml/display_watermark.c

@@ -1,1282 +0,0 @@
-/*
- * 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"
-#include "dml_inline_defs.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;
-}

+ 0 - 98
drivers/gpu/drm/amd/display/dc/dml/display_watermark.h

@@ -1,98 +0,0 @@
-/*
- * 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

+ 1905 - 0
drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c

@@ -0,0 +1,1905 @@
+/*
+ * 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 "dml1_display_rq_dlg_calc.h"
+#include "display_mode_lib.h"
+
+#include "dml_inline_defs.h"
+
+static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
+{
+	unsigned int ret_val = 0;
+
+	if (source_format == dm_444_16) {
+		if (!is_chroma)
+			ret_val = 2;
+	} else if (source_format == dm_444_32) {
+		if (!is_chroma)
+			ret_val = 4;
+	} else if (source_format == dm_444_64) {
+		if (!is_chroma)
+			ret_val = 8;
+	} else if (source_format == dm_420_8) {
+		if (is_chroma)
+			ret_val = 2;
+		else
+			ret_val = 1;
+	} else if (source_format == dm_420_10) {
+		if (is_chroma)
+			ret_val = 4;
+		else
+			ret_val = 2;
+	}
+	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,
+		unsigned int recout_width,
+		double vratio,
+		double hscale_pixel_rate,
+		unsigned int delivery_width,
+		unsigned int req_per_swath_ub)
+{
+	double refcyc_per_delivery = 0.0;
+
+	if (vratio <= 1.0) {
+		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, 1);
+	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, 1);
+	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 = (unsigned int) (dml_ceil((prefill - 1.0) / (double) swath_height, 1) + 1.0); /* prefill has to be >= 1 */
+	max_partial_sw_int =
+			(prefill == 1) ?
+					(swath_height - 1) :
+					((unsigned int) (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 dml1_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. */
+static void dml1_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, 1);
+	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),
+				1);
+
+		ASSERT(log2_dpte_row_height_linear >= 3);
+
+		if (log2_dpte_row_height_linear > 7)
+			log2_dpte_row_height_linear = 7;
+
+		log2_dpte_row_height = log2_dpte_row_height_linear;
+	} 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, 1);
+	else
+		log2_blk_height = 0; /* blk height of 1 */
+
+	log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
+
+	if (!surf_vert) {
+		rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1)
+				+ blk256_width;
+		rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
+	} else {
+		rq_dlg_param->swath_width_ub = dml_round_to_multiple(
+				vp_height - 1,
+				blk256_height,
+				1) + blk256_height;
+		rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
+	}
+
+	if (!surf_vert)
+		rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height
+				* bytes_per_element;
+	else
+		rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width
+				* bytes_per_element;
+
+	rq_misc_param->blk256_height = blk256_height;
+	rq_misc_param->blk256_width = blk256_width;
+
+	/* -------  */
+	/* meta     */
+	/* -------  */
+	log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
+
+	/* each 64b meta request for dcn is 8x8 meta elements and
+	 * a meta element covers one 256b block of the the data surface.
+	 */
+	log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
+	log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
+			- log2_meta_req_height;
+	meta_req_width = 1 << log2_meta_req_width;
+	meta_req_height = 1 << log2_meta_req_height;
+	log2_meta_row_height = 0;
+	meta_row_width_ub = 0;
+
+	/* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
+	 * calculate upper bound of the meta_row_width
+	 */
+	if (!surf_vert) {
+		log2_meta_row_height = log2_meta_req_height;
+		meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1)
+				+ meta_req_width;
+		rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width;
+	} else {
+		log2_meta_row_height = log2_meta_req_width;
+		meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1)
+				+ meta_req_height;
+		rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height;
+	}
+	rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
+
+	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),
+				1);
+
+		ASSERT(log2_dpte_row_height_linear >= 3);
+
+		if (log2_dpte_row_height_linear > 7)
+			log2_dpte_row_height_linear = 7;
+
+		log2_dpte_row_height = log2_dpte_row_height_linear;
+		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,
+			1);
+
+	dml1_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 dml1_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);
+}
+
+/* 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 dml1_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;
+	unsigned int 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;
+	unsigned int vm_bytes;
+	unsigned int meta_row_bytes;
+	unsigned int max_num_sw_l;
+	unsigned int max_num_sw_c;
+	unsigned int max_partial_sw_l;
+	unsigned int max_partial_sw_c;
+	double max_vinit_l;
+	double max_vinit_c;
+	unsigned int lsw_l;
+	unsigned int lsw_c;
+	unsigned int sw_bytes_ub_l;
+	unsigned int sw_bytes_ub_c;
+	unsigned int sw_bytes;
+	unsigned int 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;
+	unsigned int 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), 1) / 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), 1) / 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), 1) / 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,
+			1);
+	disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(
+			refcyc_per_line_delivery_l,
+			1);
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
+	ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
+
+	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,
+				1);
+		disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(
+				refcyc_per_line_delivery_c,
+				1);
+		ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
+		ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
+	}
+	disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
+
+	/* 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, 1)
+				* (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);
+}

+ 67 - 0
drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h

@@ -0,0 +1,67 @@
+/*
+ * 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 dml1_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 definition)
+ * Input:
+ *  pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+ * Output:
+ *  rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
+ */
+void dml1_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_dlg_params
+ *  Calculate deadline related parameters
+ */
+void dml1_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);
+
+#endif

+ 3 - 2
drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c

@@ -27,11 +27,12 @@
 #include "../calcs/dcn_calc_math.h"
 
 #include "dml_inline_defs.h"
+
 double dml_round(double a)
 {
 	double round_pt = 0.5;
-	double ceil = dml_ceil(a);
-	double floor = dml_floor(a);
+	double ceil = dml_ceil(a, 1);
+	double floor = dml_floor(a, 1);
 
 	if (a - floor >= round_pt)
 		return ceil;

+ 3 - 1
drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h

@@ -22,6 +22,7 @@
  * Authors: AMD
  *
  */
+
 #ifndef __DC_COMMON_DEFS_H__
 #define __DC_COMMON_DEFS_H__
 
@@ -30,7 +31,8 @@
 #include "display_mode_structs.h"
 #include "display_mode_enums.h"
 
-#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__);
+#define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
+#define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
 
 double dml_round(double a);
 

+ 45 - 4
drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h

@@ -1,5 +1,31 @@
+/*
+ * 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 __DML_INLINE_DEFS_H__
 #define __DML_INLINE_DEFS_H__
+
 #include "dml_common_defs.h"
 #include "../calcs/dcn_calc_math.h"
 
@@ -13,14 +39,29 @@ static inline double dml_max(double a, double b)
 	return (double) dcn_bw_max2(a, b);
 }
 
-static inline double dml_ceil(double a)
+static inline double dml_max3(double a, double b, double c)
+{
+	return dml_max(dml_max(a, b), c);
+}
+
+static inline double dml_max4(double a, double b, double c, double d)
+{
+	return dml_max(dml_max(a, b), dml_max(c, d));
+}
+
+static inline double dml_max5(double a, double b, double c, double d, double e)
+{
+	return dml_max(dml_max4(a, b, c, d), e);
+}
+
+static inline double dml_ceil(double a, double granularity)
 {
-	return (double) dcn_bw_ceil2(a, 1);
+	return (double) dcn_bw_ceil2(a, granularity);
 }
 
-static inline double dml_floor(double a)
+static inline double dml_floor(double a, double granularity)
 {
-	return (double) dcn_bw_floor2(a, 1);
+	return (double) dcn_bw_floor2(a, granularity);
 }
 
 static inline int dml_log2(double x)

+ 20 - 25
drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c

@@ -24,51 +24,46 @@
  */
 #include "soc_bounding_box.h"
 #include "display_mode_lib.h"
+#include "dc_features.h"
 
 #include "dml_inline_defs.h"
-void dml_socbb_set_latencies(
-		struct display_mode_lib *mode_lib,
-		struct _vcs_dpi_soc_bounding_box_st *from_box)
+void dml_socbb_set_latencies(soc_bounding_box_st *to_box, 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,
+voltage_scaling_st dml_socbb_voltage_scaling(
+		const soc_bounding_box_st *soc,
 		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;
+	const voltage_scaling_st *voltage_state;
+	const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES;
+
+	for (voltage_state = soc->clock_limits;
+			voltage_state < voltage_end && voltage_state->state != voltage;
+			voltage_state++) {
 	}
+
+	if (voltage_state < voltage_end)
+		return *voltage_state;
+	return soc->clock_limits[DC__VOLTAGE_STATES - 1];
 }
 
-double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage)
+double dml_socbb_return_bw_mhz(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);
+	voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
 
-	return_bw = dml_min(
-			((double) box->return_bus_width_bytes) * state.dcfclk_mhz,
+	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_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw);
+
 	return return_bw;
 }

+ 4 - 5
drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h

@@ -22,15 +22,14 @@
  * 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);
+void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box);
+voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage);
+double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage);
 
 #endif

+ 3 - 5
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c

@@ -130,9 +130,8 @@ failure_2:
 
 		slot = service->busyness[index_of_id];
 
-		if (slot)
-			kfree(slot);
-	};
+		kfree(slot);
+	}
 
 failure_1:
 	kfree(service);
@@ -171,8 +170,7 @@ void dal_gpio_service_destroy(
 		do {
 			uint32_t *slot = (*ptr)->busyness[index_of_id];
 
-			if (slot)
-				kfree(slot);
+			kfree(slot);
 
 			++index_of_id;
 		} while (index_of_id < GPIO_ID_COUNT);

+ 8 - 7
drivers/gpu/drm/amd/display/dc/inc/core_status.h

@@ -35,13 +35,14 @@ enum dc_status {
 	DC_FAIL_CONTROLLER_VALIDATE = 5,
 	DC_FAIL_ENC_VALIDATE = 6,
 	DC_FAIL_ATTACH_SURFACES = 7,
-	DC_FAIL_SURFACE_VALIDATE = 8,
-	DC_NO_DP_LINK_BANDWIDTH = 9,
-	DC_EXCEED_DONGLE_MAX_CLK = 10,
-	DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 11,
-	DC_FAIL_BANDWIDTH_VALIDATE = 12, /* BW and Watermark validation */
-	DC_FAIL_SCALING = 13,
-	DC_FAIL_DP_LINK_TRAINING = 14,
+	DC_FAIL_DETACH_SURFACES = 8,
+	DC_FAIL_SURFACE_VALIDATE = 9,
+	DC_NO_DP_LINK_BANDWIDTH = 10,
+	DC_EXCEED_DONGLE_MAX_CLK = 11,
+	DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12,
+	DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */
+	DC_FAIL_SCALING = 14,
+	DC_FAIL_DP_LINK_TRAINING = 15,
 
 	DC_ERROR_UNEXPECTED = -1
 };

+ 13 - 3
drivers/gpu/drm/amd/display/dc/inc/core_types.h

@@ -32,6 +32,7 @@
 #include "ddc_service_types.h"
 #include "dc_bios_types.h"
 #include "mem_input.h"
+#include "hubp.h"
 #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "mpc.h"
 #endif
@@ -58,6 +59,11 @@ struct link_init_data {
 				TODO: remove it when DC is complete. */
 };
 
+enum {
+	FREE_ACQUIRED_RESOURCE = 0,
+	KEEP_ACQUIRED_RESOURCE = 1,
+};
+
 struct dc_link *link_create(const struct link_init_data *init_params);
 void link_destroy(struct dc_link **link);
 
@@ -72,12 +78,13 @@ void core_link_enable_stream(
 		struct dc_state *state,
 		struct pipe_ctx *pipe_ctx);
 
-void core_link_disable_stream(struct pipe_ctx *pipe_ctx);
+void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option);
 
 void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
 /********** DAL Core*********************/
 #include "display_clock.h"
 #include "transform.h"
+#include "dpp.h"
 
 struct resource_pool;
 struct dc_state;
@@ -106,7 +113,7 @@ struct resource_funcs {
 			const struct resource_pool *pool,
 			struct dc_stream_state *stream);
 
-	enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state);
+	enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps);
 
 	enum dc_status (*add_stream_to_ctx)(
 			struct dc *dc,
@@ -124,8 +131,10 @@ struct audio_support{
 
 struct resource_pool {
 	struct mem_input *mis[MAX_PIPES];
+	struct hubp *hubps[MAX_PIPES];
 	struct input_pixel_processor *ipps[MAX_PIPES];
 	struct transform *transforms[MAX_PIPES];
+	struct dpp *dpps[MAX_PIPES];
 	struct output_pixel_processor *opps[MAX_PIPES];
 	struct timing_generator *timing_generators[MAX_PIPES];
 	struct stream_encoder *stream_enc[MAX_PIPES * 2];
@@ -173,10 +182,11 @@ struct stream_resource {
 
 struct plane_resource {
 	struct scaler_data scl_data;
-
+	struct hubp *hubp;
 	struct mem_input *mi;
 	struct input_pixel_processor *ipp;
 	struct transform *xfm;
+	struct dpp *dpp;
 };
 
 struct pipe_ctx {

+ 134 - 0
drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h

@@ -0,0 +1,134 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+#ifndef __DAL_DPP_H__
+#define __DAL_DPP_H__
+
+#include "transform.h"
+
+struct dpp {
+	const struct dpp_funcs *funcs;
+	struct dc_context *ctx;
+	int inst;
+	struct dpp_caps *caps;
+	struct pwl_params regamma_params;
+};
+
+struct dpp_grph_csc_adjustment {
+	struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
+	enum graphics_gamut_adjust_type gamut_adjust_type;
+};
+
+struct dpp_funcs {
+	void (*dpp_reset)(struct dpp *dpp);
+
+	void (*dpp_set_scaler)(struct dpp *dpp,
+			const struct scaler_data *scl_data);
+
+	void (*dpp_set_pixel_storage_depth)(
+			struct dpp *dpp,
+			enum lb_pixel_depth depth,
+			const struct bit_depth_reduction_params *bit_depth_params);
+
+	bool (*dpp_get_optimal_number_of_taps)(
+			struct dpp *dpp,
+			struct scaler_data *scl_data,
+			const struct scaling_taps *in_taps);
+
+	void (*dpp_set_gamut_remap)(
+			struct dpp *dpp,
+			const struct dpp_grph_csc_adjustment *adjust);
+
+	void (*opp_set_csc_default)(
+		struct dpp *dpp,
+		const struct default_adjustment *default_adjust);
+
+	void (*opp_set_csc_adjustment)(
+		struct dpp *dpp,
+		const struct out_csc_color_matrix *tbl_entry);
+
+	void (*opp_power_on_regamma_lut)(
+		struct dpp *dpp,
+		bool power_on);
+
+	void (*opp_program_regamma_lut)(
+			struct dpp *dpp,
+			const struct pwl_result_data *rgb,
+			uint32_t num);
+
+	void (*opp_configure_regamma_lut)(
+			struct dpp *dpp,
+			bool is_ram_a);
+
+	void (*opp_program_regamma_lutb_settings)(
+			struct dpp *dpp,
+			const struct pwl_params *params);
+
+	void (*opp_program_regamma_luta_settings)(
+			struct dpp *dpp,
+			const struct pwl_params *params);
+
+	void (*opp_program_regamma_pwl)(
+		struct dpp *dpp, const struct pwl_params *params);
+
+	void (*opp_set_regamma_mode)(
+			struct dpp *dpp_base,
+			enum opp_regamma mode);
+
+	void (*ipp_set_degamma)(
+			struct dpp *dpp_base,
+			enum ipp_degamma_mode mode);
+
+	void (*ipp_program_input_lut)(
+			struct dpp *dpp_base,
+			const struct dc_gamma *gamma);
+
+	void (*ipp_program_degamma_pwl)(struct dpp *dpp_base,
+									 const struct pwl_params *params);
+
+	void (*ipp_setup)(
+			struct dpp *dpp_base,
+			enum surface_pixel_format input_format,
+			enum expansion_mode mode);
+
+	void (*ipp_full_bypass)(struct dpp *dpp_base);
+
+	void (*set_cursor_attributes)(
+			struct dpp *dpp_base,
+			const struct dc_cursor_attributes *attr);
+
+	void (*set_cursor_position)(
+			struct dpp *dpp_base,
+			const struct dc_cursor_position *pos,
+			const struct dc_cursor_mi_param *param,
+			uint32_t width
+			);
+
+};
+
+
+
+#endif

+ 105 - 0
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h

@@ -0,0 +1,105 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HUBP_H__
+#define __DAL_HUBP_H__
+
+#include "mem_input.h"
+
+struct hubp {
+	struct hubp_funcs *funcs;
+	struct dc_context *ctx;
+	struct dc_plane_address request_address;
+	struct dc_plane_address current_address;
+	int inst;
+	int opp_id;
+	int mpcc_id;
+	struct dc_cursor_attributes curs_attr;
+};
+
+
+struct hubp_funcs {
+	void (*hubp_setup)(
+			struct hubp *hubp,
+			struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
+			struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
+			struct _vcs_dpi_display_rq_regs_st *rq_regs,
+			struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
+
+	void (*dcc_control)(struct hubp *hubp, bool enable,
+			bool independent_64b_blks);
+	void (*mem_program_viewport)(
+			struct hubp *hubp,
+			const struct rect *viewport,
+			const struct rect *viewport_c);
+
+	bool (*hubp_program_surface_flip_and_addr)(
+		struct hubp *hubp,
+		const struct dc_plane_address *address,
+		bool flip_immediate);
+
+	void (*hubp_program_pte_vm)(
+		struct hubp *hubp,
+		enum surface_pixel_format format,
+		union dc_tiling_info *tiling_info,
+		enum dc_rotation_angle rotation);
+
+	void (*hubp_set_vm_system_aperture_settings)(
+			struct hubp *hubp,
+			struct vm_system_aperture_param *apt);
+
+	void (*hubp_set_vm_context0_settings)(
+			struct hubp *hubp,
+			const struct vm_context0_param *vm0);
+
+	void (*hubp_program_surface_config)(
+		struct hubp *hubp,
+		enum surface_pixel_format format,
+		union dc_tiling_info *tiling_info,
+		union plane_size *plane_size,
+		enum dc_rotation_angle rotation,
+		struct dc_plane_dcc_param *dcc,
+		bool horizontal_mirror);
+
+	bool (*hubp_is_flip_pending)(struct hubp *hubp);
+
+	void (*hubp_update_dchub)(struct hubp *hubp,
+				struct dchub_init_data *dh_data);
+
+	void (*set_blank)(struct hubp *hubp, bool blank);
+	void (*set_hubp_blank_en)(struct hubp *hubp, bool blank);
+
+	void (*set_cursor_attributes)(
+			struct hubp *hubp,
+			const struct dc_cursor_attributes *attr);
+
+	void (*set_cursor_position)(
+			struct hubp *hubp,
+			const struct dc_cursor_position *pos,
+			const struct dc_cursor_mi_param *param);
+
+};
+
+#endif

+ 1 - 5
drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h

@@ -111,7 +111,7 @@ struct link_encoder_funcs {
 		const struct dc_link_settings *link_settings,
 		enum clock_source_id clock_source);
 	void (*disable_output)(struct link_encoder *link_enc,
-		enum signal_type signal);
+		enum signal_type signal, struct dc_link *link);
 	void (*dp_set_lane_settings)(struct link_encoder *enc,
 		const struct link_training_settings *link_settings);
 	void (*dp_set_phy_pattern)(struct link_encoder *enc,
@@ -123,10 +123,6 @@ struct link_encoder_funcs {
 			bool exit_link_training_required);
 	void (*psr_program_secondary_packet)(struct link_encoder *enc,
 				unsigned int sdp_transmit_line_num_deadline);
-	void (*backlight_control) (struct link_encoder *enc,
-		bool enable);
-	void (*power_control) (struct link_encoder *enc,
-		bool power_up);
 	void (*connect_dig_be_to_fe)(struct link_encoder *enc,
 		enum engine_id engine,
 		bool connect);

+ 9 - 2
drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h

@@ -69,8 +69,6 @@ struct mem_input {
 	struct dc_plane_address request_address;
 	struct dc_plane_address current_address;
 	int inst;
-	int opp_id;
-	int mpcc_id;
 	struct stutter_modes stutter_mode;
 };
 
@@ -163,6 +161,15 @@ struct mem_input_funcs {
 	void (*set_blank)(struct mem_input *mi, bool blank);
 	void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
 
+	void (*set_cursor_attributes)(
+			struct mem_input *mem_input,
+			const struct dc_cursor_attributes *attr);
+
+	void (*set_cursor_position)(
+			struct mem_input *mem_input,
+			const struct dc_cursor_position *pos,
+			const struct dc_cursor_mi_param *param);
+
 };
 
 #endif

+ 11 - 4
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h

@@ -29,8 +29,9 @@
 #include "opp.h"
 
 struct mpcc_cfg {
-	struct mem_input *mi;
-	struct output_pixel_processor *opp;
+	int dpp_id;
+	int opp_id;
+	struct mpc_tree_cfg *tree_cfg;
 	unsigned int z_index;
 
 	struct tg_color black_color;
@@ -44,11 +45,17 @@ struct mpc {
 };
 
 struct mpc_funcs {
-	void (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
+	int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
+
 	void (*remove)(struct mpc *mpc,
-			struct output_pixel_processor *opp,
+			struct mpc_tree_cfg *tree_cfg,
+			int opp_id,
 			int mpcc_inst);
+
 	void (*wait_for_idle)(struct mpc *mpc, int id);
+
+	void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg);
+
 };
 
 #endif

+ 57 - 0
drivers/gpu/drm/amd/display/dc/inc/hw/transform.h

@@ -38,6 +38,7 @@ struct transform {
 	const struct transform_funcs *funcs;
 	struct dc_context *ctx;
 	int inst;
+	struct dpp_caps *caps;
 	struct pwl_params regamma_params;
 };
 
@@ -109,6 +110,22 @@ enum graphics_gamut_adjust_type {
 	GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */
 };
 
+enum lb_memory_config {
+	/* Enable all 3 pieces of memory */
+	LB_MEMORY_CONFIG_0 = 0,
+
+	/* Enable only the first piece of memory */
+	LB_MEMORY_CONFIG_1 = 1,
+
+	/* Enable only the second piece of memory */
+	LB_MEMORY_CONFIG_2 = 2,
+
+	/* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
+	 * last piece of chroma memory used for the luma storage
+	 */
+	LB_MEMORY_CONFIG_3 = 3
+};
+
 struct xfm_grph_csc_adjustment {
 	struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
 	enum graphics_gamut_adjust_type gamut_adjust_type;
@@ -238,6 +255,17 @@ struct transform_funcs {
 
 	void (*ipp_full_bypass)(struct transform *xfm_base);
 
+	void (*set_cursor_attributes)(
+			struct transform *xfm_base,
+			const struct dc_cursor_attributes *attr);
+
+	void (*set_cursor_position)(
+			struct transform *xfm_base,
+			const struct dc_cursor_position *pos,
+			const struct dc_cursor_mi_param *param,
+			uint32_t width
+			);
+
 };
 
 const uint16_t *get_filter_2tap_16p(void);
@@ -251,4 +279,33 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio);
 const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio);
 const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio);
 
+
+/* Defines the pixel processing capability of the DSCL */
+enum dscl_data_processing_format {
+	DSCL_DATA_PRCESSING_FIXED_FORMAT,	/* The DSCL processes pixel data in fixed format */
+	DSCL_DATA_PRCESSING_FLOAT_FORMAT,	/* The DSCL processes pixel data in float format */
+};
+
+/*
+ * The DPP capabilities structure contains enumerations to specify the
+ * HW processing features and an associated function pointers to
+ * provide the function interface that can be overloaded for implementations
+ * based on different capabilities
+ */
+struct dpp_caps {
+	/* DSCL processing pixel data in fixed or float format */
+	enum dscl_data_processing_format dscl_data_proc_format;
+
+	/* Calculates the number of partitions in the line buffer.
+	 * The implementation of this function is overloaded for
+	 * different versions of DSCL LB.
+	 */
+	void (*dscl_calc_lb_num_partitions)(
+			const struct scaler_data *scl_data,
+			enum lb_memory_config lb_config,
+			int *num_part_y,
+			int *num_part_c);
+};
+
+
 #endif

+ 10 - 2
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

@@ -28,6 +28,7 @@
 #include "dc_types.h"
 #include "clock_source.h"
 #include "inc/hw/timing_generator.h"
+#include "inc/hw/link_encoder.h"
 #include "core_status.h"
 
 enum pipe_gating_control {
@@ -133,7 +134,8 @@ struct hw_sequencer_funcs {
 
 	void (*enable_stream)(struct pipe_ctx *pipe_ctx);
 
-	void (*disable_stream)(struct pipe_ctx *pipe_ctx);
+	void (*disable_stream)(struct pipe_ctx *pipe_ctx,
+			int option);
 
 	void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
 			struct dc_link_settings *link_settings);
@@ -174,8 +176,14 @@ struct hw_sequencer_funcs {
 			struct resource_pool *res_pool,
 			struct pipe_ctx *pipe_ctx);
 
-	void (*ready_shared_resources)(struct dc *dc);
+	void (*ready_shared_resources)(struct dc *dc, struct dc_state *context);
 	void (*optimize_shared_resources)(struct dc *dc);
+	void (*edp_power_control)(
+			struct link_encoder *enc,
+			bool enable);
+	void (*edp_backlight_control)(
+			struct dc_link *link,
+			bool enable);
 };
 
 void color_space_to_black_color(

+ 4 - 0
drivers/gpu/drm/amd/display/dc/inc/link_hwss.h

@@ -40,6 +40,10 @@ enum dc_status core_link_write_dpcd(
 	const uint8_t *data,
 	uint32_t size);
 
+struct gpio *get_hpd_gpio(struct dc_bios *dcb,
+		struct graphics_object_id link_id,
+		struct gpio_service *gpio_service);
+
 void dp_enable_link_phy(
 	struct dc_link *link,
 	enum signal_type signal,

+ 5 - 0
drivers/gpu/drm/amd/display/dc/inc/resource.h

@@ -164,4 +164,9 @@ bool pipe_need_reprogram(
 void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
 		struct bit_depth_reduction_params *fmt_bit_depth);
 
+void update_audio_usage(
+		struct resource_context *res_ctx,
+		const struct resource_pool *pool,
+		struct audio *audio,
+		bool acquired);
 #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */

+ 40 - 0
drivers/gpu/drm/amd/display/dc/os_types.h

@@ -56,5 +56,45 @@
 
 #endif
 
+/*
+ *
+ * general debug capabilities
+ *
+ */
+#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
+
+#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
+#define ASSERT_CRITICAL(expr) do {	\
+	if (WARN_ON(!(expr))) { \
+		kgdb_breakpoint(); \
+	} \
+} while (0)
+#else
+#define ASSERT_CRITICAL(expr) do {	\
+	if (WARN_ON(!(expr))) { \
+		; \
+	} \
+} while (0)
+#endif
+
+#if defined(CONFIG_DEBUG_KERNEL_DC)
+#define ASSERT(expr) ASSERT_CRITICAL(expr)
+
+#else
+#define ASSERT(expr) WARN_ON(!(expr))
+#endif
+
+#define BREAK_TO_DEBUGGER() ASSERT(0)
+
+#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
+
+#define DC_ERR(...)  do { \
+	dm_error(__VA_ARGS__); \
+	BREAK_TO_DEBUGGER(); \
+} while (0)
+
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+#include <asm/fpu/api.h>
+#endif
 
 #endif /* _OS_TYPES_H_ */

+ 2 - 11
drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c

@@ -58,7 +58,8 @@ static void virtual_link_encoder_enable_dp_mst_output(
 
 static void virtual_link_encoder_disable_output(
 	struct link_encoder *link_enc,
-	enum signal_type signal) {}
+	enum signal_type signal,
+	struct dc_link *link) {}
 
 static void virtual_link_encoder_dp_set_lane_settings(
 	struct link_encoder *enc,
@@ -72,14 +73,6 @@ static void virtual_link_encoder_update_mst_stream_allocation_table(
 	struct link_encoder *enc,
 	const struct link_mst_stream_allocation_table *table) {}
 
-static void virtual_link_encoder_edp_backlight_control(
-	struct link_encoder *enc,
-	bool enable) {}
-
-static void virtual_link_encoder_edp_power_control(
-	struct link_encoder *enc,
-	bool power_up) {}
-
 static void virtual_link_encoder_connect_dig_be_to_fe(
 	struct link_encoder *enc,
 	enum engine_id engine,
@@ -105,8 +98,6 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
 	.dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
 	.update_mst_stream_allocation_table =
 		virtual_link_encoder_update_mst_stream_allocation_table,
-	.backlight_control = virtual_link_encoder_edp_backlight_control,
-	.power_control = virtual_link_encoder_edp_power_control,
 	.connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe,
 	.destroy = virtual_link_encoder_destroy
 };

+ 28 - 0
drivers/gpu/drm/amd/display/include/logger_interface.h

@@ -44,6 +44,8 @@ struct dal_logger *dal_logger_create(struct dc_context *ctx, uint32_t log_mask);
 
 uint32_t dal_logger_destroy(struct dal_logger **logger);
 
+void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn);
+
 void dm_logger_write(
 		struct dal_logger *logger,
 		enum dc_log_type log_type,
@@ -157,4 +159,30 @@ void context_clock_trace(
 #define DTN_INFO_END() \
 	dm_dtn_log_end(dc_ctx)
 
+#define PERFORMANCE_TRACE_START() \
+	unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx); \
+	unsigned long long perf_trc_start_log_msk = dc->ctx->logger->mask; \
+	unsigned int perf_trc_start_log_flags = dc->ctx->logger->flags.value; \
+	if (dc->debug.performance_trace) {\
+		dm_logger_flush_buffer(dc->ctx->logger, false);\
+		dc->ctx->logger->mask = 1<<LOG_PERF_TRACE;\
+		dc->ctx->logger->flags.bits.ENABLE_CONSOLE = 0;\
+		dc->ctx->logger->flags.bits.ENABLE_BUFFER = 1;\
+	}
+
+#define PERFORMANCE_TRACE_END() do {\
+	unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx);\
+	if (dc->debug.performance_trace) {\
+		dm_logger_write(dc->ctx->logger, \
+				LOG_PERF_TRACE, \
+				"%s duration: %d ticks\n", __func__,\
+				perf_trc_end_stmp - perf_trc_start_stmp); \
+		if (perf_trc_start_log_msk != 1<<LOG_PERF_TRACE) {\
+			dc->ctx->logger->mask = perf_trc_start_log_msk;\
+			dc->ctx->logger->flags.value = perf_trc_start_log_flags;\
+			dm_logger_flush_buffer(dc->ctx->logger, false);\
+		} \
+	} \
+} while (0)
+
 #endif /* __DAL_LOGGER_INTERFACE_H__ */

+ 34 - 2
drivers/gpu/drm/amd/display/include/logger_types.h

@@ -64,8 +64,7 @@ enum dc_log_type {
 	LOG_EVENT_LINK_LOSS,
 	LOG_EVENT_UNDERFLOW,
 	LOG_IF_TRACE,
-	LOG_HW_MARKS,
-	LOG_PPLIB,
+	LOG_PERF_TRACE,
 
 	LOG_SECTION_TOTAL_COUNT
 };
@@ -131,4 +130,37 @@ struct dc_log_type_info {
 	char name[MAX_NAME_LEN];
 };
 
+/* Structure for keeping track of offsets, buffer, etc */
+
+#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
+
+/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
+ * change log line size to 896 to meet the request.
+ */
+#define LOG_MAX_LINE_SIZE 896
+
+struct dal_logger {
+
+	/* How far into the circular buffer has been read by dsat
+	 * Read offset should never cross write offset. Write \0's to
+	 * read data just to be sure?
+	 */
+	uint32_t buffer_read_offset;
+
+	/* How far into the circular buffer we have written
+	 * Write offset should never cross read offset
+	 */
+	uint32_t buffer_write_offset;
+
+	uint32_t open_count;
+
+	char *log_buffer;	/* Pointer to malloc'ed buffer */
+	uint32_t log_buffer_size; /* Size of circular buffer */
+
+	uint32_t mask; /*array of masks for major elements*/
+
+	union logger_flags flags;
+	struct dc_context *ctx;
+};
+
 #endif /* __DAL_LOGGER_TYPES_H__ */