aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-10-22 21:17:54 -0400
committerDave Airlie <airlied@redhat.com>2017-10-22 21:17:54 -0400
commitaf9111336071ee9378e1db70ac8f4c2b7fcd17a1 (patch)
tree1e60c1bd032ba2bcb2e1b1d0b611195e66314bd8
parentbd21a37d41c3b3088aeae59f54fd82de0ddb6fdd (diff)
parent9b38bd1b8f5c874c3d1f330e0dcf4e7d84137477 (diff)
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. ...
-rw-r--r--drivers/gpu/drm/amd/display/Kconfig10
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c207
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c21
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c135
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/logger.c78
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/logger.h37
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c45
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h36
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c224
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c472
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c58
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c17
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c111
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c63
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_surface.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h141
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hw_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h175
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c253
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h20
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c332
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/Makefile4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c)2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h)4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c199
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h127
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c263
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c250
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c)344
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h (renamed from drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h)139
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c486
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c189
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c215
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h45
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c100
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_services.h47
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/Makefile8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dc_features.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h56
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h900
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h194
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c6124
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h598
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c2433
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h151
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c482
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h41
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_watermark.c1282
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_watermark.h98
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c1905
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h67
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h49
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c45
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_status.h15
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h16
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h134
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h105
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h11
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h15
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/transform.h57
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h12
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/link_hwss.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/resource.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/os_types.h40
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c13
-rw-r--r--drivers/gpu/drm/amd/display/include/logger_interface.h28
-rw-r--r--drivers/gpu/drm/amd/display/include/logger_types.h36
88 files changed, 13890 insertions, 6064 deletions
diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 6d1086d0a277..ec3285f65517 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -17,6 +17,16 @@ config DRM_AMD_DC_PRE_VEGA
17 by default. This includes Polaris, Carrizo, Tonga, Bonaire, 17 by default. This includes Polaris, Carrizo, Tonga, Bonaire,
18 and Hawaii. 18 and Hawaii.
19 19
20config DRM_AMD_DC_FBC
21 bool "AMD FBC - Enable Frame Buffer Compression"
22 depends on DRM_AMD_DC
23 help
24 Choose this option if you want to use frame buffer compression
25 support.
26 This is a power optimisation feature, check its availability
27 on your hardware before enabling this option.
28
29
20config DRM_AMD_DC_DCN1_0 30config DRM_AMD_DC_DCN1_0
21 bool "DCN 1.0 Raven family" 31 bool "DCN 1.0 Raven family"
22 depends on DRM_AMD_DC && X86 32 depends on DRM_AMD_DC && X86
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8cc228ebdc9a..d0ee1b3b8b5c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/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)
538static int dm_late_init(void *handle) 538static int dm_late_init(void *handle)
539{ 539{
540 struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev; 540 struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev;
541 int r = detect_mst_link_for_all_connectors(dev);
542 541
543 return r; 542 return detect_mst_link_for_all_connectors(dev);
544} 543}
545 544
546static void s3_handle_mst(struct drm_device *dev, bool suspend) 545static void s3_handle_mst(struct drm_device *dev, bool suspend)
@@ -599,10 +598,7 @@ static int dm_suspend(void *handle)
599 WARN_ON(adev->dm.cached_state); 598 WARN_ON(adev->dm.cached_state);
600 adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev); 599 adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev);
601 600
602 dc_set_power_state( 601 dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
603 dm->dc,
604 DC_ACPI_CM_POWER_STATE_D3
605 );
606 602
607 return ret; 603 return ret;
608} 604}
@@ -632,10 +628,7 @@ static int dm_resume(void *handle)
632 struct amdgpu_display_manager *dm = &adev->dm; 628 struct amdgpu_display_manager *dm = &adev->dm;
633 629
634 /* power on hardware */ 630 /* power on hardware */
635 dc_set_power_state( 631 dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
636 dm->dc,
637 DC_ACPI_CM_POWER_STATE_D0
638 );
639 632
640 return 0; 633 return 0;
641} 634}
@@ -648,6 +641,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
648 struct drm_connector *connector; 641 struct drm_connector *connector;
649 struct drm_crtc *crtc; 642 struct drm_crtc *crtc;
650 struct drm_crtc_state *new_crtc_state; 643 struct drm_crtc_state *new_crtc_state;
644 struct dm_crtc_state *dm_crtc_state;
645 struct drm_plane *plane;
646 struct drm_plane_state *plane_state;
647 struct dm_plane_state *dm_plane_state;
648 struct dm_atomic_state *cached_state;
651 int ret = 0; 649 int ret = 0;
652 int i; 650 int i;
653 651
@@ -686,6 +684,34 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
686 for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) 684 for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i)
687 new_crtc_state->active_changed = true; 685 new_crtc_state->active_changed = true;
688 686
687 cached_state = to_dm_atomic_state(adev->dm.cached_state);
688
689 /*
690 * During suspend, the cached state is saved before all streams are
691 * disabled. Refresh cached state to match actual current state before
692 * restoring it.
693 */
694 WARN_ON(kref_read(&cached_state->context->refcount) > 1);
695 dc_release_state(cached_state->context);
696
697 for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) {
698 dm_crtc_state = to_dm_crtc_state(new_crtc_state);
699 if (dm_crtc_state->stream) {
700 WARN_ON(kref_read(&dm_crtc_state->stream->refcount) > 1);
701 dc_stream_release(dm_crtc_state->stream);
702 dm_crtc_state->stream = NULL;
703 }
704 }
705
706 for_each_new_plane_in_state(adev->dm.cached_state, plane, plane_state, i) {
707 dm_plane_state = to_dm_plane_state(plane_state);
708 if (dm_plane_state->dc_state) {
709 WARN_ON(kref_read(&dm_plane_state->dc_state->refcount) > 1);
710 dc_plane_state_release(dm_plane_state->dc_state);
711 dm_plane_state->dc_state = NULL;
712 }
713 }
714
689 ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state); 715 ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);
690 716
691 drm_atomic_state_put(adev->dm.cached_state); 717 drm_atomic_state_put(adev->dm.cached_state);
@@ -860,9 +886,9 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
860 connector); 886 connector);
861 887
862 aconnector->dc_sink = sink; 888 aconnector->dc_sink = sink;
863 if (sink->dc_edid.length == 0) 889 if (sink->dc_edid.length == 0) {
864 aconnector->edid = NULL; 890 aconnector->edid = NULL;
865 else { 891 } else {
866 aconnector->edid = 892 aconnector->edid =
867 (struct edid *) sink->dc_edid.raw_edid; 893 (struct edid *) sink->dc_edid.raw_edid;
868 894
@@ -980,8 +1006,9 @@ static void dm_handle_hpd_rx_irq(struct amdgpu_dm_connector *aconnector)
980 dpcd_bytes_to_read); 1006 dpcd_bytes_to_read);
981 1007
982 new_irq_handled = false; 1008 new_irq_handled = false;
983 } else 1009 } else {
984 break; 1010 break;
1011 }
985 } 1012 }
986 1013
987 if (process_count == max_process_count) 1014 if (process_count == max_process_count)
@@ -993,20 +1020,20 @@ static void handle_hpd_rx_irq(void *param)
993 struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param; 1020 struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
994 struct drm_connector *connector = &aconnector->base; 1021 struct drm_connector *connector = &aconnector->base;
995 struct drm_device *dev = connector->dev; 1022 struct drm_device *dev = connector->dev;
996 const struct dc_link *dc_link = aconnector->dc_link; 1023 struct dc_link *dc_link = aconnector->dc_link;
997 bool is_mst_root_connector = aconnector->mst_mgr.mst_state; 1024 bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
998 1025
999 /* TODO:Temporary add mutex to protect hpd interrupt not have a gpio 1026 /* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
1000 * conflict, after implement i2c helper, this mutex should be 1027 * conflict, after implement i2c helper, this mutex should be
1001 * retired. 1028 * retired.
1002 */ 1029 */
1003 if (aconnector->dc_link->type != dc_connection_mst_branch) 1030 if (dc_link->type != dc_connection_mst_branch)
1004 mutex_lock(&aconnector->hpd_lock); 1031 mutex_lock(&aconnector->hpd_lock);
1005 1032
1006 if (dc_link_handle_hpd_rx_irq(aconnector->dc_link, NULL) && 1033 if (dc_link_handle_hpd_rx_irq(dc_link, NULL) &&
1007 !is_mst_root_connector) { 1034 !is_mst_root_connector) {
1008 /* Downstream Port status changed. */ 1035 /* Downstream Port status changed. */
1009 if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPDRX)) { 1036 if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
1010 amdgpu_dm_update_connector_after_detect(aconnector); 1037 amdgpu_dm_update_connector_after_detect(aconnector);
1011 1038
1012 1039
@@ -1018,10 +1045,10 @@ static void handle_hpd_rx_irq(void *param)
1018 } 1045 }
1019 } 1046 }
1020 if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) || 1047 if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
1021 (dc_link->type == dc_connection_mst_branch)) 1048 (dc_link->type == dc_connection_mst_branch))
1022 dm_handle_hpd_rx_irq(aconnector); 1049 dm_handle_hpd_rx_irq(aconnector);
1023 1050
1024 if (aconnector->dc_link->type != dc_connection_mst_branch) 1051 if (dc_link->type != dc_connection_mst_branch)
1025 mutex_unlock(&aconnector->hpd_lock); 1052 mutex_unlock(&aconnector->hpd_lock);
1026} 1053}
1027 1054
@@ -1381,9 +1408,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
1381 goto fail_free_planes; 1408 goto fail_free_planes;
1382 1409
1383 aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL); 1410 aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL);
1384 if (!aencoder) { 1411 if (!aencoder)
1385 goto fail_free_connector; 1412 goto fail_free_connector;
1386 }
1387 1413
1388 if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) { 1414 if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) {
1389 DRM_ERROR("KMS: Failed to initialize encoder\n"); 1415 DRM_ERROR("KMS: Failed to initialize encoder\n");
@@ -1754,7 +1780,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
1754 int r = amdgpu_bo_reserve(rbo, false); 1780 int r = amdgpu_bo_reserve(rbo, false);
1755 1781
1756 if (unlikely(r)) { 1782 if (unlikely(r)) {
1757 DRM_ERROR("Unable to reserve buffer\n"); 1783 // Don't show error msg. when return -ERESTARTSYS
1784 if (r != -ERESTARTSYS)
1785 DRM_ERROR("Unable to reserve buffer: %d\n", r);
1758 return r; 1786 return r;
1759 } 1787 }
1760 1788
@@ -2206,11 +2234,9 @@ static void fill_audio_info(struct audio_info *audio_info,
2206 2234
2207 cea_revision = drm_connector->display_info.cea_rev; 2235 cea_revision = drm_connector->display_info.cea_rev;
2208 2236
2209 while (i < AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS && 2237 strncpy(audio_info->display_name,
2210 edid_caps->display_name[i]) { 2238 edid_caps->display_name,
2211 audio_info->display_name[i] = edid_caps->display_name[i]; 2239 AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1);
2212 i++;
2213 }
2214 2240
2215 if (cea_revision >= 3) { 2241 if (cea_revision >= 3) {
2216 audio_info->mode_count = edid_caps->audio_mode_count; 2242 audio_info->mode_count = edid_caps->audio_mode_count;
@@ -2318,8 +2344,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
2318 2344
2319 drm_connector = &aconnector->base; 2345 drm_connector = &aconnector->base;
2320 2346
2321 if (!aconnector->dc_sink) 2347 if (!aconnector->dc_sink) {
2348 /*
2349 * Exclude MST from creating fake_sink
2350 * TODO: need to enable MST into fake_sink feature
2351 */
2352 if (aconnector->mst_port)
2353 goto stream_create_fail;
2354
2322 create_fake_sink(aconnector); 2355 create_fake_sink(aconnector);
2356 }
2323 2357
2324 stream = dc_create_stream_for_sink(aconnector->dc_sink); 2358 stream = dc_create_stream_for_sink(aconnector->dc_sink);
2325 2359
@@ -2453,7 +2487,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
2453 * 2. This interface *is called* in context of user-mode ioctl. Which 2487 * 2. This interface *is called* in context of user-mode ioctl. Which
2454 * makes it a bad place for *any* MST-related activit. */ 2488 * makes it a bad place for *any* MST-related activit. */
2455 2489
2456 if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) 2490 if (aconnector->base.force == DRM_FORCE_UNSPECIFIED &&
2491 !aconnector->fake_enable)
2457 connected = (aconnector->dc_sink != NULL); 2492 connected = (aconnector->dc_sink != NULL);
2458 else 2493 else
2459 connected = (aconnector->base.force == DRM_FORCE_ON); 2494 connected = (aconnector->base.force == DRM_FORCE_ON);
@@ -2681,8 +2716,7 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
2681 (edid->extensions + 1) * EDID_LENGTH, 2716 (edid->extensions + 1) * EDID_LENGTH,
2682 &init_params); 2717 &init_params);
2683 2718
2684 if (aconnector->base.force 2719 if (aconnector->base.force == DRM_FORCE_ON)
2685 == DRM_FORCE_ON)
2686 aconnector->dc_sink = aconnector->dc_link->local_sink ? 2720 aconnector->dc_sink = aconnector->dc_link->local_sink ?
2687 aconnector->dc_link->local_sink : 2721 aconnector->dc_link->local_sink :
2688 aconnector->dc_em_sink; 2722 aconnector->dc_em_sink;
@@ -2746,7 +2780,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
2746 stream->src.height = mode->vdisplay; 2780 stream->src.height = mode->vdisplay;
2747 stream->dst = stream->src; 2781 stream->dst = stream->src;
2748 2782
2749 if (dc_validate_stream(adev->dm.dc, stream)) 2783 if (dc_validate_stream(adev->dm.dc, stream) == DC_OK)
2750 result = MODE_OK; 2784 result = MODE_OK;
2751 2785
2752 dc_stream_release(stream); 2786 dc_stream_release(stream);
@@ -2791,7 +2825,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
2791 if (!dm_crtc_state->stream) 2825 if (!dm_crtc_state->stream)
2792 return 0; 2826 return 0;
2793 2827
2794 if (dc_validate_stream(dc, dm_crtc_state->stream)) 2828 if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)
2795 return 0; 2829 return 0;
2796 2830
2797 return ret; 2831 return ret;
@@ -2835,13 +2869,13 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
2835 plane->funcs->atomic_destroy_state(plane, plane->state); 2869 plane->funcs->atomic_destroy_state(plane, plane->state);
2836 2870
2837 amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL); 2871 amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
2838 2872 WARN_ON(amdgpu_state == NULL);
2873
2839 if (amdgpu_state) { 2874 if (amdgpu_state) {
2840 plane->state = &amdgpu_state->base; 2875 plane->state = &amdgpu_state->base;
2841 plane->state->plane = plane; 2876 plane->state->plane = plane;
2842 plane->state->rotation = DRM_MODE_ROTATE_0; 2877 plane->state->rotation = DRM_MODE_ROTATE_0;
2843 } else 2878 }
2844 WARN_ON(1);
2845} 2879}
2846 2880
2847static struct drm_plane_state * 2881static struct drm_plane_state *
@@ -2986,7 +3020,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
2986 if (!dm_plane_state->dc_state) 3020 if (!dm_plane_state->dc_state)
2987 return 0; 3021 return 0;
2988 3022
2989 if (dc_validate_plane(dc, dm_plane_state->dc_state)) 3023 if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
2990 return 0; 3024 return 0;
2991 3025
2992 return -EINVAL; 3026 return -EINVAL;
@@ -3272,8 +3306,9 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
3272 drm_edid_to_eld(connector, edid); 3306 drm_edid_to_eld(connector, edid);
3273 3307
3274 amdgpu_dm_get_native_mode(connector); 3308 amdgpu_dm_get_native_mode(connector);
3275 } else 3309 } else {
3276 amdgpu_dm_connector->num_modes = 0; 3310 amdgpu_dm_connector->num_modes = 0;
3311 }
3277} 3312}
3278 3313
3279static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) 3314static 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,
3421 struct dc *dc = dm->dc; 3456 struct dc *dc = dm->dc;
3422 struct dc_link *link = dc_get_link_at_index(dc, link_index); 3457 struct dc_link *link = dc_get_link_at_index(dc, link_index);
3423 struct amdgpu_i2c_adapter *i2c; 3458 struct amdgpu_i2c_adapter *i2c;
3424 ((struct dc_link *)link)->priv = aconnector; 3459
3460 link->priv = aconnector;
3425 3461
3426 DRM_DEBUG_DRIVER("%s()\n", __func__); 3462 DRM_DEBUG_DRIVER("%s()\n", __func__);
3427 3463
@@ -3661,10 +3697,10 @@ static void handle_cursor_update(struct drm_plane *plane,
3661 return; 3697 return;
3662 3698
3663 DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n", 3699 DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n",
3664 __func__, 3700 __func__,
3665 amdgpu_crtc->crtc_id, 3701 amdgpu_crtc->crtc_id,
3666 plane->state->crtc_w, 3702 plane->state->crtc_w,
3667 plane->state->crtc_h); 3703 plane->state->crtc_h);
3668 3704
3669 ret = get_cursor_position(plane, crtc, &position); 3705 ret = get_cursor_position(plane, crtc, &position);
3670 if (ret) 3706 if (ret)
@@ -3691,14 +3727,15 @@ static void handle_cursor_update(struct drm_plane *plane,
3691 3727
3692 attributes.pitch = attributes.width; 3728 attributes.pitch = attributes.width;
3693 3729
3694 if (!dc_stream_set_cursor_attributes(crtc_state->stream, 3730 if (crtc_state->stream) {
3695 &attributes)) 3731 if (!dc_stream_set_cursor_attributes(crtc_state->stream,
3696 DRM_ERROR("DC failed to set cursor attributes\n"); 3732 &attributes))
3733 DRM_ERROR("DC failed to set cursor attributes\n");
3697 3734
3698 if (crtc_state->stream)
3699 if (!dc_stream_set_cursor_position(crtc_state->stream, 3735 if (!dc_stream_set_cursor_position(crtc_state->stream,
3700 &position)) 3736 &position))
3701 DRM_ERROR("DC failed to set cursor position\n"); 3737 DRM_ERROR("DC failed to set cursor position\n");
3738 }
3702} 3739}
3703 3740
3704static void prepare_flip_isr(struct amdgpu_crtc *acrtc) 3741static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
@@ -3726,7 +3763,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
3726 */ 3763 */
3727static void amdgpu_dm_do_flip(struct drm_crtc *crtc, 3764static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
3728 struct drm_framebuffer *fb, 3765 struct drm_framebuffer *fb,
3729 uint32_t target) 3766 uint32_t target,
3767 struct dc_state *state)
3730{ 3768{
3731 unsigned long flags; 3769 unsigned long flags;
3732 uint32_t target_vblank; 3770 uint32_t target_vblank;
@@ -3797,7 +3835,13 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
3797 surface_updates->flip_addr = &addr; 3835 surface_updates->flip_addr = &addr;
3798 3836
3799 3837
3800 dc_update_planes_and_stream(adev->dm.dc, surface_updates, 1, acrtc_state->stream, NULL); 3838 dc_commit_updates_for_stream(adev->dm.dc,
3839 surface_updates,
3840 1,
3841 acrtc_state->stream,
3842 NULL,
3843 &surface_updates->surface,
3844 state);
3801 3845
3802 DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n", 3846 DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
3803 __func__, 3847 __func__,
@@ -3823,6 +3867,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
3823 struct drm_crtc_state *new_pcrtc_state = 3867 struct drm_crtc_state *new_pcrtc_state =
3824 drm_atomic_get_new_crtc_state(state, pcrtc); 3868 drm_atomic_get_new_crtc_state(state, pcrtc);
3825 struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state); 3869 struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
3870 struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
3826 int planes_count = 0; 3871 int planes_count = 0;
3827 unsigned long flags; 3872 unsigned long flags;
3828 3873
@@ -3880,7 +3925,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
3880 amdgpu_dm_do_flip( 3925 amdgpu_dm_do_flip(
3881 crtc, 3926 crtc,
3882 fb, 3927 fb,
3883 drm_crtc_vblank_count(crtc) + *wait_for_vblank); 3928 drm_crtc_vblank_count(crtc) + *wait_for_vblank,
3929 dm_state->context);
3884 } 3930 }
3885 3931
3886 } 3932 }
@@ -3900,7 +3946,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
3900 if (false == dc_commit_planes_to_stream(dm->dc, 3946 if (false == dc_commit_planes_to_stream(dm->dc,
3901 plane_states_constructed, 3947 plane_states_constructed,
3902 planes_count, 3948 planes_count,
3903 dc_stream_attach)) 3949 dc_stream_attach,
3950 dm_state->context))
3904 dm_error("%s: Failed to attach plane!\n", __func__); 3951 dm_error("%s: Failed to attach plane!\n", __func__);
3905 } else { 3952 } else {
3906 /*TODO BUG Here should go disable planes on CRTC. */ 3953 /*TODO BUG Here should go disable planes on CRTC. */
@@ -3931,6 +3978,8 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
3931 if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream) 3978 if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
3932 manage_dm_interrupts(adev, acrtc, false); 3979 manage_dm_interrupts(adev, acrtc, false);
3933 } 3980 }
3981 /* Add check here for SoC's that support hardware cursor plane, to
3982 * unset legacy_cursor_update */
3934 3983
3935 return drm_atomic_helper_commit(dev, state, nonblock); 3984 return drm_atomic_helper_commit(dev, state, nonblock);
3936 3985
@@ -4120,7 +4169,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
4120 dm->dc, 4169 dm->dc,
4121 status->plane_states, 4170 status->plane_states,
4122 status->plane_count, 4171 status->plane_count,
4123 dm_new_crtc_state->stream)) 4172 dm_new_crtc_state->stream,
4173 dm_state->context))
4124 dm_error("%s: Failed to update stream scaling!\n", __func__); 4174 dm_error("%s: Failed to update stream scaling!\n", __func__);
4125 } 4175 }
4126 4176
@@ -4339,7 +4389,8 @@ static int dm_update_crtcs_state(struct dc *dc,
4339 aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); 4389 aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
4340 4390
4341 /* TODO This hack should go away */ 4391 /* TODO This hack should go away */
4342 if (aconnector) { 4392 if (aconnector && enable) {
4393 // Make sure fake sink is created in plug-in scenario
4343 new_con_state = drm_atomic_get_connector_state(state, 4394 new_con_state = drm_atomic_get_connector_state(state,
4344 &aconnector->base); 4395 &aconnector->base);
4345 4396
@@ -4368,12 +4419,13 @@ static int dm_update_crtcs_state(struct dc *dc,
4368 } 4419 }
4369 } 4420 }
4370 4421
4371 if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream)) { 4422 if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
4423 dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
4372 4424
4373 new_crtc_state->mode_changed = false; 4425 new_crtc_state->mode_changed = false;
4374 4426
4375 DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d", 4427 DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d",
4376 new_crtc_state->mode_changed); 4428 new_crtc_state->mode_changed);
4377 } 4429 }
4378 4430
4379 4431
@@ -4402,10 +4454,10 @@ static int dm_update_crtcs_state(struct dc *dc,
4402 crtc->base.id); 4454 crtc->base.id);
4403 4455
4404 /* i.e. reset mode */ 4456 /* i.e. reset mode */
4405 if (!dc_remove_stream_from_ctx( 4457 if (dc_remove_stream_from_ctx(
4406 dc, 4458 dc,
4407 dm_state->context, 4459 dm_state->context,
4408 dm_old_crtc_state->stream)) { 4460 dm_old_crtc_state->stream) != DC_OK) {
4409 ret = -EINVAL; 4461 ret = -EINVAL;
4410 goto fail; 4462 goto fail;
4411 } 4463 }
@@ -4416,6 +4468,13 @@ static int dm_update_crtcs_state(struct dc *dc,
4416 *lock_and_validation_needed = true; 4468 *lock_and_validation_needed = true;
4417 4469
4418 } else {/* Add stream for any updated/enabled CRTC */ 4470 } else {/* Add stream for any updated/enabled CRTC */
4471 /*
4472 * Quick fix to prevent NULL pointer on new_stream when
4473 * added MST connectors not found in existing crtc_state in the chained mode
4474 * TODO: need to dig out the root cause of that
4475 */
4476 if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port))
4477 goto next_crtc;
4419 4478
4420 if (modereset_required(new_crtc_state)) 4479 if (modereset_required(new_crtc_state))
4421 goto next_crtc; 4480 goto next_crtc;
@@ -4431,10 +4490,10 @@ static int dm_update_crtcs_state(struct dc *dc,
4431 DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n", 4490 DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n",
4432 crtc->base.id); 4491 crtc->base.id);
4433 4492
4434 if (!dc_add_stream_to_ctx( 4493 if (dc_add_stream_to_ctx(
4435 dc, 4494 dc,
4436 dm_state->context, 4495 dm_state->context,
4437 dm_new_crtc_state->stream)) { 4496 dm_new_crtc_state->stream) != DC_OK) {
4438 ret = -EINVAL; 4497 ret = -EINVAL;
4439 goto fail; 4498 goto fail;
4440 } 4499 }
@@ -4586,7 +4645,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
4586 struct drm_connector *connector; 4645 struct drm_connector *connector;
4587 struct drm_connector_state *old_con_state, *new_con_state; 4646 struct drm_connector_state *old_con_state, *new_con_state;
4588 struct drm_crtc *crtc; 4647 struct drm_crtc *crtc;
4589 struct drm_crtc_state *new_crtc_state; 4648 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
4590 4649
4591 /* 4650 /*
4592 * This bool will be set for true for any modeset/reset 4651 * 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,
4595 bool lock_and_validation_needed = false; 4654 bool lock_and_validation_needed = false;
4596 4655
4597 ret = drm_atomic_helper_check_modeset(dev, state); 4656 ret = drm_atomic_helper_check_modeset(dev, state);
4598
4599 if (ret) { 4657 if (ret) {
4600 DRM_ERROR("Atomic state validation failed with error :%d !\n", ret); 4658 DRM_ERROR("Atomic state validation failed with error :%d !\n", ret);
4601 return ret; 4659 return ret;
4602 } 4660 }
4603 4661
4604 /* 4662 /*
4605 * Hack: Commit needs planes right now, specifically for gamma 4663 * legacy_cursor_update should be made false for SoC's having
4606 * TODO rework commit to check CRTC for gamma change 4664 * a dedicated hardware plane for cursor in amdgpu_dm_atomic_commit(),
4665 * otherwise for software cursor plane,
4666 * we should not add it to list of affected planes.
4607 */ 4667 */
4608 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 4668 if (state->legacy_cursor_update) {
4609 if (new_crtc_state->color_mgmt_changed) { 4669 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
4670 if (new_crtc_state->color_mgmt_changed) {
4671 ret = drm_atomic_add_affected_planes(state, crtc);
4672 if (ret)
4673 goto fail;
4674 }
4675 }
4676 } else {
4677 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
4678 if (!new_crtc_state->enable)
4679 continue;
4680
4681 ret = drm_atomic_add_affected_connectors(state, crtc);
4682 if (ret)
4683 return ret;
4684
4610 ret = drm_atomic_add_affected_planes(state, crtc); 4685 ret = drm_atomic_add_affected_planes(state, crtc);
4611 if (ret) 4686 if (ret)
4612 goto fail; 4687 goto fail;
@@ -4684,7 +4759,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
4684 if (ret) 4759 if (ret)
4685 goto fail; 4760 goto fail;
4686 4761
4687 if (!dc_validate_global_state(dc, dm_state->context)) { 4762 if (dc_validate_global_state(dc, dm_state->context) != DC_OK) {
4688 ret = -EINVAL; 4763 ret = -EINVAL;
4689 goto fail; 4764 goto fail;
4690 } 4765 }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
index 52b6e4a91d8b..ca5d0d1581dc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
@@ -208,24 +208,21 @@ static void remove_timer_handler(struct amdgpu_device *adev,
208 DM_IRQ_TABLE_LOCK(adev, irq_table_flags); 208 DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
209 } 209 }
210 210
211 if (handler_in == NULL) { 211 /* Remove ALL handlers. */
212 /* Remove ALL handlers. */ 212 if (handler_in == NULL)
213 continue; 213 continue;
214 }
215 214
216 if (handler_in == handler_temp) { 215 /* Remove a SPECIFIC handler.
217 /* Remove a SPECIFIC handler. 216 * Found our handler - we can stop here. */
218 * Found our handler - we can stop here. */ 217 if (handler_in == handler_temp)
219 break; 218 break;
220 }
221 } 219 }
222 220
223 DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); 221 DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
224 222
225 if (handler_in != NULL && handler_removed == false) { 223 if (handler_in != NULL && handler_removed == false)
226 DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n", 224 DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
227 handler_in); 225 handler_in);
228 }
229} 226}
230 227
231static bool 228static bool
@@ -435,7 +432,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
435 * Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK 432 * Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK
436 * will be disabled from manage_dm_interrupts on disable CRTC. 433 * will be disabled from manage_dm_interrupts on disable CRTC.
437 */ 434 */
438 for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6RX; src++) { 435 for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
439 hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; 436 hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
440 hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; 437 hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
441 if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) 438 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)
462 DRM_DEBUG_KMS("DM_IRQ: early resume\n"); 459 DRM_DEBUG_KMS("DM_IRQ: early resume\n");
463 460
464 /* re-enable short pulse interrupts HW interrupt */ 461 /* re-enable short pulse interrupts HW interrupt */
465 for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) { 462 for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
466 hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; 463 hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
467 hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; 464 hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
468 if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) 465 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)
488 * Renable HW interrupt for HPD and only since FLIP and VBLANK 485 * Renable HW interrupt for HPD and only since FLIP and VBLANK
489 * will be enabled from manage_dm_interrupts on enable CRTC. 486 * will be enabled from manage_dm_interrupts on enable CRTC.
490 */ 487 */
491 for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6; src++) { 488 for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
492 hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; 489 hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
493 hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; 490 hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
494 if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) 491 if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index dfcfb5a722e0..3b05da7a90e8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -174,14 +174,60 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
174 .atomic_get_property = amdgpu_dm_connector_atomic_get_property 174 .atomic_get_property = amdgpu_dm_connector_atomic_get_property
175}; 175};
176 176
177static int dm_connector_update_modes(struct drm_connector *connector,
178 struct edid *edid)
179{
180 int ret;
181
182 ret = drm_add_edid_modes(connector, edid);
183 drm_edid_to_eld(connector, edid);
184
185 return ret;
186}
187
177static int dm_dp_mst_get_modes(struct drm_connector *connector) 188static int dm_dp_mst_get_modes(struct drm_connector *connector)
178{ 189{
179 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 190 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
180 int ret = 0; 191 int ret = 0;
181 192
182 ret = drm_add_edid_modes(&aconnector->base, aconnector->edid); 193 if (!aconnector)
194 return dm_connector_update_modes(connector, NULL);
195
196 if (!aconnector->edid) {
197 struct edid *edid;
198 struct dc_sink *dc_sink;
199 struct dc_sink_init_data init_params = {
200 .link = aconnector->dc_link,
201 .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
202 edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
183 203
184 drm_edid_to_eld(&aconnector->base, aconnector->edid); 204 if (!edid) {
205 drm_mode_connector_update_edid_property(
206 &aconnector->base,
207 NULL);
208 return ret;
209 }
210
211 aconnector->edid = edid;
212
213 dc_sink = dc_link_add_remote_sink(
214 aconnector->dc_link,
215 (uint8_t *)edid,
216 (edid->extensions + 1) * EDID_LENGTH,
217 &init_params);
218
219 dc_sink->priv = aconnector;
220 aconnector->dc_sink = dc_sink;
221
222 if (aconnector->dc_sink)
223 amdgpu_dm_add_sink_to_freesync_module(
224 connector, edid);
225
226 drm_mode_connector_update_edid_property(
227 &aconnector->base, edid);
228 }
229
230 ret = dm_connector_update_modes(connector, aconnector->edid);
185 231
186 return ret; 232 return ret;
187} 233}
@@ -241,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
241 struct amdgpu_device *adev = dev->dev_private; 287 struct amdgpu_device *adev = dev->dev_private;
242 struct amdgpu_dm_connector *aconnector; 288 struct amdgpu_dm_connector *aconnector;
243 struct drm_connector *connector; 289 struct drm_connector *connector;
290 struct drm_connector_list_iter conn_iter;
244 291
245 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); 292 drm_connector_list_iter_begin(dev, &conn_iter);
246 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 293 drm_for_each_connector_iter(connector, &conn_iter) {
247 aconnector = to_amdgpu_dm_connector(connector); 294 aconnector = to_amdgpu_dm_connector(connector);
248 if (aconnector->mst_port == master 295 if (aconnector->mst_port == master
249 && !aconnector->port) { 296 && !aconnector->port) {
@@ -253,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
253 aconnector->port = port; 300 aconnector->port = port;
254 drm_mode_connector_set_path_property(connector, pathprop); 301 drm_mode_connector_set_path_property(connector, pathprop);
255 302
256 drm_modeset_unlock(&dev->mode_config.connection_mutex); 303 drm_connector_list_iter_end(&conn_iter);
257 return &aconnector->base; 304 return &aconnector->base;
258 } 305 }
259 } 306 }
260 drm_modeset_unlock(&dev->mode_config.connection_mutex); 307 drm_connector_list_iter_end(&conn_iter);
261 308
262 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); 309 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
263 if (!aconnector) 310 if (!aconnector)
@@ -343,92 +390,20 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
343{ 390{
344 struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); 391 struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
345 struct drm_device *dev = master->base.dev; 392 struct drm_device *dev = master->base.dev;
346 struct amdgpu_device *adev = dev->dev_private;
347 struct drm_connector *connector;
348 struct amdgpu_dm_connector *aconnector;
349 struct edid *edid;
350 struct dc_sink *dc_sink;
351
352 drm_modeset_lock_all(dev);
353 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
354 aconnector = to_amdgpu_dm_connector(connector);
355 if (aconnector->port &&
356 aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
357 aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
358 !aconnector->dc_sink) {
359 /*
360 * This is plug in case, where port has been created but
361 * sink hasn't been created yet
362 */
363 if (!aconnector->edid) {
364 struct dc_sink_init_data init_params = {
365 .link = aconnector->dc_link,
366 .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
367 edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
368
369 if (!edid) {
370 drm_mode_connector_update_edid_property(
371 &aconnector->base,
372 NULL);
373 continue;
374 }
375
376 aconnector->edid = edid;
377
378 dc_sink = dc_link_add_remote_sink(
379 aconnector->dc_link,
380 (uint8_t *)edid,
381 (edid->extensions + 1) * EDID_LENGTH,
382 &init_params);
383
384 dc_sink->priv = aconnector;
385 aconnector->dc_sink = dc_sink;
386
387 if (aconnector->dc_sink)
388 amdgpu_dm_add_sink_to_freesync_module(
389 connector,
390 edid);
391
392 dm_restore_drm_connector_state(connector->dev, connector);
393 } else
394 edid = aconnector->edid;
395
396 DRM_DEBUG_KMS("edid retrieved %p\n", edid);
397 393
398 drm_mode_connector_update_edid_property( 394 drm_kms_helper_hotplug_event(dev);
399 &aconnector->base,
400 aconnector->edid);
401 }
402 }
403 drm_modeset_unlock_all(dev);
404
405 schedule_work(&adev->dm.mst_hotplug_work);
406} 395}
407 396
408static void dm_dp_mst_register_connector(struct drm_connector *connector) 397static void dm_dp_mst_register_connector(struct drm_connector *connector)
409{ 398{
410 struct drm_device *dev = connector->dev; 399 struct drm_device *dev = connector->dev;
411 struct amdgpu_device *adev = dev->dev_private; 400 struct amdgpu_device *adev = dev->dev_private;
412 int i;
413
414 drm_modeset_lock_all(dev);
415 if (adev->mode_info.rfbdev) {
416 /*Do not add if already registered in past*/
417 for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) {
418 if (adev->mode_info.rfbdev->helper.connector_info[i]->connector
419 == connector) {
420 drm_modeset_unlock_all(dev);
421 return;
422 }
423 }
424 401
402 if (adev->mode_info.rfbdev)
425 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); 403 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
426 }
427 else 404 else
428 DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); 405 DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
429 406
430 drm_modeset_unlock_all(dev);
431
432 drm_connector_register(connector); 407 drm_connector_register(connector);
433 408
434} 409}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
index 26bf9918fcb7..5df8fd5b537c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
@@ -35,6 +35,12 @@
35#include "amdgpu_dm_irq.h" 35#include "amdgpu_dm_irq.h"
36#include "amdgpu_pm.h" 36#include "amdgpu_pm.h"
37 37
38unsigned long long dm_get_timestamp(struct dc_context *ctx)
39{
40 /* TODO: return actual timestamp */
41 return 0;
42}
43
38bool dm_write_persistent_data(struct dc_context *ctx, 44bool dm_write_persistent_data(struct dc_context *ctx,
39 const struct dc_sink *sink, 45 const struct dc_sink *sink,
40 const char *module_name, 46 const char *module_name,
diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.c b/drivers/gpu/drm/amd/display/dc/basics/logger.c
index afb6d2d80e0c..e04e8ecd4874 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/logger.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/logger.c
@@ -80,8 +80,6 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger,
80 logger->buffer_read_offset = 0; 80 logger->buffer_read_offset = 0;
81 logger->buffer_write_offset = 0; 81 logger->buffer_write_offset = 0;
82 82
83 logger->write_wrap_count = 0;
84 logger->read_wrap_count = 0;
85 logger->open_count = 0; 83 logger->open_count = 0;
86 84
87 logger->flags.bits.ENABLE_CONSOLE = 1; 85 logger->flags.bits.ENABLE_CONSOLE = 1;
@@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry)
162} 160}
163 161
164/* Print everything unread existing in log_buffer to debug console*/ 162/* Print everything unread existing in log_buffer to debug console*/
165static void flush_to_debug_console(struct dal_logger *logger) 163void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn)
166{ 164{
167 int i = logger->buffer_read_offset; 165 char *string_start = &logger->log_buffer[logger->buffer_read_offset];
168 char *string_start = &logger->log_buffer[i];
169 166
170 dm_output_to_console( 167 if (should_warn)
171 "---------------- FLUSHING LOG BUFFER ----------------\n"); 168 dm_output_to_console(
172 while (i < logger->buffer_write_offset) { 169 "---------------- FLUSHING LOG BUFFER ----------------\n");
170 while (logger->buffer_read_offset < logger->buffer_write_offset) {
173 171
174 if (logger->log_buffer[i] == '\0') { 172 if (logger->log_buffer[logger->buffer_read_offset] == '\0') {
175 dm_output_to_console("%s", string_start); 173 dm_output_to_console("%s", string_start);
176 string_start = (char *)logger->log_buffer + i + 1; 174 string_start = logger->log_buffer + logger->buffer_read_offset + 1;
177 } 175 }
178 i++; 176 logger->buffer_read_offset++;
179 } 177 }
180 dm_output_to_console( 178 if (should_warn)
181 "-------------- END FLUSHING LOG BUFFER --------------\n\n"); 179 dm_output_to_console(
180 "-------------- END FLUSHING LOG BUFFER --------------\n\n");
182} 181}
183 182
184static void log_to_internal_buffer(struct log_entry *entry) 183static void log_to_internal_buffer(struct log_entry *entry)
@@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry)
195 194
196 if (size > 0 && size < logger->log_buffer_size) { 195 if (size > 0 && size < logger->log_buffer_size) {
197 196
198 int total_free_space = 0; 197 int buffer_space = logger->log_buffer_size -
199 int space_before_wrap = 0; 198 logger->buffer_write_offset;
200 199
201 if (logger->buffer_write_offset > logger->buffer_read_offset) { 200 if (logger->buffer_write_offset == logger->buffer_read_offset) {
202 total_free_space = logger->log_buffer_size -
203 logger->buffer_write_offset +
204 logger->buffer_read_offset;
205 space_before_wrap = logger->log_buffer_size -
206 logger->buffer_write_offset;
207 } else if (logger->buffer_write_offset <
208 logger->buffer_read_offset) {
209 total_free_space = logger->log_buffer_size -
210 logger->buffer_read_offset +
211 logger->buffer_write_offset;
212 space_before_wrap = total_free_space;
213 } else if (logger->write_wrap_count !=
214 logger->read_wrap_count) {
215 /* Buffer is completely full already */
216 total_free_space = 0;
217 space_before_wrap = 0;
218 } else {
219 /* Buffer is empty, start writing at beginning */ 201 /* Buffer is empty, start writing at beginning */
220 total_free_space = logger->log_buffer_size; 202 buffer_space = logger->log_buffer_size;
221 space_before_wrap = logger->log_buffer_size;
222 logger->buffer_write_offset = 0; 203 logger->buffer_write_offset = 0;
223 logger->buffer_read_offset = 0; 204 logger->buffer_read_offset = 0;
224 } 205 }
225 206
226 if (space_before_wrap > size) { 207 if (buffer_space > size) {
227 /* No wrap around, copy 'size' bytes 208 /* No wrap around, copy 'size' bytes
228 * from 'entry->buf' to 'log_buffer' 209 * from 'entry->buf' to 'log_buffer'
229 */ 210 */
@@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry)
232 entry->buf, size); 213 entry->buf, size);
233 logger->buffer_write_offset += size; 214 logger->buffer_write_offset += size;
234 215
235 } else if (total_free_space > size) {
236 /* We have enough room without flushing,
237 * but need to wrap around */
238
239 int space_after_wrap = total_free_space -
240 space_before_wrap;
241
242 memmove(logger->log_buffer +
243 logger->buffer_write_offset,
244 entry->buf, space_before_wrap);
245 memmove(logger->log_buffer, entry->buf +
246 space_before_wrap, space_after_wrap);
247
248 logger->buffer_write_offset = space_after_wrap;
249 logger->write_wrap_count++;
250
251 } else { 216 } else {
252 /* Not enough room remaining, we should flush 217 /* Not enough room remaining, we should flush
253 * existing logs */ 218 * existing logs */
254 219
255 /* Flush existing unread logs to console */ 220 /* Flush existing unread logs to console */
256 flush_to_debug_console(logger); 221 dm_logger_flush_buffer(logger, true);
257 222
258 /* Start writing to beginning of buffer */ 223 /* Start writing to beginning of buffer */
259 memmove(logger->log_buffer, entry->buf, size); 224 memmove(logger->log_buffer, entry->buf, size);
@@ -325,9 +290,10 @@ void dm_logger_write(
325 log_heading(&entry); 290 log_heading(&entry);
326 291
327 size = dm_log_to_buffer( 292 size = dm_log_to_buffer(
328 buffer, LOG_MAX_LINE_SIZE, msg, args); 293 buffer, LOG_MAX_LINE_SIZE - 1, msg, args);
329 294
330 entry.buf_offset += size; 295 buffer[entry.buf_offset + size] = '\0';
296 entry.buf_offset += size + 1;
331 297
332 /* --Flush log_entry buffer-- */ 298 /* --Flush log_entry buffer-- */
333 /* print to kernel console */ 299 /* print to kernel console */
diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.h b/drivers/gpu/drm/amd/display/dc/basics/logger.h
index 2f7a5df4c811..09722f0f8aa3 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/logger.h
+++ b/drivers/gpu/drm/amd/display/dc/basics/logger.h
@@ -26,42 +26,5 @@
26#ifndef __DAL_LOGGER_H__ 26#ifndef __DAL_LOGGER_H__
27#define __DAL_LOGGER_H__ 27#define __DAL_LOGGER_H__
28 28
29/* Structure for keeping track of offsets, buffer, etc */
30
31#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
32
33/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
34 * change log line size to 896 to meet the request.
35 */
36#define LOG_MAX_LINE_SIZE 896
37
38#include "include/logger_types.h"
39
40struct dal_logger {
41
42 /* How far into the circular buffer has been read by dsat
43 * Read offset should never cross write offset. Write \0's to
44 * read data just to be sure?
45 */
46 uint32_t buffer_read_offset;
47
48 /* How far into the circular buffer we have written
49 * Write offset should never cross read offset
50 */
51 uint32_t buffer_write_offset;
52
53 uint32_t write_wrap_count;
54 uint32_t read_wrap_count;
55
56 uint32_t open_count;
57
58 char *log_buffer; /* Pointer to malloc'ed buffer */
59 uint32_t log_buffer_size; /* Size of circular buffer */
60
61 uint32_t mask; /*array of masks for major elements*/
62
63 union logger_flags flags;
64 struct dc_context *ctx;
65};
66 29
67#endif /* __DAL_LOGGER_H__ */ 30#endif /* __DAL_LOGGER_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index cb94e18cc455..43e9a9959288 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -1042,13 +1042,13 @@ static enum bp_result get_embedded_panel_info_v2_1(
1042 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; 1042 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
1043 1043
1044 info->lcd_timing.misc_info.H_REPLICATION_BY2 = 1044 info->lcd_timing.misc_info.H_REPLICATION_BY2 =
1045 lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2; 1045 !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
1046 info->lcd_timing.misc_info.V_REPLICATION_BY2 = 1046 info->lcd_timing.misc_info.V_REPLICATION_BY2 =
1047 lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2; 1047 !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
1048 info->lcd_timing.misc_info.COMPOSITE_SYNC = 1048 info->lcd_timing.misc_info.COMPOSITE_SYNC =
1049 lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC; 1049 !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
1050 info->lcd_timing.misc_info.INTERLACE = 1050 info->lcd_timing.misc_info.INTERLACE =
1051 lvds->lcd_timing.miscinfo & ATOM_INTERLACE; 1051 !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
1052 1052
1053 /* not provided by VBIOS*/ 1053 /* not provided by VBIOS*/
1054 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; 1054 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
@@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1(
1056 info->ss_id = 0; 1056 info->ss_id = 0;
1057 1057
1058 info->realtek_eDPToLVDS = 1058 info->realtek_eDPToLVDS =
1059 (lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0); 1059 !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
1060 1060
1061 return BP_RESULT_OK; 1061 return BP_RESULT_OK;
1062} 1062}
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
index a095472bf4b5..41ef35995b02 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
@@ -5,7 +5,7 @@
5 5
6CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4 6CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4
7CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4 7CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4
8CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 8CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 -Wno-tautological-compare
9 9
10BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o 10BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
11 11
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
index 05cf5f77ec60..b6abe0f3bb15 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c
@@ -25,6 +25,41 @@
25 25
26#include "dcn_calc_math.h" 26#include "dcn_calc_math.h"
27 27
28float dcn_bw_mod(const float arg1, const float arg2)
29{
30 if (arg1 != arg1)
31 return arg2;
32 if (arg2 != arg2)
33 return arg1;
34 return arg1 - arg1 * ((int) (arg1 / arg2));
35}
36
37float dcn_bw_min2(const float arg1, const float arg2)
38{
39 if (arg1 != arg1)
40 return arg2;
41 if (arg2 != arg2)
42 return arg1;
43 return arg1 < arg2 ? arg1 : arg2;
44}
45
46unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
47{
48 if (arg1 != arg1)
49 return arg2;
50 if (arg2 != arg2)
51 return arg1;
52 return arg1 > arg2 ? arg1 : arg2;
53}
54float dcn_bw_max2(const float arg1, const float arg2)
55{
56 if (arg1 != arg1)
57 return arg2;
58 if (arg2 != arg2)
59 return arg1;
60 return arg1 > arg2 ? arg1 : arg2;
61}
62
28float dcn_bw_floor2(const float arg, const float significance) 63float dcn_bw_floor2(const float arg, const float significance)
29{ 64{
30 if (significance == 0) 65 if (significance == 0)
@@ -40,6 +75,16 @@ float dcn_bw_ceil2(const float arg, const float significance)
40 return flr + 0.00001 >= arg ? arg : flr + significance; 75 return flr + 0.00001 >= arg ? arg : flr + significance;
41} 76}
42 77
78float dcn_bw_max3(float v1, float v2, float v3)
79{
80 return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
81}
82
83float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
84{
85 return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
86}
87
43float dcn_bw_pow(float a, float exp) 88float dcn_bw_pow(float a, float exp)
44{ 89{
45 float temp; 90 float temp;
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h
index 6f66d9d164d1..f46ab0e24ca1 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h
@@ -26,38 +26,14 @@
26#ifndef _DCN_CALC_MATH_H_ 26#ifndef _DCN_CALC_MATH_H_
27#define _DCN_CALC_MATH_H_ 27#define _DCN_CALC_MATH_H_
28 28
29static inline float dcn_bw_mod(const float arg1, const float arg2) 29float dcn_bw_mod(const float arg1, const float arg2);
30{ 30float dcn_bw_min2(const float arg1, const float arg2);
31 return arg1 - arg1 * ((int) (arg1 / arg2)); 31unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
32} 32float dcn_bw_max2(const float arg1, const float arg2);
33
34static inline float dcn_bw_min2(const float arg1, const float arg2)
35{
36 return arg1 < arg2 ? arg1 : arg2;
37}
38
39static inline unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
40{
41 return arg1 > arg2 ? arg1 : arg2;
42}
43
44static inline float dcn_bw_max2(const float arg1, const float arg2)
45{
46 return arg1 > arg2 ? arg1 : arg2;
47}
48
49static inline float dcn_bw_max3(float v1, float v2, float v3)
50{
51 return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
52}
53
54static inline float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
55{
56 return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
57}
58
59float dcn_bw_floor2(const float arg, const float significance); 33float dcn_bw_floor2(const float arg, const float significance);
60float dcn_bw_ceil2(const float arg, const float significance); 34float dcn_bw_ceil2(const float arg, const float significance);
35float dcn_bw_max3(float v1, float v2, float v3);
36float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
61float dcn_bw_pow(float a, float exp); 37float dcn_bw_pow(float a, float exp);
62float dcn_bw_log(float a, float b); 38float dcn_bw_log(float a, float b);
63 39
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
index 8ca6c3e4e65a..e1515230c661 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -364,7 +364,8 @@ static void pipe_ctx_to_e2e_pipe_params (
364 } 364 }
365 365
366 366
367 input->dest.vactive = pipe->stream->timing.v_addressable; 367 input->dest.vactive = pipe->stream->timing.v_addressable + pipe->stream->timing.v_border_top
368 + pipe->stream->timing.v_border_bottom;
368 369
369 input->dest.recout_width = pipe->plane_res.scl_data.recout.width; 370 input->dest.recout_width = pipe->plane_res.scl_data.recout.width;
370 input->dest.recout_height = pipe->plane_res.scl_data.recout.height; 371 input->dest.recout_height = pipe->plane_res.scl_data.recout.height;
@@ -385,10 +386,6 @@ static void pipe_ctx_to_e2e_pipe_params (
385 - pipe->stream->timing.v_addressable 386 - pipe->stream->timing.v_addressable
386 - pipe->stream->timing.v_border_bottom 387 - pipe->stream->timing.v_border_bottom
387 - pipe->stream->timing.v_border_top; 388 - pipe->stream->timing.v_border_top;
388
389 input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total
390 - pipe->stream->timing.v_addressable
391 - pipe->stream->timing.v_front_porch;
392 input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0; 389 input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0;
393 input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start; 390 input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start;
394 input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset; 391 input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset;
@@ -458,9 +455,9 @@ static void dcn_bw_calc_rq_dlg_ttu(
458 /*todo: soc->sr_enter_plus_exit_time??*/ 455 /*todo: soc->sr_enter_plus_exit_time??*/
459 dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep; 456 dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
460 457
461 dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src); 458 dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
462 extract_rq_regs(dml, rq_regs, rq_param); 459 dml1_extract_rq_regs(dml, rq_regs, rq_param);
463 dml_rq_dlg_get_dlg_params( 460 dml1_rq_dlg_get_dlg_params(
464 dml, 461 dml,
465 dlg_regs, 462 dlg_regs,
466 ttu_regs, 463 ttu_regs,
@@ -473,96 +470,6 @@ static void dcn_bw_calc_rq_dlg_ttu(
473 pipe->plane_state->flip_immediate); 470 pipe->plane_state->flip_immediate);
474} 471}
475 472
476static void dcn_dml_wm_override(
477 const struct dcn_bw_internal_vars *v,
478 struct display_mode_lib *dml,
479 struct dc_state *context,
480 const struct resource_pool *pool)
481{
482 int i, in_idx, active_count;
483
484 struct _vcs_dpi_display_e2e_pipe_params_st *input = kzalloc(pool->pipe_count * sizeof(struct _vcs_dpi_display_e2e_pipe_params_st),
485 GFP_KERNEL);
486 struct wm {
487 double urgent;
488 struct _vcs_dpi_cstate_pstate_watermarks_st cpstate;
489 double pte_meta_urgent;
490 } a;
491
492
493 for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
494 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
495
496 if (!pipe->stream || !pipe->plane_state)
497 continue;
498
499 input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk;
500 input[in_idx].clks_cfg.dispclk_mhz = v->dispclk;
501 input[in_idx].clks_cfg.dppclk_mhz = v->dppclk;
502 input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000;
503 input[in_idx].clks_cfg.socclk_mhz = v->socclk;
504 input[in_idx].clks_cfg.voltage = v->voltage_level;
505 input[in_idx].dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
506 input[in_idx].dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
507 //input[in_idx].dout.output_standard;
508 switch (v->output_deep_color[in_idx]) {
509 case dcn_bw_encoder_12bpc:
510 input[in_idx].dout.output_bpc = dm_out_12;
511 break;
512 case dcn_bw_encoder_10bpc:
513 input[in_idx].dout.output_bpc = dm_out_10;
514 break;
515 case dcn_bw_encoder_8bpc:
516 default:
517 input[in_idx].dout.output_bpc = dm_out_8;
518 break;
519 }
520 pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe);
521 dml_rq_dlg_get_rq_reg(
522 dml,
523 &pipe->rq_regs,
524 input[in_idx].pipe.src);
525 in_idx++;
526 }
527 active_count = in_idx;
528
529 a.urgent = dml_wm_urgent_e2e(dml, input, active_count);
530 a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count);
531 a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent);
532
533 context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns =
534 a.cpstate.cstate_exit_us * 1000;
535 context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
536 a.cpstate.cstate_enter_plus_exit_us * 1000;
537 context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns =
538 a.cpstate.pstate_change_us * 1000;
539 context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000;
540 context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000;
541 context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a;
542 context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a;
543 context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a;
544
545
546 for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
547 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
548
549 if (!pipe->stream || !pipe->plane_state)
550 continue;
551
552 dml_rq_dlg_get_dlg_reg(dml,
553 &pipe->dlg_regs,
554 &pipe->ttu_regs,
555 input, active_count,
556 in_idx,
557 true,
558 true,
559 v->pte_enable == dcn_bw_yes,
560 pipe->plane_state->flip_immediate);
561 in_idx++;
562 }
563 kfree(input);
564}
565
566static void split_stream_across_pipes( 473static void split_stream_across_pipes(
567 struct resource_context *res_ctx, 474 struct resource_context *res_ctx,
568 const struct resource_pool *pool, 475 const struct resource_pool *pool,
@@ -578,8 +485,10 @@ static void split_stream_across_pipes(
578 485
579 secondary_pipe->pipe_idx = pipe_idx; 486 secondary_pipe->pipe_idx = pipe_idx;
580 secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx]; 487 secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx];
488 secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx];
581 secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx]; 489 secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
582 secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx]; 490 secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
491 secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
583 if (primary_pipe->bottom_pipe) { 492 if (primary_pipe->bottom_pipe) {
584 ASSERT(primary_pipe->bottom_pipe != secondary_pipe); 493 ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
585 secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe; 494 secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
@@ -719,6 +628,49 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
719 return updated; 628 return updated;
720} 629}
721 630
631void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
632{
633 /*
634 * disable optional pipe split by lower dispclk bounding box
635 * at DPM0
636 */
637 v->max_dispclk[0] = v->max_dppclk_vmin0p65;
638}
639
640void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
641 unsigned int pixel_rate_khz)
642{
643 float pixel_rate_mhz = pixel_rate_khz / 1000;
644
645 /*
646 * force enabling pipe split by lower dpp clock for DPM0 to just
647 * below the specify pixel_rate, so bw calc would split pipe.
648 */
649 if (pixel_rate_mhz < v->max_dppclk[0])
650 v->max_dppclk[0] = pixel_rate_mhz;
651}
652
653void hack_bounding_box(struct dcn_bw_internal_vars *v,
654 struct dc_debug *dbg,
655 struct dc_state *context)
656{
657 if (dbg->pipe_split_policy == MPC_SPLIT_AVOID) {
658 hack_disable_optional_pipe_split(v);
659 }
660
661 if (dbg->pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP &&
662 context->stream_count >= 2) {
663 hack_disable_optional_pipe_split(v);
664 }
665
666 if (context->stream_count == 1 &&
667 dbg->force_single_disp_pipe_split) {
668 struct dc_stream_state *stream0 = context->streams[0];
669
670 hack_force_pipe_split(v, stream0->timing.pix_clk_khz);
671 }
672}
673
722bool dcn_validate_bandwidth( 674bool dcn_validate_bandwidth(
723 struct dc *dc, 675 struct dc *dc,
724 struct dc_state *context) 676 struct dc_state *context)
@@ -730,6 +682,7 @@ bool dcn_validate_bandwidth(
730 bool bw_limit_pass; 682 bool bw_limit_pass;
731 float bw_limit; 683 float bw_limit;
732 684
685 PERFORMANCE_TRACE_START();
733 if (dcn_bw_apply_registry_override(dc)) 686 if (dcn_bw_apply_registry_override(dc))
734 dcn_bw_sync_calcs_and_dml(dc); 687 dcn_bw_sync_calcs_and_dml(dc);
735 688
@@ -850,9 +803,7 @@ bool dcn_validate_bandwidth(
850 v->phyclk_per_state[1] = v->phyclkv_mid0p72; 803 v->phyclk_per_state[1] = v->phyclkv_mid0p72;
851 v->phyclk_per_state[0] = v->phyclkv_min0p65; 804 v->phyclk_per_state[0] = v->phyclkv_min0p65;
852 805
853 if (dc->debug.disable_pipe_split) { 806 hack_bounding_box(v, &dc->debug, context);
854 v->max_dispclk[0] = v->max_dppclk_vmin0p65;
855 }
856 807
857 if (v->voltage_override == dcn_bw_v_max0p9) { 808 if (v->voltage_override == dcn_bw_v_max0p9) {
858 v->voltage_override_level = number_of_states - 1; 809 v->voltage_override_level = number_of_states - 1;
@@ -882,10 +833,11 @@ bool dcn_validate_bandwidth(
882 833
883 v->htotal[input_idx] = pipe->stream->timing.h_total; 834 v->htotal[input_idx] = pipe->stream->timing.h_total;
884 v->vtotal[input_idx] = pipe->stream->timing.v_total; 835 v->vtotal[input_idx] = pipe->stream->timing.v_total;
836 v->vactive[input_idx] = pipe->stream->timing.v_addressable +
837 pipe->stream->timing.v_border_top + pipe->stream->timing.v_border_bottom;
885 v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total 838 v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total
886 - pipe->stream->timing.v_addressable 839 - v->vactive[input_idx]
887 - pipe->stream->timing.v_front_porch; 840 - pipe->stream->timing.v_front_porch;
888 v->vactive[input_idx] = pipe->stream->timing.v_addressable;
889 v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f; 841 v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f;
890 842
891 if (!pipe->plane_state) { 843 if (!pipe->plane_state) {
@@ -1006,6 +958,10 @@ bool dcn_validate_bandwidth(
1006 else 958 else
1007 bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9; 959 bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9;
1008 960
961 if (bw_consumed < v->fabric_and_dram_bandwidth)
962 if (dc->debug.voltage_align_fclk)
963 bw_consumed = v->fabric_and_dram_bandwidth;
964
1009 display_pipe_configuration(v); 965 display_pipe_configuration(v);
1010 calc_wm_sets_and_perf_params(context, v); 966 calc_wm_sets_and_perf_params(context, v);
1011 context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 / 967 context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 /
@@ -1018,9 +974,17 @@ bool dcn_validate_bandwidth(
1018 context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin); 974 context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin);
1019 context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); 975 context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000);
1020 context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000); 976 context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000);
977
1021 context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000); 978 context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000);
1022 if (dc->debug.max_disp_clk == true) 979 if (dc->debug.max_disp_clk == true)
1023 context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); 980 context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000);
981
982 if (context->bw.dcn.calc_clk.dispclk_khz <
983 dc->debug.min_disp_clk_khz) {
984 context->bw.dcn.calc_clk.dispclk_khz =
985 dc->debug.min_disp_clk_khz;
986 }
987
1024 context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2; 988 context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2;
1025 989
1026 for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { 990 for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
@@ -1108,9 +1072,6 @@ bool dcn_validate_bandwidth(
1108 1072
1109 input_idx++; 1073 input_idx++;
1110 } 1074 }
1111 if (dc->debug.use_dml_wm)
1112 dcn_dml_wm_override(v, (struct display_mode_lib *)
1113 &dc->dml, context, pool);
1114 } 1075 }
1115 1076
1116 if (v->voltage_level == 0) { 1077 if (v->voltage_level == 0) {
@@ -1129,6 +1090,8 @@ bool dcn_validate_bandwidth(
1129 1090
1130 kernel_fpu_end(); 1091 kernel_fpu_end();
1131 1092
1093 PERFORMANCE_TRACE_END();
1094
1132 if (bw_limit_pass && v->voltage_level != 5) 1095 if (bw_limit_pass && v->voltage_level != 5)
1133 return true; 1096 return true;
1134 else 1097 else
@@ -1263,7 +1226,7 @@ unsigned int dcn_find_dcfclk_suits_all(
1263 else 1226 else
1264 dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000; 1227 dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000;
1265 1228
1266 dm_logger_write(dc->ctx->logger, LOG_HW_MARKS, 1229 dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
1267 "\tdcf_clk for voltage = %d\n", dcf_clk); 1230 "\tdcf_clk for voltage = %d\n", dcf_clk);
1268 return dcf_clk; 1231 return dcf_clk;
1269} 1232}
@@ -1386,6 +1349,53 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
1386 ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz; 1349 ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz;
1387 ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz; 1350 ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz;
1388 1351
1352 if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
1353 ranges.reader_wm_sets[0].wm_inst = WM_A;
1354 ranges.reader_wm_sets[0].min_drain_clk_khz = 300000;
1355 ranges.reader_wm_sets[0].max_drain_clk_khz = 654000;
1356 ranges.reader_wm_sets[0].min_fill_clk_khz = 800000;
1357 ranges.reader_wm_sets[0].max_fill_clk_khz = 800000;
1358 ranges.writer_wm_sets[0].wm_inst = WM_A;
1359 ranges.writer_wm_sets[0].min_fill_clk_khz = 200000;
1360 ranges.writer_wm_sets[0].max_fill_clk_khz = 757000;
1361 ranges.writer_wm_sets[0].min_drain_clk_khz = 800000;
1362 ranges.writer_wm_sets[0].max_drain_clk_khz = 800000;
1363
1364 ranges.reader_wm_sets[1].wm_inst = WM_B;
1365 ranges.reader_wm_sets[1].min_drain_clk_khz = 300000;
1366 ranges.reader_wm_sets[1].max_drain_clk_khz = 654000;
1367 ranges.reader_wm_sets[1].min_fill_clk_khz = 933000;
1368 ranges.reader_wm_sets[1].max_fill_clk_khz = 933000;
1369 ranges.writer_wm_sets[1].wm_inst = WM_B;
1370 ranges.writer_wm_sets[1].min_fill_clk_khz = 200000;
1371 ranges.writer_wm_sets[1].max_fill_clk_khz = 757000;
1372 ranges.writer_wm_sets[1].min_drain_clk_khz = 933000;
1373 ranges.writer_wm_sets[1].max_drain_clk_khz = 933000;
1374
1375
1376 ranges.reader_wm_sets[2].wm_inst = WM_C;
1377 ranges.reader_wm_sets[2].min_drain_clk_khz = 300000;
1378 ranges.reader_wm_sets[2].max_drain_clk_khz = 654000;
1379 ranges.reader_wm_sets[2].min_fill_clk_khz = 1067000;
1380 ranges.reader_wm_sets[2].max_fill_clk_khz = 1067000;
1381 ranges.writer_wm_sets[2].wm_inst = WM_C;
1382 ranges.writer_wm_sets[2].min_fill_clk_khz = 200000;
1383 ranges.writer_wm_sets[2].max_fill_clk_khz = 757000;
1384 ranges.writer_wm_sets[2].min_drain_clk_khz = 1067000;
1385 ranges.writer_wm_sets[2].max_drain_clk_khz = 1067000;
1386
1387 ranges.reader_wm_sets[3].wm_inst = WM_D;
1388 ranges.reader_wm_sets[3].min_drain_clk_khz = 300000;
1389 ranges.reader_wm_sets[3].max_drain_clk_khz = 654000;
1390 ranges.reader_wm_sets[3].min_fill_clk_khz = 1200000;
1391 ranges.reader_wm_sets[3].max_fill_clk_khz = 1200000;
1392 ranges.writer_wm_sets[3].wm_inst = WM_D;
1393 ranges.writer_wm_sets[3].min_fill_clk_khz = 200000;
1394 ranges.writer_wm_sets[3].max_fill_clk_khz = 757000;
1395 ranges.writer_wm_sets[3].min_drain_clk_khz = 1200000;
1396 ranges.writer_wm_sets[3].max_drain_clk_khz = 1200000;
1397 }
1398
1389 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ 1399 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1390 pp->set_wm_ranges(&pp->pp_smu, &ranges); 1400 pp->set_wm_ranges(&pp->pp_smu, &ranges);
1391} 1401}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index f41f15faf019..a71392ffc46d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -38,6 +38,7 @@
38#include "bios_parser_interface.h" 38#include "bios_parser_interface.h"
39#include "include/irq_service_interface.h" 39#include "include/irq_service_interface.h"
40#include "transform.h" 40#include "transform.h"
41#include "dpp.h"
41#include "timing_generator.h" 42#include "timing_generator.h"
42#include "virtual/virtual_link_encoder.h" 43#include "virtual/virtual_link_encoder.h"
43 44
@@ -47,6 +48,7 @@
47#include "dc_link_ddc.h" 48#include "dc_link_ddc.h"
48#include "dm_helpers.h" 49#include "dm_helpers.h"
49#include "mem_input.h" 50#include "mem_input.h"
51#include "hubp.h"
50 52
51 53
52/******************************************************************************* 54/*******************************************************************************
@@ -332,10 +334,19 @@ static void set_dither_option(struct dc_stream_state *stream,
332{ 334{
333 struct bit_depth_reduction_params params; 335 struct bit_depth_reduction_params params;
334 struct dc_link *link = stream->status.link; 336 struct dc_link *link = stream->status.link;
335 struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; 337 struct pipe_ctx *pipes = NULL;
338 int i;
339
340 for (i = 0; i < MAX_PIPES; i++) {
341 if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
342 stream) {
343 pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
344 break;
345 }
346 }
336 347
337 memset(&params, 0, sizeof(params)); 348 memset(&params, 0, sizeof(params));
338 if (!stream) 349 if (!pipes)
339 return; 350 return;
340 if (option > DITHER_OPTION_MAX) 351 if (option > DITHER_OPTION_MAX)
341 return; 352 return;
@@ -349,6 +360,36 @@ static void set_dither_option(struct dc_stream_state *stream,
349 opp_program_bit_depth_reduction(pipes->stream_res.opp, &params); 360 opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
350} 361}
351 362
363void set_dpms(
364 struct dc *dc,
365 struct dc_stream_state *stream,
366 bool dpms_off)
367{
368 struct pipe_ctx *pipe_ctx = NULL;
369 int i;
370
371 for (i = 0; i < MAX_PIPES; i++) {
372 if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
373 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
374 break;
375 }
376 }
377
378 if (!pipe_ctx) {
379 ASSERT(0);
380 return;
381 }
382
383 if (stream->dpms_off != dpms_off) {
384 stream->dpms_off = dpms_off;
385 if (dpms_off)
386 core_link_disable_stream(pipe_ctx,
387 KEEP_ACQUIRED_RESOURCE);
388 else
389 core_link_enable_stream(dc->current_state, pipe_ctx);
390 }
391}
392
352static void allocate_dc_stream_funcs(struct dc *dc) 393static void allocate_dc_stream_funcs(struct dc *dc)
353{ 394{
354 if (dc->hwss.set_drr != NULL) { 395 if (dc->hwss.set_drr != NULL) {
@@ -371,6 +412,9 @@ static void allocate_dc_stream_funcs(struct dc *dc)
371 dc->stream_funcs.set_dither_option = 412 dc->stream_funcs.set_dither_option =
372 set_dither_option; 413 set_dither_option;
373 414
415 dc->stream_funcs.set_dpms =
416 set_dpms;
417
374 dc->link_funcs.set_drive_settings = 418 dc->link_funcs.set_drive_settings =
375 set_drive_settings; 419 set_drive_settings;
376 420
@@ -507,7 +551,7 @@ static bool construct(struct dc *dc,
507 551
508 dc_version = resource_parse_asic_id(init_params->asic_id); 552 dc_version = resource_parse_asic_id(init_params->asic_id);
509 dc->ctx->dce_version = dc_version; 553 dc->ctx->dce_version = dc_version;
510#ifdef ENABLE_FBC 554#if defined(CONFIG_DRM_AMD_DC_FBC)
511 dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr; 555 dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr;
512#endif 556#endif
513 /* Resource should construct all asic specific resources. 557 /* Resource should construct all asic specific resources.
@@ -749,7 +793,7 @@ bool dc_enable_stereo(
749 * Applies given context to HW and copy it into current context. 793 * Applies given context to HW and copy it into current context.
750 * It's up to the user to release the src context afterwards. 794 * It's up to the user to release the src context afterwards.
751 */ 795 */
752static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context) 796static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
753{ 797{
754 struct dc_bios *dcb = dc->ctx->dc_bios; 798 struct dc_bios *dcb = dc->ctx->dc_bios;
755 enum dc_status result = DC_ERROR_UNEXPECTED; 799 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)
763 if (!dcb->funcs->is_accelerated_mode(dcb)) 807 if (!dcb->funcs->is_accelerated_mode(dcb))
764 dc->hwss.enable_accelerated_mode(dc); 808 dc->hwss.enable_accelerated_mode(dc);
765 809
766 dc->hwss.ready_shared_resources(dc);
767
768 for (i = 0; i < dc->res_pool->pipe_count; i++) {
769 pipe = &context->res_ctx.pipe_ctx[i];
770 dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
771 }
772 result = dc->hwss.apply_ctx_to_hw(dc, context);
773
774 program_timing_sync(dc, context);
775
776 for (i = 0; i < context->stream_count; i++) { 810 for (i = 0; i < context->stream_count; i++) {
777 const struct dc_sink *sink = context->streams[i]->sink; 811 const struct dc_sink *sink = context->streams[i]->sink;
778 812
779 for (j = 0; j < context->stream_status[i].plane_count; j++) { 813 dc->hwss.apply_ctx_for_surface(
780 dc->hwss.apply_ctx_for_surface( 814 dc, context->streams[i],
781 dc, context->streams[i], 815 context->stream_status[i].plane_count,
782 context->stream_status[i].plane_count, 816 context);
783 context);
784 817
785 /* 818 /*
786 * enable stereo 819 * enable stereo
787 * TODO rework dc_enable_stereo call to work with validation sets? 820 * TODO rework dc_enable_stereo call to work with validation sets?
788 */ 821 */
789 for (k = 0; k < MAX_PIPES; k++) { 822 for (k = 0; k < MAX_PIPES; k++) {
790 pipe = &context->res_ctx.pipe_ctx[k]; 823 pipe = &context->res_ctx.pipe_ctx[k];
791 824
792 for (l = 0 ; pipe && l < context->stream_count; l++) { 825 for (l = 0 ; pipe && l < context->stream_count; l++) {
793 if (context->streams[l] && 826 if (context->streams[l] &&
794 context->streams[l] == pipe->stream && 827 context->streams[l] == pipe->stream &&
795 dc->hwss.setup_stereo) 828 dc->hwss.setup_stereo)
796 dc->hwss.setup_stereo(pipe, dc); 829 dc->hwss.setup_stereo(pipe, dc);
797 }
798 } 830 }
799 } 831 }
800 832
833
834
801 CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}", 835 CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
802 context->streams[i]->timing.h_addressable, 836 context->streams[i]->timing.h_addressable,
803 context->streams[i]->timing.v_addressable, 837 context->streams[i]->timing.v_addressable,
@@ -806,8 +840,27 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
806 context->streams[i]->timing.pix_clk_khz); 840 context->streams[i]->timing.pix_clk_khz);
807 } 841 }
808 842
843 dc->hwss.ready_shared_resources(dc, context);
844
845 for (i = 0; i < dc->res_pool->pipe_count; i++) {
846 pipe = &context->res_ctx.pipe_ctx[i];
847 dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
848 }
849 result = dc->hwss.apply_ctx_to_hw(dc, context);
850
851 program_timing_sync(dc, context);
852
809 dc_enable_stereo(dc, context, dc_streams, context->stream_count); 853 dc_enable_stereo(dc, context, dc_streams, context->stream_count);
810 854
855 for (i = 0; i < context->stream_count; i++) {
856 for (j = 0; j < MAX_PIPES; j++) {
857 pipe = &context->res_ctx.pipe_ctx[j];
858
859 if (!pipe->top_pipe && pipe->stream == context->streams[i])
860 dc->hwss.pipe_control_lock(dc, pipe, false);
861 }
862 }
863
811 dc_release_state(dc->current_state); 864 dc_release_state(dc->current_state);
812 865
813 dc->current_state = context; 866 dc->current_state = context;
@@ -816,7 +869,7 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
816 869
817 dc->hwss.optimize_shared_resources(dc); 870 dc->hwss.optimize_shared_resources(dc);
818 871
819 return (result == DC_OK); 872 return result;
820} 873}
821 874
822bool dc_commit_state(struct dc *dc, struct dc_state *context) 875bool dc_commit_state(struct dc *dc, struct dc_state *context)
@@ -865,16 +918,24 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
865 return true; 918 return true;
866} 919}
867 920
921/*
922 * TODO this whole function needs to go
923 *
924 * dc_surface_update is needlessly complex. See if we can just replace this
925 * with a dc_plane_state and follow the atomic model a bit more closely here.
926 */
868bool dc_commit_planes_to_stream( 927bool dc_commit_planes_to_stream(
869 struct dc *dc, 928 struct dc *dc,
870 struct dc_plane_state **plane_states, 929 struct dc_plane_state **plane_states,
871 uint8_t new_plane_count, 930 uint8_t new_plane_count,
872 struct dc_stream_state *dc_stream) 931 struct dc_stream_state *dc_stream,
932 struct dc_state *state)
873{ 933{
934 /* no need to dynamically allocate this. it's pretty small */
874 struct dc_surface_update updates[MAX_SURFACES]; 935 struct dc_surface_update updates[MAX_SURFACES];
875 struct dc_flip_addrs flip_addr[MAX_SURFACES]; 936 struct dc_flip_addrs *flip_addr;
876 struct dc_plane_info plane_info[MAX_SURFACES]; 937 struct dc_plane_info *plane_info;
877 struct dc_scaling_info scaling_info[MAX_SURFACES]; 938 struct dc_scaling_info *scaling_info;
878 int i; 939 int i;
879 struct dc_stream_update *stream_update = 940 struct dc_stream_update *stream_update =
880 kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL); 941 kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
@@ -884,10 +945,14 @@ bool dc_commit_planes_to_stream(
884 return false; 945 return false;
885 } 946 }
886 947
948 flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs),
949 GFP_KERNEL);
950 plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info),
951 GFP_KERNEL);
952 scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info),
953 GFP_KERNEL);
954
887 memset(updates, 0, sizeof(updates)); 955 memset(updates, 0, sizeof(updates));
888 memset(flip_addr, 0, sizeof(flip_addr));
889 memset(plane_info, 0, sizeof(plane_info));
890 memset(scaling_info, 0, sizeof(scaling_info));
891 956
892 stream_update->src = dc_stream->src; 957 stream_update->src = dc_stream->src;
893 stream_update->dst = dc_stream->dst; 958 stream_update->dst = dc_stream->dst;
@@ -920,14 +985,15 @@ bool dc_commit_planes_to_stream(
920 updates[i].scaling_info = &scaling_info[i]; 985 updates[i].scaling_info = &scaling_info[i];
921 } 986 }
922 987
923 dc_update_planes_and_stream( 988 dc_commit_updates_for_stream(
924 dc, 989 dc,
925 updates, 990 updates,
926 new_plane_count, 991 new_plane_count,
927 dc_stream, stream_update); 992 dc_stream, stream_update, plane_states, state);
928
929 dc_post_update_surfaces_to_stream(dc);
930 993
994 kfree(flip_addr);
995 kfree(plane_info);
996 kfree(scaling_info);
931 kfree(stream_update); 997 kfree(stream_update);
932 return true; 998 return true;
933} 999}
@@ -1030,7 +1096,6 @@ static enum surface_update_type get_plane_info_update_type(
1030 temp_plane_info.plane_size = u->surface->plane_size; 1096 temp_plane_info.plane_size = u->surface->plane_size;
1031 temp_plane_info.rotation = u->surface->rotation; 1097 temp_plane_info.rotation = u->surface->rotation;
1032 temp_plane_info.stereo_format = u->surface->stereo_format; 1098 temp_plane_info.stereo_format = u->surface->stereo_format;
1033 temp_plane_info.tiling_info = u->surface->tiling_info;
1034 1099
1035 if (surface_index == 0) 1100 if (surface_index == 0)
1036 temp_plane_info.visible = u->plane_info->visible; 1101 temp_plane_info.visible = u->plane_info->visible;
@@ -1043,10 +1108,26 @@ static enum surface_update_type get_plane_info_update_type(
1043 1108
1044 if (pixel_format_to_bpp(u->plane_info->format) != 1109 if (pixel_format_to_bpp(u->plane_info->format) !=
1045 pixel_format_to_bpp(u->surface->format)) { 1110 pixel_format_to_bpp(u->surface->format)) {
1111 /* different bytes per element will require full bandwidth
1112 * and DML calculation
1113 */
1046 return UPDATE_TYPE_FULL; 1114 return UPDATE_TYPE_FULL;
1047 } else {
1048 return UPDATE_TYPE_MED;
1049 } 1115 }
1116
1117 if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
1118 sizeof(union dc_tiling_info)) != 0) {
1119 /* todo: below are HW dependent, we should add a hook to
1120 * DCE/N resource and validated there.
1121 */
1122 if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
1123 /* swizzled mode requires RQ to be setup properly,
1124 * thus need to run DML to calculate RQ settings
1125 */
1126 return UPDATE_TYPE_FULL;
1127 }
1128 }
1129
1130 return UPDATE_TYPE_MED;
1050} 1131}
1051 1132
1052static enum surface_update_type get_scaling_info_update_type( 1133static enum surface_update_type get_scaling_info_update_type(
@@ -1150,192 +1231,20 @@ static struct dc_stream_status *stream_get_status(
1150 1231
1151static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; 1232static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
1152 1233
1153void dc_update_planes_and_stream(struct dc *dc, 1234
1154 struct dc_surface_update *srf_updates, int surface_count, 1235static void commit_planes_for_stream(struct dc *dc,
1236 struct dc_surface_update *srf_updates,
1237 int surface_count,
1155 struct dc_stream_state *stream, 1238 struct dc_stream_state *stream,
1156 struct dc_stream_update *stream_update) 1239 struct dc_stream_update *stream_update,
1240 enum surface_update_type update_type,
1241 struct dc_state *context)
1157{ 1242{
1158 struct dc_state *context;
1159 int i, j; 1243 int i, j;
1160 enum surface_update_type update_type;
1161 const struct dc_stream_status *stream_status;
1162 struct dc_context *dc_ctx = dc->ctx;
1163
1164 stream_status = dc_stream_get_status(stream);
1165
1166 ASSERT(stream_status);
1167 if (!stream_status)
1168 return; /* Cannot commit surface to stream that is not committed */
1169
1170#ifdef ENABLE_FBC
1171 if (srf_updates->flip_addr) {
1172 if (srf_updates->flip_addr->address.grph.addr.low_part == 0)
1173 ASSERT(0);
1174 }
1175#endif
1176 context = dc->current_state;
1177
1178 /* update current stream with the new updates */
1179 if (stream_update) {
1180 if ((stream_update->src.height != 0) &&
1181 (stream_update->src.width != 0))
1182 stream->src = stream_update->src;
1183
1184 if ((stream_update->dst.height != 0) &&
1185 (stream_update->dst.width != 0))
1186 stream->dst = stream_update->dst;
1187
1188 if (stream_update->out_transfer_func &&
1189 stream_update->out_transfer_func !=
1190 stream->out_transfer_func) {
1191 if (stream->out_transfer_func != NULL)
1192 dc_transfer_func_release(stream->out_transfer_func);
1193 dc_transfer_func_retain(stream_update->out_transfer_func);
1194 stream->out_transfer_func =
1195 stream_update->out_transfer_func;
1196 }
1197 }
1198
1199 /* do not perform surface update if surface has invalid dimensions
1200 * (all zero) and no scaling_info is provided
1201 */
1202 if (surface_count > 0 &&
1203 srf_updates->surface->src_rect.width == 0 &&
1204 srf_updates->surface->src_rect.height == 0 &&
1205 srf_updates->surface->dst_rect.width == 0 &&
1206 srf_updates->surface->dst_rect.height == 0 &&
1207 !srf_updates->scaling_info) {
1208 ASSERT(false);
1209 return;
1210 }
1211
1212 update_type = dc_check_update_surfaces_for_stream(
1213 dc, srf_updates, surface_count, stream_update, stream_status);
1214
1215 if (update_type >= update_surface_trace_level)
1216 update_surface_trace(dc, srf_updates, surface_count);
1217
1218 if (update_type >= UPDATE_TYPE_FULL) {
1219 struct dc_plane_state *new_planes[MAX_SURFACES] = {0};
1220
1221 for (i = 0; i < surface_count; i++)
1222 new_planes[i] = srf_updates[i].surface;
1223
1224 /* initialize scratch memory for building context */
1225 context = dc_create_state();
1226 if (context == NULL) {
1227 DC_ERROR("Failed to allocate new validate context!\n");
1228 return;
1229 }
1230
1231 dc_resource_state_copy_construct(
1232 dc->current_state, context);
1233
1234 /*remove old surfaces from context */
1235 if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
1236
1237 BREAK_TO_DEBUGGER();
1238 goto fail;
1239 }
1240
1241 /* add surface to context */
1242 if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
1243
1244 BREAK_TO_DEBUGGER();
1245 goto fail;
1246 }
1247 }
1248
1249 /* save update parameters into surface */
1250 for (i = 0; i < surface_count; i++) {
1251 struct dc_plane_state *surface = srf_updates[i].surface;
1252
1253 if (srf_updates[i].flip_addr) {
1254 surface->address = srf_updates[i].flip_addr->address;
1255 surface->flip_immediate =
1256 srf_updates[i].flip_addr->flip_immediate;
1257 }
1258
1259 if (srf_updates[i].scaling_info) {
1260 surface->scaling_quality =
1261 srf_updates[i].scaling_info->scaling_quality;
1262 surface->dst_rect =
1263 srf_updates[i].scaling_info->dst_rect;
1264 surface->src_rect =
1265 srf_updates[i].scaling_info->src_rect;
1266 surface->clip_rect =
1267 srf_updates[i].scaling_info->clip_rect;
1268 }
1269
1270 if (srf_updates[i].plane_info) {
1271 surface->color_space =
1272 srf_updates[i].plane_info->color_space;
1273 surface->format =
1274 srf_updates[i].plane_info->format;
1275 surface->plane_size =
1276 srf_updates[i].plane_info->plane_size;
1277 surface->rotation =
1278 srf_updates[i].plane_info->rotation;
1279 surface->horizontal_mirror =
1280 srf_updates[i].plane_info->horizontal_mirror;
1281 surface->stereo_format =
1282 srf_updates[i].plane_info->stereo_format;
1283 surface->tiling_info =
1284 srf_updates[i].plane_info->tiling_info;
1285 surface->visible =
1286 srf_updates[i].plane_info->visible;
1287 surface->per_pixel_alpha =
1288 srf_updates[i].plane_info->per_pixel_alpha;
1289 surface->dcc =
1290 srf_updates[i].plane_info->dcc;
1291 }
1292
1293 if (update_type >= UPDATE_TYPE_MED) {
1294 for (j = 0; j < dc->res_pool->pipe_count; j++) {
1295 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1296
1297 if (pipe_ctx->plane_state != surface)
1298 continue;
1299
1300 resource_build_scaling_params(pipe_ctx);
1301 }
1302 }
1303
1304 if (srf_updates[i].gamma &&
1305 srf_updates[i].gamma != surface->gamma_correction) {
1306 if (surface->gamma_correction != NULL)
1307 dc_gamma_release(&surface->gamma_correction);
1308
1309 dc_gamma_retain(srf_updates[i].gamma);
1310 surface->gamma_correction = srf_updates[i].gamma;
1311 }
1312
1313 if (srf_updates[i].in_transfer_func &&
1314 srf_updates[i].in_transfer_func != surface->in_transfer_func) {
1315 if (surface->in_transfer_func != NULL)
1316 dc_transfer_func_release(
1317 surface->
1318 in_transfer_func);
1319
1320 dc_transfer_func_retain(
1321 srf_updates[i].in_transfer_func);
1322 surface->in_transfer_func =
1323 srf_updates[i].in_transfer_func;
1324 }
1325
1326 if (srf_updates[i].hdr_static_metadata)
1327 surface->hdr_static_ctx =
1328 *(srf_updates[i].hdr_static_metadata);
1329 }
1330 1244
1331 if (update_type == UPDATE_TYPE_FULL) { 1245 if (update_type == UPDATE_TYPE_FULL) {
1332 if (!dc->res_pool->funcs->validate_bandwidth(dc, context)) { 1246 dc->hwss.set_bandwidth(dc, context, false);
1333 BREAK_TO_DEBUGGER(); 1247 context_clock_trace(dc, context);
1334 goto fail;
1335 } else {
1336 dc->hwss.set_bandwidth(dc, context, false);
1337 context_clock_trace(dc, context);
1338 }
1339 } 1248 }
1340 1249
1341 if (update_type > UPDATE_TYPE_FAST) { 1250 if (update_type > UPDATE_TYPE_FAST) {
@@ -1346,8 +1255,14 @@ void dc_update_planes_and_stream(struct dc *dc,
1346 } 1255 }
1347 } 1256 }
1348 1257
1349 if (surface_count == 0) 1258 if (surface_count == 0) {
1259 /*
1260 * In case of turning off screen, no need to program front end a second time.
1261 * just return after program front end.
1262 */
1350 dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context); 1263 dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context);
1264 return;
1265 }
1351 1266
1352 /* Lock pipes for provided surfaces, or all active if full update*/ 1267 /* Lock pipes for provided surfaces, or all active if full update*/
1353 for (i = 0; i < surface_count; i++) { 1268 for (i = 0; i < surface_count; i++) {
@@ -1373,10 +1288,6 @@ void dc_update_planes_and_stream(struct dc *dc,
1373 /* Full fe update*/ 1288 /* Full fe update*/
1374 for (j = 0; j < dc->res_pool->pipe_count; j++) { 1289 for (j = 0; j < dc->res_pool->pipe_count; j++) {
1375 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 1290 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1376 struct pipe_ctx *cur_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[j];
1377 bool is_new_pipe_surface = cur_pipe_ctx->plane_state != pipe_ctx->plane_state;
1378 struct dc_cursor_position position = { 0 };
1379
1380 1291
1381 if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state) 1292 if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state)
1382 continue; 1293 continue;
@@ -1387,17 +1298,6 @@ void dc_update_planes_and_stream(struct dc *dc,
1387 dc->hwss.apply_ctx_for_surface( 1298 dc->hwss.apply_ctx_for_surface(
1388 dc, pipe_ctx->stream, stream_status->plane_count, context); 1299 dc, pipe_ctx->stream, stream_status->plane_count, context);
1389 } 1300 }
1390
1391 /* TODO: this is a hack w/a for switching from mpo to pipe split */
1392 dc_stream_set_cursor_position(pipe_ctx->stream, &position);
1393
1394 if (is_new_pipe_surface) {
1395 dc->hwss.update_plane_addr(dc, pipe_ctx);
1396 dc->hwss.set_input_transfer_func(
1397 pipe_ctx, pipe_ctx->plane_state);
1398 dc->hwss.set_output_transfer_func(
1399 pipe_ctx, pipe_ctx->stream);
1400 }
1401 } 1301 }
1402 1302
1403 if (update_type > UPDATE_TYPE_FAST) 1303 if (update_type > UPDATE_TYPE_FAST)
@@ -1423,7 +1323,9 @@ void dc_update_planes_and_stream(struct dc *dc,
1423 if (update_type == UPDATE_TYPE_FAST) 1323 if (update_type == UPDATE_TYPE_FAST)
1424 continue; 1324 continue;
1425 1325
1426 if (srf_updates[i].in_transfer_func) 1326 /* work around to program degamma regs for split pipe after set mode. */
1327 if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe &&
1328 pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state))
1427 dc->hwss.set_input_transfer_func( 1329 dc->hwss.set_input_transfer_func(
1428 pipe_ctx, pipe_ctx->plane_state); 1330 pipe_ctx, pipe_ctx->plane_state);
1429 1331
@@ -1459,16 +1361,79 @@ void dc_update_planes_and_stream(struct dc *dc,
1459 break; 1361 break;
1460 } 1362 }
1461 } 1363 }
1364}
1462 1365
1463 if (dc->current_state != context) { 1366void dc_commit_updates_for_stream(struct dc *dc,
1367 struct dc_surface_update *srf_updates,
1368 int surface_count,
1369 struct dc_stream_state *stream,
1370 struct dc_stream_update *stream_update,
1371 struct dc_plane_state **plane_states,
1372 struct dc_state *state)
1373{
1374 const struct dc_stream_status *stream_status;
1375 enum surface_update_type update_type;
1376 struct dc_state *context;
1377 struct dc_context *dc_ctx = dc->ctx;
1378 int i, j;
1379
1380 stream_status = dc_stream_get_status(stream);
1381 context = dc->current_state;
1382
1383 update_type = dc_check_update_surfaces_for_stream(
1384 dc, srf_updates, surface_count, stream_update, stream_status);
1385
1386 if (update_type >= update_surface_trace_level)
1387 update_surface_trace(dc, srf_updates, surface_count);
1388
1389
1390 if (update_type >= UPDATE_TYPE_FULL) {
1391
1392 /* initialize scratch memory for building context */
1393 context = dc_create_state();
1394 if (context == NULL) {
1395 DC_ERROR("Failed to allocate new validate context!\n");
1396 return;
1397 }
1398
1399 dc_resource_state_copy_construct(state, context);
1400 }
1401
1402
1403 for (i = 0; i < surface_count; i++) {
1404 struct dc_plane_state *surface = srf_updates[i].surface;
1464 1405
1465 /* Since memory free requires elevated IRQL, an interrupt 1406 /* TODO: On flip we don't build the state, so it still has the
1466 * request is generated by mem free. If this happens 1407 * old address. Which is why we are updating the address here
1467 * between freeing and reassigning the context, our vsync
1468 * interrupt will call into dc and cause a memory
1469 * corruption BSOD. Hence, we first reassign the context,
1470 * then free the old context.
1471 */ 1408 */
1409 if (srf_updates[i].flip_addr)
1410 surface->address = srf_updates[i].flip_addr->address;
1411
1412 if (update_type >= UPDATE_TYPE_MED) {
1413 for (j = 0; j < dc->res_pool->pipe_count; j++) {
1414 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
1415
1416 if (pipe_ctx->plane_state != surface)
1417 continue;
1418
1419 resource_build_scaling_params(pipe_ctx);
1420 }
1421 }
1422 }
1423
1424 commit_planes_for_stream(
1425 dc,
1426 srf_updates,
1427 surface_count,
1428 stream,
1429 stream_update,
1430 update_type,
1431 context);
1432
1433 if (update_type >= UPDATE_TYPE_FULL)
1434 dc_post_update_surfaces_to_stream(dc);
1435
1436 if (dc->current_state != context) {
1472 1437
1473 struct dc_state *old = dc->current_state; 1438 struct dc_state *old = dc->current_state;
1474 1439
@@ -1476,10 +1441,9 @@ void dc_update_planes_and_stream(struct dc *dc,
1476 dc_release_state(old); 1441 dc_release_state(old);
1477 1442
1478 } 1443 }
1444
1479 return; 1445 return;
1480 1446
1481fail:
1482 dc_release_state(context);
1483} 1447}
1484 1448
1485uint8_t dc_get_current_stream_count(struct dc *dc) 1449uint8_t dc_get_current_stream_count(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 4a70948c91b1..c47da645d3b8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -45,6 +45,7 @@
45#include "dce/dce_11_0_enum.h" 45#include "dce/dce_11_0_enum.h"
46#include "dce/dce_11_0_sh_mask.h" 46#include "dce/dce_11_0_sh_mask.h"
47 47
48#define EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK 0x007C /* Copied from atombios.h */
48#define LINK_INFO(...) \ 49#define LINK_INFO(...) \
49 dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \ 50 dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \
50 __VA_ARGS__) 51 __VA_ARGS__)
@@ -78,14 +79,15 @@ static void destruct(struct dc_link *link)
78 dc_sink_release(link->remote_sinks[i]); 79 dc_sink_release(link->remote_sinks[i]);
79} 80}
80 81
81static struct gpio *get_hpd_gpio(const struct dc_link *link) 82struct gpio *get_hpd_gpio(struct dc_bios *dcb,
83 struct graphics_object_id link_id,
84 struct gpio_service *gpio_service)
82{ 85{
83 enum bp_result bp_result; 86 enum bp_result bp_result;
84 struct dc_bios *dcb = link->ctx->dc_bios;
85 struct graphics_object_hpd_info hpd_info; 87 struct graphics_object_hpd_info hpd_info;
86 struct gpio_pin_info pin_info; 88 struct gpio_pin_info pin_info;
87 89
88 if (dcb->funcs->get_hpd_info(dcb, link->link_id, &hpd_info) != BP_RESULT_OK) 90 if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
89 return NULL; 91 return NULL;
90 92
91 bp_result = dcb->funcs->get_gpio_pin_info(dcb, 93 bp_result = dcb->funcs->get_gpio_pin_info(dcb,
@@ -97,7 +99,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link)
97 } 99 }
98 100
99 return dal_gpio_service_create_irq( 101 return dal_gpio_service_create_irq(
100 link->ctx->gpio_service, 102 gpio_service,
101 pin_info.offset, 103 pin_info.offset,
102 pin_info.mask); 104 pin_info.mask);
103} 105}
@@ -153,7 +155,7 @@ static bool program_hpd_filter(
153 } 155 }
154 156
155 /* Obtain HPD handle */ 157 /* Obtain HPD handle */
156 hpd = get_hpd_gpio(link); 158 hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
157 159
158 if (!hpd) 160 if (!hpd)
159 return result; 161 return result;
@@ -186,7 +188,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
186 struct gpio *hpd_pin; 188 struct gpio *hpd_pin;
187 189
188 /* todo: may need to lock gpio access */ 190 /* todo: may need to lock gpio access */
189 hpd_pin = get_hpd_gpio(link); 191 hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
190 if (hpd_pin == NULL) 192 if (hpd_pin == NULL)
191 goto hpd_gpio_failure; 193 goto hpd_gpio_failure;
192 194
@@ -496,6 +498,7 @@ static void detect_dp(
496 } 498 }
497 if (is_mst_supported(link)) { 499 if (is_mst_supported(link)) {
498 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST; 500 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
501 link->type = dc_connection_mst_branch;
499 502
500 /* 503 /*
501 * This call will initiate MST topology discovery. Which 504 * This call will initiate MST topology discovery. Which
@@ -524,12 +527,11 @@ static void detect_dp(
524 if (reason == DETECT_REASON_BOOT) 527 if (reason == DETECT_REASON_BOOT)
525 boot = true; 528 boot = true;
526 529
527 if (dm_helpers_dp_mst_start_top_mgr( 530 if (!dm_helpers_dp_mst_start_top_mgr(
528 link->ctx, 531 link->ctx,
529 link, boot)) { 532 link, boot)) {
530 link->type = dc_connection_mst_branch;
531 } else {
532 /* MST not supported */ 533 /* MST not supported */
534 link->type = dc_connection_single;
533 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; 535 sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
534 } 536 }
535 } 537 }
@@ -638,8 +640,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
638 if (link->dpcd_caps.sink_count.bits.SINK_COUNT) 640 if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
639 link->dpcd_sink_count = link->dpcd_caps.sink_count. 641 link->dpcd_sink_count = link->dpcd_caps.sink_count.
640 bits.SINK_COUNT; 642 bits.SINK_COUNT;
641 else 643 else
642 link->dpcd_sink_count = 1; 644 link->dpcd_sink_count = 1;
643 645
644 dal_ddc_service_set_transaction_type( 646 dal_ddc_service_set_transaction_type(
645 link->ddc, 647 link->ddc,
@@ -746,6 +748,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
746 if (link->type == dc_connection_mst_branch) { 748 if (link->type == dc_connection_mst_branch) {
747 LINK_INFO("link=%d, mst branch is now Disconnected\n", 749 LINK_INFO("link=%d, mst branch is now Disconnected\n",
748 link->link_index); 750 link->link_index);
751
749 dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); 752 dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
750 753
751 link->mst_stream_alloc_table.stream_count = 0; 754 link->mst_stream_alloc_table.stream_count = 0;
@@ -770,7 +773,7 @@ static enum hpd_source_id get_hpd_line(
770 struct gpio *hpd; 773 struct gpio *hpd;
771 enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN; 774 enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
772 775
773 hpd = get_hpd_gpio(link); 776 hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
774 777
775 if (hpd) { 778 if (hpd) {
776 switch (dal_irq_get_source(hpd)) { 779 switch (dal_irq_get_source(hpd)) {
@@ -940,7 +943,7 @@ static bool construct(
940 goto create_fail; 943 goto create_fail;
941 } 944 }
942 945
943 hpd_gpio = get_hpd_gpio(link); 946 hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
944 947
945 if (hpd_gpio != NULL) 948 if (hpd_gpio != NULL)
946 link->irq_source_hpd = dal_irq_get_source(hpd_gpio); 949 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,
1343 sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings)); 1346 sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
1344 result = true; 1347 result = true;
1345 break; 1348 break;
1346 1349 case ENGINE_ID_DIGD:
1350 settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
1351 settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
1352 settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
1353 memmove(settings->reg_settings,
1354 integrated_info->dp3_ext_hdmi_reg_settings,
1355 sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
1356 memmove(settings->reg_settings_6g,
1357 integrated_info->dp3_ext_hdmi_6g_reg_settings,
1358 sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
1359 result = true;
1360 break;
1347 default: 1361 default:
1348 break; 1362 break;
1349 } 1363 }
@@ -1680,7 +1694,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
1680 is_over_340mhz = true; 1694 is_over_340mhz = true;
1681 1695
1682 if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { 1696 if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
1683 if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) { 1697 unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
1698 EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
1699 if (masked_chip_caps == (0x2 << 2)) {
1684 /* DP159, Retimer settings */ 1700 /* DP159, Retimer settings */
1685 eng_id = pipe_ctx->stream_res.stream_enc->id; 1701 eng_id = pipe_ctx->stream_res.stream_enc->id;
1686 1702
@@ -1691,7 +1707,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
1691 write_i2c_default_retimer_setting(pipe_ctx, 1707 write_i2c_default_retimer_setting(pipe_ctx,
1692 is_vga_mode, is_over_340mhz); 1708 is_vga_mode, is_over_340mhz);
1693 } 1709 }
1694 } else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) { 1710 } else if (masked_chip_caps == (0x1 << 2)) {
1695 /* PI3EQX1204, Redriver settings */ 1711 /* PI3EQX1204, Redriver settings */
1696 write_i2c_redriver_setting(pipe_ctx, is_over_340mhz); 1712 write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
1697 } 1713 }
@@ -1782,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
1782 else 1798 else
1783 dp_disable_link_phy_mst(link, signal); 1799 dp_disable_link_phy_mst(link, signal);
1784 } else 1800 } else
1785 link->link_enc->funcs->disable_output(link->link_enc, signal); 1801 link->link_enc->funcs->disable_output(link->link_enc, signal, link);
1786} 1802}
1787 1803
1788enum dc_status dc_link_validate_mode_timing( 1804enum dc_status dc_link_validate_mode_timing(
@@ -2319,16 +2335,20 @@ void core_link_enable_stream(
2319 2335
2320 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) 2336 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2321 allocate_mst_payload(pipe_ctx); 2337 allocate_mst_payload(pipe_ctx);
2338
2339 if (dc_is_dp_signal(pipe_ctx->stream->signal))
2340 core_dc->hwss.unblank_stream(pipe_ctx,
2341 &pipe_ctx->stream->sink->link->cur_link_settings);
2322} 2342}
2323 2343
2324void core_link_disable_stream(struct pipe_ctx *pipe_ctx) 2344void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
2325{ 2345{
2326 struct dc *core_dc = pipe_ctx->stream->ctx->dc; 2346 struct dc *core_dc = pipe_ctx->stream->ctx->dc;
2327 2347
2328 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) 2348 if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2329 deallocate_mst_payload(pipe_ctx); 2349 deallocate_mst_payload(pipe_ctx);
2330 2350
2331 core_dc->hwss.disable_stream(pipe_ctx); 2351 core_dc->hwss.disable_stream(pipe_ctx, option);
2332 2352
2333 disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal); 2353 disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
2334} 2354}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index b735782b8fe0..ced42484dcfc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1700,6 +1700,12 @@ static void dp_test_send_link_training(struct dc_link *link)
1700 dp_retrain_link_dp_test(link, &link_settings, false); 1700 dp_retrain_link_dp_test(link, &link_settings, false);
1701} 1701}
1702 1702
1703/* TODO hbr2 compliance eye output is unstable
1704 * (toggling on and off) with debugger break
1705 * This caueses intermittent PHY automation failure
1706 * Need to look into the root cause */
1707static uint8_t force_tps4_for_cp2520 = 1;
1708
1703static void dp_test_send_phy_test_pattern(struct dc_link *link) 1709static void dp_test_send_phy_test_pattern(struct dc_link *link)
1704{ 1710{
1705 union phy_test_pattern dpcd_test_pattern; 1711 union phy_test_pattern dpcd_test_pattern;
@@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
1758 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM; 1764 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
1759 break; 1765 break;
1760 case PHY_TEST_PATTERN_CP2520_1: 1766 case PHY_TEST_PATTERN_CP2520_1:
1761 test_pattern = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; 1767 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
1768 test_pattern = (force_tps4_for_cp2520 == 1) ?
1769 DP_TEST_PATTERN_TRAINING_PATTERN4 :
1770 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
1762 break; 1771 break;
1763 case PHY_TEST_PATTERN_CP2520_2: 1772 case PHY_TEST_PATTERN_CP2520_2:
1764 test_pattern = DP_TEST_PATTERN_CP2520_2; 1773 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
1774 test_pattern = (force_tps4_for_cp2520 == 1) ?
1775 DP_TEST_PATTERN_TRAINING_PATTERN4 :
1776 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
1765 break; 1777 break;
1766 case PHY_TEST_PATTERN_CP2520_3: 1778 case PHY_TEST_PATTERN_CP2520_3:
1767 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; 1779 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
index 5f815cab94b5..9a33b471270a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
@@ -89,12 +89,12 @@ void dp_enable_link_phy(
89 89
90 if (dc_is_dp_sst_signal(signal)) { 90 if (dc_is_dp_sst_signal(signal)) {
91 if (signal == SIGNAL_TYPE_EDP) { 91 if (signal == SIGNAL_TYPE_EDP) {
92 link_enc->funcs->power_control(link_enc, true); 92 link->dc->hwss.edp_power_control(link->link_enc, true);
93 link_enc->funcs->enable_dp_output( 93 link_enc->funcs->enable_dp_output(
94 link_enc, 94 link_enc,
95 link_settings, 95 link_settings,
96 clock_source); 96 clock_source);
97 link_enc->funcs->backlight_control(link_enc, true); 97 link->dc->hwss.edp_backlight_control(link, true);
98 } else 98 } else
99 link_enc->funcs->enable_dp_output( 99 link_enc->funcs->enable_dp_output(
100 link_enc, 100 link_enc,
@@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
138 dp_receiver_power_ctrl(link, false); 138 dp_receiver_power_ctrl(link, false);
139 139
140 if (signal == SIGNAL_TYPE_EDP) { 140 if (signal == SIGNAL_TYPE_EDP) {
141 link->link_enc->funcs->backlight_control(link->link_enc, false); 141 link->dc->hwss.edp_backlight_control(link, false);
142 edp_receiver_ready_T9(link); 142 edp_receiver_ready_T9(link);
143 link->link_enc->funcs->disable_output(link->link_enc, signal); 143 link->link_enc->funcs->disable_output(link->link_enc, signal, link);
144 link->link_enc->funcs->power_control(link->link_enc, false); 144 link->dc->hwss.edp_power_control(link->link_enc, false);
145 } else 145 } else
146 link->link_enc->funcs->disable_output(link->link_enc, signal); 146 link->link_enc->funcs->disable_output(link->link_enc, signal, link);
147 147
148 /* Clear current link setting.*/ 148 /* Clear current link setting.*/
149 memset(&link->cur_link_settings, 0, 149 memset(&link->cur_link_settings, 0,
@@ -282,11 +282,12 @@ void dp_retrain_link_dp_test(struct dc_link *link,
282 282
283 dp_receiver_power_ctrl(link, false); 283 dp_receiver_power_ctrl(link, false);
284 284
285 link->dc->hwss.disable_stream(&pipes[i]); 285 link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
286 286
287 link->link_enc->funcs->disable_output( 287 link->link_enc->funcs->disable_output(
288 link->link_enc, 288 link->link_enc,
289 SIGNAL_TYPE_DISPLAY_PORT); 289 SIGNAL_TYPE_DISPLAY_PORT,
290 link);
290 291
291 /* Clear current link setting. */ 292 /* Clear current link setting. */
292 memset(&link->cur_link_settings, 0, 293 memset(&link->cur_link_settings, 0,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 77b3474a7c9e..d1cdf9f8853d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -31,6 +31,7 @@
31#include "opp.h" 31#include "opp.h"
32#include "timing_generator.h" 32#include "timing_generator.h"
33#include "transform.h" 33#include "transform.h"
34#include "dpp.h"
34#include "core_types.h" 35#include "core_types.h"
35#include "set_mode_types.h" 36#include "set_mode_types.h"
36#include "virtual/virtual_stream_encoder.h" 37#include "virtual/virtual_stream_encoder.h"
@@ -242,7 +243,10 @@ bool resource_construct(
242 pool->stream_enc_count++; 243 pool->stream_enc_count++;
243 } 244 }
244 } 245 }
245 246 dc->caps.dynamic_audio = false;
247 if (pool->audio_count < pool->stream_enc_count) {
248 dc->caps.dynamic_audio = true;
249 }
246 for (i = 0; i < num_virtual_links; i++) { 250 for (i = 0; i < num_virtual_links; i++) {
247 pool->stream_enc[pool->stream_enc_count] = 251 pool->stream_enc[pool->stream_enc_count] =
248 virtual_stream_encoder_create( 252 virtual_stream_encoder_create(
@@ -846,12 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
846 */ 850 */
847 pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; 851 pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
848 852
849 pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable; 853 pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
850 pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable; 854 pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
855
856 pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
857 pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
851 858
852 /* Taps calculations */ 859 /* Taps calculations */
853 res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( 860 if (pipe_ctx->plane_res.xfm != NULL)
854 pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); 861 res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
862 pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
863
864 if (pipe_ctx->plane_res.dpp != NULL)
865 res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
866 pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
855 867
856 if (!res) { 868 if (!res) {
857 /* Try 24 bpp linebuffer */ 869 /* Try 24 bpp linebuffer */
@@ -859,6 +871,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
859 871
860 res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps( 872 res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
861 pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality); 873 pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
874
875 res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
876 pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
862 } 877 }
863 878
864 if (res) 879 if (res)
@@ -1021,9 +1036,9 @@ static int acquire_first_split_pipe(
1021 1036
1022 memset(pipe_ctx, 0, sizeof(*pipe_ctx)); 1037 memset(pipe_ctx, 0, sizeof(*pipe_ctx));
1023 pipe_ctx->stream_res.tg = pool->timing_generators[i]; 1038 pipe_ctx->stream_res.tg = pool->timing_generators[i];
1024 pipe_ctx->plane_res.mi = pool->mis[i]; 1039 pipe_ctx->plane_res.hubp = pool->hubps[i];
1025 pipe_ctx->plane_res.ipp = pool->ipps[i]; 1040 pipe_ctx->plane_res.ipp = pool->ipps[i];
1026 pipe_ctx->plane_res.xfm = pool->transforms[i]; 1041 pipe_ctx->plane_res.dpp = pool->dpps[i];
1027 pipe_ctx->stream_res.opp = pool->opps[i]; 1042 pipe_ctx->stream_res.opp = pool->opps[i];
1028 pipe_ctx->pipe_idx = i; 1043 pipe_ctx->pipe_idx = i;
1029 1044
@@ -1070,9 +1085,6 @@ bool dc_add_plane_to_context(
1070 return false; 1085 return false;
1071 } 1086 }
1072 1087
1073 /* retain new surfaces */
1074 dc_plane_state_retain(plane_state);
1075
1076 free_pipe = acquire_free_pipe_for_stream(context, pool, stream); 1088 free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
1077 1089
1078#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1090#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
@@ -1082,11 +1094,11 @@ bool dc_add_plane_to_context(
1082 free_pipe = &context->res_ctx.pipe_ctx[pipe_idx]; 1094 free_pipe = &context->res_ctx.pipe_ctx[pipe_idx];
1083 } 1095 }
1084#endif 1096#endif
1085 if (!free_pipe) { 1097 if (!free_pipe)
1086 stream_status->plane_states[i] = NULL;
1087 return false; 1098 return false;
1088 }
1089 1099
1100 /* retain new surfaces */
1101 dc_plane_state_retain(plane_state);
1090 free_pipe->plane_state = plane_state; 1102 free_pipe->plane_state = plane_state;
1091 1103
1092 if (head_pipe != free_pipe) { 1104 if (head_pipe != free_pipe) {
@@ -1178,8 +1190,8 @@ bool dc_remove_plane_from_context(
1178 1190
1179 stream_status->plane_count--; 1191 stream_status->plane_count--;
1180 1192
1181 /* Trim back arrays */ 1193 /* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */
1182 for (i = 0; i < stream_status->plane_count; i++) 1194 for (; i < stream_status->plane_count; i++)
1183 stream_status->plane_states[i] = stream_status->plane_states[i + 1]; 1195 stream_status->plane_states[i] = stream_status->plane_states[i + 1];
1184 1196
1185 stream_status->plane_states[stream_status->plane_count] = NULL; 1197 stream_status->plane_states[stream_status->plane_count] = NULL;
@@ -1312,6 +1324,28 @@ bool dc_is_stream_unchanged(
1312 return true; 1324 return true;
1313} 1325}
1314 1326
1327bool dc_is_stream_scaling_unchanged(
1328 struct dc_stream_state *old_stream, struct dc_stream_state *stream)
1329{
1330 if (old_stream == stream)
1331 return true;
1332
1333 if (old_stream == NULL || stream == NULL)
1334 return false;
1335
1336 if (memcmp(&old_stream->src,
1337 &stream->src,
1338 sizeof(struct rect)) != 0)
1339 return false;
1340
1341 if (memcmp(&old_stream->dst,
1342 &stream->dst,
1343 sizeof(struct rect)) != 0)
1344 return false;
1345
1346 return true;
1347}
1348
1315/* Maximum TMDS single link pixel clock 165MHz */ 1349/* Maximum TMDS single link pixel clock 165MHz */
1316#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 1350#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
1317 1351
@@ -1330,7 +1364,7 @@ static void update_stream_engine_usage(
1330} 1364}
1331 1365
1332/* TODO: release audio object */ 1366/* TODO: release audio object */
1333static void update_audio_usage( 1367void update_audio_usage(
1334 struct resource_context *res_ctx, 1368 struct resource_context *res_ctx,
1335 const struct resource_pool *pool, 1369 const struct resource_pool *pool,
1336 struct audio *audio, 1370 struct audio *audio,
@@ -1356,8 +1390,10 @@ static int acquire_first_free_pipe(
1356 1390
1357 pipe_ctx->stream_res.tg = pool->timing_generators[i]; 1391 pipe_ctx->stream_res.tg = pool->timing_generators[i];
1358 pipe_ctx->plane_res.mi = pool->mis[i]; 1392 pipe_ctx->plane_res.mi = pool->mis[i];
1393 pipe_ctx->plane_res.hubp = pool->hubps[i];
1359 pipe_ctx->plane_res.ipp = pool->ipps[i]; 1394 pipe_ctx->plane_res.ipp = pool->ipps[i];
1360 pipe_ctx->plane_res.xfm = pool->transforms[i]; 1395 pipe_ctx->plane_res.xfm = pool->transforms[i];
1396 pipe_ctx->plane_res.dpp = pool->dpps[i];
1361 pipe_ctx->stream_res.opp = pool->opps[i]; 1397 pipe_ctx->stream_res.opp = pool->opps[i];
1362 pipe_ctx->pipe_idx = i; 1398 pipe_ctx->pipe_idx = i;
1363 1399
@@ -1415,11 +1451,16 @@ static struct audio *find_first_free_audio(
1415{ 1451{
1416 int i; 1452 int i;
1417 for (i = 0; i < pool->audio_count; i++) { 1453 for (i = 0; i < pool->audio_count; i++) {
1454 if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {
1455 return pool->audios[i];
1456 }
1457 }
1458 /*not found the matching one, first come first serve*/
1459 for (i = 0; i < pool->audio_count; i++) {
1418 if (res_ctx->is_audio_acquired[i] == false) { 1460 if (res_ctx->is_audio_acquired[i] == false) {
1419 return pool->audios[i]; 1461 return pool->audios[i];
1420 } 1462 }
1421 } 1463 }
1422
1423 return 0; 1464 return 0;
1424} 1465}
1425 1466
@@ -1438,7 +1479,7 @@ bool resource_is_stream_unchanged(
1438 return false; 1479 return false;
1439} 1480}
1440 1481
1441bool dc_add_stream_to_ctx( 1482enum dc_status dc_add_stream_to_ctx(
1442 struct dc *dc, 1483 struct dc *dc,
1443 struct dc_state *new_ctx, 1484 struct dc_state *new_ctx,
1444 struct dc_stream_state *stream) 1485 struct dc_stream_state *stream)
@@ -1459,10 +1500,10 @@ bool dc_add_stream_to_ctx(
1459 if (res != DC_OK) 1500 if (res != DC_OK)
1460 DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res); 1501 DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res);
1461 1502
1462 return res == DC_OK; 1503 return res;
1463} 1504}
1464 1505
1465bool dc_remove_stream_from_ctx( 1506enum dc_status dc_remove_stream_from_ctx(
1466 struct dc *dc, 1507 struct dc *dc,
1467 struct dc_state *new_ctx, 1508 struct dc_state *new_ctx,
1468 struct dc_stream_state *stream) 1509 struct dc_stream_state *stream)
@@ -1632,10 +1673,11 @@ enum dc_status resource_map_pool_resources(
1632 /* acquire new resources */ 1673 /* acquire new resources */
1633 pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); 1674 pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
1634 1675
1635#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1676#ifdef CONFIG_DRM_AMD_DC_DCN1_0
1636 if (pipe_idx < 0) 1677 if (pipe_idx < 0)
1637 acquire_first_split_pipe(&context->res_ctx, pool, stream); 1678 pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
1638#endif 1679#endif
1680
1639 if (pipe_idx < 0) 1681 if (pipe_idx < 0)
1640 return DC_NO_CONTROLLER_RESOURCE; 1682 return DC_NO_CONTROLLER_RESOURCE;
1641 1683
@@ -1716,17 +1758,18 @@ void dc_resource_state_construct(
1716 dst_ctx->dis_clk = dc->res_pool->display_clock; 1758 dst_ctx->dis_clk = dc->res_pool->display_clock;
1717} 1759}
1718 1760
1719bool dc_validate_global_state( 1761enum dc_status dc_validate_global_state(
1720 struct dc *dc, 1762 struct dc *dc,
1721 struct dc_state *new_ctx) 1763 struct dc_state *new_ctx)
1722{ 1764{
1723 enum dc_status result = DC_ERROR_UNEXPECTED; 1765 enum dc_status result = DC_ERROR_UNEXPECTED;
1724 int i, j; 1766 int i, j;
1725 1767
1726 if (dc->res_pool->funcs->validate_global && 1768 if (dc->res_pool->funcs->validate_global) {
1727 dc->res_pool->funcs->validate_global( 1769 result = dc->res_pool->funcs->validate_global(dc, new_ctx);
1728 dc, new_ctx) != DC_OK) 1770 if (result != DC_OK)
1729 return false; 1771 return result;
1772 }
1730 1773
1731 for (i = 0; new_ctx && i < new_ctx->stream_count; i++) { 1774 for (i = 0; new_ctx && i < new_ctx->stream_count; i++) {
1732 struct dc_stream_state *stream = new_ctx->streams[i]; 1775 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,
2713 fmt_bit_depth->pixel_encoding = pixel_encoding; 2756 fmt_bit_depth->pixel_encoding = pixel_encoding;
2714} 2757}
2715 2758
2716bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) 2759enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
2717{ 2760{
2718 struct dc *core_dc = dc; 2761 struct dc *core_dc = dc;
2719 struct dc_link *link = stream->sink->link; 2762 struct dc_link *link = stream->sink->link;
@@ -2737,16 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
2737 link, 2780 link,
2738 &stream->timing); 2781 &stream->timing);
2739 2782
2740 return res == DC_OK; 2783 return res;
2741} 2784}
2742 2785
2743bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state) 2786enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
2744{ 2787{
2745 struct dc *core_dc = dc; 2788 enum dc_status res = DC_OK;
2746 2789
2747 /* TODO For now validates pixel format only */ 2790 /* TODO For now validates pixel format only */
2748 if (core_dc->res_pool->funcs->validate_plane) 2791 if (dc->res_pool->funcs->validate_plane)
2749 return core_dc->res_pool->funcs->validate_plane(plane_state) == DC_OK; 2792 return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
2750 2793
2751 return true; 2794 return res;
2752} 2795}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 23df7bc020d2..5cf69af9693d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -173,7 +173,7 @@ struct dc_stream_status *dc_stream_get_status(
173 * Update the cursor attributes and set cursor surface address 173 * Update the cursor attributes and set cursor surface address
174 */ 174 */
175bool dc_stream_set_cursor_attributes( 175bool dc_stream_set_cursor_attributes(
176 const struct dc_stream_state *stream, 176 struct dc_stream_state *stream,
177 const struct dc_cursor_attributes *attributes) 177 const struct dc_cursor_attributes *attributes)
178{ 178{
179 int i; 179 int i;
@@ -189,21 +189,51 @@ bool dc_stream_set_cursor_attributes(
189 return false; 189 return false;
190 } 190 }
191 191
192 if (attributes->address.quad_part == 0) {
193 dm_output_to_console("DC: Cursor address is 0!\n");
194 return false;
195 }
196
192 core_dc = stream->ctx->dc; 197 core_dc = stream->ctx->dc;
193 res_ctx = &core_dc->current_state->res_ctx; 198 res_ctx = &core_dc->current_state->res_ctx;
194 199
195 for (i = 0; i < MAX_PIPES; i++) { 200 for (i = 0; i < MAX_PIPES; i++) {
196 struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; 201 struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
197 202
198 if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp) 203 if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
199 continue; 204 continue;
200 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 205 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
201 continue; 206 continue;
202 207
203 pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 208
204 pipe_ctx->plane_res.ipp, attributes); 209 if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
210 pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
211 pipe_ctx->plane_res.ipp, attributes);
212
213 if (pipe_ctx->plane_res.hubp != NULL &&
214 pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
215 pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
216 pipe_ctx->plane_res.hubp, attributes);
217
218 if (pipe_ctx->plane_res.mi != NULL &&
219 pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
220 pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
221 pipe_ctx->plane_res.mi, attributes);
222
223
224 if (pipe_ctx->plane_res.xfm != NULL &&
225 pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
226 pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
227 pipe_ctx->plane_res.xfm, attributes);
228
229 if (pipe_ctx->plane_res.dpp != NULL &&
230 pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
231 pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
232 pipe_ctx->plane_res.dpp, attributes);
205 } 233 }
206 234
235 stream->cursor_attributes = *attributes;
236
207 return true; 237 return true;
208} 238}
209 239
@@ -231,6 +261,10 @@ bool dc_stream_set_cursor_position(
231 for (i = 0; i < MAX_PIPES; i++) { 261 for (i = 0; i < MAX_PIPES; i++) {
232 struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; 262 struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
233 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 263 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
264 struct mem_input *mi = pipe_ctx->plane_res.mi;
265 struct hubp *hubp = pipe_ctx->plane_res.hubp;
266 struct transform *xfm = pipe_ctx->plane_res.xfm;
267 struct dpp *dpp = pipe_ctx->plane_res.dpp;
234 struct dc_cursor_position pos_cpy = *position; 268 struct dc_cursor_position pos_cpy = *position;
235 struct dc_cursor_mi_param param = { 269 struct dc_cursor_mi_param param = {
236 .pixel_clk_khz = stream->timing.pix_clk_khz, 270 .pixel_clk_khz = stream->timing.pix_clk_khz,
@@ -241,7 +275,9 @@ bool dc_stream_set_cursor_position(
241 }; 275 };
242 276
243 if (pipe_ctx->stream != stream || 277 if (pipe_ctx->stream != stream ||
244 !pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state) 278 (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
279 !pipe_ctx->plane_state ||
280 (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
245 continue; 281 continue;
246 282
247 if (pipe_ctx->plane_state->address.type 283 if (pipe_ctx->plane_state->address.type
@@ -251,7 +287,22 @@ bool dc_stream_set_cursor_position(
251 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 287 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
252 pos_cpy.enable = false; 288 pos_cpy.enable = false;
253 289
254 ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param); 290
291 if (ipp->funcs->ipp_cursor_set_position != NULL)
292 ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
293
294 if (mi != NULL && mi->funcs->set_cursor_position != NULL)
295 mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
296
297 if (hubp != NULL && hubp->funcs->set_cursor_position != NULL)
298 hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
299
300 if (xfm != NULL && xfm->funcs->set_cursor_position != NULL)
301 xfm->funcs->set_cursor_position(xfm, &pos_cpy, &param, hubp->curs_attr.width);
302
303 if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
304 dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
305
255 } 306 }
256 307
257 return true; 308 return true;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index d43783a45ab6..5aa2270f36fd 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -30,6 +30,7 @@
30/* DC core (private) */ 30/* DC core (private) */
31#include "core_types.h" 31#include "core_types.h"
32#include "transform.h" 32#include "transform.h"
33#include "dpp.h"
33 34
34/******************************************************************************* 35/*******************************************************************************
35 * Private functions 36 * Private functions
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 4ff543826476..9d8f4a55c74e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -38,7 +38,7 @@
38#include "inc/compressor.h" 38#include "inc/compressor.h"
39#include "dml/display_mode_lib.h" 39#include "dml/display_mode_lib.h"
40 40
41#define DC_VER "3.1.01" 41#define DC_VER "3.1.07"
42 42
43#define MAX_SURFACES 3 43#define MAX_SURFACES 3
44#define MAX_STREAMS 6 44#define MAX_STREAMS 6
@@ -56,11 +56,12 @@ struct dc_caps {
56 uint32_t max_planes; 56 uint32_t max_planes;
57 uint32_t max_downscale_ratio; 57 uint32_t max_downscale_ratio;
58 uint32_t i2c_speed_in_khz; 58 uint32_t i2c_speed_in_khz;
59
60 unsigned int max_cursor_size; 59 unsigned int max_cursor_size;
60 unsigned int max_video_width;
61 bool dcc_const_color;
62 bool dynamic_audio;
61}; 63};
62 64
63
64struct dc_dcc_surface_param { 65struct dc_dcc_surface_param {
65 struct dc_size surface_size; 66 struct dc_size surface_size;
66 enum surface_pixel_format format; 67 enum surface_pixel_format format;
@@ -132,6 +133,10 @@ struct dc_stream_state_funcs {
132 133
133 void (*set_dither_option)(struct dc_stream_state *stream, 134 void (*set_dither_option)(struct dc_stream_state *stream,
134 enum dc_dither_option option); 135 enum dc_dither_option option);
136
137 void (*set_dpms)(struct dc *dc,
138 struct dc_stream_state *stream,
139 bool dpms_off);
135}; 140};
136 141
137struct link_training_settings; 142struct link_training_settings;
@@ -162,6 +167,23 @@ struct dc_config {
162 bool disable_disp_pll_sharing; 167 bool disable_disp_pll_sharing;
163}; 168};
164 169
170enum dcc_option {
171 DCC_ENABLE = 0,
172 DCC_DISABLE = 1,
173 DCC_HALF_REQ_DISALBE = 2,
174};
175
176enum pipe_split_policy {
177 MPC_SPLIT_DYNAMIC = 0,
178 MPC_SPLIT_AVOID = 1,
179 MPC_SPLIT_AVOID_MULT_DISP = 2,
180};
181
182enum wm_report_mode {
183 WM_REPORT_DEFAULT = 0,
184 WM_REPORT_OVERRIDE = 1,
185};
186
165struct dc_debug { 187struct dc_debug {
166 bool surface_visual_confirm; 188 bool surface_visual_confirm;
167 bool sanity_checks; 189 bool sanity_checks;
@@ -170,14 +192,21 @@ struct dc_debug {
170 bool timing_trace; 192 bool timing_trace;
171 bool clock_trace; 193 bool clock_trace;
172 bool validation_trace; 194 bool validation_trace;
195
196 /* stutter efficiency related */
173 bool disable_stutter; 197 bool disable_stutter;
174 bool disable_dcc; 198 bool use_max_lb;
199 enum dcc_option disable_dcc;
200 enum pipe_split_policy pipe_split_policy;
201 bool force_single_disp_pipe_split;
202 bool voltage_align_fclk;
203
175 bool disable_dfs_bypass; 204 bool disable_dfs_bypass;
176 bool disable_dpp_power_gate; 205 bool disable_dpp_power_gate;
177 bool disable_hubp_power_gate; 206 bool disable_hubp_power_gate;
178 bool disable_pplib_wm_range; 207 bool disable_pplib_wm_range;
179 bool use_dml_wm; 208 enum wm_report_mode pplib_wm_report_mode;
180 bool disable_pipe_split; 209 unsigned int min_disp_clk_khz;
181 int sr_exit_time_dpm0_ns; 210 int sr_exit_time_dpm0_ns;
182 int sr_enter_plus_exit_time_dpm0_ns; 211 int sr_enter_plus_exit_time_dpm0_ns;
183 int sr_exit_time_ns; 212 int sr_exit_time_ns;
@@ -191,6 +220,11 @@ struct dc_debug {
191 bool disable_dmcu; 220 bool disable_dmcu;
192 bool disable_psr; 221 bool disable_psr;
193 bool force_abm_enable; 222 bool force_abm_enable;
223 bool disable_hbup_pg;
224 bool disable_dpp_pg;
225 bool disable_stereo_support;
226 bool vsr_support;
227 bool performance_trace;
194}; 228};
195struct dc_state; 229struct dc_state;
196struct resource_pool; 230struct resource_pool;
@@ -233,7 +267,7 @@ struct dc {
233 struct dm_pp_display_configuration prev_display_config; 267 struct dm_pp_display_configuration prev_display_config;
234 268
235 /* FBC compressor */ 269 /* FBC compressor */
236#ifdef ENABLE_FBC 270#if defined(CONFIG_DRM_AMD_DC_FBC)
237 struct compressor *fbc_compressor; 271 struct compressor *fbc_compressor;
238#endif 272#endif
239}; 273};
@@ -268,7 +302,7 @@ struct dc_init_data {
268 302
269 struct dc_config flags; 303 struct dc_config flags;
270 uint32_t log_mask; 304 uint32_t log_mask;
271#ifdef ENABLE_FBC 305#if defined(CONFIG_DRM_AMD_DC_FBC)
272 uint64_t fbc_gpu_addr; 306 uint64_t fbc_gpu_addr;
273#endif 307#endif
274}; 308};
@@ -285,6 +319,38 @@ enum {
285 TRANSFER_FUNC_POINTS = 1025 319 TRANSFER_FUNC_POINTS = 1025
286}; 320};
287 321
322// Moved here from color module for linux
323enum color_transfer_func {
324 transfer_func_unknown,
325 transfer_func_srgb,
326 transfer_func_bt709,
327 transfer_func_pq2084,
328 transfer_func_pq2084_interim,
329 transfer_func_linear_0_1,
330 transfer_func_linear_0_125,
331 transfer_func_dolbyvision,
332 transfer_func_gamma_22,
333 transfer_func_gamma_26
334};
335
336enum color_color_space {
337 color_space_unsupported,
338 color_space_srgb,
339 color_space_bt601,
340 color_space_bt709,
341 color_space_xv_ycc_bt601,
342 color_space_xv_ycc_bt709,
343 color_space_xr_rgb,
344 color_space_bt2020,
345 color_space_adobe,
346 color_space_dci_p3,
347 color_space_sc_rgb_ms_ref,
348 color_space_display_native,
349 color_space_app_ctrl,
350 color_space_dolby_vision,
351 color_space_custom_coordinates
352};
353
288struct dc_hdr_static_metadata { 354struct dc_hdr_static_metadata {
289 /* display chromaticities and white point in units of 0.00001 */ 355 /* display chromaticities and white point in units of 0.00001 */
290 unsigned int chromaticity_green_x; 356 unsigned int chromaticity_green_x;
@@ -365,6 +431,12 @@ struct dc_plane_state {
365 struct dc_gamma *gamma_correction; 431 struct dc_gamma *gamma_correction;
366 struct dc_transfer_func *in_transfer_func; 432 struct dc_transfer_func *in_transfer_func;
367 433
434 // sourceContentAttribute cache
435 bool is_source_input_valid;
436 struct dc_hdr_static_metadata source_input_mastering_info;
437 enum color_color_space source_input_color_space;
438 enum color_transfer_func source_input_tf;
439
368 enum dc_color_space color_space; 440 enum dc_color_space color_space;
369 enum surface_pixel_format format; 441 enum surface_pixel_format format;
370 enum dc_rotation_angle rotation; 442 enum dc_rotation_angle rotation;
@@ -449,23 +521,6 @@ struct dc_flip_addrs {
449 /* TODO: add flip duration for FreeSync */ 521 /* TODO: add flip duration for FreeSync */
450}; 522};
451 523
452/*
453 * Set up surface attributes and associate to a stream
454 * The surfaces parameter is an absolute set of all surface active for the stream.
455 * If no surfaces are provided, the stream will be blanked; no memory read.
456 * Any flip related attribute changes must be done through this interface.
457 *
458 * After this call:
459 * Surfaces attributes are programmed and configured to be composed into stream.
460 * This does not trigger a flip. No surface address is programmed.
461 */
462
463bool dc_commit_planes_to_stream(
464 struct dc *dc,
465 struct dc_plane_state **plane_states,
466 uint8_t new_plane_count,
467 struct dc_stream_state *stream);
468
469bool dc_post_update_surfaces_to_stream( 524bool dc_post_update_surfaces_to_stream(
470 struct dc *dc); 525 struct dc *dc);
471 526
@@ -554,9 +609,12 @@ struct dc_stream_state {
554 609
555 int phy_pix_clk; 610 int phy_pix_clk;
556 enum signal_type signal; 611 enum signal_type signal;
612 bool dpms_off;
557 613
558 struct dc_stream_status status; 614 struct dc_stream_status status;
559 615
616 struct dc_cursor_attributes cursor_attributes;
617
560 /* from stream struct */ 618 /* from stream struct */
561 struct kref refcount; 619 struct kref refcount;
562}; 620};
@@ -569,11 +627,10 @@ struct dc_stream_update {
569 627
570bool dc_is_stream_unchanged( 628bool dc_is_stream_unchanged(
571 struct dc_stream_state *old_stream, struct dc_stream_state *stream); 629 struct dc_stream_state *old_stream, struct dc_stream_state *stream);
630bool dc_is_stream_scaling_unchanged(
631 struct dc_stream_state *old_stream, struct dc_stream_state *stream);
572 632
573/* 633/*
574 * Setup stream attributes if no stream updates are provided
575 * there will be no impact on the stream parameters
576 *
577 * Set up surface attributes and associate to a stream 634 * Set up surface attributes and associate to a stream
578 * The surfaces parameter is an absolute set of all surface active for the stream. 635 * The surfaces parameter is an absolute set of all surface active for the stream.
579 * If no surfaces are provided, the stream will be blanked; no memory read. 636 * If no surfaces are provided, the stream will be blanked; no memory read.
@@ -582,14 +639,22 @@ bool dc_is_stream_unchanged(
582 * After this call: 639 * After this call:
583 * Surfaces attributes are programmed and configured to be composed into stream. 640 * Surfaces attributes are programmed and configured to be composed into stream.
584 * This does not trigger a flip. No surface address is programmed. 641 * This does not trigger a flip. No surface address is programmed.
585 *
586 */ 642 */
587 643
588void dc_update_planes_and_stream(struct dc *dc, 644bool dc_commit_planes_to_stream(
589 struct dc_surface_update *surface_updates, int surface_count, 645 struct dc *dc,
646 struct dc_plane_state **plane_states,
647 uint8_t new_plane_count,
590 struct dc_stream_state *dc_stream, 648 struct dc_stream_state *dc_stream,
591 struct dc_stream_update *stream_update); 649 struct dc_state *state);
592 650
651void dc_commit_updates_for_stream(struct dc *dc,
652 struct dc_surface_update *srf_updates,
653 int surface_count,
654 struct dc_stream_state *stream,
655 struct dc_stream_update *stream_update,
656 struct dc_plane_state **plane_states,
657 struct dc_state *state);
593/* 658/*
594 * Log the current stream state. 659 * Log the current stream state.
595 */ 660 */
@@ -616,12 +681,12 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
616 uint32_t *h_position, 681 uint32_t *h_position,
617 uint32_t *v_position); 682 uint32_t *v_position);
618 683
619bool dc_add_stream_to_ctx( 684enum dc_status dc_add_stream_to_ctx(
620 struct dc *dc, 685 struct dc *dc,
621 struct dc_state *new_ctx, 686 struct dc_state *new_ctx,
622 struct dc_stream_state *stream); 687 struct dc_stream_state *stream);
623 688
624bool dc_remove_stream_from_ctx( 689enum dc_status dc_remove_stream_from_ctx(
625 struct dc *dc, 690 struct dc *dc,
626 struct dc_state *new_ctx, 691 struct dc_state *new_ctx,
627 struct dc_stream_state *stream); 692 struct dc_stream_state *stream);
@@ -660,11 +725,11 @@ struct dc_validation_set {
660 uint8_t plane_count; 725 uint8_t plane_count;
661}; 726};
662 727
663bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream); 728enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
664 729
665bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); 730enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
666 731
667bool dc_validate_global_state( 732enum dc_status dc_validate_global_state(
668 struct dc *dc, 733 struct dc *dc,
669 struct dc_state *new_ctx); 734 struct dc_state *new_ctx);
670 735
@@ -991,7 +1056,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
991 ******************************************************************************/ 1056 ******************************************************************************/
992/* TODO: Deprecated once we switch to dc_set_cursor_position */ 1057/* TODO: Deprecated once we switch to dc_set_cursor_position */
993bool dc_stream_set_cursor_attributes( 1058bool dc_stream_set_cursor_attributes(
994 const struct dc_stream_state *stream, 1059 struct dc_stream_state *stream,
995 const struct dc_cursor_attributes *attributes); 1060 const struct dc_cursor_attributes *attributes);
996 1061
997bool dc_stream_set_cursor_position( 1062bool dc_stream_set_cursor_position(
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 4ab109314e4b..1a9f57fb0838 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -204,6 +204,8 @@ enum surface_pixel_format {
204 /*grow 444 video here if necessary */ 204 /*grow 444 video here if necessary */
205}; 205};
206 206
207
208
207/* Pixel format */ 209/* Pixel format */
208enum pixel_format { 210enum pixel_format {
209 /*graph*/ 211 /*graph*/
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 6b891fde400c..a8698e399111 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -92,7 +92,7 @@ struct dc_context {
92 bool created_bios; 92 bool created_bios;
93 struct gpio_service *gpio_service; 93 struct gpio_service *gpio_service;
94 struct i2caux *i2caux; 94 struct i2caux *i2caux;
95#ifdef ENABLE_FBC 95#if defined(CONFIG_DRM_AMD_DC_FBC)
96 uint64_t fbc_gpu_addr; 96 uint64_t fbc_gpu_addr;
97#endif 97#endif
98}; 98};
@@ -151,6 +151,7 @@ enum dc_edid_status {
151 EDID_BAD_INPUT, 151 EDID_BAD_INPUT,
152 EDID_NO_RESPONSE, 152 EDID_NO_RESPONSE,
153 EDID_BAD_CHECKSUM, 153 EDID_BAD_CHECKSUM,
154 EDID_THE_SAME,
154}; 155};
155 156
156/* audio capability from EDID*/ 157/* audio capability from EDID*/
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
index 2d3a41f744af..52506155e361 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -27,6 +27,10 @@
27 27
28#include "hw_sequencer.h" 28#include "hw_sequencer.h"
29 29
30#define BL_REG_LIST()\
31 SR(LVTMA_PWRSEQ_CNTL), \
32 SR(LVTMA_PWRSEQ_STATE)
33
30#define HWSEQ_DCEF_REG_LIST_DCE8() \ 34#define HWSEQ_DCEF_REG_LIST_DCE8() \
31 .DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \ 35 .DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
32 .DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \ 36 .DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \
@@ -86,24 +90,27 @@
86 SRII(BLND_CONTROL, BLND, 0),\ 90 SRII(BLND_CONTROL, BLND, 0),\
87 SRII(BLND_CONTROL, BLND, 1),\ 91 SRII(BLND_CONTROL, BLND, 1),\
88 SR(BLNDV_CONTROL),\ 92 SR(BLNDV_CONTROL),\
89 HWSEQ_PIXEL_RATE_REG_LIST(CRTC) 93 HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
94 BL_REG_LIST()
90 95
91#define HWSEQ_DCE8_REG_LIST() \ 96#define HWSEQ_DCE8_REG_LIST() \
92 HWSEQ_DCEF_REG_LIST_DCE8(), \ 97 HWSEQ_DCEF_REG_LIST_DCE8(), \
93 HWSEQ_BLND_REG_LIST(), \ 98 HWSEQ_BLND_REG_LIST(), \
94 HWSEQ_PIXEL_RATE_REG_LIST(CRTC) 99 HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
100 BL_REG_LIST()
95 101
96#define HWSEQ_DCE10_REG_LIST() \ 102#define HWSEQ_DCE10_REG_LIST() \
97 HWSEQ_DCEF_REG_LIST(), \ 103 HWSEQ_DCEF_REG_LIST(), \
98 HWSEQ_BLND_REG_LIST(), \ 104 HWSEQ_BLND_REG_LIST(), \
99 HWSEQ_PIXEL_RATE_REG_LIST(CRTC) 105 HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
106 BL_REG_LIST()
100 107
101#define HWSEQ_ST_REG_LIST() \ 108#define HWSEQ_ST_REG_LIST() \
102 HWSEQ_DCE11_REG_LIST_BASE(), \ 109 HWSEQ_DCE11_REG_LIST_BASE(), \
103 .DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \ 110 .DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
104 .CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \ 111 .CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
105 .BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \ 112 .BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
106 .BLND_CONTROL[2] = mmBLNDV_CONTROL, 113 .BLND_CONTROL[2] = mmBLNDV_CONTROL
107 114
108#define HWSEQ_CZ_REG_LIST() \ 115#define HWSEQ_CZ_REG_LIST() \
109 HWSEQ_DCE11_REG_LIST_BASE(), \ 116 HWSEQ_DCE11_REG_LIST_BASE(), \
@@ -123,16 +130,16 @@
123 SR(DCHUB_FB_LOCATION),\ 130 SR(DCHUB_FB_LOCATION),\
124 SR(DCHUB_AGP_BASE),\ 131 SR(DCHUB_AGP_BASE),\
125 SR(DCHUB_AGP_BOT),\ 132 SR(DCHUB_AGP_BOT),\
126 SR(DCHUB_AGP_TOP) 133 SR(DCHUB_AGP_TOP), \
134 BL_REG_LIST()
127 135
128#define HWSEQ_DCE112_REG_LIST() \ 136#define HWSEQ_DCE112_REG_LIST() \
129 HWSEQ_DCE10_REG_LIST(), \ 137 HWSEQ_DCE10_REG_LIST(), \
130 HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \ 138 HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
131 HWSEQ_PHYPLL_REG_LIST(CRTC) 139 HWSEQ_PHYPLL_REG_LIST(CRTC), \
140 BL_REG_LIST()
132 141
133#define HWSEQ_DCN_REG_LIST()\ 142#define HWSEQ_DCN_REG_LIST()\
134 HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
135 HWSEQ_PHYPLL_REG_LIST(OTG), \
136 SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \ 143 SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \
137 SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 1), \ 144 SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 1), \
138 SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 2), \ 145 SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 2), \
@@ -156,23 +163,15 @@
156 SR(REFCLK_CNTL), \ 163 SR(REFCLK_CNTL), \
157 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\ 164 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
158 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\ 165 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\
159 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
160 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
161 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\ 166 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\
162 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\ 167 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\
163 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\ 168 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\
164 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
165 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
166 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\ 169 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\
167 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\ 170 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
168 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\ 171 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\
169 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
170 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
171 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\ 172 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\
172 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\ 173 SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\
173 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\ 174 SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\
174 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
175 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\
176 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\ 175 SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\
177 SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\ 176 SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
178 SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\ 177 SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
@@ -181,32 +180,11 @@
181 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \ 180 SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
182 SR(DCHUBBUB_TEST_DEBUG_INDEX), \ 181 SR(DCHUBBUB_TEST_DEBUG_INDEX), \
183 SR(DCHUBBUB_TEST_DEBUG_DATA), \ 182 SR(DCHUBBUB_TEST_DEBUG_DATA), \
184 SR(DC_IP_REQUEST_CNTL), \
185 SR(DOMAIN0_PG_CONFIG), \
186 SR(DOMAIN1_PG_CONFIG), \
187 SR(DOMAIN2_PG_CONFIG), \
188 SR(DOMAIN3_PG_CONFIG), \
189 SR(DOMAIN4_PG_CONFIG), \
190 SR(DOMAIN5_PG_CONFIG), \
191 SR(DOMAIN6_PG_CONFIG), \
192 SR(DOMAIN7_PG_CONFIG), \
193 SR(DOMAIN0_PG_STATUS), \
194 SR(DOMAIN1_PG_STATUS), \
195 SR(DOMAIN2_PG_STATUS), \
196 SR(DOMAIN3_PG_STATUS), \
197 SR(DOMAIN4_PG_STATUS), \
198 SR(DOMAIN5_PG_STATUS), \
199 SR(DOMAIN6_PG_STATUS), \
200 SR(DOMAIN7_PG_STATUS), \
201 SR(DIO_MEM_PWR_CTRL), \ 183 SR(DIO_MEM_PWR_CTRL), \
202 SR(DCCG_GATE_DISABLE_CNTL), \ 184 SR(DCCG_GATE_DISABLE_CNTL), \
203 SR(DCCG_GATE_DISABLE_CNTL2), \ 185 SR(DCCG_GATE_DISABLE_CNTL2), \
204 SR(DCFCLK_CNTL),\ 186 SR(DCFCLK_CNTL),\
205 SR(DCFCLK_CNTL), \ 187 SR(DCFCLK_CNTL), \
206 SR(D1VGA_CONTROL), \
207 SR(D2VGA_CONTROL), \
208 SR(D3VGA_CONTROL), \
209 SR(D4VGA_CONTROL), \
210 /* todo: get these from GVM instead of reading registers ourselves */\ 188 /* todo: get these from GVM instead of reading registers ourselves */\
211 MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\ 189 MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
212 MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\ 190 MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
@@ -221,17 +199,56 @@
221 MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\ 199 MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
222 MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR) 200 MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
223 201
202#define HWSEQ_SR_WATERMARK_REG_LIST()\
203 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
204 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
205 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
206 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
207 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
208 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
209 SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
210 SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D)
211
224#define HWSEQ_DCN1_REG_LIST()\ 212#define HWSEQ_DCN1_REG_LIST()\
225 HWSEQ_DCN_REG_LIST(), \ 213 HWSEQ_DCN_REG_LIST(), \
214 HWSEQ_SR_WATERMARK_REG_LIST(), \
215 HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
216 HWSEQ_PHYPLL_REG_LIST(OTG), \
226 SR(DCHUBBUB_SDPIF_FB_TOP),\ 217 SR(DCHUBBUB_SDPIF_FB_TOP),\
227 SR(DCHUBBUB_SDPIF_FB_BASE),\ 218 SR(DCHUBBUB_SDPIF_FB_BASE),\
228 SR(DCHUBBUB_SDPIF_FB_OFFSET),\ 219 SR(DCHUBBUB_SDPIF_FB_OFFSET),\
229 SR(DCHUBBUB_SDPIF_AGP_BASE),\ 220 SR(DCHUBBUB_SDPIF_AGP_BASE),\
230 SR(DCHUBBUB_SDPIF_AGP_BOT),\ 221 SR(DCHUBBUB_SDPIF_AGP_BOT),\
231 SR(DCHUBBUB_SDPIF_AGP_TOP) 222 SR(DCHUBBUB_SDPIF_AGP_TOP),\
232 223 SR(DOMAIN0_PG_CONFIG), \
224 SR(DOMAIN1_PG_CONFIG), \
225 SR(DOMAIN2_PG_CONFIG), \
226 SR(DOMAIN3_PG_CONFIG), \
227 SR(DOMAIN4_PG_CONFIG), \
228 SR(DOMAIN5_PG_CONFIG), \
229 SR(DOMAIN6_PG_CONFIG), \
230 SR(DOMAIN7_PG_CONFIG), \
231 SR(DOMAIN0_PG_STATUS), \
232 SR(DOMAIN1_PG_STATUS), \
233 SR(DOMAIN2_PG_STATUS), \
234 SR(DOMAIN3_PG_STATUS), \
235 SR(DOMAIN4_PG_STATUS), \
236 SR(DOMAIN5_PG_STATUS), \
237 SR(DOMAIN6_PG_STATUS), \
238 SR(DOMAIN7_PG_STATUS), \
239 SR(D1VGA_CONTROL), \
240 SR(D2VGA_CONTROL), \
241 SR(D3VGA_CONTROL), \
242 SR(D4VGA_CONTROL), \
243 SR(DC_IP_REQUEST_CNTL), \
244 BL_REG_LIST()
233 245
234struct dce_hwseq_registers { 246struct dce_hwseq_registers {
247
248 /* Backlight registers */
249 uint32_t LVTMA_PWRSEQ_CNTL;
250 uint32_t LVTMA_PWRSEQ_STATE;
251
235 uint32_t DCFE_CLOCK_CONTROL[6]; 252 uint32_t DCFE_CLOCK_CONTROL[6];
236 uint32_t DCFEV_CLOCK_CONTROL; 253 uint32_t DCFEV_CLOCK_CONTROL;
237 uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL; 254 uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
@@ -376,20 +393,28 @@ struct dce_hwseq_registers {
376 HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\ 393 HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
377 HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\ 394 HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
378 HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\ 395 HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
396 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
397 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
379 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) 398 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
380 399
381#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\ 400#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
382 HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\ 401 HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
383 HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\ 402 HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
384 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) 403 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \
404 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
405 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
385 406
386#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\ 407#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
387 HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ 408 HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
388 SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\ 409 SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
410 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
411 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
389 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_) 412 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
390 413
391#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\ 414#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
392 HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\ 415 HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
416 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
417 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
393 HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_) 418 HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
394 419
395#define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\ 420#define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\
@@ -397,14 +422,18 @@ struct dce_hwseq_registers {
397 SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\ 422 SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\
398 SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\ 423 SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\
399 SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\ 424 SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\
400 SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh) 425 SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \
426 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
427 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
401 428
402#define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\ 429#define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\
403 HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\ 430 HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\
404 HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\ 431 HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\
405 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\ 432 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\
406 HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\ 433 HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\
407 HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh) 434 HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \
435 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
436 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
408 437
409#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\ 438#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
410 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\ 439 HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
@@ -416,35 +445,12 @@ struct dce_hwseq_registers {
416 HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \ 445 HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \
417 HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\ 446 HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\
418 HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ 447 HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
419 HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
420 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
421 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
422 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
423 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
424 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
425 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
426 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
427 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
428 HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
429 HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
430 HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
431 HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
432 HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
433 HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
434 HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
435 HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
436 HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
437 HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
438 HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
439 HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
440 HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
441 HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
442 HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
443 HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
444 HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \ 448 HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
445 HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \ 449 HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
446 HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \ 450 HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
447 HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \ 451 HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
452 HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
453 HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
448 HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \ 454 HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
449 HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \ 455 HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
450 HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh) 456 HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh)
@@ -468,7 +474,34 @@ struct dce_hwseq_registers {
468 HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\ 474 HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
469 HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\ 475 HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
470 HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\ 476 HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
471 HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh) 477 HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\
478 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
479 HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
480 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
481 HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
482 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
483 HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
484 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
485 HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
486 HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
487 HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
488 HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
489 HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
490 HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
491 HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
492 HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
493 HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
494 HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
495 HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
496 HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
497 HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
498 HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
499 HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
500 HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
501 HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
502 HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
503 HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
504 HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
472 505
473#define HWSEQ_REG_FIELD_LIST(type) \ 506#define HWSEQ_REG_FIELD_LIST(type) \
474 type DCFE_CLOCK_ENABLE; \ 507 type DCFE_CLOCK_ENABLE; \
@@ -498,7 +531,9 @@ struct dce_hwseq_registers {
498 type PHYSICAL_PAGE_NUMBER_LSB;\ 531 type PHYSICAL_PAGE_NUMBER_LSB;\
499 type LOGICAL_ADDR; \ 532 type LOGICAL_ADDR; \
500 type ENABLE_L1_TLB;\ 533 type ENABLE_L1_TLB;\
501 type SYSTEM_ACCESS_MODE; 534 type SYSTEM_ACCESS_MODE;\
535 type LVTMA_BLON;\
536 type LVTMA_PWRSEQ_TARGET_STATE_R;
502 537
503#define HWSEQ_DCN_REG_FIELD_LIST(type) \ 538#define HWSEQ_DCN_REG_FIELD_LIST(type) \
504 type VUPDATE_NO_LOCK_EVENT_CLEAR; \ 539 type VUPDATE_NO_LOCK_EVENT_CLEAR; \
@@ -524,6 +559,8 @@ struct dce_hwseq_registers {
524 type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\ 559 type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\
525 type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE;\ 560 type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE;\
526 type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE;\ 561 type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE;\
562 type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE;\
563 type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE;\
527 type DCHUBBUB_ARB_SAT_LEVEL;\ 564 type DCHUBBUB_ARB_SAT_LEVEL;\
528 type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\ 565 type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\
529 type OPP_PIPE_CLOCK_EN;\ 566 type OPP_PIPE_CLOCK_EN;\
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
index fa481d481132..d618fdd0cc82 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
@@ -37,6 +37,7 @@
37#define CTX \ 37#define CTX \
38 ipp_dce->base.ctx 38 ipp_dce->base.ctx
39 39
40
40static void dce_ipp_cursor_set_position( 41static void dce_ipp_cursor_set_position(
41 struct input_pixel_processor *ipp, 42 struct input_pixel_processor *ipp,
42 const struct dc_cursor_position *position, 43 const struct dc_cursor_position *position,
@@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
133 REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false); 134 REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
134} 135}
135 136
137
136static void dce_ipp_program_prescale( 138static void dce_ipp_program_prescale(
137 struct input_pixel_processor *ipp, 139 struct input_pixel_processor *ipp,
138 struct ipp_prescale_params *params) 140 struct ipp_prescale_params *params)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 37aeddfb7431..fe88852b4774 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -82,13 +82,6 @@
82#define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 82#define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
83#define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 83#define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
84 84
85/* all values are in milliseconds */
86/* For eDP, after power-up/power/down,
87 * 300/500 msec max. delay from LCDVCC to black video generation */
88#define PANEL_POWER_UP_TIMEOUT 300
89#define PANEL_POWER_DOWN_TIMEOUT 500
90#define HPD_CHECK_INTERVAL 10
91
92/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */ 85/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
93#define TMDS_MIN_PIXEL_CLOCK 25000 86#define TMDS_MIN_PIXEL_CLOCK 25000
94/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */ 87/* 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 = {
122 .psr_program_dp_dphy_fast_training = 115 .psr_program_dp_dphy_fast_training =
123 dce110_psr_program_dp_dphy_fast_training, 116 dce110_psr_program_dp_dphy_fast_training,
124 .psr_program_secondary_packet = dce110_psr_program_secondary_packet, 117 .psr_program_secondary_packet = dce110_psr_program_secondary_packet,
125 .backlight_control = dce110_link_encoder_edp_backlight_control,
126 .power_control = dce110_link_encoder_edp_power_control,
127 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, 118 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
128 .enable_hpd = dce110_link_encoder_enable_hpd, 119 .enable_hpd = dce110_link_encoder_enable_hpd,
129 .disable_hpd = dce110_link_encoder_disable_hpd, 120 .disable_hpd = dce110_link_encoder_disable_hpd,
@@ -493,165 +484,6 @@ static void configure_encoder(
493 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1); 484 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
494} 485}
495 486
496static bool is_panel_powered_on(struct dce110_link_encoder *enc110)
497{
498 bool ret;
499 uint32_t value;
500
501 REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
502 ret = value;
503
504 return ret == 1;
505}
506
507
508/* TODO duplicate of dc_link.c version */
509static struct gpio *get_hpd_gpio(const struct link_encoder *enc)
510{
511 enum bp_result bp_result;
512 struct dc_bios *dcb = enc->ctx->dc_bios;
513 struct graphics_object_hpd_info hpd_info;
514 struct gpio_pin_info pin_info;
515
516 if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK)
517 return NULL;
518
519 bp_result = dcb->funcs->get_gpio_pin_info(dcb,
520 hpd_info.hpd_int_gpio_uid, &pin_info);
521
522 if (bp_result != BP_RESULT_OK) {
523 ASSERT(bp_result == BP_RESULT_NORECORD);
524 return NULL;
525 }
526
527 return dal_gpio_service_create_irq(
528 enc->ctx->gpio_service,
529 pin_info.offset,
530 pin_info.mask);
531}
532
533/*
534 * @brief
535 * eDP only.
536 */
537static void link_encoder_edp_wait_for_hpd_ready(
538 struct dce110_link_encoder *enc110,
539 bool power_up)
540{
541 struct dc_context *ctx = enc110->base.ctx;
542 struct graphics_object_id connector = enc110->base.connector;
543 struct gpio *hpd;
544 bool edp_hpd_high = false;
545 uint32_t time_elapsed = 0;
546 uint32_t timeout = power_up ?
547 PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
548
549 if (dal_graphics_object_id_get_connector_id(connector) !=
550 CONNECTOR_ID_EDP) {
551 BREAK_TO_DEBUGGER();
552 return;
553 }
554
555 if (!power_up)
556 /* from KV, we will not HPD low after turning off VCC -
557 * instead, we will check the SW timer in power_up(). */
558 return;
559
560 /* when we power on/off the eDP panel,
561 * we need to wait until SENSE bit is high/low */
562
563 /* obtain HPD */
564 /* TODO what to do with this? */
565 hpd = get_hpd_gpio(&enc110->base);
566
567 if (!hpd) {
568 BREAK_TO_DEBUGGER();
569 return;
570 }
571
572 dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
573
574 /* wait until timeout or panel detected */
575
576 do {
577 uint32_t detected = 0;
578
579 dal_gpio_get_value(hpd, &detected);
580
581 if (!(detected ^ power_up)) {
582 edp_hpd_high = true;
583 break;
584 }
585
586 msleep(HPD_CHECK_INTERVAL);
587
588 time_elapsed += HPD_CHECK_INTERVAL;
589 } while (time_elapsed < timeout);
590
591 dal_gpio_close(hpd);
592
593 dal_gpio_destroy_irq(&hpd);
594
595 if (false == edp_hpd_high) {
596 dm_logger_write(ctx->logger, LOG_ERROR,
597 "%s: wait timed out!\n", __func__);
598 }
599}
600
601/*
602 * @brief
603 * eDP only. Control the power of the eDP panel.
604 */
605void dce110_link_encoder_edp_power_control(
606 struct link_encoder *enc,
607 bool power_up)
608{
609 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
610 struct dc_context *ctx = enc110->base.ctx;
611 struct bp_transmitter_control cntl = { 0 };
612 enum bp_result bp_result;
613
614 if (dal_graphics_object_id_get_connector_id(enc110->base.connector) !=
615 CONNECTOR_ID_EDP) {
616 BREAK_TO_DEBUGGER();
617 return;
618 }
619
620 if ((power_up && !is_panel_powered_on(enc110)) ||
621 (!power_up && is_panel_powered_on(enc110))) {
622
623 /* Send VBIOS command to prompt eDP panel power */
624
625 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
626 "%s: Panel Power action: %s\n",
627 __func__, (power_up ? "On":"Off"));
628
629 cntl.action = power_up ?
630 TRANSMITTER_CONTROL_POWER_ON :
631 TRANSMITTER_CONTROL_POWER_OFF;
632 cntl.transmitter = enc110->base.transmitter;
633 cntl.connector_obj_id = enc110->base.connector;
634 cntl.coherent = false;
635 cntl.lanes_number = LANE_COUNT_FOUR;
636 cntl.hpd_sel = enc110->base.hpd_source;
637
638 bp_result = link_transmitter_control(enc110, &cntl);
639
640 if (BP_RESULT_OK != bp_result) {
641
642 dm_logger_write(ctx->logger, LOG_ERROR,
643 "%s: Panel Power bp_result: %d\n",
644 __func__, bp_result);
645 }
646 } else {
647 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
648 "%s: Skipping Panel Power action: %s\n",
649 __func__, (power_up ? "On":"Off"));
650 }
651
652 link_encoder_edp_wait_for_hpd_ready(enc110, true);
653}
654
655static void aux_initialize( 487static void aux_initialize(
656 struct dce110_link_encoder *enc110) 488 struct dce110_link_encoder *enc110)
657{ 489{
@@ -674,16 +506,6 @@ static void aux_initialize(
674 506
675} 507}
676 508
677/*todo: cloned in stream enc, fix*/
678static bool is_panel_backlight_on(struct dce110_link_encoder *enc110)
679{
680 uint32_t value;
681
682 REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
683
684 return value;
685}
686
687void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc, 509void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
688 bool exit_link_training_required) 510 bool exit_link_training_required)
689{ 511{
@@ -718,69 +540,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
718 DP_SEC_GSP0_PRIORITY, 1); 540 DP_SEC_GSP0_PRIORITY, 1);
719} 541}
720 542
721/*todo: cloned in stream enc, fix*/
722/*
723 * @brief
724 * eDP only. Control the backlight of the eDP panel
725 */
726void dce110_link_encoder_edp_backlight_control(
727 struct link_encoder *enc,
728 bool enable)
729{
730 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
731 struct dc_context *ctx = enc110->base.ctx;
732 struct bp_transmitter_control cntl = { 0 };
733
734 if (dal_graphics_object_id_get_connector_id(enc110->base.connector)
735 != CONNECTOR_ID_EDP) {
736 BREAK_TO_DEBUGGER();
737 return;
738 }
739
740 if (enable && is_panel_backlight_on(enc110)) {
741 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
742 "%s: panel already powered up. Do nothing.\n",
743 __func__);
744 return;
745 }
746
747 if (!enable && !is_panel_backlight_on(enc110)) {
748 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
749 "%s: panel already powered down. Do nothing.\n",
750 __func__);
751 return;
752 }
753
754 /* Send VBIOS command to control eDP panel backlight */
755
756 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
757 "%s: backlight action: %s\n",
758 __func__, (enable ? "On":"Off"));
759
760 cntl.action = enable ?
761 TRANSMITTER_CONTROL_BACKLIGHT_ON :
762 TRANSMITTER_CONTROL_BACKLIGHT_OFF;
763 /*cntl.engine_id = ctx->engine;*/
764 cntl.transmitter = enc110->base.transmitter;
765 cntl.connector_obj_id = enc110->base.connector;
766 /*todo: unhardcode*/
767 cntl.lanes_number = LANE_COUNT_FOUR;
768 cntl.hpd_sel = enc110->base.hpd_source;
769
770 /* For eDP, the following delays might need to be considered
771 * after link training completed:
772 * idle period - min. accounts for required BS-Idle pattern,
773 * max. allows for source frame synchronization);
774 * 50 msec max. delay from valid video data from source
775 * to video on dislpay or backlight enable.
776 *
777 * Disable the delay for now.
778 * Enable it in the future if necessary.
779 */
780 /* dc_service_sleep_in_milliseconds(50); */
781 link_transmitter_control(enc110, &cntl);
782}
783
784static bool is_dig_enabled(const struct dce110_link_encoder *enc110) 543static bool is_dig_enabled(const struct dce110_link_encoder *enc110)
785{ 544{
786 uint32_t value; 545 uint32_t value;
@@ -998,11 +757,6 @@ void dce110_link_encoder_construct(
998 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; 757 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
999 } 758 }
1000 759
1001 dm_logger_write(init_data->ctx->logger, LOG_I2C_AUX,
1002 "Using channel: %s [%d]\n",
1003 DECODE_CHANNEL_ID(init_data->channel),
1004 init_data->channel);
1005
1006 /* Override features with DCE-specific values */ 760 /* Override features with DCE-specific values */
1007 if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info( 761 if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
1008 enc110->base.ctx->dc_bios, enc110->base.id, 762 enc110->base.ctx->dc_bios, enc110->base.id,
@@ -1092,7 +846,7 @@ void dce110_link_encoder_hw_init(
1092 ASSERT(result == BP_RESULT_OK); 846 ASSERT(result == BP_RESULT_OK);
1093 847
1094 } else if (enc110->base.connector.id == CONNECTOR_ID_EDP) { 848 } else if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
1095 enc->funcs->power_control(&enc110->base, true); 849 ctx->dc->hwss.edp_power_control(enc, true);
1096 } 850 }
1097 aux_initialize(enc110); 851 aux_initialize(enc110);
1098 852
@@ -1279,7 +1033,8 @@ void dce110_link_encoder_enable_dp_mst_output(
1279 */ 1033 */
1280void dce110_link_encoder_disable_output( 1034void dce110_link_encoder_disable_output(
1281 struct link_encoder *enc, 1035 struct link_encoder *enc,
1282 enum signal_type signal) 1036 enum signal_type signal,
1037 struct dc_link *link)
1283{ 1038{
1284 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1039 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1285 struct dc_context *ctx = enc110->base.ctx; 1040 struct dc_context *ctx = enc110->base.ctx;
@@ -1291,7 +1046,7 @@ void dce110_link_encoder_disable_output(
1291 return; 1046 return;
1292 } 1047 }
1293 if (enc110->base.connector.id == CONNECTOR_ID_EDP) 1048 if (enc110->base.connector.id == CONNECTOR_ID_EDP)
1294 dce110_link_encoder_edp_backlight_control(enc, false); 1049 ctx->dc->hwss.edp_backlight_control(link, false);
1295 /* Power-down RX and disable GPU PHY should be paired. 1050 /* Power-down RX and disable GPU PHY should be paired.
1296 * Disabling PHY without powering down RX may cause 1051 * Disabling PHY without powering down RX may cause
1297 * symbol lock loss, on which we will get DP Sink interrupt. */ 1052 * symbol lock loss, on which we will get DP Sink interrupt. */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index be0a45bdc5e2..494067dedd03 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -44,8 +44,6 @@
44 SRI(DC_HPD_CONTROL, HPD, id) 44 SRI(DC_HPD_CONTROL, HPD, id)
45 45
46#define LE_COMMON_REG_LIST_BASE(id) \ 46#define LE_COMMON_REG_LIST_BASE(id) \
47 SR(LVTMA_PWRSEQ_CNTL), \
48 SR(LVTMA_PWRSEQ_STATE), \
49 SR(DMCU_RAM_ACCESS_CTRL), \ 47 SR(DMCU_RAM_ACCESS_CTRL), \
50 SR(DMCU_IRAM_RD_CTRL), \ 48 SR(DMCU_IRAM_RD_CTRL), \
51 SR(DMCU_IRAM_RD_DATA), \ 49 SR(DMCU_IRAM_RD_DATA), \
@@ -104,8 +102,7 @@
104 LE_COMMON_REG_LIST_BASE(id), \ 102 LE_COMMON_REG_LIST_BASE(id), \
105 SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \ 103 SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
106 SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \ 104 SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
107 SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \ 105 SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
108 SR(DMU_MEM_PWR_CNTL)
109 106
110struct dce110_link_enc_aux_registers { 107struct dce110_link_enc_aux_registers {
111 uint32_t AUX_CONTROL; 108 uint32_t AUX_CONTROL;
@@ -117,10 +114,6 @@ struct dce110_link_enc_hpd_registers {
117}; 114};
118 115
119struct dce110_link_enc_registers { 116struct dce110_link_enc_registers {
120 /* Backlight registers */
121 uint32_t LVTMA_PWRSEQ_CNTL;
122 uint32_t LVTMA_PWRSEQ_STATE;
123
124 /* DMCU registers */ 117 /* DMCU registers */
125 uint32_t MASTER_COMM_DATA_REG1; 118 uint32_t MASTER_COMM_DATA_REG1;
126 uint32_t MASTER_COMM_DATA_REG2; 119 uint32_t MASTER_COMM_DATA_REG2;
@@ -236,7 +229,8 @@ void dce110_link_encoder_enable_dp_mst_output(
236/* disable PHY output */ 229/* disable PHY output */
237void dce110_link_encoder_disable_output( 230void dce110_link_encoder_disable_output(
238 struct link_encoder *link_enc, 231 struct link_encoder *link_enc,
239 enum signal_type signal); 232 enum signal_type signal,
233 struct dc_link *link);
240 234
241/* set DP lane settings */ 235/* set DP lane settings */
242void dce110_link_encoder_dp_set_lane_settings( 236void dce110_link_encoder_dp_set_lane_settings(
@@ -252,14 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table(
252 struct link_encoder *enc, 246 struct link_encoder *enc,
253 const struct link_mst_stream_allocation_table *table); 247 const struct link_mst_stream_allocation_table *table);
254 248
255void dce110_link_encoder_edp_backlight_control(
256 struct link_encoder *enc,
257 bool enable);
258
259void dce110_link_encoder_edp_power_control(
260 struct link_encoder *enc,
261 bool power_up);
262
263void dce110_link_encoder_connect_dig_be_to_fe( 249void dce110_link_encoder_connect_dig_be_to_fe(
264 struct link_encoder *enc, 250 struct link_encoder *enc,
265 enum engine_id engine, 251 enum engine_id engine,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
index 83d9caa4f438..0790f25c7b3b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c
@@ -361,7 +361,7 @@ static void program_grph_pixel_format(
361 enum surface_pixel_format format) 361 enum surface_pixel_format format)
362{ 362{
363 uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */ 363 uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
364 uint32_t grph_depth, grph_format; 364 uint32_t grph_depth = 0, grph_format = 0;
365 uint32_t sign = 0, floating = 0; 365 uint32_t sign = 0, floating = 0;
366 366
367 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 || 367 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
@@ -685,9 +685,6 @@ void dce_mem_input_construct(
685 dce_mi->regs = regs; 685 dce_mi->regs = regs;
686 dce_mi->shifts = mi_shift; 686 dce_mi->shifts = mi_shift;
687 dce_mi->masks = mi_mask; 687 dce_mi->masks = mi_mask;
688
689 dce_mi->base.mpcc_id = 0xf;
690 dce_mi->base.opp_id = 0xf;
691} 688}
692 689
693void dce112_mem_input_construct( 690void dce112_mem_input_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
index b1cf591b3408..90911258bdb3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
@@ -743,7 +743,7 @@ static void dce100_destroy_resource_pool(struct resource_pool **pool)
743 *pool = NULL; 743 *pool = NULL;
744} 744}
745 745
746enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state) 746enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
747{ 747{
748 748
749 if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 749 if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
index f52cae24ee23..de8fdf438f9b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.h
@@ -16,7 +16,7 @@ struct resource_pool *dce100_create_resource_pool(
16 uint8_t num_virtual_links, 16 uint8_t num_virtual_links,
17 struct dc *dc); 17 struct dc *dc);
18 18
19enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state); 19enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps);
20 20
21enum dc_status dce100_add_stream_to_ctx( 21enum dc_status dce100_add_stream_to_ctx(
22 struct dc *dc, 22 struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
index 3872febb4f6b..6923662413cd 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
@@ -514,7 +514,7 @@ void dce110_compressor_construct(struct dce110_compressor *compressor,
514 compressor->base.lpt_channels_num = 0; 514 compressor->base.lpt_channels_num = 0;
515 compressor->base.attached_inst = 0; 515 compressor->base.attached_inst = 0;
516 compressor->base.is_enabled = false; 516 compressor->base.is_enabled = false;
517#ifdef ENABLE_FBC 517#if defined(CONFIG_DRM_AMD_DC_FBC)
518 compressor->base.funcs = &dce110_compressor_funcs; 518 compressor->base.funcs = &dce110_compressor_funcs;
519 519
520#endif 520#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index de154329b049..2a6d3ca12954 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -32,8 +32,9 @@
32#include "dce110_hw_sequencer.h" 32#include "dce110_hw_sequencer.h"
33#include "dce110_timing_generator.h" 33#include "dce110_timing_generator.h"
34#include "dce/dce_hwseq.h" 34#include "dce/dce_hwseq.h"
35#include "gpio_service_interface.h"
35 36
36#ifdef ENABLE_FBC 37#if defined(CONFIG_DRM_AMD_DC_FBC)
37#include "dce110_compressor.h" 38#include "dce110_compressor.h"
38#endif 39#endif
39 40
@@ -45,10 +46,10 @@
45#include "transform.h" 46#include "transform.h"
46#include "stream_encoder.h" 47#include "stream_encoder.h"
47#include "link_encoder.h" 48#include "link_encoder.h"
49#include "link_hwss.h"
48#include "clock_source.h" 50#include "clock_source.h"
49#include "abm.h" 51#include "abm.h"
50#include "audio.h" 52#include "audio.h"
51#include "dce/dce_hwseq.h"
52#include "reg_helper.h" 53#include "reg_helper.h"
53 54
54/* include DCE11 register header files */ 55/* include DCE11 register header files */
@@ -56,6 +57,24 @@
56#include "dce/dce_11_0_sh_mask.h" 57#include "dce/dce_11_0_sh_mask.h"
57#include "custom_float.h" 58#include "custom_float.h"
58 59
60/*
61 * All values are in milliseconds;
62 * For eDP, after power-up/power/down,
63 * 300/500 msec max. delay from LCDVCC to black video generation
64 */
65#define PANEL_POWER_UP_TIMEOUT 300
66#define PANEL_POWER_DOWN_TIMEOUT 500
67#define HPD_CHECK_INTERVAL 10
68
69#define CTX \
70 hws->ctx
71#define REG(reg)\
72 hws->regs->reg
73
74#undef FN
75#define FN(reg_name, field_name) \
76 hws->shifts->field_name, hws->masks->field_name
77
59struct dce110_hw_seq_reg_offsets { 78struct dce110_hw_seq_reg_offsets {
60 uint32_t crtc; 79 uint32_t crtc;
61}; 80};
@@ -761,10 +780,216 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
761 780
762} 781}
763 782
764void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 783/*todo: cloned in stream enc, fix*/
784static bool is_panel_backlight_on(struct dce_hwseq *hws)
785{
786 uint32_t value;
787
788 REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
789
790 return value;
791}
792
793static bool is_panel_powered_on(struct dce_hwseq *hws)
794{
795 uint32_t value;
796
797 REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
798 return value == 1;
799}
800
801static enum bp_result link_transmitter_control(
802 struct dc_bios *bios,
803 struct bp_transmitter_control *cntl)
804{
805 enum bp_result result;
806
807 result = bios->funcs->transmitter_control(bios, cntl);
808
809 return result;
810}
811
812/*
813 * @brief
814 * eDP only.
815 */
816void hwss_edp_wait_for_hpd_ready(
817 struct link_encoder *enc,
818 bool power_up)
819{
820 struct dc_context *ctx = enc->ctx;
821 struct graphics_object_id connector = enc->connector;
822 struct gpio *hpd;
823 bool edp_hpd_high = false;
824 uint32_t time_elapsed = 0;
825 uint32_t timeout = power_up ?
826 PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
827
828 if (dal_graphics_object_id_get_connector_id(connector)
829 != CONNECTOR_ID_EDP) {
830 BREAK_TO_DEBUGGER();
831 return;
832 }
833
834 if (!power_up)
835 /*
836 * From KV, we will not HPD low after turning off VCC -
837 * instead, we will check the SW timer in power_up().
838 */
839 return;
840
841 /*
842 * When we power on/off the eDP panel,
843 * we need to wait until SENSE bit is high/low.
844 */
845
846 /* obtain HPD */
847 /* TODO what to do with this? */
848 hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
849
850 if (!hpd) {
851 BREAK_TO_DEBUGGER();
852 return;
853 }
854
855 dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
856
857 /* wait until timeout or panel detected */
858
859 do {
860 uint32_t detected = 0;
861
862 dal_gpio_get_value(hpd, &detected);
863
864 if (!(detected ^ power_up)) {
865 edp_hpd_high = true;
866 break;
867 }
868
869 msleep(HPD_CHECK_INTERVAL);
870
871 time_elapsed += HPD_CHECK_INTERVAL;
872 } while (time_elapsed < timeout);
873
874 dal_gpio_close(hpd);
875
876 dal_gpio_destroy_irq(&hpd);
877
878 if (false == edp_hpd_high) {
879 dm_logger_write(ctx->logger, LOG_ERROR,
880 "%s: wait timed out!\n", __func__);
881 }
882}
883
884void hwss_edp_power_control(
885 struct link_encoder *enc,
886 bool power_up)
887{
888 struct dc_context *ctx = enc->ctx;
889 struct dce_hwseq *hwseq = ctx->dc->hwseq;
890 struct bp_transmitter_control cntl = { 0 };
891 enum bp_result bp_result;
892
893
894 if (dal_graphics_object_id_get_connector_id(enc->connector)
895 != CONNECTOR_ID_EDP) {
896 BREAK_TO_DEBUGGER();
897 return;
898 }
899
900 if (power_up != is_panel_powered_on(hwseq)) {
901 /* Send VBIOS command to prompt eDP panel power */
902
903 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
904 "%s: Panel Power action: %s\n",
905 __func__, (power_up ? "On":"Off"));
906
907 cntl.action = power_up ?
908 TRANSMITTER_CONTROL_POWER_ON :
909 TRANSMITTER_CONTROL_POWER_OFF;
910 cntl.transmitter = enc->transmitter;
911 cntl.connector_obj_id = enc->connector;
912 cntl.coherent = false;
913 cntl.lanes_number = LANE_COUNT_FOUR;
914 cntl.hpd_sel = enc->hpd_source;
915
916 bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
917
918 if (bp_result != BP_RESULT_OK)
919 dm_logger_write(ctx->logger, LOG_ERROR,
920 "%s: Panel Power bp_result: %d\n",
921 __func__, bp_result);
922 } else {
923 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
924 "%s: Skipping Panel Power action: %s\n",
925 __func__, (power_up ? "On":"Off"));
926 }
927
928 hwss_edp_wait_for_hpd_ready(enc, true);
929}
930
931/*todo: cloned in stream enc, fix*/
932/*
933 * @brief
934 * eDP only. Control the backlight of the eDP panel
935 */
936void hwss_edp_backlight_control(
937 struct dc_link *link,
938 bool enable)
939{
940 struct dce_hwseq *hws = link->dc->hwseq;
941 struct dc_context *ctx = link->dc->ctx;
942 struct bp_transmitter_control cntl = { 0 };
943
944 if (dal_graphics_object_id_get_connector_id(link->link_id)
945 != CONNECTOR_ID_EDP) {
946 BREAK_TO_DEBUGGER();
947 return;
948 }
949
950 if (enable && is_panel_backlight_on(hws)) {
951 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
952 "%s: panel already powered up. Do nothing.\n",
953 __func__);
954 return;
955 }
956
957 /* Send VBIOS command to control eDP panel backlight */
958
959 dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
960 "%s: backlight action: %s\n",
961 __func__, (enable ? "On":"Off"));
962
963 cntl.action = enable ?
964 TRANSMITTER_CONTROL_BACKLIGHT_ON :
965 TRANSMITTER_CONTROL_BACKLIGHT_OFF;
966
967 /*cntl.engine_id = ctx->engine;*/
968 cntl.transmitter = link->link_enc->transmitter;
969 cntl.connector_obj_id = link->link_enc->connector;
970 /*todo: unhardcode*/
971 cntl.lanes_number = LANE_COUNT_FOUR;
972 cntl.hpd_sel = link->link_enc->hpd_source;
973
974 /* For eDP, the following delays might need to be considered
975 * after link training completed:
976 * idle period - min. accounts for required BS-Idle pattern,
977 * max. allows for source frame synchronization);
978 * 50 msec max. delay from valid video data from source
979 * to video on dislpay or backlight enable.
980 *
981 * Disable the delay for now.
982 * Enable it in the future if necessary.
983 */
984 /* dc_service_sleep_in_milliseconds(50); */
985 link_transmitter_control(link->dc->ctx->dc_bios, &cntl);
986}
987
988void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
765{ 989{
766 struct dc_stream_state *stream = pipe_ctx->stream; 990 struct dc_stream_state *stream = pipe_ctx->stream;
767 struct dc_link *link = stream->sink->link; 991 struct dc_link *link = stream->sink->link;
992 struct dc *dc = pipe_ctx->stream->ctx->dc;
768 993
769 if (pipe_ctx->stream_res.audio) { 994 if (pipe_ctx->stream_res.audio) {
770 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); 995 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)
775 else 1000 else
776 pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( 1001 pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
777 pipe_ctx->stream_res.stream_enc); 1002 pipe_ctx->stream_res.stream_enc);
1003 /*don't free audio if it is from retrain or internal disable stream*/
1004 if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
1005 /*we have to dynamic arbitrate the audio endpoints*/
1006 pipe_ctx->stream_res.audio = NULL;
1007 /*we free the resource, need reset is_audio_acquired*/
1008 update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
1009 }
778 1010
779 /* TODO: notify audio driver for if audio modes list changed 1011 /* TODO: notify audio driver for if audio modes list changed
780 * add audio mode list change flag */ 1012 * add audio mode list change flag */
@@ -798,7 +1030,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
798 /* blank at encoder level */ 1030 /* blank at encoder level */
799 if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 1031 if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
800 if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP) 1032 if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
801 link->link_enc->funcs->backlight_control(link->link_enc, false); 1033 hwss_edp_backlight_control(link, false);
802 pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); 1034 pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
803 } 1035 }
804 link->link_enc->funcs->connect_dig_be_to_fe( 1036 link->link_enc->funcs->connect_dig_be_to_fe(
@@ -820,7 +1052,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
820 params.link_settings.link_rate = link_settings->link_rate; 1052 params.link_settings.link_rate = link_settings->link_rate;
821 pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params); 1053 pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
822 if (link->connector_signal == SIGNAL_TYPE_EDP) 1054 if (link->connector_signal == SIGNAL_TYPE_EDP)
823 link->link_enc->funcs->backlight_control(link->link_enc, true); 1055 hwss_edp_backlight_control(link, true);
824} 1056}
825 1057
826 1058
@@ -1132,33 +1364,21 @@ static enum dc_status apply_single_controller_ctx_to_hw(
1132 resource_build_info_frame(pipe_ctx); 1364 resource_build_info_frame(pipe_ctx);
1133 dce110_update_info_frame(pipe_ctx); 1365 dce110_update_info_frame(pipe_ctx);
1134 if (!pipe_ctx_old->stream) { 1366 if (!pipe_ctx_old->stream) {
1135 core_link_enable_stream(context, pipe_ctx); 1367 if (!pipe_ctx->stream->dpms_off)
1136 1368 core_link_enable_stream(context, pipe_ctx);
1137
1138 if (dc_is_dp_signal(pipe_ctx->stream->signal))
1139 dce110_unblank_stream(pipe_ctx,
1140 &stream->sink->link->cur_link_settings);
1141 } 1369 }
1142 1370
1143 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 1371 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
1144 /* program_scaler and allocate_mem_input are not new asic */
1145 if ((!pipe_ctx_old ||
1146 memcmp(&pipe_ctx_old->plane_res.scl_data, &pipe_ctx->plane_res.scl_data,
1147 sizeof(struct scaler_data)) != 0) &&
1148 pipe_ctx->plane_state) {
1149 program_scaler(dc, pipe_ctx);
1150 }
1151 1372
1152 /* mst support - use total stream count */ 1373 /* mst support - use total stream count */
1153#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 1374 if (pipe_ctx->plane_res.mi != NULL) {
1154 if (pipe_ctx->plane_res.mi->funcs->allocate_mem_input != NULL)
1155#endif
1156 pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 1375 pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
1157 pipe_ctx->plane_res.mi, 1376 pipe_ctx->plane_res.mi,
1158 stream->timing.h_total, 1377 stream->timing.h_total,
1159 stream->timing.v_total, 1378 stream->timing.v_total,
1160 stream->timing.pix_clk_khz, 1379 stream->timing.pix_clk_khz,
1161 context->stream_count); 1380 context->stream_count);
1381 }
1162 1382
1163 pipe_ctx->stream->sink->link->psr_enabled = false; 1383 pipe_ctx->stream->sink->link->psr_enabled = false;
1164 1384
@@ -1171,6 +1391,16 @@ static void power_down_encoders(struct dc *dc)
1171{ 1391{
1172 int i; 1392 int i;
1173 enum connector_id connector_id; 1393 enum connector_id connector_id;
1394 enum signal_type signal = SIGNAL_TYPE_NONE;
1395
1396 /* do not know BIOS back-front mapping, simply blank all. It will not
1397 * hurt for non-DP
1398 */
1399 for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
1400 dc->res_pool->stream_enc[i]->funcs->dp_blank(
1401 dc->res_pool->stream_enc[i]);
1402 }
1403
1174 for (i = 0; i < dc->link_count; i++) { 1404 for (i = 0; i < dc->link_count; i++) {
1175 connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id); 1405 connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
1176 if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) || 1406 if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
@@ -1178,10 +1408,12 @@ static void power_down_encoders(struct dc *dc)
1178 1408
1179 if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) 1409 if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
1180 dp_receiver_power_ctrl(dc->links[i], false); 1410 dp_receiver_power_ctrl(dc->links[i], false);
1411 if (connector_id == CONNECTOR_ID_EDP)
1412 signal = SIGNAL_TYPE_EDP;
1181 } 1413 }
1182 1414
1183 dc->links[i]->link_enc->funcs->disable_output( 1415 dc->links[i]->link_enc->funcs->disable_output(
1184 dc->links[i]->link_enc, SIGNAL_TYPE_NONE); 1416 dc->links[i]->link_enc, signal, dc->links[i]);
1185 } 1417 }
1186} 1418}
1187 1419
@@ -1218,7 +1450,7 @@ static void power_down_all_hw_blocks(struct dc *dc)
1218 1450
1219 power_down_clock_sources(dc); 1451 power_down_clock_sources(dc);
1220 1452
1221#ifdef ENABLE_FBC 1453#if defined(CONFIG_DRM_AMD_DC_FBC)
1222 if (dc->fbc_compressor) 1454 if (dc->fbc_compressor)
1223 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 1455 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
1224#endif 1456#endif
@@ -1325,7 +1557,7 @@ static void set_safe_displaymarks(
1325 SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 1557 SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
1326 1558
1327 for (i = 0; i < MAX_PIPES; i++) { 1559 for (i = 0; i < MAX_PIPES; i++) {
1328 if (res_ctx->pipe_ctx[i].stream == NULL) 1560 if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
1329 continue; 1561 continue;
1330 1562
1331 res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 1563 res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
@@ -1334,6 +1566,7 @@ static void set_safe_displaymarks(
1334 max_marks, 1566 max_marks,
1335 max_marks, 1567 max_marks,
1336 MAX_WATERMARK); 1568 MAX_WATERMARK);
1569
1337 if (i == underlay_idx) 1570 if (i == underlay_idx)
1338 res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 1571 res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
1339 res_ctx->pipe_ctx[i].plane_res.mi, 1572 res_ctx->pipe_ctx[i].plane_res.mi,
@@ -1341,6 +1574,7 @@ static void set_safe_displaymarks(
1341 max_marks, 1574 max_marks,
1342 max_marks, 1575 max_marks,
1343 MAX_WATERMARK); 1576 MAX_WATERMARK);
1577
1344 } 1578 }
1345} 1579}
1346 1580
@@ -1391,7 +1625,7 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
1391 if (events->cursor_update) 1625 if (events->cursor_update)
1392 value |= 0x2; 1626 value |= 0x2;
1393 1627
1394#ifdef ENABLE_FBC 1628#if defined(CONFIG_DRM_AMD_DC_FBC)
1395 value |= 0x84; 1629 value |= 0x84;
1396#endif 1630#endif
1397 1631
@@ -1521,7 +1755,7 @@ static void apply_min_clocks(
1521 } 1755 }
1522} 1756}
1523 1757
1524#ifdef ENABLE_FBC 1758#if defined(CONFIG_DRM_AMD_DC_FBC)
1525 1759
1526/* 1760/*
1527 * Check if FBC can be enabled 1761 * Check if FBC can be enabled
@@ -1644,7 +1878,10 @@ static void dce110_reset_hw_ctx_wrap(
1644 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 1878 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
1645 struct clock_source *old_clk = pipe_ctx_old->clock_source; 1879 struct clock_source *old_clk = pipe_ctx_old->clock_source;
1646 1880
1647 core_link_disable_stream(pipe_ctx_old); 1881 /* disable already, no need to disable again */
1882 if (pipe_ctx->stream && !pipe_ctx->stream->dpms_off)
1883 core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
1884
1648 pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 1885 pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
1649 if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 1886 if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
1650 dm_error("DC: failed to blank crtc!\n"); 1887 dm_error("DC: failed to blank crtc!\n");
@@ -1713,7 +1950,7 @@ enum dc_status dce110_apply_ctx_to_hw(
1713 1950
1714 set_safe_displaymarks(&context->res_ctx, dc->res_pool); 1951 set_safe_displaymarks(&context->res_ctx, dc->res_pool);
1715 1952
1716#ifdef ENABLE_FBC 1953#if defined(CONFIG_DRM_AMD_DC_FBC)
1717 if (dc->fbc_compressor) 1954 if (dc->fbc_compressor)
1718 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 1955 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
1719#endif 1956#endif
@@ -1889,6 +2126,7 @@ enum dc_status dce110_apply_ctx_to_hw(
1889 return status; 2126 return status;
1890 } 2127 }
1891 2128
2129 /* pplib is notified if disp_num changed */
1892 dc->hwss.set_bandwidth(dc, context, true); 2130 dc->hwss.set_bandwidth(dc, context, true);
1893 2131
1894 /* to save power */ 2132 /* to save power */
@@ -1896,7 +2134,7 @@ enum dc_status dce110_apply_ctx_to_hw(
1896 2134
1897 dcb->funcs->set_scratch_critical_state(dcb, false); 2135 dcb->funcs->set_scratch_critical_state(dcb, false);
1898 2136
1899#ifdef ENABLE_FBC 2137#if defined(CONFIG_DRM_AMD_DC_FBC)
1900 if (dc->fbc_compressor) 2138 if (dc->fbc_compressor)
1901 enable_fbc(dc, context); 2139 enable_fbc(dc, context);
1902 2140
@@ -2305,7 +2543,7 @@ static void init_hw(struct dc *dc)
2305 abm->funcs->init_backlight(abm); 2543 abm->funcs->init_backlight(abm);
2306 abm->funcs->abm_init(abm); 2544 abm->funcs->abm_init(abm);
2307 } 2545 }
2308#ifdef ENABLE_FBC 2546#if defined(CONFIG_DRM_AMD_DC_FBC)
2309 if (dc->fbc_compressor) 2547 if (dc->fbc_compressor)
2310 dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2548 dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
2311#endif 2549#endif
@@ -2490,6 +2728,8 @@ static void dce110_program_front_end_for_pipe(
2490 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2728 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2491 struct xfm_grph_csc_adjustment adjust; 2729 struct xfm_grph_csc_adjustment adjust;
2492 struct out_csc_color_matrix tbl_entry; 2730 struct out_csc_color_matrix tbl_entry;
2731 struct pipe_ctx *cur_pipe_ctx =
2732 &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
2493 unsigned int i; 2733 unsigned int i;
2494 2734
2495 memset(&tbl_entry, 0, sizeof(tbl_entry)); 2735 memset(&tbl_entry, 0, sizeof(tbl_entry));
@@ -2553,6 +2793,15 @@ static void dce110_program_front_end_for_pipe(
2553 2793
2554 program_scaler(dc, pipe_ctx); 2794 program_scaler(dc, pipe_ctx);
2555 2795
2796#if defined(CONFIG_DRM_AMD_DC_FBC)
2797 if (dc->fbc_compressor && old_pipe->stream) {
2798 if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
2799 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
2800 else
2801 enable_fbc(dc, dc->current_state);
2802 }
2803#endif
2804
2556 mi->funcs->mem_input_program_surface_config( 2805 mi->funcs->mem_input_program_surface_config(
2557 mi, 2806 mi,
2558 plane_state->format, 2807 plane_state->format,
@@ -2571,6 +2820,14 @@ static void dce110_program_front_end_for_pipe(
2571 &plane_state->tiling_info, 2820 &plane_state->tiling_info,
2572 plane_state->rotation); 2821 plane_state->rotation);
2573 2822
2823 /* Moved programming gamma from dc to hwss */
2824 if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
2825 dc->hwss.set_input_transfer_func(
2826 pipe_ctx, pipe_ctx->plane_state);
2827 dc->hwss.set_output_transfer_func(
2828 pipe_ctx, pipe_ctx->stream);
2829 }
2830
2574 dm_logger_write(dc->ctx->logger, LOG_SURFACE, 2831 dm_logger_write(dc->ctx->logger, LOG_SURFACE,
2575 "Pipe:%d 0x%x: addr hi:0x%x, " 2832 "Pipe:%d 0x%x: addr hi:0x%x, "
2576 "addr low:0x%x, " 2833 "addr low:0x%x, "
@@ -2683,7 +2940,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
2683 } 2940 }
2684} 2941}
2685 2942
2686static void ready_shared_resources(struct dc *dc) {} 2943static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
2687 2944
2688static void optimize_shared_resources(struct dc *dc) {} 2945static void optimize_shared_resources(struct dc *dc) {}
2689 2946
@@ -2720,7 +2977,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
2720 .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 2977 .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
2721 .ready_shared_resources = ready_shared_resources, 2978 .ready_shared_resources = ready_shared_resources,
2722 .optimize_shared_resources = optimize_shared_resources, 2979 .optimize_shared_resources = optimize_shared_resources,
2723 2980 .edp_backlight_control = hwss_edp_backlight_control,
2981 .edp_power_control = hwss_edp_power_control,
2724}; 2982};
2725 2983
2726void dce110_hw_sequencer_construct(struct dc *dc) 2984void dce110_hw_sequencer_construct(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
index db6c19cd15eb..4d72bb99be93 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
@@ -47,7 +47,7 @@ void dce110_set_displaymarks(
47 47
48void dce110_enable_stream(struct pipe_ctx *pipe_ctx); 48void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
49 49
50void dce110_disable_stream(struct pipe_ctx *pipe_ctx); 50void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option);
51 51
52void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 52void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
53 struct dc_link_settings *link_settings); 53 struct dc_link_settings *link_settings);
@@ -68,5 +68,14 @@ void dce110_fill_display_configs(
68uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context); 68uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
69 69
70void dp_receiver_power_ctrl(struct dc_link *link, bool on); 70void dp_receiver_power_ctrl(struct dc_link *link, bool on);
71
72void hwss_edp_power_control(
73 struct link_encoder *enc,
74 bool power_up);
75
76void hwss_edp_backlight_control(
77 struct dc_link *link,
78 bool enable);
79
71#endif /* __DC_HWSS_DCE110_H__ */ 80#endif /* __DC_HWSS_DCE110_H__ */
72 81
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
index 28e768de744c..db96d2b47ff1 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -52,7 +52,7 @@
52#include "dce/dce_abm.h" 52#include "dce/dce_abm.h"
53#include "dce/dce_dmcu.h" 53#include "dce/dce_dmcu.h"
54 54
55#ifdef ENABLE_FBC 55#if defined(CONFIG_DRM_AMD_DC_FBC)
56#include "dce110/dce110_compressor.h" 56#include "dce110/dce110_compressor.h"
57#endif 57#endif
58 58
@@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth(
849static bool dce110_validate_surface_sets( 849static bool dce110_validate_surface_sets(
850 struct dc_state *context) 850 struct dc_state *context)
851{ 851{
852 int i; 852 int i, j;
853 853
854 for (i = 0; i < context->stream_count; i++) { 854 for (i = 0; i < context->stream_count; i++) {
855 if (context->stream_status[i].plane_count == 0) 855 if (context->stream_status[i].plane_count == 0)
@@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets(
858 if (context->stream_status[i].plane_count > 2) 858 if (context->stream_status[i].plane_count > 2)
859 return false; 859 return false;
860 860
861 if ((context->stream_status[i].plane_states[i]->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) && 861 for (j = 0; j < context->stream_status[i].plane_count; j++) {
862 (context->stream_status[i].plane_states[i]->src_rect.width > 1920 || 862 struct dc_plane_state *plane =
863 context->stream_status[i].plane_states[i]->src_rect.height > 1080)) 863 context->stream_status[i].plane_states[j];
864 return false;
865 864
866 /* irrespective of plane format, stream should be RGB encoded */ 865 /* underlay validation */
867 if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB) 866 if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
868 return false; 867
868 if ((plane->src_rect.width > 1920 ||
869 plane->src_rect.height > 1080))
870 return false;
871
872 /* irrespective of plane format,
873 * stream should be RGB encoded
874 */
875 if (context->streams[i]->timing.pixel_encoding
876 != PIXEL_ENCODING_RGB)
877 return false;
878
879 }
880
881 }
869 } 882 }
870 883
871 return true; 884 return true;
@@ -1266,7 +1279,7 @@ static bool construct(
1266 } 1279 }
1267 } 1280 }
1268 1281
1269#ifdef ENABLE_FBC 1282#if defined(CONFIG_DRM_AMD_DC_FBC)
1270 dc->fbc_compressor = dce110_compressor_create(ctx); 1283 dc->fbc_compressor = dce110_compressor_create(ctx);
1271 1284
1272 1285
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
index 2d6d3a371858..ebeb88283a14 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile
@@ -3,8 +3,8 @@
3 3
4DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ 4DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
5 dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \ 5 dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \
6 dcn10_mem_input.o dcn10_mpc.o \ 6 dcn10_hubp.o dcn10_mpc.o \
7 dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_dpp_cm_helper.o 7 dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o
8 8
9AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) 9AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
10 10
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index f616e08759de..7f579cb19f4b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -26,7 +26,7 @@
26#include "reg_helper.h" 26#include "reg_helper.h"
27#include "dcn10_dpp.h" 27#include "dcn10_dpp.h"
28 28
29#include "dcn10_dpp_cm_helper.h" 29#include "dcn10_cm_common.h"
30 30
31#define REG(reg) reg 31#define REG(reg) reg
32 32
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
index 1155ee522898..64836dcf21f2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.h
@@ -23,8 +23,8 @@
23 * 23 *
24 */ 24 */
25 25
26#ifndef __DAL_DPP_DCN10_CM_HELPER_H__ 26#ifndef __DAL_DCN10_CM_COMMON_H__
27#define __DAL_DPP_DCN10_CM_HELPER_H__ 27#define __DAL_DCN10_CM_COMMON_H__
28 28
29#define TF_HELPER_REG_FIELD_LIST(type) \ 29#define TF_HELPER_REG_FIELD_LIST(type) \
30 type exp_region0_lut_offset; \ 30 type exp_region0_lut_offset; \
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index 9d9604f05095..74e7c82bdc76 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -39,14 +39,14 @@
39#define BLACK_OFFSET_CBCR 0x8000 39#define BLACK_OFFSET_CBCR 0x8000
40 40
41#define REG(reg)\ 41#define REG(reg)\
42 xfm->tf_regs->reg 42 dpp->tf_regs->reg
43 43
44#define CTX \ 44#define CTX \
45 xfm->base.ctx 45 dpp->base.ctx
46 46
47#undef FN 47#undef FN
48#define FN(reg_name, field_name) \ 48#define FN(reg_name, field_name) \
49 xfm->tf_shift->field_name, xfm->tf_mask->field_name 49 dpp->tf_shift->field_name, dpp->tf_mask->field_name
50 50
51enum pixel_format_description { 51enum pixel_format_description {
52 PIXEL_FORMAT_FIXED = 0, 52 PIXEL_FORMAT_FIXED = 0,
@@ -99,7 +99,7 @@ enum gamut_remap_select {
99}; 99};
100 100
101/* Program gamut remap in bypass mode */ 101/* Program gamut remap in bypass mode */
102void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm) 102void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp)
103{ 103{
104 REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 104 REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
105 CM_GAMUT_REMAP_MODE, 0); 105 CM_GAMUT_REMAP_MODE, 0);
@@ -110,7 +110,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
110 110
111 111
112bool dpp_get_optimal_number_of_taps( 112bool dpp_get_optimal_number_of_taps(
113 struct transform *xfm, 113 struct dpp *dpp,
114 struct scaler_data *scl_data, 114 struct scaler_data *scl_data,
115 const struct scaling_taps *in_taps) 115 const struct scaling_taps *in_taps)
116{ 116{
@@ -154,28 +154,29 @@ bool dpp_get_optimal_number_of_taps(
154 else 154 else
155 scl_data->taps.h_taps_c = in_taps->h_taps_c; 155 scl_data->taps.h_taps_c = in_taps->h_taps_c;
156 156
157 if (!xfm->ctx->dc->debug.always_scale) { 157 if (!dpp->ctx->dc->debug.always_scale) {
158 if (IDENTITY_RATIO(scl_data->ratios.horz)) 158 if (IDENTITY_RATIO(scl_data->ratios.horz))
159 scl_data->taps.h_taps = 1; 159 scl_data->taps.h_taps = 1;
160 if (IDENTITY_RATIO(scl_data->ratios.vert)) 160 if (IDENTITY_RATIO(scl_data->ratios.vert))
161 scl_data->taps.v_taps = 1; 161 scl_data->taps.v_taps = 1;
162 if (IDENTITY_RATIO(scl_data->ratios.horz_c)) 162 /*
163 scl_data->taps.h_taps_c = 1; 163 * Spreadsheet doesn't handle taps_c is one properly,
164 if (IDENTITY_RATIO(scl_data->ratios.vert_c)) 164 * need to force Chroma to always be scaled to pass
165 scl_data->taps.v_taps_c = 1; 165 * bandwidth validation.
166 */
166 } 167 }
167 168
168 return true; 169 return true;
169} 170}
170 171
171void dpp_reset(struct transform *xfm_base) 172void dpp_reset(struct dpp *dpp_base)
172{ 173{
173 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 174 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
174 175
175 xfm->filter_h_c = NULL; 176 dpp->filter_h_c = NULL;
176 xfm->filter_v_c = NULL; 177 dpp->filter_v_c = NULL;
177 xfm->filter_h = NULL; 178 dpp->filter_h = NULL;
178 xfm->filter_v = NULL; 179 dpp->filter_v = NULL;
179 180
180 /* set boundary mode to 0 */ 181 /* set boundary mode to 0 */
181 REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0); 182 REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0);
@@ -183,28 +184,28 @@ void dpp_reset(struct transform *xfm_base)
183 184
184 185
185 186
186static void dcn10_dpp_cm_set_regamma_pwl( 187static void dpp1_cm_set_regamma_pwl(
187 struct transform *xfm_base, const struct pwl_params *params) 188 struct dpp *dpp_base, const struct pwl_params *params)
188{ 189{
189 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 190 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
190 191
191 dcn10_dpp_cm_power_on_regamma_lut(xfm_base, true); 192 dpp1_cm_power_on_regamma_lut(dpp_base, true);
192 dcn10_dpp_cm_configure_regamma_lut(xfm_base, xfm->is_write_to_ram_a_safe); 193 dpp1_cm_configure_regamma_lut(dpp_base, dpp->is_write_to_ram_a_safe);
193 194
194 if (xfm->is_write_to_ram_a_safe) 195 if (dpp->is_write_to_ram_a_safe)
195 dcn10_dpp_cm_program_regamma_luta_settings(xfm_base, params); 196 dpp1_cm_program_regamma_luta_settings(dpp_base, params);
196 else 197 else
197 dcn10_dpp_cm_program_regamma_lutb_settings(xfm_base, params); 198 dpp1_cm_program_regamma_lutb_settings(dpp_base, params);
198 199
199 dcn10_dpp_cm_program_regamma_lut( 200 dpp1_cm_program_regamma_lut(
200 xfm_base, params->rgb_resulted, params->hw_points_num); 201 dpp_base, params->rgb_resulted, params->hw_points_num);
201} 202}
202 203
203static void dcn10_dpp_cm_set_regamma_mode( 204static void dpp1_cm_set_regamma_mode(
204 struct transform *xfm_base, 205 struct dpp *dpp_base,
205 enum opp_regamma mode) 206 enum opp_regamma mode)
206{ 207{
207 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 208 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
208 uint32_t re_mode = 0; 209 uint32_t re_mode = 0;
209 uint32_t obuf_bypass = 0; /* need for pipe split */ 210 uint32_t obuf_bypass = 0; /* need for pipe split */
210 uint32_t obuf_hupscale = 0; 211 uint32_t obuf_hupscale = 0;
@@ -220,8 +221,8 @@ static void dcn10_dpp_cm_set_regamma_mode(
220 re_mode = 2; 221 re_mode = 2;
221 break; 222 break;
222 case OPP_REGAMMA_USER: 223 case OPP_REGAMMA_USER:
223 re_mode = xfm->is_write_to_ram_a_safe ? 3 : 4; 224 re_mode = dpp->is_write_to_ram_a_safe ? 3 : 4;
224 xfm->is_write_to_ram_a_safe = !xfm->is_write_to_ram_a_safe; 225 dpp->is_write_to_ram_a_safe = !dpp->is_write_to_ram_a_safe;
225 break; 226 break;
226 default: 227 default:
227 break; 228 break;
@@ -233,7 +234,7 @@ static void dcn10_dpp_cm_set_regamma_mode(
233 OBUF_H_2X_UPSCALE_EN, obuf_hupscale); 234 OBUF_H_2X_UPSCALE_EN, obuf_hupscale);
234} 235}
235 236
236static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\ 237static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
237 enum pixel_format_description *fmt) 238 enum pixel_format_description *fmt)
238{ 239{
239 240
@@ -246,11 +247,11 @@ static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
246 *fmt = PIXEL_FORMAT_FIXED; 247 *fmt = PIXEL_FORMAT_FIXED;
247} 248}
248 249
249static void ippn10_set_degamma_format_float( 250static void dpp1_set_degamma_format_float(
250 struct transform *xfm_base, 251 struct dpp *dpp_base,
251 bool is_float) 252 bool is_float)
252{ 253{
253 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 254 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
254 255
255 if (is_float) { 256 if (is_float) {
256 REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3); 257 REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3);
@@ -261,8 +262,8 @@ static void ippn10_set_degamma_format_float(
261 } 262 }
262} 263}
263 264
264void ippn10_cnv_setup ( 265void dpp1_cnv_setup (
265 struct transform *xfm_base, 266 struct dpp *dpp_base,
266 enum surface_pixel_format input_format, 267 enum surface_pixel_format input_format,
267 enum expansion_mode mode) 268 enum expansion_mode mode)
268{ 269{
@@ -272,10 +273,10 @@ void ippn10_cnv_setup (
272 enum dc_color_space color_space; 273 enum dc_color_space color_space;
273 enum dcn10_input_csc_select select; 274 enum dcn10_input_csc_select select;
274 bool is_float; 275 bool is_float;
275 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 276 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
276 bool force_disable_cursor = false; 277 bool force_disable_cursor = false;
277 278
278 ippn10_setup_format_flags(input_format, &fmt); 279 dpp1_setup_format_flags(input_format, &fmt);
279 alpha_en = 1; 280 alpha_en = 1;
280 pixel_format = 0; 281 pixel_format = 0;
281 color_space = COLOR_SPACE_SRGB; 282 color_space = COLOR_SPACE_SRGB;
@@ -303,7 +304,7 @@ void ippn10_cnv_setup (
303 break; 304 break;
304 } 305 }
305 306
306 ippn10_set_degamma_format_float(xfm_base, is_float); 307 dpp1_set_degamma_format_float(dpp_base, is_float);
307 308
308 switch (input_format) { 309 switch (input_format) {
309 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 310 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
@@ -361,7 +362,7 @@ void ippn10_cnv_setup (
361 CNVC_SURFACE_PIXEL_FORMAT, pixel_format); 362 CNVC_SURFACE_PIXEL_FORMAT, pixel_format);
362 REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en); 363 REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
363 364
364 ippn10_program_input_csc(xfm_base, color_space, select); 365 dpp1_program_input_csc(dpp_base, color_space, select);
365 366
366 if (force_disable_cursor) { 367 if (force_disable_cursor) {
367 REG_UPDATE(CURSOR_CONTROL, 368 REG_UPDATE(CURSOR_CONTROL,
@@ -371,54 +372,110 @@ void ippn10_cnv_setup (
371 } 372 }
372} 373}
373 374
374static const struct transform_funcs dcn10_dpp_funcs = { 375void dpp1_set_cursor_attributes(
375 .transform_reset = dpp_reset, 376 struct dpp *dpp_base,
376 .transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale, 377 const struct dc_cursor_attributes *attr)
377 .transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, 378{
378 .transform_set_gamut_remap = dcn10_dpp_cm_set_gamut_remap, 379 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
379 .opp_set_csc_adjustment = dcn10_dpp_cm_set_output_csc_adjustment, 380 enum dc_cursor_color_format color_format = attr->color_format;
380 .opp_set_csc_default = dcn10_dpp_cm_set_output_csc_default, 381
381 .opp_power_on_regamma_lut = dcn10_dpp_cm_power_on_regamma_lut, 382 REG_UPDATE_2(CURSOR0_CONTROL,
382 .opp_program_regamma_lut = dcn10_dpp_cm_program_regamma_lut, 383 CUR0_MODE, color_format,
383 .opp_configure_regamma_lut = dcn10_dpp_cm_configure_regamma_lut, 384 CUR0_EXPANSION_MODE, 0);
384 .opp_program_regamma_lutb_settings = dcn10_dpp_cm_program_regamma_lutb_settings, 385
385 .opp_program_regamma_luta_settings = dcn10_dpp_cm_program_regamma_luta_settings, 386 if (color_format == CURSOR_MODE_MONO) {
386 .opp_program_regamma_pwl = dcn10_dpp_cm_set_regamma_pwl, 387 /* todo: clarify what to program these to */
387 .opp_set_regamma_mode = dcn10_dpp_cm_set_regamma_mode, 388 REG_UPDATE(CURSOR0_COLOR0,
388 .ipp_set_degamma = ippn10_set_degamma, 389 CUR0_COLOR0, 0x00000000);
389 .ipp_program_input_lut = ippn10_program_input_lut, 390 REG_UPDATE(CURSOR0_COLOR1,
390 .ipp_program_degamma_pwl = ippn10_set_degamma_pwl, 391 CUR0_COLOR1, 0xFFFFFFFF);
391 .ipp_setup = ippn10_cnv_setup, 392 }
392 .ipp_full_bypass = ippn10_full_bypass, 393
394 /* TODO: Fixed vs float */
395
396 REG_UPDATE_3(FORMAT_CONTROL,
397 CNVC_BYPASS, 0,
398 FORMAT_CONTROL__ALPHA_EN, 1,
399 FORMAT_EXPANSION_MODE, 0);
400}
401
402
403void dpp1_set_cursor_position(
404 struct dpp *dpp_base,
405 const struct dc_cursor_position *pos,
406 const struct dc_cursor_mi_param *param,
407 uint32_t width)
408{
409 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
410 int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
411 uint32_t cur_en = pos->enable ? 1 : 0;
412
413 if (src_x_offset >= (int)param->viewport_width)
414 cur_en = 0; /* not visible beyond right edge*/
415
416 if (src_x_offset + (int)width < 0)
417 cur_en = 0; /* not visible beyond left edge*/
418
419 REG_UPDATE(CURSOR0_CONTROL,
420 CUR0_ENABLE, cur_en);
421
422}
423
424static const struct dpp_funcs dcn10_dpp_funcs = {
425 .dpp_reset = dpp_reset,
426 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
427 .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
428 .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
429 .opp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment,
430 .opp_set_csc_default = dpp1_cm_set_output_csc_default,
431 .opp_power_on_regamma_lut = dpp1_cm_power_on_regamma_lut,
432 .opp_program_regamma_lut = dpp1_cm_program_regamma_lut,
433 .opp_configure_regamma_lut = dpp1_cm_configure_regamma_lut,
434 .opp_program_regamma_lutb_settings = dpp1_cm_program_regamma_lutb_settings,
435 .opp_program_regamma_luta_settings = dpp1_cm_program_regamma_luta_settings,
436 .opp_program_regamma_pwl = dpp1_cm_set_regamma_pwl,
437 .opp_set_regamma_mode = dpp1_cm_set_regamma_mode,
438 .ipp_set_degamma = dpp1_set_degamma,
439 .ipp_program_input_lut = dpp1_program_input_lut,
440 .ipp_program_degamma_pwl = dpp1_set_degamma_pwl,
441 .ipp_setup = dpp1_cnv_setup,
442 .ipp_full_bypass = dpp1_full_bypass,
443 .set_cursor_attributes = dpp1_set_cursor_attributes,
444 .set_cursor_position = dpp1_set_cursor_position,
393}; 445};
394 446
447static struct dpp_caps dcn10_dpp_cap = {
448 .dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT,
449 .dscl_calc_lb_num_partitions = dpp1_dscl_calc_lb_num_partitions,
450};
395 451
396/*****************************************/ 452/*****************************************/
397/* Constructor, Destructor */ 453/* Constructor, Destructor */
398/*****************************************/ 454/*****************************************/
399 455
400void dcn10_dpp_construct( 456void dpp1_construct(
401 struct dcn10_dpp *xfm, 457 struct dcn10_dpp *dpp,
402 struct dc_context *ctx, 458 struct dc_context *ctx,
403 uint32_t inst, 459 uint32_t inst,
404 const struct dcn_dpp_registers *tf_regs, 460 const struct dcn_dpp_registers *tf_regs,
405 const struct dcn_dpp_shift *tf_shift, 461 const struct dcn_dpp_shift *tf_shift,
406 const struct dcn_dpp_mask *tf_mask) 462 const struct dcn_dpp_mask *tf_mask)
407{ 463{
408 xfm->base.ctx = ctx; 464 dpp->base.ctx = ctx;
409 465
410 xfm->base.inst = inst; 466 dpp->base.inst = inst;
411 xfm->base.funcs = &dcn10_dpp_funcs; 467 dpp->base.funcs = &dcn10_dpp_funcs;
468 dpp->base.caps = &dcn10_dpp_cap;
412 469
413 xfm->tf_regs = tf_regs; 470 dpp->tf_regs = tf_regs;
414 xfm->tf_shift = tf_shift; 471 dpp->tf_shift = tf_shift;
415 xfm->tf_mask = tf_mask; 472 dpp->tf_mask = tf_mask;
416 473
417 xfm->lb_pixel_depth_supported = 474 dpp->lb_pixel_depth_supported =
418 LB_PIXEL_DEPTH_18BPP | 475 LB_PIXEL_DEPTH_18BPP |
419 LB_PIXEL_DEPTH_24BPP | 476 LB_PIXEL_DEPTH_24BPP |
420 LB_PIXEL_DEPTH_30BPP; 477 LB_PIXEL_DEPTH_30BPP;
421 478
422 xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY; 479 dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
423 xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/ 480 dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
424} 481}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index a1f6b01a2eb4..a9782b1aba47 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -25,10 +25,10 @@
25#ifndef __DAL_DPP_DCN10_H__ 25#ifndef __DAL_DPP_DCN10_H__
26#define __DAL_DPP_DCN10_H__ 26#define __DAL_DPP_DCN10_H__
27 27
28#include "transform.h" 28#include "dpp.h"
29 29
30#define TO_DCN10_DPP(transform)\ 30#define TO_DCN10_DPP(dpp)\
31 container_of(transform, struct dcn10_dpp, base) 31 container_of(dpp, struct dcn10_dpp, base)
32 32
33/* TODO: Use correct number of taps. Using polaris values for now */ 33/* TODO: Use correct number of taps. Using polaris values for now */
34#define LB_TOTAL_NUMBER_OF_ENTRIES 5124 34#define LB_TOTAL_NUMBER_OF_ENTRIES 5124
@@ -112,7 +112,9 @@
112 SRI(CM_DGAM_CONTROL, CM, id), \ 112 SRI(CM_DGAM_CONTROL, CM, id), \
113 SRI(FORMAT_CONTROL, CNVC_CFG, id), \ 113 SRI(FORMAT_CONTROL, CNVC_CFG, id), \
114 SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \ 114 SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
115 SRI(CURSOR0_CONTROL, CNVC_CUR, id) 115 SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
116 SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
117 SRI(CURSOR0_COLOR1, CNVC_CUR, id)
116 118
117 119
118 120
@@ -162,7 +164,8 @@
162 SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \ 164 SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \
163 SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \ 165 SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \
164 SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \ 166 SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \
165 SRI(CURSOR_CONTROL, CURSOR, id) 167 SRI(CURSOR_CONTROL, CURSOR, id), \
168 SRI(CM_CMOUT_CONTROL, CM, id)
166 169
167 170
168#define TF_REG_LIST_SH_MASK_DCN(mask_sh)\ 171#define TF_REG_LIST_SH_MASK_DCN(mask_sh)\
@@ -302,7 +305,9 @@
302 TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \ 305 TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
303 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \ 306 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
304 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \ 307 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
305 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh) 308 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
309 TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
310 TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
306 311
307#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\ 312#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
308 TF_REG_LIST_SH_MASK_DCN(mask_sh),\ 313 TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@@ -397,6 +402,7 @@
397 TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \ 402 TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \
398 TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \ 403 TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \
399 TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \ 404 TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \
405 TF_SF(CM0_CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, mask_sh), \
400 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ 406 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
401 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ 407 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
402 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ 408 TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
@@ -545,6 +551,7 @@
545 type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \ 551 type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \
546 type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \ 552 type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \
547 type CM_RGAM_LUT_MODE; \ 553 type CM_RGAM_LUT_MODE; \
554 type CM_CMOUT_ROUND_TRUNC_MODE; \
548 type OBUF_BYPASS; \ 555 type OBUF_BYPASS; \
549 type OBUF_H_2X_UPSCALE_EN; \ 556 type OBUF_H_2X_UPSCALE_EN; \
550 type CM_BLNDGAM_LUT_MODE; \ 557 type CM_BLNDGAM_LUT_MODE; \
@@ -989,7 +996,9 @@
989 type CUR0_EXPANSION_MODE; \ 996 type CUR0_EXPANSION_MODE; \
990 type CUR0_ENABLE; \ 997 type CUR0_ENABLE; \
991 type CM_BYPASS; \ 998 type CM_BYPASS; \
992 type FORMAT_CONTROL__ALPHA_EN 999 type FORMAT_CONTROL__ALPHA_EN; \
1000 type CUR0_COLOR0; \
1001 type CUR0_COLOR1
993 1002
994 1003
995 1004
@@ -1075,6 +1084,7 @@ struct dcn_dpp_registers {
1075 uint32_t CM_RGAM_RAMA_REGION_0_1; 1084 uint32_t CM_RGAM_RAMA_REGION_0_1;
1076 uint32_t CM_RGAM_RAMA_REGION_32_33; 1085 uint32_t CM_RGAM_RAMA_REGION_32_33;
1077 uint32_t CM_RGAM_CONTROL; 1086 uint32_t CM_RGAM_CONTROL;
1087 uint32_t CM_CMOUT_CONTROL;
1078 uint32_t OBUF_CONTROL; 1088 uint32_t OBUF_CONTROL;
1079 uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK; 1089 uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK;
1080 uint32_t CM_BLNDGAM_CONTROL; 1090 uint32_t CM_BLNDGAM_CONTROL;
@@ -1237,10 +1247,12 @@ struct dcn_dpp_registers {
1237 uint32_t CNVC_SURFACE_PIXEL_FORMAT; 1247 uint32_t CNVC_SURFACE_PIXEL_FORMAT;
1238 uint32_t CURSOR_CONTROL; 1248 uint32_t CURSOR_CONTROL;
1239 uint32_t CURSOR0_CONTROL; 1249 uint32_t CURSOR0_CONTROL;
1250 uint32_t CURSOR0_COLOR0;
1251 uint32_t CURSOR0_COLOR1;
1240}; 1252};
1241 1253
1242struct dcn10_dpp { 1254struct dcn10_dpp {
1243 struct transform base; 1255 struct dpp base;
1244 1256
1245 const struct dcn_dpp_registers *tf_regs; 1257 const struct dcn_dpp_registers *tf_regs;
1246 const struct dcn_dpp_shift *tf_shift; 1258 const struct dcn_dpp_shift *tf_shift;
@@ -1256,107 +1268,116 @@ struct dcn10_dpp {
1256 bool is_write_to_ram_a_safe; 1268 bool is_write_to_ram_a_safe;
1257}; 1269};
1258 1270
1259
1260
1261enum dcn10_input_csc_select { 1271enum dcn10_input_csc_select {
1262 INPUT_CSC_SELECT_BYPASS = 0, 1272 INPUT_CSC_SELECT_BYPASS = 0,
1263 INPUT_CSC_SELECT_ICSC, 1273 INPUT_CSC_SELECT_ICSC,
1264 INPUT_CSC_SELECT_COMA 1274 INPUT_CSC_SELECT_COMA
1265}; 1275};
1266 1276
1267void ippn10_degamma_ram_select( 1277bool dpp1_dscl_is_lb_conf_valid(
1268 struct transform *xfm_base, 1278 int ceil_vratio,
1279 int num_partitions,
1280 int vtaps);
1281
1282void dpp1_dscl_calc_lb_num_partitions(
1283 const struct scaler_data *scl_data,
1284 enum lb_memory_config lb_config,
1285 int *num_part_y,
1286 int *num_part_c);
1287
1288void dpp1_degamma_ram_select(
1289 struct dpp *dpp_base,
1269 bool use_ram_a); 1290 bool use_ram_a);
1270 1291
1271void ippn10_program_degamma_luta_settings( 1292void dpp1_program_degamma_luta_settings(
1272 struct transform *xfm_base, 1293 struct dpp *dpp_base,
1273 const struct pwl_params *params); 1294 const struct pwl_params *params);
1274 1295
1275void ippn10_program_degamma_lutb_settings( 1296void dpp1_program_degamma_lutb_settings(
1276 struct transform *xfm_base, 1297 struct dpp *dpp_base,
1277 const struct pwl_params *params); 1298 const struct pwl_params *params);
1278 1299
1279void ippn10_program_degamma_lut( 1300void dpp1_program_degamma_lut(
1280 struct transform *xfm_base, 1301 struct dpp *dpp_base,
1281 const struct pwl_result_data *rgb, 1302 const struct pwl_result_data *rgb,
1282 uint32_t num, 1303 uint32_t num,
1283 bool is_ram_a); 1304 bool is_ram_a);
1284 1305
1285void ippn10_power_on_degamma_lut( 1306void dpp1_power_on_degamma_lut(
1286 struct transform *xfm_base, 1307 struct dpp *dpp_base,
1287 bool power_on); 1308 bool power_on);
1288 1309
1289void ippn10_program_input_csc( 1310void dpp1_program_input_csc(
1290 struct transform *xfm_base, 1311 struct dpp *dpp_base,
1291 enum dc_color_space color_space, 1312 enum dc_color_space color_space,
1292 enum dcn10_input_csc_select select); 1313 enum dcn10_input_csc_select select);
1293 1314
1294void ippn10_program_input_lut( 1315void dpp1_program_input_lut(
1295 struct transform *xfm_base, 1316 struct dpp *dpp_base,
1296 const struct dc_gamma *gamma); 1317 const struct dc_gamma *gamma);
1297 1318
1298void ippn10_full_bypass(struct transform *xfm_base); 1319void dpp1_full_bypass(struct dpp *dpp_base);
1299 1320
1300void ippn10_set_degamma( 1321void dpp1_set_degamma(
1301 struct transform *xfm_base, 1322 struct dpp *dpp_base,
1302 enum ipp_degamma_mode mode); 1323 enum ipp_degamma_mode mode);
1303 1324
1304void ippn10_set_degamma_pwl(struct transform *xfm_base, 1325void dpp1_set_degamma_pwl(struct dpp *dpp_base,
1305 const struct pwl_params *params); 1326 const struct pwl_params *params);
1306 1327
1307bool dpp_get_optimal_number_of_taps( 1328bool dpp_get_optimal_number_of_taps(
1308 struct transform *xfm, 1329 struct dpp *dpp,
1309 struct scaler_data *scl_data, 1330 struct scaler_data *scl_data,
1310 const struct scaling_taps *in_taps); 1331 const struct scaling_taps *in_taps);
1311 1332
1312void dpp_reset(struct transform *xfm_base); 1333void dpp_reset(struct dpp *dpp_base);
1313 1334
1314void dcn10_dpp_cm_program_regamma_lut( 1335void dpp1_cm_program_regamma_lut(
1315 struct transform *xfm_base, 1336 struct dpp *dpp_base,
1316 const struct pwl_result_data *rgb, 1337 const struct pwl_result_data *rgb,
1317 uint32_t num); 1338 uint32_t num);
1318 1339
1319void dcn10_dpp_cm_power_on_regamma_lut( 1340void dpp1_cm_power_on_regamma_lut(
1320 struct transform *xfm_base, 1341 struct dpp *dpp_base,
1321 bool power_on); 1342 bool power_on);
1322 1343
1323void dcn10_dpp_cm_configure_regamma_lut( 1344void dpp1_cm_configure_regamma_lut(
1324 struct transform *xfm_base, 1345 struct dpp *dpp_base,
1325 bool is_ram_a); 1346 bool is_ram_a);
1326 1347
1327/*program re gamma RAM A*/ 1348/*program re gamma RAM A*/
1328void dcn10_dpp_cm_program_regamma_luta_settings( 1349void dpp1_cm_program_regamma_luta_settings(
1329 struct transform *xfm_base, 1350 struct dpp *dpp_base,
1330 const struct pwl_params *params); 1351 const struct pwl_params *params);
1331 1352
1332/*program re gamma RAM B*/ 1353/*program re gamma RAM B*/
1333void dcn10_dpp_cm_program_regamma_lutb_settings( 1354void dpp1_cm_program_regamma_lutb_settings(
1334 struct transform *xfm_base, 1355 struct dpp *dpp_base,
1335 const struct pwl_params *params); 1356 const struct pwl_params *params);
1336void dcn10_dpp_cm_set_output_csc_adjustment( 1357void dpp1_cm_set_output_csc_adjustment(
1337 struct transform *xfm_base, 1358 struct dpp *dpp_base,
1338 const struct out_csc_color_matrix *tbl_entry); 1359 const struct out_csc_color_matrix *tbl_entry);
1339 1360
1340void dcn10_dpp_cm_set_output_csc_default( 1361void dpp1_cm_set_output_csc_default(
1341 struct transform *xfm_base, 1362 struct dpp *dpp_base,
1342 const struct default_adjustment *default_adjust); 1363 const struct default_adjustment *default_adjust);
1343 1364
1344void dcn10_dpp_cm_set_gamut_remap( 1365void dpp1_cm_set_gamut_remap(
1345 struct transform *xfm, 1366 struct dpp *dpp,
1346 const struct xfm_grph_csc_adjustment *adjust); 1367 const struct dpp_grph_csc_adjustment *adjust);
1347 1368
1348void dcn10_dpp_dscl_set_scaler_manual_scale( 1369void dpp1_dscl_set_scaler_manual_scale(
1349 struct transform *xfm_base, 1370 struct dpp *dpp_base,
1350 const struct scaler_data *scl_data); 1371 const struct scaler_data *scl_data);
1351 1372
1352void ippn10_cnv_setup ( 1373void dpp1_cnv_setup (
1353 struct transform *xfm_base, 1374 struct dpp *dpp_base,
1354 enum surface_pixel_format input_format, 1375 enum surface_pixel_format input_format,
1355 enum expansion_mode mode); 1376 enum expansion_mode mode);
1356 1377
1357void ippn10_full_bypass(struct transform *xfm_base); 1378void dpp1_full_bypass(struct dpp *dpp_base);
1358 1379
1359void dcn10_dpp_construct(struct dcn10_dpp *xfm110, 1380void dpp1_construct(struct dcn10_dpp *dpp1,
1360 struct dc_context *ctx, 1381 struct dc_context *ctx,
1361 uint32_t inst, 1382 uint32_t inst,
1362 const struct dcn_dpp_registers *tf_regs, 1383 const struct dcn_dpp_registers *tf_regs,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
index d0e72acfc1d5..7784001c3a17 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
@@ -29,8 +29,8 @@
29 29
30#include "reg_helper.h" 30#include "reg_helper.h"
31#include "dcn10_dpp.h" 31#include "dcn10_dpp.h"
32#include "dcn10_dpp_cm_helper.h"
33#include "basics/conversion.h" 32#include "basics/conversion.h"
33#include "dcn10_cm_common.h"
34 34
35#define NUM_PHASES 64 35#define NUM_PHASES 64
36#define HORZ_MAX_TAPS 8 36#define HORZ_MAX_TAPS 8
@@ -40,14 +40,14 @@
40#define BLACK_OFFSET_CBCR 0x8000 40#define BLACK_OFFSET_CBCR 0x8000
41 41
42#define REG(reg)\ 42#define REG(reg)\
43 xfm->tf_regs->reg 43 dpp->tf_regs->reg
44 44
45#define CTX \ 45#define CTX \
46 xfm->base.ctx 46 dpp->base.ctx
47 47
48#undef FN 48#undef FN
49#define FN(reg_name, field_name) \ 49#define FN(reg_name, field_name) \
50 xfm->tf_shift->field_name, xfm->tf_mask->field_name 50 dpp->tf_shift->field_name, dpp->tf_mask->field_name
51 51
52struct dcn10_input_csc_matrix { 52struct dcn10_input_csc_matrix {
53 enum dc_color_space color_space; 53 enum dc_color_space color_space;
@@ -120,7 +120,7 @@ static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = {
120 120
121 121
122static void program_gamut_remap( 122static void program_gamut_remap(
123 struct dcn10_dpp *xfm, 123 struct dcn10_dpp *dpp,
124 const uint16_t *regval, 124 const uint16_t *regval,
125 enum gamut_remap_select select) 125 enum gamut_remap_select select)
126{ 126{
@@ -146,10 +146,10 @@ static void program_gamut_remap(
146 break; 146 break;
147 } 147 }
148 148
149 gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_GAMUT_REMAP_C11; 149 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
150 gam_regs.masks.csc_c11 = xfm->tf_mask->CM_GAMUT_REMAP_C11; 150 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11;
151 gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_GAMUT_REMAP_C12; 151 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
152 gam_regs.masks.csc_c12 = xfm->tf_mask->CM_GAMUT_REMAP_C12; 152 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
153 153
154 154
155 if (select == GAMUT_REMAP_COEFF) { 155 if (select == GAMUT_REMAP_COEFF) {
@@ -157,7 +157,7 @@ static void program_gamut_remap(
157 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); 157 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
158 158
159 cm_helper_program_color_matrices( 159 cm_helper_program_color_matrices(
160 xfm->base.ctx, 160 dpp->base.ctx,
161 regval, 161 regval,
162 &gam_regs); 162 &gam_regs);
163 163
@@ -167,7 +167,7 @@ static void program_gamut_remap(
167 gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34); 167 gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
168 168
169 cm_helper_program_color_matrices( 169 cm_helper_program_color_matrices(
170 xfm->base.ctx, 170 dpp->base.ctx,
171 regval, 171 regval,
172 &gam_regs); 172 &gam_regs);
173 173
@@ -177,7 +177,7 @@ static void program_gamut_remap(
177 gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34); 177 gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
178 178
179 cm_helper_program_color_matrices( 179 cm_helper_program_color_matrices(
180 xfm->base.ctx, 180 dpp->base.ctx,
181 regval, 181 regval,
182 &gam_regs); 182 &gam_regs);
183 } 183 }
@@ -188,15 +188,15 @@ static void program_gamut_remap(
188 188
189} 189}
190 190
191void dcn10_dpp_cm_set_gamut_remap( 191void dpp1_cm_set_gamut_remap(
192 struct transform *xfm, 192 struct dpp *dpp_base,
193 const struct xfm_grph_csc_adjustment *adjust) 193 const struct dpp_grph_csc_adjustment *adjust)
194{ 194{
195 struct dcn10_dpp *dcn_xfm = TO_DCN10_DPP(xfm); 195 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
196 196
197 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 197 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
198 /* Bypass if type is bypass or hw */ 198 /* Bypass if type is bypass or hw */
199 program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS); 199 program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS);
200 else { 200 else {
201 struct fixed31_32 arr_matrix[12]; 201 struct fixed31_32 arr_matrix[12];
202 uint16_t arr_reg_val[12]; 202 uint16_t arr_reg_val[12];
@@ -219,16 +219,16 @@ void dcn10_dpp_cm_set_gamut_remap(
219 convert_float_matrix( 219 convert_float_matrix(
220 arr_reg_val, arr_matrix, 12); 220 arr_reg_val, arr_matrix, 12);
221 221
222 program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF); 222 program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF);
223 } 223 }
224} 224}
225 225
226void dcn10_dpp_cm_set_output_csc_default( 226void dpp1_cm_set_output_csc_default(
227 struct transform *xfm_base, 227 struct dpp *dpp_base,
228 const struct default_adjustment *default_adjust) 228 const struct default_adjustment *default_adjust)
229{ 229{
230 230
231 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 231 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
232 uint32_t ocsc_mode = 0; 232 uint32_t ocsc_mode = 0;
233 233
234 if (default_adjust != NULL) { 234 if (default_adjust != NULL) {
@@ -260,35 +260,35 @@ void dcn10_dpp_cm_set_output_csc_default(
260 260
261} 261}
262 262
263static void dcn10_dpp_cm_get_reg_field( 263static void dpp1_cm_get_reg_field(
264 struct dcn10_dpp *xfm, 264 struct dcn10_dpp *dpp,
265 struct xfer_func_reg *reg) 265 struct xfer_func_reg *reg)
266{ 266{
267 reg->shifts.exp_region0_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; 267 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
268 reg->masks.exp_region0_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; 268 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
269 reg->shifts.exp_region0_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 269 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
270 reg->masks.exp_region0_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 270 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
271 reg->shifts.exp_region1_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; 271 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
272 reg->masks.exp_region1_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; 272 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
273 reg->shifts.exp_region1_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 273 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
274 reg->masks.exp_region1_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 274 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
275 275
276 reg->shifts.field_region_end = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B; 276 reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
277 reg->masks.field_region_end = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B; 277 reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
278 reg->shifts.field_region_end_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; 278 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
279 reg->masks.field_region_end_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; 279 reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
280 reg->shifts.field_region_end_base = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; 280 reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
281 reg->masks.field_region_end_base = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; 281 reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
282 reg->shifts.field_region_linear_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; 282 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
283 reg->masks.field_region_linear_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; 283 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
284 reg->shifts.exp_region_start = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B; 284 reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
285 reg->masks.exp_region_start = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B; 285 reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
286 reg->shifts.exp_resion_start_segment = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; 286 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
287 reg->masks.exp_resion_start_segment = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; 287 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
288} 288}
289 289
290static void dcn10_dpp_cm_program_color_matrix( 290static void dpp1_cm_program_color_matrix(
291 struct dcn10_dpp *xfm, 291 struct dcn10_dpp *dpp,
292 const struct out_csc_color_matrix *tbl_entry) 292 const struct out_csc_color_matrix *tbl_entry)
293{ 293{
294 uint32_t mode; 294 uint32_t mode;
@@ -301,10 +301,10 @@ static void dcn10_dpp_cm_program_color_matrix(
301 return; 301 return;
302 } 302 }
303 303
304 gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_OCSC_C11; 304 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
305 gam_regs.masks.csc_c11 = xfm->tf_mask->CM_OCSC_C11; 305 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11;
306 gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_OCSC_C12; 306 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
307 gam_regs.masks.csc_c12 = xfm->tf_mask->CM_OCSC_C12; 307 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12;
308 308
309 if (mode == 4) { 309 if (mode == 4) {
310 310
@@ -312,7 +312,7 @@ static void dcn10_dpp_cm_program_color_matrix(
312 gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34); 312 gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34);
313 313
314 cm_helper_program_color_matrices( 314 cm_helper_program_color_matrices(
315 xfm->base.ctx, 315 dpp->base.ctx,
316 tbl_entry->regval, 316 tbl_entry->regval,
317 &gam_regs); 317 &gam_regs);
318 318
@@ -322,17 +322,17 @@ static void dcn10_dpp_cm_program_color_matrix(
322 gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34); 322 gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
323 323
324 cm_helper_program_color_matrices( 324 cm_helper_program_color_matrices(
325 xfm->base.ctx, 325 dpp->base.ctx,
326 tbl_entry->regval, 326 tbl_entry->regval,
327 &gam_regs); 327 &gam_regs);
328 } 328 }
329} 329}
330 330
331void dcn10_dpp_cm_set_output_csc_adjustment( 331void dpp1_cm_set_output_csc_adjustment(
332 struct transform *xfm_base, 332 struct dpp *dpp_base,
333 const struct out_csc_color_matrix *tbl_entry) 333 const struct out_csc_color_matrix *tbl_entry)
334{ 334{
335 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 335 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
336 //enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC; 336 //enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
337 uint32_t ocsc_mode = 4; 337 uint32_t ocsc_mode = 4;
338 338
@@ -364,26 +364,26 @@ void dcn10_dpp_cm_set_output_csc_adjustment(
364 */ 364 */
365 365
366 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); 366 REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
367 dcn10_dpp_cm_program_color_matrix(xfm, tbl_entry); 367 dpp1_cm_program_color_matrix(dpp, tbl_entry);
368} 368}
369 369
370void dcn10_dpp_cm_power_on_regamma_lut( 370void dpp1_cm_power_on_regamma_lut(
371 struct transform *xfm_base, 371 struct dpp *dpp_base,
372 bool power_on) 372 bool power_on)
373{ 373{
374 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 374 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
375 REG_SET(CM_MEM_PWR_CTRL, 0, 375 REG_SET(CM_MEM_PWR_CTRL, 0,
376 RGAM_MEM_PWR_FORCE, power_on == true ? 0:1); 376 RGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
377 377
378} 378}
379 379
380void dcn10_dpp_cm_program_regamma_lut( 380void dpp1_cm_program_regamma_lut(
381 struct transform *xfm_base, 381 struct dpp *dpp_base,
382 const struct pwl_result_data *rgb, 382 const struct pwl_result_data *rgb,
383 uint32_t num) 383 uint32_t num)
384{ 384{
385 uint32_t i; 385 uint32_t i;
386 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 386 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
387 for (i = 0 ; i < num; i++) { 387 for (i = 0 ; i < num; i++) {
388 REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg); 388 REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg);
389 REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg); 389 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(
400 400
401} 401}
402 402
403void dcn10_dpp_cm_configure_regamma_lut( 403void dpp1_cm_configure_regamma_lut(
404 struct transform *xfm_base, 404 struct dpp *dpp_base,
405 bool is_ram_a) 405 bool is_ram_a)
406{ 406{
407 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 407 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
408 408
409 REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK, 409 REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK,
410 CM_RGAM_LUT_WRITE_EN_MASK, 7); 410 CM_RGAM_LUT_WRITE_EN_MASK, 7);
@@ -414,14 +414,14 @@ void dcn10_dpp_cm_configure_regamma_lut(
414} 414}
415 415
416/*program re gamma RAM A*/ 416/*program re gamma RAM A*/
417void dcn10_dpp_cm_program_regamma_luta_settings( 417void dpp1_cm_program_regamma_luta_settings(
418 struct transform *xfm_base, 418 struct dpp *dpp_base,
419 const struct pwl_params *params) 419 const struct pwl_params *params)
420{ 420{
421 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 421 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
422 struct xfer_func_reg gam_regs; 422 struct xfer_func_reg gam_regs;
423 423
424 dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); 424 dpp1_cm_get_reg_field(dpp, &gam_regs);
425 425
426 gam_regs.start_cntl_b = REG(CM_RGAM_RAMA_START_CNTL_B); 426 gam_regs.start_cntl_b = REG(CM_RGAM_RAMA_START_CNTL_B);
427 gam_regs.start_cntl_g = REG(CM_RGAM_RAMA_START_CNTL_G); 427 gam_regs.start_cntl_g = REG(CM_RGAM_RAMA_START_CNTL_G);
@@ -438,19 +438,19 @@ void dcn10_dpp_cm_program_regamma_luta_settings(
438 gam_regs.region_start = REG(CM_RGAM_RAMA_REGION_0_1); 438 gam_regs.region_start = REG(CM_RGAM_RAMA_REGION_0_1);
439 gam_regs.region_end = REG(CM_RGAM_RAMA_REGION_32_33); 439 gam_regs.region_end = REG(CM_RGAM_RAMA_REGION_32_33);
440 440
441 cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); 441 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
442 442
443} 443}
444 444
445/*program re gamma RAM B*/ 445/*program re gamma RAM B*/
446void dcn10_dpp_cm_program_regamma_lutb_settings( 446void dpp1_cm_program_regamma_lutb_settings(
447 struct transform *xfm_base, 447 struct dpp *dpp_base,
448 const struct pwl_params *params) 448 const struct pwl_params *params)
449{ 449{
450 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 450 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
451 struct xfer_func_reg gam_regs; 451 struct xfer_func_reg gam_regs;
452 452
453 dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); 453 dpp1_cm_get_reg_field(dpp, &gam_regs);
454 454
455 gam_regs.start_cntl_b = REG(CM_RGAM_RAMB_START_CNTL_B); 455 gam_regs.start_cntl_b = REG(CM_RGAM_RAMB_START_CNTL_B);
456 gam_regs.start_cntl_g = REG(CM_RGAM_RAMB_START_CNTL_G); 456 gam_regs.start_cntl_g = REG(CM_RGAM_RAMB_START_CNTL_G);
@@ -467,15 +467,15 @@ void dcn10_dpp_cm_program_regamma_lutb_settings(
467 gam_regs.region_start = REG(CM_RGAM_RAMB_REGION_0_1); 467 gam_regs.region_start = REG(CM_RGAM_RAMB_REGION_0_1);
468 gam_regs.region_end = REG(CM_RGAM_RAMB_REGION_32_33); 468 gam_regs.region_end = REG(CM_RGAM_RAMB_REGION_32_33);
469 469
470 cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); 470 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
471} 471}
472 472
473void ippn10_program_input_csc( 473void dpp1_program_input_csc(
474 struct transform *xfm_base, 474 struct dpp *dpp_base,
475 enum dc_color_space color_space, 475 enum dc_color_space color_space,
476 enum dcn10_input_csc_select select) 476 enum dcn10_input_csc_select select)
477{ 477{
478 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 478 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
479 int i; 479 int i;
480 int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix); 480 int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix);
481 const uint16_t *regval = NULL; 481 const uint16_t *regval = NULL;
@@ -503,10 +503,10 @@ void ippn10_program_input_csc(
503 REG_SET(CM_ICSC_CONTROL, 0, 503 REG_SET(CM_ICSC_CONTROL, 0,
504 CM_ICSC_MODE, selection); 504 CM_ICSC_MODE, selection);
505 505
506 gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_ICSC_C11; 506 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
507 gam_regs.masks.csc_c11 = xfm->tf_mask->CM_ICSC_C11; 507 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
508 gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_ICSC_C12; 508 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
509 gam_regs.masks.csc_c12 = xfm->tf_mask->CM_ICSC_C12; 509 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
510 510
511 511
512 if (select == INPUT_CSC_SELECT_ICSC) { 512 if (select == INPUT_CSC_SELECT_ICSC) {
@@ -515,7 +515,7 @@ void ippn10_program_input_csc(
515 gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34); 515 gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
516 516
517 cm_helper_program_color_matrices( 517 cm_helper_program_color_matrices(
518 xfm->base.ctx, 518 dpp->base.ctx,
519 regval, 519 regval,
520 &gam_regs); 520 &gam_regs);
521 } else { 521 } else {
@@ -524,21 +524,21 @@ void ippn10_program_input_csc(
524 gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34); 524 gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
525 525
526 cm_helper_program_color_matrices( 526 cm_helper_program_color_matrices(
527 xfm->base.ctx, 527 dpp->base.ctx,
528 regval, 528 regval,
529 &gam_regs); 529 &gam_regs);
530 } 530 }
531} 531}
532 532
533/*program de gamma RAM B*/ 533/*program de gamma RAM B*/
534void ippn10_program_degamma_lutb_settings( 534void dpp1_program_degamma_lutb_settings(
535 struct transform *xfm_base, 535 struct dpp *dpp_base,
536 const struct pwl_params *params) 536 const struct pwl_params *params)
537{ 537{
538 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 538 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
539 struct xfer_func_reg gam_regs; 539 struct xfer_func_reg gam_regs;
540 540
541 dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); 541 dpp1_cm_get_reg_field(dpp, &gam_regs);
542 542
543 gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B); 543 gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B);
544 gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G); 544 gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G);
@@ -556,18 +556,18 @@ void ippn10_program_degamma_lutb_settings(
556 gam_regs.region_end = REG(CM_DGAM_RAMB_REGION_14_15); 556 gam_regs.region_end = REG(CM_DGAM_RAMB_REGION_14_15);
557 557
558 558
559 cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); 559 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
560} 560}
561 561
562/*program de gamma RAM A*/ 562/*program de gamma RAM A*/
563void ippn10_program_degamma_luta_settings( 563void dpp1_program_degamma_luta_settings(
564 struct transform *xfm_base, 564 struct dpp *dpp_base,
565 const struct pwl_params *params) 565 const struct pwl_params *params)
566{ 566{
567 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 567 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
568 struct xfer_func_reg gam_regs; 568 struct xfer_func_reg gam_regs;
569 569
570 dcn10_dpp_cm_get_reg_field(xfm, &gam_regs); 570 dpp1_cm_get_reg_field(dpp, &gam_regs);
571 571
572 gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B); 572 gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B);
573 gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G); 573 gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G);
@@ -584,34 +584,35 @@ void ippn10_program_degamma_luta_settings(
584 gam_regs.region_start = REG(CM_DGAM_RAMA_REGION_0_1); 584 gam_regs.region_start = REG(CM_DGAM_RAMA_REGION_0_1);
585 gam_regs.region_end = REG(CM_DGAM_RAMA_REGION_14_15); 585 gam_regs.region_end = REG(CM_DGAM_RAMA_REGION_14_15);
586 586
587 cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs); 587 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
588} 588}
589 589
590void ippn10_power_on_degamma_lut( 590void dpp1_power_on_degamma_lut(
591 struct transform *xfm_base, 591 struct dpp *dpp_base,
592 bool power_on) 592 bool power_on)
593{ 593{
594 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 594 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
595 595
596 REG_SET(CM_MEM_PWR_CTRL, 0, 596 REG_SET(CM_MEM_PWR_CTRL, 0,
597 SHARED_MEM_PWR_DIS, power_on == true ? 0:1); 597 SHARED_MEM_PWR_DIS, power_on == true ? 0:1);
598 598
599} 599}
600 600
601static void ippn10_enable_cm_block( 601static void dpp1_enable_cm_block(
602 struct transform *xfm_base) 602 struct dpp *dpp_base)
603{ 603{
604 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 604 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
605 605
606 REG_UPDATE(CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, 8);
606 REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0); 607 REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0);
607} 608}
608 609
609void ippn10_set_degamma( 610void dpp1_set_degamma(
610 struct transform *xfm_base, 611 struct dpp *dpp_base,
611 enum ipp_degamma_mode mode) 612 enum ipp_degamma_mode mode)
612{ 613{
613 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 614 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
614 ippn10_enable_cm_block(xfm_base); 615 dpp1_enable_cm_block(dpp_base);
615 616
616 switch (mode) { 617 switch (mode) {
617 case IPP_DEGAMMA_MODE_BYPASS: 618 case IPP_DEGAMMA_MODE_BYPASS:
@@ -630,11 +631,11 @@ void ippn10_set_degamma(
630 } 631 }
631} 632}
632 633
633void ippn10_degamma_ram_select( 634void dpp1_degamma_ram_select(
634 struct transform *xfm_base, 635 struct dpp *dpp_base,
635 bool use_ram_a) 636 bool use_ram_a)
636{ 637{
637 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 638 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
638 639
639 if (use_ram_a) 640 if (use_ram_a)
640 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3); 641 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
@@ -643,13 +644,13 @@ void ippn10_degamma_ram_select(
643 644
644} 645}
645 646
646static bool ippn10_degamma_ram_inuse( 647static bool dpp1_degamma_ram_inuse(
647 struct transform *xfm_base, 648 struct dpp *dpp_base,
648 bool *ram_a_inuse) 649 bool *ram_a_inuse)
649{ 650{
650 bool ret = false; 651 bool ret = false;
651 uint32_t status_reg = 0; 652 uint32_t status_reg = 0;
652 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 653 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
653 654
654 REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS, 655 REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
655 &status_reg); 656 &status_reg);
@@ -664,15 +665,15 @@ static bool ippn10_degamma_ram_inuse(
664 return ret; 665 return ret;
665} 666}
666 667
667void ippn10_program_degamma_lut( 668void dpp1_program_degamma_lut(
668 struct transform *xfm_base, 669 struct dpp *dpp_base,
669 const struct pwl_result_data *rgb, 670 const struct pwl_result_data *rgb,
670 uint32_t num, 671 uint32_t num,
671 bool is_ram_a) 672 bool is_ram_a)
672{ 673{
673 uint32_t i; 674 uint32_t i;
674 675
675 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 676 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
676 REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0); 677 REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0);
677 REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, 678 REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
678 CM_DGAM_LUT_WRITE_EN_MASK, 7); 679 CM_DGAM_LUT_WRITE_EN_MASK, 7);
@@ -694,27 +695,27 @@ void ippn10_program_degamma_lut(
694 } 695 }
695} 696}
696 697
697void ippn10_set_degamma_pwl(struct transform *xfm_base, 698void dpp1_set_degamma_pwl(struct dpp *dpp_base,
698 const struct pwl_params *params) 699 const struct pwl_params *params)
699{ 700{
700 bool is_ram_a = true; 701 bool is_ram_a = true;
701 702
702 ippn10_power_on_degamma_lut(xfm_base, true); 703 dpp1_power_on_degamma_lut(dpp_base, true);
703 ippn10_enable_cm_block(xfm_base); 704 dpp1_enable_cm_block(dpp_base);
704 ippn10_degamma_ram_inuse(xfm_base, &is_ram_a); 705 dpp1_degamma_ram_inuse(dpp_base, &is_ram_a);
705 if (is_ram_a == true) 706 if (is_ram_a == true)
706 ippn10_program_degamma_lutb_settings(xfm_base, params); 707 dpp1_program_degamma_lutb_settings(dpp_base, params);
707 else 708 else
708 ippn10_program_degamma_luta_settings(xfm_base, params); 709 dpp1_program_degamma_luta_settings(dpp_base, params);
709 710
710 ippn10_program_degamma_lut(xfm_base, params->rgb_resulted, 711 dpp1_program_degamma_lut(dpp_base, params->rgb_resulted,
711 params->hw_points_num, !is_ram_a); 712 params->hw_points_num, !is_ram_a);
712 ippn10_degamma_ram_select(xfm_base, !is_ram_a); 713 dpp1_degamma_ram_select(dpp_base, !is_ram_a);
713} 714}
714 715
715void ippn10_full_bypass(struct transform *xfm_base) 716void dpp1_full_bypass(struct dpp *dpp_base)
716{ 717{
717 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 718 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
718 719
719 /* Input pixel format: ARGB8888 */ 720 /* Input pixel format: ARGB8888 */
720 REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, 721 REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
@@ -727,19 +728,19 @@ void ippn10_full_bypass(struct transform *xfm_base)
727 FORMAT_EXPANSION_MODE, 0); 728 FORMAT_EXPANSION_MODE, 0);
728 729
729 /* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */ 730 /* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */
730 if (xfm->tf_mask->CM_BYPASS_EN) 731 if (dpp->tf_mask->CM_BYPASS_EN)
731 REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1); 732 REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1);
732 733
733 /* Setting degamma bypass for now */ 734 /* Setting degamma bypass for now */
734 REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0); 735 REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0);
735} 736}
736 737
737static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base, 738static bool dpp1_ingamma_ram_inuse(struct dpp *dpp_base,
738 bool *ram_a_inuse) 739 bool *ram_a_inuse)
739{ 740{
740 bool in_use = false; 741 bool in_use = false;
741 uint32_t status_reg = 0; 742 uint32_t status_reg = 0;
742 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 743 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
743 744
744 REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS, 745 REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
745 &status_reg); 746 &status_reg);
@@ -765,19 +766,19 @@ static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
765 * In the future, this function should support additional input gamma methods, 766 * In the future, this function should support additional input gamma methods,
766 * such as piecewise linear mapping, and input gamma bypass. 767 * such as piecewise linear mapping, and input gamma bypass.
767 */ 768 */
768void ippn10_program_input_lut( 769void dpp1_program_input_lut(
769 struct transform *xfm_base, 770 struct dpp *dpp_base,
770 const struct dc_gamma *gamma) 771 const struct dc_gamma *gamma)
771{ 772{
772 int i; 773 int i;
773 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 774 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
774 bool rama_occupied = false; 775 bool rama_occupied = false;
775 uint32_t ram_num; 776 uint32_t ram_num;
776 // Power on LUT memory. 777 // Power on LUT memory.
777 REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1); 778 REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1);
778 ippn10_enable_cm_block(xfm_base); 779 dpp1_enable_cm_block(dpp_base);
779 // Determine whether to use RAM A or RAM B 780 // Determine whether to use RAM A or RAM B
780 ippn10_ingamma_ram_inuse(xfm_base, &rama_occupied); 781 dpp1_ingamma_ram_inuse(dpp_base, &rama_occupied);
781 if (!rama_occupied) 782 if (!rama_occupied)
782 REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0); 783 REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0);
783 else 784 else
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
index 82b8887d4973..cbad36410b32 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c
@@ -31,6 +31,7 @@
31#include "dcn10_dpp.h" 31#include "dcn10_dpp.h"
32#include "basics/conversion.h" 32#include "basics/conversion.h"
33 33
34
34#define NUM_PHASES 64 35#define NUM_PHASES 64
35#define HORZ_MAX_TAPS 8 36#define HORZ_MAX_TAPS 8
36#define VERT_MAX_TAPS 8 37#define VERT_MAX_TAPS 8
@@ -39,14 +40,14 @@
39#define BLACK_OFFSET_CBCR 0x8000 40#define BLACK_OFFSET_CBCR 0x8000
40 41
41#define REG(reg)\ 42#define REG(reg)\
42 xfm->tf_regs->reg 43 dpp->tf_regs->reg
43 44
44#define CTX \ 45#define CTX \
45 xfm->base.ctx 46 dpp->base.ctx
46 47
47#undef FN 48#undef FN
48#define FN(reg_name, field_name) \ 49#define FN(reg_name, field_name) \
49 xfm->tf_shift->field_name, xfm->tf_mask->field_name 50 dpp->tf_shift->field_name, dpp->tf_mask->field_name
50 51
51enum dcn10_coef_filter_type_sel { 52enum dcn10_coef_filter_type_sel {
52 SCL_COEF_LUMA_VERT_FILTER = 0, 53 SCL_COEF_LUMA_VERT_FILTER = 0,
@@ -57,22 +58,6 @@ enum dcn10_coef_filter_type_sel {
57 SCL_COEF_ALPHA_HORZ_FILTER = 5 58 SCL_COEF_ALPHA_HORZ_FILTER = 5
58}; 59};
59 60
60enum lb_memory_config {
61 /* Enable all 3 pieces of memory */
62 LB_MEMORY_CONFIG_0 = 0,
63
64 /* Enable only the first piece of memory */
65 LB_MEMORY_CONFIG_1 = 1,
66
67 /* Enable only the second piece of memory */
68 LB_MEMORY_CONFIG_2 = 2,
69
70 /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
71 * last piece of chroma memory used for the luma storage
72 */
73 LB_MEMORY_CONFIG_3 = 3
74};
75
76enum dscl_autocal_mode { 61enum dscl_autocal_mode {
77 AUTOCAL_MODE_OFF = 0, 62 AUTOCAL_MODE_OFF = 0,
78 63
@@ -100,8 +85,8 @@ enum dscl_mode_sel {
100 DSCL_MODE_DSCL_BYPASS = 6 85 DSCL_MODE_DSCL_BYPASS = 6
101}; 86};
102 87
103static void dpp_set_overscan( 88static void dpp1_dscl_set_overscan(
104 struct dcn10_dpp *xfm, 89 struct dcn10_dpp *dpp,
105 const struct scaler_data *data) 90 const struct scaler_data *data)
106{ 91{
107 uint32_t left = data->recout.x; 92 uint32_t left = data->recout.x;
@@ -128,8 +113,8 @@ static void dpp_set_overscan(
128 EXT_OVERSCAN_TOP, top); 113 EXT_OVERSCAN_TOP, top);
129} 114}
130 115
131static void dpp_set_otg_blank( 116static void dpp1_dscl_set_otg_blank(
132 struct dcn10_dpp *xfm, const struct scaler_data *data) 117 struct dcn10_dpp *dpp, const struct scaler_data *data)
133{ 118{
134 uint32_t h_blank_start = data->h_active; 119 uint32_t h_blank_start = data->h_active;
135 uint32_t h_blank_end = 0; 120 uint32_t h_blank_end = 0;
@@ -145,7 +130,7 @@ static void dpp_set_otg_blank(
145 OTG_V_BLANK_END, v_blank_end); 130 OTG_V_BLANK_END, v_blank_end);
146} 131}
147 132
148static int get_pixel_depth_val(enum lb_pixel_depth depth) 133static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)
149{ 134{
150 if (depth == LB_PIXEL_DEPTH_30BPP) 135 if (depth == LB_PIXEL_DEPTH_30BPP)
151 return 0; /* 10 bpc */ 136 return 0; /* 10 bpc */
@@ -161,23 +146,36 @@ static int get_pixel_depth_val(enum lb_pixel_depth depth)
161 } 146 }
162} 147}
163 148
164static enum dscl_mode_sel get_dscl_mode( 149static bool dpp1_dscl_is_video_format(enum pixel_format format)
165 const struct scaler_data *data, bool dbg_always_scale)
166{ 150{
167 const long long one = dal_fixed31_32_one.value; 151 if (format >= PIXEL_FORMAT_VIDEO_BEGIN
168 bool ycbcr = false; 152 && format <= PIXEL_FORMAT_VIDEO_END)
169 bool format420 = false; 153 return true;
154 else
155 return false;
156}
170 157
171 if (data->format == PIXEL_FORMAT_FP16) 158static bool dpp1_dscl_is_420_format(enum pixel_format format)
172 return DSCL_MODE_DSCL_BYPASS; 159{
160 if (format == PIXEL_FORMAT_420BPP8 ||
161 format == PIXEL_FORMAT_420BPP10)
162 return true;
163 else
164 return false;
165}
173 166
174 if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN 167static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
175 && data->format <= PIXEL_FORMAT_VIDEO_END) 168 struct dpp *dpp_base,
176 ycbcr = true; 169 const struct scaler_data *data,
170 bool dbg_always_scale)
171{
172 const long long one = dal_fixed31_32_one.value;
177 173
178 if (data->format == PIXEL_FORMAT_420BPP8 || 174 if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
179 data->format == PIXEL_FORMAT_420BPP10) 175 /* DSCL is processing data in fixed format */
180 format420 = true; 176 if (data->format == PIXEL_FORMAT_FP16)
177 return DSCL_MODE_DSCL_BYPASS;
178 }
181 179
182 if (data->ratios.horz.value == one 180 if (data->ratios.horz.value == one
183 && data->ratios.vert.value == one 181 && data->ratios.vert.value == one
@@ -186,8 +184,8 @@ static enum dscl_mode_sel get_dscl_mode(
186 && !dbg_always_scale) 184 && !dbg_always_scale)
187 return DSCL_MODE_SCALING_444_BYPASS; 185 return DSCL_MODE_SCALING_444_BYPASS;
188 186
189 if (!format420) { 187 if (!dpp1_dscl_is_420_format(data->format)) {
190 if (ycbcr) 188 if (dpp1_dscl_is_video_format(data->format))
191 return DSCL_MODE_SCALING_444_YCBCR_ENABLE; 189 return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
192 else 190 else
193 return DSCL_MODE_SCALING_444_RGB_ENABLE; 191 return DSCL_MODE_SCALING_444_RGB_ENABLE;
@@ -200,16 +198,17 @@ static enum dscl_mode_sel get_dscl_mode(
200 return DSCL_MODE_SCALING_420_YCBCR_ENABLE; 198 return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
201} 199}
202 200
203static void dpp_set_lb( 201static void dpp1_dscl_set_lb(
204 struct dcn10_dpp *xfm, 202 struct dcn10_dpp *dpp,
205 const struct line_buffer_params *lb_params, 203 const struct line_buffer_params *lb_params,
206 enum lb_memory_config mem_size_config) 204 enum lb_memory_config mem_size_config)
207{ 205{
208 uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth);
209 uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
210
211 /* LB */ 206 /* LB */
212 if (xfm->tf_mask->PIXEL_DEPTH) { 207 if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
208 /* DSCL caps: pixel data processed in fixed format */
209 uint32_t pixel_depth = dpp1_dscl_get_pixel_depth_val(lb_params->depth);
210 uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
211
213 REG_SET_7(LB_DATA_FORMAT, 0, 212 REG_SET_7(LB_DATA_FORMAT, 0,
214 PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */ 213 PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */
215 PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */ 214 PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */
@@ -225,7 +224,7 @@ static void dpp_set_lb(
225 LB_MAX_PARTITIONS, 63); 224 LB_MAX_PARTITIONS, 63);
226} 225}
227 226
228static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) 227static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
229{ 228{
230 if (taps == 8) 229 if (taps == 8)
231 return get_filter_8tap_64p(ratio); 230 return get_filter_8tap_64p(ratio);
@@ -250,8 +249,8 @@ static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
250 } 249 }
251} 250}
252 251
253static void dpp_set_scaler_filter( 252static void dpp1_dscl_set_scaler_filter(
254 struct dcn10_dpp *xfm, 253 struct dcn10_dpp *dpp,
255 uint32_t taps, 254 uint32_t taps,
256 enum dcn10_coef_filter_type_sel filter_type, 255 enum dcn10_coef_filter_type_sel filter_type,
257 const uint16_t *filter) 256 const uint16_t *filter)
@@ -288,8 +287,8 @@ static void dpp_set_scaler_filter(
288 287
289} 288}
290 289
291static void dpp_set_scl_filter( 290static void dpp1_dscl_set_scl_filter(
292 struct dcn10_dpp *xfm, 291 struct dcn10_dpp *dpp,
293 const struct scaler_data *scl_data, 292 const struct scaler_data *scl_data,
294 bool chroma_coef_mode) 293 bool chroma_coef_mode)
295{ 294{
@@ -307,10 +306,10 @@ static void dpp_set_scl_filter(
307 306
308 h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3 307 h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3
309 && scl_data->taps.h_taps_c < 3 308 && scl_data->taps.h_taps_c < 3
310 && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1); 309 && (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1);
311 v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3 310 v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3
312 && scl_data->taps.v_taps_c < 3 311 && scl_data->taps.v_taps_c < 3
313 && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1); 312 && (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1);
314 313
315 h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0; 314 h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0;
316 v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0; 315 v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0;
@@ -326,56 +325,56 @@ static void dpp_set_scl_filter(
326 if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) { 325 if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) {
327 bool filter_updated = false; 326 bool filter_updated = false;
328 327
329 filter_h = get_filter_coeffs_64p( 328 filter_h = dpp1_dscl_get_filter_coeffs_64p(
330 scl_data->taps.h_taps, scl_data->ratios.horz); 329 scl_data->taps.h_taps, scl_data->ratios.horz);
331 filter_v = get_filter_coeffs_64p( 330 filter_v = dpp1_dscl_get_filter_coeffs_64p(
332 scl_data->taps.v_taps, scl_data->ratios.vert); 331 scl_data->taps.v_taps, scl_data->ratios.vert);
333 332
334 filter_updated = (filter_h && (filter_h != xfm->filter_h)) 333 filter_updated = (filter_h && (filter_h != dpp->filter_h))
335 || (filter_v && (filter_v != xfm->filter_v)); 334 || (filter_v && (filter_v != dpp->filter_v));
336 335
337 if (chroma_coef_mode) { 336 if (chroma_coef_mode) {
338 filter_h_c = get_filter_coeffs_64p( 337 filter_h_c = dpp1_dscl_get_filter_coeffs_64p(
339 scl_data->taps.h_taps_c, scl_data->ratios.horz_c); 338 scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
340 filter_v_c = get_filter_coeffs_64p( 339 filter_v_c = dpp1_dscl_get_filter_coeffs_64p(
341 scl_data->taps.v_taps_c, scl_data->ratios.vert_c); 340 scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
342 filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c)) 341 filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c))
343 || (filter_v_c && (filter_v_c != xfm->filter_v_c)); 342 || (filter_v_c && (filter_v_c != dpp->filter_v_c));
344 } 343 }
345 344
346 if (filter_updated) { 345 if (filter_updated) {
347 uint32_t scl_mode = REG_READ(SCL_MODE); 346 uint32_t scl_mode = REG_READ(SCL_MODE);
348 347
349 if (!h_2tap_hardcode_coef_en && filter_h) { 348 if (!h_2tap_hardcode_coef_en && filter_h) {
350 dpp_set_scaler_filter( 349 dpp1_dscl_set_scaler_filter(
351 xfm, scl_data->taps.h_taps, 350 dpp, scl_data->taps.h_taps,
352 SCL_COEF_LUMA_HORZ_FILTER, filter_h); 351 SCL_COEF_LUMA_HORZ_FILTER, filter_h);
353 } 352 }
354 xfm->filter_h = filter_h; 353 dpp->filter_h = filter_h;
355 if (!v_2tap_hardcode_coef_en && filter_v) { 354 if (!v_2tap_hardcode_coef_en && filter_v) {
356 dpp_set_scaler_filter( 355 dpp1_dscl_set_scaler_filter(
357 xfm, scl_data->taps.v_taps, 356 dpp, scl_data->taps.v_taps,
358 SCL_COEF_LUMA_VERT_FILTER, filter_v); 357 SCL_COEF_LUMA_VERT_FILTER, filter_v);
359 } 358 }
360 xfm->filter_v = filter_v; 359 dpp->filter_v = filter_v;
361 if (chroma_coef_mode) { 360 if (chroma_coef_mode) {
362 if (!h_2tap_hardcode_coef_en && filter_h_c) { 361 if (!h_2tap_hardcode_coef_en && filter_h_c) {
363 dpp_set_scaler_filter( 362 dpp1_dscl_set_scaler_filter(
364 xfm, scl_data->taps.h_taps_c, 363 dpp, scl_data->taps.h_taps_c,
365 SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); 364 SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
366 } 365 }
367 if (!v_2tap_hardcode_coef_en && filter_v_c) { 366 if (!v_2tap_hardcode_coef_en && filter_v_c) {
368 dpp_set_scaler_filter( 367 dpp1_dscl_set_scaler_filter(
369 xfm, scl_data->taps.v_taps_c, 368 dpp, scl_data->taps.v_taps_c,
370 SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); 369 SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
371 } 370 }
372 } 371 }
373 xfm->filter_h_c = filter_h_c; 372 dpp->filter_h_c = filter_h_c;
374 xfm->filter_v_c = filter_v_c; 373 dpp->filter_v_c = filter_v_c;
375 374
376 coef_ram_current = get_reg_field_value_ex( 375 coef_ram_current = get_reg_field_value_ex(
377 scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, 376 scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
378 xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); 377 dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
379 378
380 /* Swap coefficient RAM and set chroma coefficient mode */ 379 /* Swap coefficient RAM and set chroma coefficient mode */
381 REG_SET_2(SCL_MODE, scl_mode, 380 REG_SET_2(SCL_MODE, scl_mode,
@@ -385,7 +384,7 @@ static void dpp_set_scl_filter(
385 } 384 }
386} 385}
387 386
388static int get_lb_depth_bpc(enum lb_pixel_depth depth) 387static int dpp1_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth)
389{ 388{
390 if (depth == LB_PIXEL_DEPTH_30BPP) 389 if (depth == LB_PIXEL_DEPTH_30BPP)
391 return 10; 390 return 10;
@@ -401,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth)
401 } 400 }
402} 401}
403 402
404static void calc_lb_num_partitions( 403void dpp1_dscl_calc_lb_num_partitions(
405 const struct scaler_data *scl_data, 404 const struct scaler_data *scl_data,
406 enum lb_memory_config lb_config, 405 enum lb_memory_config lb_config,
407 int *num_part_y, 406 int *num_part_y,
@@ -411,7 +410,7 @@ static void calc_lb_num_partitions(
411 scl_data->viewport.width : scl_data->recout.width; 410 scl_data->viewport.width : scl_data->recout.width;
412 int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ? 411 int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
413 scl_data->viewport_c.width : scl_data->recout.width; 412 scl_data->viewport_c.width : scl_data->recout.width;
414 int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth); 413 int lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
415 int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */ 414 int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
416 int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */ 415 int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
417 int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */ 416 int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
@@ -426,6 +425,7 @@ static void calc_lb_num_partitions(
426 lb_memory_size_c = 1088; 425 lb_memory_size_c = 1088;
427 lb_memory_size_a = 1312; 426 lb_memory_size_a = 1312;
428 } else if (lb_config == LB_MEMORY_CONFIG_3) { 427 } else if (lb_config == LB_MEMORY_CONFIG_3) {
428 /* 420 mode: using 3rd mem from Y, Cr and Cb */
429 lb_memory_size = 816 + 1088 + 848 + 848 + 848; 429 lb_memory_size = 816 + 1088 + 848 + 848 + 848;
430 lb_memory_size_c = 816 + 1088; 430 lb_memory_size_c = 816 + 1088;
431 lb_memory_size_a = 984 + 1312 + 456; 431 lb_memory_size_a = 984 + 1312 + 456;
@@ -449,7 +449,7 @@ static void calc_lb_num_partitions(
449 449
450} 450}
451 451
452static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) 452bool dpp1_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
453{ 453{
454 if (ceil_vratio > 2) 454 if (ceil_vratio > 2)
455 return vtaps <= (num_partitions - ceil_vratio + 2); 455 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)
458} 458}
459 459
460/*find first match configuration which meets the min required lb size*/ 460/*find first match configuration which meets the min required lb size*/
461static enum lb_memory_config dpp10_find_lb_memory_config( 461static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *dpp,
462 const struct scaler_data *scl_data) 462 const struct scaler_data *scl_data)
463{ 463{
464 int num_part_y, num_part_c; 464 int num_part_y, num_part_c;
@@ -466,75 +466,67 @@ static enum lb_memory_config dpp10_find_lb_memory_config(
466 int vtaps_c = scl_data->taps.v_taps_c; 466 int vtaps_c = scl_data->taps.v_taps_c;
467 int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); 467 int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert);
468 int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); 468 int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c);
469 enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
470
471 if (dpp->base.ctx->dc->debug.use_max_lb)
472 return mem_cfg;
469 473
470 calc_lb_num_partitions( 474 dpp->base.caps->dscl_calc_lb_num_partitions(
471 scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); 475 scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
472 476
473 if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 477 if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
474 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 478 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
475 return LB_MEMORY_CONFIG_1; 479 return LB_MEMORY_CONFIG_1;
476 480
477 calc_lb_num_partitions( 481 dpp->base.caps->dscl_calc_lb_num_partitions(
478 scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); 482 scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c);
479 483
480 if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 484 if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
481 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 485 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
482 return LB_MEMORY_CONFIG_2; 486 return LB_MEMORY_CONFIG_2;
483 487
484 if (scl_data->format == PIXEL_FORMAT_420BPP8 488 if (scl_data->format == PIXEL_FORMAT_420BPP8
485 || scl_data->format == PIXEL_FORMAT_420BPP10) { 489 || scl_data->format == PIXEL_FORMAT_420BPP10) {
486 calc_lb_num_partitions( 490 dpp->base.caps->dscl_calc_lb_num_partitions(
487 scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); 491 scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c);
488 492
489 if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 493 if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
490 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) 494 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
491 return LB_MEMORY_CONFIG_3; 495 return LB_MEMORY_CONFIG_3;
492 } 496 }
493 497
494 calc_lb_num_partitions( 498 dpp->base.caps->dscl_calc_lb_num_partitions(
495 scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); 499 scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c);
496 500
497 /*Ensure we can support the requested number of vtaps*/ 501 /*Ensure we can support the requested number of vtaps*/
498 ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) 502 ASSERT(dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
499 && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); 503 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
500 504
501 return LB_MEMORY_CONFIG_0; 505 return LB_MEMORY_CONFIG_0;
502} 506}
503 507
504/*find first match configuration which meets the min required lb size*/ 508void dpp1_dscl_set_scaler_auto_scale(
505static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm, 509 struct dpp *dpp_base,
506 const struct scaler_data *scl_data)
507{
508 enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
509
510 if (xfm->tf_mask->PIXEL_DEPTH) {
511 mem_cfg = dpp10_find_lb_memory_config(scl_data);
512 }
513 return mem_cfg;
514}
515
516void dpp_set_scaler_auto_scale(
517 struct transform *xfm_base,
518 const struct scaler_data *scl_data) 510 const struct scaler_data *scl_data)
519{ 511{
520 enum lb_memory_config lb_config; 512 enum lb_memory_config lb_config;
521 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 513 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
522 enum dscl_mode_sel dscl_mode = get_dscl_mode( 514 enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
523 scl_data, xfm_base->ctx->dc->debug.always_scale); 515 dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
524 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 516 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
525 && scl_data->format <= PIXEL_FORMAT_VIDEO_END; 517 && scl_data->format <= PIXEL_FORMAT_VIDEO_END;
526 518
527 dpp_set_overscan(xfm, scl_data); 519 dpp1_dscl_set_overscan(dpp, scl_data);
528 520
529 dpp_set_otg_blank(xfm, scl_data); 521 dpp1_dscl_set_otg_blank(dpp, scl_data);
530 522
531 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); 523 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
532 524
533 if (dscl_mode == DSCL_MODE_DSCL_BYPASS) 525 if (dscl_mode == DSCL_MODE_DSCL_BYPASS)
534 return; 526 return;
535 527
536 lb_config = find_lb_memory_config(xfm, scl_data); 528 lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
537 dpp_set_lb(xfm, &scl_data->lb_params, lb_config); 529 dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
538 530
539 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) 531 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
540 return; 532 return;
@@ -562,12 +554,12 @@ void dpp_set_scaler_auto_scale(
562 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, 554 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
563 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); 555 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
564 556
565 dpp_set_scl_filter(xfm, scl_data, ycbcr); 557 dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
566} 558}
567 559
568 560
569static void dpp_set_manual_ratio_init( 561static void dpp1_dscl_set_manual_ratio_init(
570 struct dcn10_dpp *xfm, const struct scaler_data *data) 562 struct dcn10_dpp *dpp, const struct scaler_data *data)
571{ 563{
572 uint32_t init_frac = 0; 564 uint32_t init_frac = 0;
573 uint32_t init_int = 0; 565 uint32_t init_int = 0;
@@ -626,8 +618,8 @@ static void dpp_set_manual_ratio_init(
626 618
627 619
628 620
629static void dpp_set_recout( 621static void dpp1_dscl_set_recout(
630 struct dcn10_dpp *xfm, const struct rect *recout) 622 struct dcn10_dpp *dpp, const struct rect *recout)
631{ 623{
632 REG_SET_2(RECOUT_START, 0, 624 REG_SET_2(RECOUT_START, 0,
633 /* First pixel of RECOUT */ 625 /* First pixel of RECOUT */
@@ -640,24 +632,24 @@ static void dpp_set_recout(
640 RECOUT_WIDTH, recout->width, 632 RECOUT_WIDTH, recout->width,
641 /* Number of RECOUT vertical lines */ 633 /* Number of RECOUT vertical lines */
642 RECOUT_HEIGHT, recout->height 634 RECOUT_HEIGHT, recout->height
643 - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 * 635 - dpp->base.ctx->dc->debug.surface_visual_confirm * 4 *
644 (xfm->base.inst + 1)); 636 (dpp->base.inst + 1));
645} 637}
646 638
647/* Main function to program scaler and line buffer in manual scaling mode */ 639/* Main function to program scaler and line buffer in manual scaling mode */
648void dcn10_dpp_dscl_set_scaler_manual_scale( 640void dpp1_dscl_set_scaler_manual_scale(
649 struct transform *xfm_base, 641 struct dpp *dpp_base,
650 const struct scaler_data *scl_data) 642 const struct scaler_data *scl_data)
651{ 643{
652 enum lb_memory_config lb_config; 644 enum lb_memory_config lb_config;
653 struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); 645 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
654 enum dscl_mode_sel dscl_mode = get_dscl_mode( 646 enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
655 scl_data, xfm_base->ctx->dc->debug.always_scale); 647 dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
656 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN 648 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
657 && scl_data->format <= PIXEL_FORMAT_VIDEO_END; 649 && scl_data->format <= PIXEL_FORMAT_VIDEO_END;
658 650
659 /* Recout */ 651 /* Recout */
660 dpp_set_recout(xfm, &scl_data->recout); 652 dpp1_dscl_set_recout(dpp, &scl_data->recout);
661 653
662 /* MPC Size */ 654 /* MPC Size */
663 REG_SET_2(MPC_SIZE, 0, 655 REG_SET_2(MPC_SIZE, 0,
@@ -673,8 +665,8 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
673 return; 665 return;
674 666
675 /* LB */ 667 /* LB */
676 lb_config = find_lb_memory_config(xfm, scl_data); 668 lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
677 dpp_set_lb(xfm, &scl_data->lb_params, lb_config); 669 dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
678 670
679 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) 671 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
680 return; 672 return;
@@ -697,7 +689,7 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
697 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); 689 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
698 690
699 /* Manually calculate scale ratio and init values */ 691 /* Manually calculate scale ratio and init values */
700 dpp_set_manual_ratio_init(xfm, scl_data); 692 dpp1_dscl_set_manual_ratio_init(dpp, scl_data);
701 693
702 /* HTaps/VTaps */ 694 /* HTaps/VTaps */
703 REG_SET_4(SCL_TAP_CONTROL, 0, 695 REG_SET_4(SCL_TAP_CONTROL, 0,
@@ -706,5 +698,5 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
706 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, 698 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
707 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); 699 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
708 700
709 dpp_set_scl_filter(xfm, scl_data, ycbcr); 701 dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
710} 702}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index a28495d95a15..b13dee64e0ce 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -24,23 +24,23 @@
24 */ 24 */
25#include "dm_services.h" 25#include "dm_services.h"
26#include "dce_calcs.h" 26#include "dce_calcs.h"
27#include "dcn10_mem_input.h"
28#include "reg_helper.h" 27#include "reg_helper.h"
29#include "basics/conversion.h" 28#include "basics/conversion.h"
29#include "dcn10_hubp.h"
30 30
31#define REG(reg)\ 31#define REG(reg)\
32 mi->mi_regs->reg 32 hubp1->mi_regs->reg
33 33
34#define CTX \ 34#define CTX \
35 mi->base.ctx 35 hubp1->base.ctx
36 36
37#undef FN 37#undef FN
38#define FN(reg_name, field_name) \ 38#define FN(reg_name, field_name) \
39 mi->mi_shift->field_name, mi->mi_mask->field_name 39 hubp1->mi_shift->field_name, hubp1->mi_mask->field_name
40 40
41static void min10_set_blank(struct mem_input *mem_input, bool blank) 41void hubp1_set_blank(struct hubp *hubp, bool blank)
42{ 42{
43 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 43 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
44 uint32_t blank_en = blank ? 1 : 0; 44 uint32_t blank_en = blank ? 1 : 0;
45 45
46 REG_UPDATE_2(DCHUBP_CNTL, 46 REG_UPDATE_2(DCHUBP_CNTL,
@@ -51,24 +51,24 @@ static void min10_set_blank(struct mem_input *mem_input, bool blank)
51 REG_WAIT(DCHUBP_CNTL, 51 REG_WAIT(DCHUBP_CNTL,
52 HUBP_NO_OUTSTANDING_REQ, 1, 52 HUBP_NO_OUTSTANDING_REQ, 1,
53 1, 200); 53 1, 200);
54 mem_input->mpcc_id = 0xf; 54 hubp->mpcc_id = 0xf;
55 mem_input->opp_id = 0xf; 55 hubp->opp_id = 0xf;
56 } 56 }
57} 57}
58 58
59static void min10_set_hubp_blank_en(struct mem_input *mem_input, bool blank) 59static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
60{ 60{
61 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 61 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
62 uint32_t blank_en = blank ? 1 : 0; 62 uint32_t blank_en = blank ? 1 : 0;
63 63
64 REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en); 64 REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
65} 65}
66 66
67static void min10_vready_workaround(struct mem_input *mem_input, 67static void hubp1_vready_workaround(struct hubp *hubp,
68 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest) 68 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
69{ 69{
70 uint32_t value = 0; 70 uint32_t value = 0;
71 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 71 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
72 72
73 /* set HBUBREQ_DEBUG_DB[12] = 1 */ 73 /* set HBUBREQ_DEBUG_DB[12] = 1 */
74 value = REG_READ(HUBPREQ_DEBUG_DB); 74 value = REG_READ(HUBPREQ_DEBUG_DB);
@@ -87,8 +87,8 @@ static void min10_vready_workaround(struct mem_input *mem_input,
87 REG_WRITE(HUBPREQ_DEBUG_DB, value); 87 REG_WRITE(HUBPREQ_DEBUG_DB, value);
88} 88}
89 89
90static void min10_program_tiling( 90void hubp1_program_tiling(
91 struct dcn10_mem_input *mi, 91 struct dcn10_hubp *hubp1,
92 const union dc_tiling_info *info, 92 const union dc_tiling_info *info,
93 const enum surface_pixel_format pixel_format) 93 const enum surface_pixel_format pixel_format)
94{ 94{
@@ -107,8 +107,8 @@ static void min10_program_tiling(
107 PIPE_ALIGNED, info->gfx9.pipe_aligned); 107 PIPE_ALIGNED, info->gfx9.pipe_aligned);
108} 108}
109 109
110static void min10_program_size_and_rotation( 110void hubp1_program_size_and_rotation(
111 struct dcn10_mem_input *mi, 111 struct dcn10_hubp *hubp1,
112 enum dc_rotation_angle rotation, 112 enum dc_rotation_angle rotation,
113 enum surface_pixel_format format, 113 enum surface_pixel_format format,
114 const union plane_size *plane_size, 114 const union plane_size *plane_size,
@@ -169,8 +169,8 @@ static void min10_program_size_and_rotation(
169 H_MIRROR_EN, mirror); 169 H_MIRROR_EN, mirror);
170} 170}
171 171
172static void min10_program_pixel_format( 172void hubp1_program_pixel_format(
173 struct dcn10_mem_input *mi, 173 struct dcn10_hubp *hubp1,
174 enum surface_pixel_format format) 174 enum surface_pixel_format format)
175{ 175{
176 uint32_t red_bar = 3; 176 uint32_t red_bar = 3;
@@ -245,12 +245,12 @@ static void min10_program_pixel_format(
245 /* don't see the need of program the xbar in DCN 1.0 */ 245 /* don't see the need of program the xbar in DCN 1.0 */
246} 246}
247 247
248static bool min10_program_surface_flip_and_addr( 248bool hubp1_program_surface_flip_and_addr(
249 struct mem_input *mem_input, 249 struct hubp *hubp,
250 const struct dc_plane_address *address, 250 const struct dc_plane_address *address,
251 bool flip_immediate) 251 bool flip_immediate)
252{ 252{
253 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 253 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
254 254
255 /* program flip type */ 255 /* program flip type */
256 REG_SET(DCSURF_FLIP_CONTROL, 0, 256 REG_SET(DCSURF_FLIP_CONTROL, 0,
@@ -387,28 +387,28 @@ static bool min10_program_surface_flip_and_addr(
387 break; 387 break;
388 } 388 }
389 389
390 mem_input->request_address = *address; 390 hubp->request_address = *address;
391 391
392 if (flip_immediate) 392 if (flip_immediate)
393 mem_input->current_address = *address; 393 hubp->current_address = *address;
394 394
395 return true; 395 return true;
396} 396}
397 397
398static void min10_dcc_control(struct mem_input *mem_input, bool enable, 398void hubp1_dcc_control(struct hubp *hubp, bool enable,
399 bool independent_64b_blks) 399 bool independent_64b_blks)
400{ 400{
401 uint32_t dcc_en = enable ? 1 : 0; 401 uint32_t dcc_en = enable ? 1 : 0;
402 uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0; 402 uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
403 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 403 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
404 404
405 REG_UPDATE_2(DCSURF_SURFACE_CONTROL, 405 REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
406 PRIMARY_SURFACE_DCC_EN, dcc_en, 406 PRIMARY_SURFACE_DCC_EN, dcc_en,
407 PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk); 407 PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
408} 408}
409 409
410static void min10_program_surface_config( 410void hubp1_program_surface_config(
411 struct mem_input *mem_input, 411 struct hubp *hubp,
412 enum surface_pixel_format format, 412 enum surface_pixel_format format,
413 union dc_tiling_info *tiling_info, 413 union dc_tiling_info *tiling_info,
414 union plane_size *plane_size, 414 union plane_size *plane_size,
@@ -416,20 +416,20 @@ static void min10_program_surface_config(
416 struct dc_plane_dcc_param *dcc, 416 struct dc_plane_dcc_param *dcc,
417 bool horizontal_mirror) 417 bool horizontal_mirror)
418{ 418{
419 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 419 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
420 420
421 min10_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks); 421 hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
422 min10_program_tiling(mi, tiling_info, format); 422 hubp1_program_tiling(hubp1, tiling_info, format);
423 min10_program_size_and_rotation( 423 hubp1_program_size_and_rotation(
424 mi, rotation, format, plane_size, dcc, horizontal_mirror); 424 hubp1, rotation, format, plane_size, dcc, horizontal_mirror);
425 min10_program_pixel_format(mi, format); 425 hubp1_program_pixel_format(hubp1, format);
426} 426}
427 427
428static void min10_program_requestor( 428void hubp1_program_requestor(
429 struct mem_input *mem_input, 429 struct hubp *hubp,
430 struct _vcs_dpi_display_rq_regs_st *rq_regs) 430 struct _vcs_dpi_display_rq_regs_st *rq_regs)
431{ 431{
432 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 432 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
433 433
434 REG_UPDATE(HUBPRET_CONTROL, 434 REG_UPDATE(HUBPRET_CONTROL,
435 DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address); 435 DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
@@ -459,12 +459,12 @@ static void min10_program_requestor(
459} 459}
460 460
461 461
462static void min10_program_deadline( 462void hubp1_program_deadline(
463 struct mem_input *mem_input, 463 struct hubp *hubp,
464 struct _vcs_dpi_display_dlg_regs_st *dlg_attr, 464 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
465 struct _vcs_dpi_display_ttu_regs_st *ttu_attr) 465 struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
466{ 466{
467 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 467 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
468 468
469 /* DLG - Per hubp */ 469 /* DLG - Per hubp */
470 REG_SET_2(BLANK_OFFSET_0, 0, 470 REG_SET_2(BLANK_OFFSET_0, 0,
@@ -580,8 +580,8 @@ static void min10_program_deadline(
580 ttu_attr->refcyc_per_req_delivery_pre_c); 580 ttu_attr->refcyc_per_req_delivery_pre_c);
581} 581}
582 582
583static void min10_setup( 583static void hubp1_setup(
584 struct mem_input *mem_input, 584 struct hubp *hubp,
585 struct _vcs_dpi_display_dlg_regs_st *dlg_attr, 585 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
586 struct _vcs_dpi_display_ttu_regs_st *ttu_attr, 586 struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
587 struct _vcs_dpi_display_rq_regs_st *rq_regs, 587 struct _vcs_dpi_display_rq_regs_st *rq_regs,
@@ -590,27 +590,15 @@ static void min10_setup(
590 /* otg is locked when this func is called. Register are double buffered. 590 /* otg is locked when this func is called. Register are double buffered.
591 * disable the requestors is not needed 591 * disable the requestors is not needed
592 */ 592 */
593 min10_program_requestor(mem_input, rq_regs); 593 hubp1_program_requestor(hubp, rq_regs);
594 min10_program_deadline(mem_input, dlg_attr, ttu_attr); 594 hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
595 min10_vready_workaround(mem_input, pipe_dest); 595 hubp1_vready_workaround(hubp, pipe_dest);
596} 596}
597 597
598static void min10_program_display_marks( 598bool hubp1_is_flip_pending(struct hubp *hubp)
599 struct mem_input *mem_input,
600 struct dce_watermarks nbp,
601 struct dce_watermarks stutter,
602 struct dce_watermarks urgent,
603 uint32_t total_dest_line_time_ns)
604{
605 /* only for dce
606 * dcn use only program_watermarks
607 */
608}
609
610static bool min10_is_flip_pending(struct mem_input *mem_input)
611{ 599{
612 uint32_t flip_pending = 0; 600 uint32_t flip_pending = 0;
613 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 601 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
614 struct dc_plane_address earliest_inuse_address; 602 struct dc_plane_address earliest_inuse_address;
615 603
616 REG_GET(DCSURF_FLIP_CONTROL, 604 REG_GET(DCSURF_FLIP_CONTROL,
@@ -625,17 +613,20 @@ static bool min10_is_flip_pending(struct mem_input *mem_input)
625 if (flip_pending) 613 if (flip_pending)
626 return true; 614 return true;
627 615
628 if (earliest_inuse_address.grph.addr.quad_part != mem_input->request_address.grph.addr.quad_part) 616 if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
629 return true; 617 return true;
630 618
631 mem_input->current_address = mem_input->request_address; 619 hubp->current_address = hubp->request_address;
632 return false; 620 return false;
633} 621}
634 622
635static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input, 623uint32_t aperture_default_system = 1;
624uint32_t context0_default_system; /* = 0;*/
625
626static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
636 struct vm_system_aperture_param *apt) 627 struct vm_system_aperture_param *apt)
637{ 628{
638 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 629 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
639 PHYSICAL_ADDRESS_LOC mc_vm_apt_default; 630 PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
640 PHYSICAL_ADDRESS_LOC mc_vm_apt_low; 631 PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
641 PHYSICAL_ADDRESS_LOC mc_vm_apt_high; 632 PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
@@ -645,7 +636,7 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
645 mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12; 636 mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
646 637
647 REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0, 638 REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
648 MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, 1, /* 1 = system physical memory */ 639 MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */
649 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part); 640 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
650 REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0, 641 REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
651 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part); 642 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,
661 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part); 652 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
662} 653}
663 654
664static void min10_set_vm_context0_settings(struct mem_input *mem_input, 655static void hubp1_set_vm_context0_settings(struct hubp *hubp,
665 const struct vm_context0_param *vm0) 656 const struct vm_context0_param *vm0)
666{ 657{
667 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 658 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
668 /* pte base */ 659 /* pte base */
669 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0, 660 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
670 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part); 661 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,
684 VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part); 675 VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
685 676
686 /* fault handling */ 677 /* fault handling */
687 REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0, 678 REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
688 VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->fault_default.high_part); 679 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
689 /* VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, 0 */ 680 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
690 REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0, 681 REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
691 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part); 682 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
692 683
@@ -696,12 +687,12 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
696 SYSTEM_ACCESS_MODE, 3); 687 SYSTEM_ACCESS_MODE, 3);
697} 688}
698 689
699static void min_set_viewport( 690void min_set_viewport(
700 struct mem_input *mem_input, 691 struct hubp *hubp,
701 const struct rect *viewport, 692 const struct rect *viewport,
702 const struct rect *viewport_c) 693 const struct rect *viewport_c)
703{ 694{
704 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 695 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
705 696
706 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0, 697 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
707 PRI_VIEWPORT_WIDTH, viewport->width, 698 PRI_VIEWPORT_WIDTH, viewport->width,
@@ -730,7 +721,7 @@ static void min_set_viewport(
730 PRI_VIEWPORT_Y_START_C, viewport_c->y); 721 PRI_VIEWPORT_Y_START_C, viewport_c->y);
731} 722}
732 723
733void dcn10_mem_input_read_state(struct dcn10_mem_input *mi, 724void hubp1_read_state(struct dcn10_hubp *hubp1,
734 struct dcn_hubp_state *s) 725 struct dcn_hubp_state *s)
735{ 726{
736 REG_GET(DCSURF_SURFACE_CONFIG, 727 REG_GET(DCSURF_SURFACE_CONFIG,
@@ -766,41 +757,204 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
766 QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm); 757 QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
767} 758}
768 759
769static struct mem_input_funcs dcn10_mem_input_funcs = { 760enum cursor_pitch {
770 .mem_input_program_display_marks = min10_program_display_marks, 761 CURSOR_PITCH_64_PIXELS = 0,
771 .mem_input_program_surface_flip_and_addr = 762 CURSOR_PITCH_128_PIXELS,
772 min10_program_surface_flip_and_addr, 763 CURSOR_PITCH_256_PIXELS
773 .mem_input_program_surface_config = 764};
774 min10_program_surface_config, 765
775 .mem_input_is_flip_pending = min10_is_flip_pending, 766enum cursor_lines_per_chunk {
776 .mem_input_setup = min10_setup, 767 CURSOR_LINE_PER_CHUNK_2 = 1,
777 .mem_input_set_vm_system_aperture_settings = min10_set_vm_system_aperture_settings, 768 CURSOR_LINE_PER_CHUNK_4,
778 .mem_input_set_vm_context0_settings = min10_set_vm_context0_settings, 769 CURSOR_LINE_PER_CHUNK_8,
779 .set_blank = min10_set_blank, 770 CURSOR_LINE_PER_CHUNK_16
780 .dcc_control = min10_dcc_control, 771};
772
773static bool ippn10_cursor_program_control(
774 struct dcn10_hubp *hubp1,
775 bool pixel_data_invert,
776 enum dc_cursor_color_format color_format)
777{
778 if (REG(CURSOR_SETTINS))
779 REG_SET_2(CURSOR_SETTINS, 0,
780 /* no shift of the cursor HDL schedule */
781 CURSOR0_DST_Y_OFFSET, 0,
782 /* used to shift the cursor chunk request deadline */
783 CURSOR0_CHUNK_HDL_ADJUST, 3);
784 else
785 REG_SET_2(CURSOR_SETTINGS, 0,
786 /* no shift of the cursor HDL schedule */
787 CURSOR0_DST_Y_OFFSET, 0,
788 /* used to shift the cursor chunk request deadline */
789 CURSOR0_CHUNK_HDL_ADJUST, 3);
790
791 return true;
792}
793
794static enum cursor_pitch ippn10_get_cursor_pitch(
795 unsigned int pitch)
796{
797 enum cursor_pitch hw_pitch;
798
799 switch (pitch) {
800 case 64:
801 hw_pitch = CURSOR_PITCH_64_PIXELS;
802 break;
803 case 128:
804 hw_pitch = CURSOR_PITCH_128_PIXELS;
805 break;
806 case 256:
807 hw_pitch = CURSOR_PITCH_256_PIXELS;
808 break;
809 default:
810 DC_ERR("Invalid cursor pitch of %d. "
811 "Only 64/128/256 is supported on DCN.\n", pitch);
812 hw_pitch = CURSOR_PITCH_64_PIXELS;
813 break;
814 }
815 return hw_pitch;
816}
817
818static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
819 unsigned int cur_width,
820 enum dc_cursor_color_format format)
821{
822 enum cursor_lines_per_chunk line_per_chunk;
823
824 if (format == CURSOR_MODE_MONO)
825 /* impl B. expansion in CUR Buffer reader */
826 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
827 else if (cur_width <= 32)
828 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
829 else if (cur_width <= 64)
830 line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
831 else if (cur_width <= 128)
832 line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
833 else
834 line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
835
836 return line_per_chunk;
837}
838
839void hubp1_cursor_set_attributes(
840 struct hubp *hubp,
841 const struct dc_cursor_attributes *attr)
842{
843 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
844 enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
845 enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
846 attr->width, attr->color_format);
847
848 hubp->curs_attr = *attr;
849
850 REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
851 CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
852 REG_UPDATE(CURSOR_SURFACE_ADDRESS,
853 CURSOR_SURFACE_ADDRESS, attr->address.low_part);
854
855 REG_UPDATE_2(CURSOR_SIZE,
856 CURSOR_WIDTH, attr->width,
857 CURSOR_HEIGHT, attr->height);
858 REG_UPDATE_3(CURSOR_CONTROL,
859 CURSOR_MODE, attr->color_format,
860 CURSOR_PITCH, hw_pitch,
861 CURSOR_LINES_PER_CHUNK, lpc);
862 ippn10_cursor_program_control(hubp1,
863 attr->attribute_flags.bits.INVERT_PIXEL_DATA,
864 attr->color_format);
865}
866
867void hubp1_cursor_set_position(
868 struct hubp *hubp,
869 const struct dc_cursor_position *pos,
870 const struct dc_cursor_mi_param *param)
871{
872 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
873 int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
874 uint32_t cur_en = pos->enable ? 1 : 0;
875 uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
876
877 /*
878 * Guard aganst cursor_set_position() from being called with invalid
879 * attributes
880 *
881 * TODO: Look at combining cursor_set_position() and
882 * cursor_set_attributes() into cursor_update()
883 */
884 if (hubp->curs_attr.address.quad_part == 0)
885 return;
886
887 dst_x_offset *= param->ref_clk_khz;
888 dst_x_offset /= param->pixel_clk_khz;
889
890 ASSERT(param->h_scale_ratio.value);
891
892 if (param->h_scale_ratio.value)
893 dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
894 dal_fixed31_32_from_int(dst_x_offset),
895 param->h_scale_ratio));
896
897 if (src_x_offset >= (int)param->viewport_width)
898 cur_en = 0; /* not visible beyond right edge*/
899
900 if (src_x_offset + (int)hubp->curs_attr.width < 0)
901 cur_en = 0; /* not visible beyond left edge*/
902
903 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
904 hubp1_cursor_set_attributes(hubp, &hubp->curs_attr);
905 REG_UPDATE(CURSOR_CONTROL,
906 CURSOR_ENABLE, cur_en);
907
908 REG_SET_2(CURSOR_POSITION, 0,
909 CURSOR_X_POSITION, pos->x,
910 CURSOR_Y_POSITION, pos->y);
911
912 REG_SET_2(CURSOR_HOT_SPOT, 0,
913 CURSOR_HOT_SPOT_X, pos->x_hotspot,
914 CURSOR_HOT_SPOT_Y, pos->y_hotspot);
915
916 REG_SET(CURSOR_DST_OFFSET, 0,
917 CURSOR_DST_X_OFFSET, dst_x_offset);
918 /* TODO Handle surface pixel formats other than 4:4:4 */
919}
920
921static struct hubp_funcs dcn10_hubp_funcs = {
922 .hubp_program_surface_flip_and_addr =
923 hubp1_program_surface_flip_and_addr,
924 .hubp_program_surface_config =
925 hubp1_program_surface_config,
926 .hubp_is_flip_pending = hubp1_is_flip_pending,
927 .hubp_setup = hubp1_setup,
928 .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
929 .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
930 .set_blank = hubp1_set_blank,
931 .dcc_control = hubp1_dcc_control,
781 .mem_program_viewport = min_set_viewport, 932 .mem_program_viewport = min_set_viewport,
782 .set_hubp_blank_en = min10_set_hubp_blank_en, 933 .set_hubp_blank_en = hubp1_set_hubp_blank_en,
934 .set_cursor_attributes = hubp1_cursor_set_attributes,
935 .set_cursor_position = hubp1_cursor_set_position,
783}; 936};
784 937
785/*****************************************/ 938/*****************************************/
786/* Constructor, Destructor */ 939/* Constructor, Destructor */
787/*****************************************/ 940/*****************************************/
788 941
789void dcn10_mem_input_construct( 942void dcn10_hubp_construct(
790 struct dcn10_mem_input *mi, 943 struct dcn10_hubp *hubp1,
791 struct dc_context *ctx, 944 struct dc_context *ctx,
792 uint32_t inst, 945 uint32_t inst,
793 const struct dcn_mi_registers *mi_regs, 946 const struct dcn_mi_registers *mi_regs,
794 const struct dcn_mi_shift *mi_shift, 947 const struct dcn_mi_shift *mi_shift,
795 const struct dcn_mi_mask *mi_mask) 948 const struct dcn_mi_mask *mi_mask)
796{ 949{
797 mi->base.funcs = &dcn10_mem_input_funcs; 950 hubp1->base.funcs = &dcn10_hubp_funcs;
798 mi->base.ctx = ctx; 951 hubp1->base.ctx = ctx;
799 mi->mi_regs = mi_regs; 952 hubp1->mi_regs = mi_regs;
800 mi->mi_shift = mi_shift; 953 hubp1->mi_shift = mi_shift;
801 mi->mi_mask = mi_mask; 954 hubp1->mi_mask = mi_mask;
802 mi->base.inst = inst; 955 hubp1->base.inst = inst;
803 mi->base.opp_id = 0xf; 956 hubp1->base.opp_id = 0xf;
804 mi->base.mpcc_id = 0xf; 957 hubp1->base.mpcc_id = 0xf;
805} 958}
806 959
960
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index aefd3e7bd7eb..66db453c801b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -25,11 +25,10 @@
25#ifndef __DC_MEM_INPUT_DCN10_H__ 25#ifndef __DC_MEM_INPUT_DCN10_H__
26#define __DC_MEM_INPUT_DCN10_H__ 26#define __DC_MEM_INPUT_DCN10_H__
27 27
28#include "mem_input.h" 28#include "hubp.h"
29
30#define TO_DCN10_MEM_INPUT(mi)\
31 container_of(mi, struct dcn10_mem_input, base)
32 29
30#define TO_DCN10_HUBP(hubp)\
31 container_of(hubp, struct dcn10_hubp, base)
33 32
34#define MI_REG_LIST_DCN(id)\ 33#define MI_REG_LIST_DCN(id)\
35 SRI(DCHUBP_CNTL, HUBP, id),\ 34 SRI(DCHUBP_CNTL, HUBP, id),\
@@ -118,7 +117,17 @@
118 SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\ 117 SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
119 SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\ 118 SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
120 SR(DCHUBBUB_SDPIF_FB_BASE),\ 119 SR(DCHUBBUB_SDPIF_FB_BASE),\
121 SR(DCHUBBUB_SDPIF_FB_OFFSET) 120 SR(DCHUBBUB_SDPIF_FB_OFFSET),\
121 SRI(CURSOR_SETTINS, HUBPREQ, id), \
122 SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
123 SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
124 SRI(CURSOR_SIZE, CURSOR, id), \
125 SRI(CURSOR_CONTROL, CURSOR, id), \
126 SRI(CURSOR_POSITION, CURSOR, id), \
127 SRI(CURSOR_HOT_SPOT, CURSOR, id), \
128 SRI(CURSOR_DST_OFFSET, CURSOR, id)
129
130
122 131
123struct dcn_mi_registers { 132struct dcn_mi_registers {
124 uint32_t DCHUBP_CNTL; 133 uint32_t DCHUBP_CNTL;
@@ -215,6 +224,15 @@ struct dcn_mi_registers {
215 uint32_t DCN_VM_AGP_BASE; 224 uint32_t DCN_VM_AGP_BASE;
216 uint32_t DCN_VM_AGP_BOT; 225 uint32_t DCN_VM_AGP_BOT;
217 uint32_t DCN_VM_AGP_TOP; 226 uint32_t DCN_VM_AGP_TOP;
227 uint32_t CURSOR_SETTINS;
228 uint32_t CURSOR_SETTINGS;
229 uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
230 uint32_t CURSOR_SURFACE_ADDRESS;
231 uint32_t CURSOR_SIZE;
232 uint32_t CURSOR_CONTROL;
233 uint32_t CURSOR_POSITION;
234 uint32_t CURSOR_HOT_SPOT;
235 uint32_t CURSOR_DST_OFFSET;
218}; 236};
219 237
220#define MI_SF(reg_name, field_name, post_fix)\ 238#define MI_SF(reg_name, field_name, post_fix)\
@@ -351,6 +369,7 @@ struct dcn_mi_registers {
351 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\ 369 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\
352 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\ 370 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\
353 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\ 371 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\
372 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, mask_sh),\
354 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\ 373 MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\
355 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\ 374 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\
356 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\ 375 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 {
360 MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\ 379 MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
361 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\ 380 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
362 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\ 381 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
363 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh) 382 MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
383 MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
384 MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
385 MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
386 MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
387 MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
388 MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
389 MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
390 MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
391 MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
392 MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
393 MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
394 MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
395 MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
396 MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
397 MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
398 MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
364 399
365#define DCN_MI_REG_FIELD_LIST(type) \ 400#define DCN_MI_REG_FIELD_LIST(type) \
366 type HUBP_BLANK_EN;\ 401 type HUBP_BLANK_EN;\
@@ -488,6 +523,7 @@ struct dcn_mi_registers {
488 type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\ 523 type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\
489 type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\ 524 type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\
490 type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\ 525 type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\
526 type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM;\
491 type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\ 527 type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\
492 type ENABLE_L1_TLB;\ 528 type ENABLE_L1_TLB;\
493 type SYSTEM_ACCESS_MODE;\ 529 type SYSTEM_ACCESS_MODE;\
@@ -521,7 +557,24 @@ struct dcn_mi_registers {
521 type PHYSICAL_PAGE_ADDR_LO32;\ 557 type PHYSICAL_PAGE_ADDR_LO32;\
522 type PHYSICAL_PAGE_NUMBER_MSB;\ 558 type PHYSICAL_PAGE_NUMBER_MSB;\
523 type PHYSICAL_PAGE_NUMBER_LSB;\ 559 type PHYSICAL_PAGE_NUMBER_LSB;\
524 type LOGICAL_ADDR 560 type LOGICAL_ADDR;\
561 type CURSOR0_DST_Y_OFFSET; \
562 type CURSOR0_CHUNK_HDL_ADJUST; \
563 type CURSOR_SURFACE_ADDRESS_HIGH; \
564 type CURSOR_SURFACE_ADDRESS; \
565 type CURSOR_WIDTH; \
566 type CURSOR_HEIGHT; \
567 type CURSOR_MODE; \
568 type CURSOR_2X_MAGNIFY; \
569 type CURSOR_PITCH; \
570 type CURSOR_LINES_PER_CHUNK; \
571 type CURSOR_ENABLE; \
572 type CURSOR_X_POSITION; \
573 type CURSOR_Y_POSITION; \
574 type CURSOR_HOT_SPOT_X; \
575 type CURSOR_HOT_SPOT_Y; \
576 type CURSOR_DST_X_OFFSET; \
577 type OUTPUT_FP
525 578
526struct dcn_mi_shift { 579struct dcn_mi_shift {
527 DCN_MI_REG_FIELD_LIST(uint8_t); 580 DCN_MI_REG_FIELD_LIST(uint8_t);
@@ -531,21 +584,83 @@ struct dcn_mi_mask {
531 DCN_MI_REG_FIELD_LIST(uint32_t); 584 DCN_MI_REG_FIELD_LIST(uint32_t);
532}; 585};
533 586
534struct dcn10_mem_input { 587struct dcn10_hubp {
535 struct mem_input base; 588 struct hubp base;
536 const struct dcn_mi_registers *mi_regs; 589 const struct dcn_mi_registers *mi_regs;
537 const struct dcn_mi_shift *mi_shift; 590 const struct dcn_mi_shift *mi_shift;
538 const struct dcn_mi_mask *mi_mask; 591 const struct dcn_mi_mask *mi_mask;
539}; 592};
540 593
541void dcn10_mem_input_construct( 594void hubp1_program_surface_config(
542 struct dcn10_mem_input *mi, 595 struct hubp *hubp,
596 enum surface_pixel_format format,
597 union dc_tiling_info *tiling_info,
598 union plane_size *plane_size,
599 enum dc_rotation_angle rotation,
600 struct dc_plane_dcc_param *dcc,
601 bool horizontal_mirror);
602
603void hubp1_program_deadline(
604 struct hubp *hubp,
605 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
606 struct _vcs_dpi_display_ttu_regs_st *ttu_attr);
607
608void hubp1_program_requestor(
609 struct hubp *hubp,
610 struct _vcs_dpi_display_rq_regs_st *rq_regs);
611
612void hubp1_program_pixel_format(
613 struct dcn10_hubp *hubp,
614 enum surface_pixel_format format);
615
616void hubp1_program_size_and_rotation(
617 struct dcn10_hubp *hubp,
618 enum dc_rotation_angle rotation,
619 enum surface_pixel_format format,
620 const union plane_size *plane_size,
621 struct dc_plane_dcc_param *dcc,
622 bool horizontal_mirror);
623
624void hubp1_program_tiling(
625 struct dcn10_hubp *hubp,
626 const union dc_tiling_info *info,
627 const enum surface_pixel_format pixel_format);
628
629void hubp1_dcc_control(struct hubp *hubp,
630 bool enable,
631 bool independent_64b_blks);
632
633bool hubp1_program_surface_flip_and_addr(
634 struct hubp *hubp,
635 const struct dc_plane_address *address,
636 bool flip_immediate);
637
638bool hubp1_is_flip_pending(struct hubp *hubp);
639
640void hubp1_cursor_set_attributes(
641 struct hubp *hubp,
642 const struct dc_cursor_attributes *attr);
643
644void hubp1_cursor_set_position(
645 struct hubp *hubp,
646 const struct dc_cursor_position *pos,
647 const struct dc_cursor_mi_param *param);
648
649void hubp1_set_blank(struct hubp *hubp, bool blank);
650
651void min_set_viewport(struct hubp *hubp,
652 const struct rect *viewport,
653 const struct rect *viewport_c);
654
655void dcn10_hubp_construct(
656 struct dcn10_hubp *hubp1,
543 struct dc_context *ctx, 657 struct dc_context *ctx,
544 uint32_t inst, 658 uint32_t inst,
545 const struct dcn_mi_registers *mi_regs, 659 const struct dcn_mi_registers *mi_regs,
546 const struct dcn_mi_shift *mi_shift, 660 const struct dcn_mi_shift *mi_shift,
547 const struct dcn_mi_mask *mi_mask); 661 const struct dcn_mi_mask *mi_mask);
548 662
663
549struct dcn_hubp_state { 664struct dcn_hubp_state {
550 uint32_t pixel_format; 665 uint32_t pixel_format;
551 uint32_t inuse_addr_hi; 666 uint32_t inuse_addr_hi;
@@ -562,7 +677,7 @@ struct dcn_hubp_state {
562 uint32_t qos_level_low_wm; 677 uint32_t qos_level_low_wm;
563 uint32_t qos_level_high_wm; 678 uint32_t qos_level_high_wm;
564}; 679};
565void dcn10_mem_input_read_state(struct dcn10_mem_input *mi, 680void hubp1_read_state(struct dcn10_hubp *hubp1,
566 struct dcn_hubp_state *s); 681 struct dcn_hubp_state *s);
567 682
568#endif 683#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index d3fee15aeb79..63c2f5266142 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -31,7 +31,6 @@
31#include "dce110/dce110_hw_sequencer.h" 31#include "dce110/dce110_hw_sequencer.h"
32#include "dce/dce_hwseq.h" 32#include "dce/dce_hwseq.h"
33#include "abm.h" 33#include "abm.h"
34#include "dcn10/dcn10_mem_input.h"
35#include "dcn10/dcn10_timing_generator.h" 34#include "dcn10/dcn10_timing_generator.h"
36#include "dcn10/dcn10_dpp.h" 35#include "dcn10/dcn10_dpp.h"
37#include "dcn10/dcn10_mpc.h" 36#include "dcn10/dcn10_mpc.h"
@@ -41,6 +40,7 @@
41#include "mpc.h" 40#include "mpc.h"
42#include "reg_helper.h" 41#include "reg_helper.h"
43#include "custom_float.h" 42#include "custom_float.h"
43#include "dcn10_hubp.h"
44 44
45#define CTX \ 45#define CTX \
46 hws->ctx 46 hws->ctx
@@ -172,10 +172,10 @@ static void dcn10_log_hw_state(struct dc *dc)
172 "min_ttu_vblank \t qos_low_wm \t qos_high_wm \n"); 172 "min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
173 173
174 for (i = 0; i < pool->pipe_count; i++) { 174 for (i = 0; i < pool->pipe_count; i++) {
175 struct mem_input *mi = pool->mis[i]; 175 struct hubp *hubp = pool->hubps[i];
176 struct dcn_hubp_state s; 176 struct dcn_hubp_state s;
177 177
178 dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s); 178 hubp1_read_state(TO_DCN10_HUBP(hubp), &s);
179 179
180 DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t " 180 DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t "
181 "%xh \t %xh \t %xh \t " 181 "%xh \t %xh \t %xh \t "
@@ -245,15 +245,19 @@ static void verify_allow_pstate_change_high(
245{ 245{
246 /* pstate latency is ~20us so if we wait over 40us and pstate allow 246 /* pstate latency is ~20us so if we wait over 40us and pstate allow
247 * still not asserted, we are probably stuck and going to hang 247 * still not asserted, we are probably stuck and going to hang
248 *
249 * TODO: Figure out why it takes ~100us on linux
250 * pstate takes around ~100us on linux. Unknown currently as to
251 * why it takes that long on linux
248 */ 252 */
249 static unsigned int pstate_wait_timeout_us = 40; 253 static unsigned int pstate_wait_timeout_us = 200;
254 static unsigned int pstate_wait_expected_timeout_us = 40;
250 static unsigned int max_sampled_pstate_wait_us; /* data collection */ 255 static unsigned int max_sampled_pstate_wait_us; /* data collection */
251 static bool forced_pstate_allow; /* help with revert wa */ 256 static bool forced_pstate_allow; /* help with revert wa */
252 static bool should_log_hw_state; /* prevent hw state log by default */ 257 static bool should_log_hw_state; /* prevent hw state log by default */
253 258
254 unsigned int debug_index = 0x7; 259 unsigned int debug_index = 0x7;
255 unsigned int debug_data; 260 unsigned int debug_data;
256 unsigned int force_allow_pstate = 0x30;
257 unsigned int i; 261 unsigned int i;
258 262
259 if (forced_pstate_allow) { 263 if (forced_pstate_allow) {
@@ -261,7 +265,9 @@ static void verify_allow_pstate_change_high(
261 * we verify_allow_pstate_change_high. so disable force 265 * we verify_allow_pstate_change_high. so disable force
262 * here so we can check status 266 * here so we can check status
263 */ 267 */
264 REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0); 268 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
269 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
270 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
265 forced_pstate_allow = false; 271 forced_pstate_allow = false;
266 } 272 }
267 273
@@ -292,9 +298,15 @@ static void verify_allow_pstate_change_high(
292 for (i = 0; i < pstate_wait_timeout_us; i++) { 298 for (i = 0; i < pstate_wait_timeout_us; i++) {
293 debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA); 299 debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
294 300
295 if (debug_data & (1 << 30)) 301 if (debug_data & (1 << 30)) {
296 return; 302
303 if (i > pstate_wait_expected_timeout_us)
304 dm_logger_write(hws->ctx->logger, LOG_WARNING,
305 "pstate took longer than expected ~%dus\n",
306 i);
297 307
308 return;
309 }
298 if (max_sampled_pstate_wait_us < i) 310 if (max_sampled_pstate_wait_us < i)
299 max_sampled_pstate_wait_us = i; 311 max_sampled_pstate_wait_us = i;
300 312
@@ -304,13 +316,18 @@ static void verify_allow_pstate_change_high(
304 /* force pstate allow to prevent system hang 316 /* force pstate allow to prevent system hang
305 * and break to debugger to investigate 317 * and break to debugger to investigate
306 */ 318 */
307 REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate); 319 REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
320 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
321 DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
308 forced_pstate_allow = true; 322 forced_pstate_allow = true;
309 323
310 if (should_log_hw_state) { 324 if (should_log_hw_state) {
311 dcn10_log_hw_state(hws->ctx->dc); 325 dcn10_log_hw_state(hws->ctx->dc);
312 } 326 }
313 327
328 dm_logger_write(hws->ctx->logger, LOG_WARNING,
329 "pstate TEST_DEBUG_DATA: 0x%X\n",
330 debug_data);
314 BREAK_TO_DEBUGGER(); 331 BREAK_TO_DEBUGGER();
315} 332}
316 333
@@ -451,7 +468,7 @@ static void program_watermarks(
451 refclk_mhz, 0x1fffff); 468 refclk_mhz, 0x1fffff);
452 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); 469 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
453 470
454 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 471 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
455 "URGENCY_WATERMARK_A calculated =%d\n" 472 "URGENCY_WATERMARK_A calculated =%d\n"
456 "HW register value = 0x%x\n", 473 "HW register value = 0x%x\n",
457 watermarks->a.urgent_ns, prog_wm_value); 474 watermarks->a.urgent_ns, prog_wm_value);
@@ -459,38 +476,37 @@ static void program_watermarks(
459 prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, 476 prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
460 refclk_mhz, 0x1fffff); 477 refclk_mhz, 0x1fffff);
461 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); 478 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
462 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 479 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
463 "PTE_META_URGENCY_WATERMARK_A calculated =%d\n" 480 "PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
464 "HW register value = 0x%x\n", 481 "HW register value = 0x%x\n",
465 watermarks->a.pte_meta_urgent_ns, prog_wm_value); 482 watermarks->a.pte_meta_urgent_ns, prog_wm_value);
466 483
484 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
485 prog_wm_value = convert_and_clamp(
486 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
487 refclk_mhz, 0x1fffff);
488 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
489 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
490 "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
491 "HW register value = 0x%x\n",
492 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
467 493
468 prog_wm_value = convert_and_clamp(
469 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
470 refclk_mhz, 0x1fffff);
471
472 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
473 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
474 "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
475 "HW register value = 0x%x\n",
476 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
477
478
479 prog_wm_value = convert_and_clamp(
480 watermarks->a.cstate_pstate.cstate_exit_ns,
481 refclk_mhz, 0x1fffff);
482 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
483 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
484 "SR_EXIT_WATERMARK_A calculated =%d\n"
485 "HW register value = 0x%x\n",
486 watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
487 494
495 prog_wm_value = convert_and_clamp(
496 watermarks->a.cstate_pstate.cstate_exit_ns,
497 refclk_mhz, 0x1fffff);
498 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
499 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
500 "SR_EXIT_WATERMARK_A calculated =%d\n"
501 "HW register value = 0x%x\n",
502 watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
503 }
488 504
489 prog_wm_value = convert_and_clamp( 505 prog_wm_value = convert_and_clamp(
490 watermarks->a.cstate_pstate.pstate_change_ns, 506 watermarks->a.cstate_pstate.pstate_change_ns,
491 refclk_mhz, 0x1fffff); 507 refclk_mhz, 0x1fffff);
492 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); 508 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
493 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 509 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
494 "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" 510 "DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
495 "HW register value = 0x%x\n\n", 511 "HW register value = 0x%x\n\n",
496 watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); 512 watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -500,7 +516,7 @@ static void program_watermarks(
500 prog_wm_value = convert_and_clamp( 516 prog_wm_value = convert_and_clamp(
501 watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); 517 watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
502 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); 518 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
503 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 519 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
504 "URGENCY_WATERMARK_B calculated =%d\n" 520 "URGENCY_WATERMARK_B calculated =%d\n"
505 "HW register value = 0x%x\n", 521 "HW register value = 0x%x\n",
506 watermarks->b.urgent_ns, prog_wm_value); 522 watermarks->b.urgent_ns, prog_wm_value);
@@ -510,36 +526,38 @@ static void program_watermarks(
510 watermarks->b.pte_meta_urgent_ns, 526 watermarks->b.pte_meta_urgent_ns,
511 refclk_mhz, 0x1fffff); 527 refclk_mhz, 0x1fffff);
512 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); 528 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
513 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 529 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
514 "PTE_META_URGENCY_WATERMARK_B calculated =%d\n" 530 "PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
515 "HW register value = 0x%x\n", 531 "HW register value = 0x%x\n",
516 watermarks->b.pte_meta_urgent_ns, prog_wm_value); 532 watermarks->b.pte_meta_urgent_ns, prog_wm_value);
517 533
518 534
519 prog_wm_value = convert_and_clamp( 535 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
520 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, 536 prog_wm_value = convert_and_clamp(
521 refclk_mhz, 0x1fffff); 537 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
522 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); 538 refclk_mhz, 0x1fffff);
523 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 539 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
524 "SR_ENTER_WATERMARK_B calculated =%d\n" 540 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
525 "HW register value = 0x%x\n", 541 "SR_ENTER_WATERMARK_B calculated =%d\n"
526 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 542 "HW register value = 0x%x\n",
543 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
527 544
528 545
529 prog_wm_value = convert_and_clamp( 546 prog_wm_value = convert_and_clamp(
530 watermarks->b.cstate_pstate.cstate_exit_ns, 547 watermarks->b.cstate_pstate.cstate_exit_ns,
531 refclk_mhz, 0x1fffff); 548 refclk_mhz, 0x1fffff);
532 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); 549 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
533 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 550 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
534 "SR_EXIT_WATERMARK_B calculated =%d\n" 551 "SR_EXIT_WATERMARK_B calculated =%d\n"
535 "HW register value = 0x%x\n", 552 "HW register value = 0x%x\n",
536 watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); 553 watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
554 }
537 555
538 prog_wm_value = convert_and_clamp( 556 prog_wm_value = convert_and_clamp(
539 watermarks->b.cstate_pstate.pstate_change_ns, 557 watermarks->b.cstate_pstate.pstate_change_ns,
540 refclk_mhz, 0x1fffff); 558 refclk_mhz, 0x1fffff);
541 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); 559 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
542 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 560 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
543 "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" 561 "DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
544 "HW register value = 0x%x\n", 562 "HW register value = 0x%x\n",
545 watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); 563 watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -548,7 +566,7 @@ static void program_watermarks(
548 prog_wm_value = convert_and_clamp( 566 prog_wm_value = convert_and_clamp(
549 watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); 567 watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
550 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); 568 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
551 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 569 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
552 "URGENCY_WATERMARK_C calculated =%d\n" 570 "URGENCY_WATERMARK_C calculated =%d\n"
553 "HW register value = 0x%x\n", 571 "HW register value = 0x%x\n",
554 watermarks->c.urgent_ns, prog_wm_value); 572 watermarks->c.urgent_ns, prog_wm_value);
@@ -558,37 +576,38 @@ static void program_watermarks(
558 watermarks->c.pte_meta_urgent_ns, 576 watermarks->c.pte_meta_urgent_ns,
559 refclk_mhz, 0x1fffff); 577 refclk_mhz, 0x1fffff);
560 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); 578 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
561 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 579 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
562 "PTE_META_URGENCY_WATERMARK_C calculated =%d\n" 580 "PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
563 "HW register value = 0x%x\n", 581 "HW register value = 0x%x\n",
564 watermarks->c.pte_meta_urgent_ns, prog_wm_value); 582 watermarks->c.pte_meta_urgent_ns, prog_wm_value);
565 583
566 584
567 prog_wm_value = convert_and_clamp( 585 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
568 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, 586 prog_wm_value = convert_and_clamp(
569 refclk_mhz, 0x1fffff); 587 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
570 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); 588 refclk_mhz, 0x1fffff);
571 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 589 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
572 "SR_ENTER_WATERMARK_C calculated =%d\n" 590 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
573 "HW register value = 0x%x\n", 591 "SR_ENTER_WATERMARK_C calculated =%d\n"
574 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 592 "HW register value = 0x%x\n",
593 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
575 594
576 595
577 prog_wm_value = convert_and_clamp( 596 prog_wm_value = convert_and_clamp(
578 watermarks->c.cstate_pstate.cstate_exit_ns, 597 watermarks->c.cstate_pstate.cstate_exit_ns,
579 refclk_mhz, 0x1fffff); 598 refclk_mhz, 0x1fffff);
580 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); 599 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
581 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 600 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
582 "SR_EXIT_WATERMARK_C calculated =%d\n" 601 "SR_EXIT_WATERMARK_C calculated =%d\n"
583 "HW register value = 0x%x\n", 602 "HW register value = 0x%x\n",
584 watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); 603 watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
585 604 }
586 605
587 prog_wm_value = convert_and_clamp( 606 prog_wm_value = convert_and_clamp(
588 watermarks->c.cstate_pstate.pstate_change_ns, 607 watermarks->c.cstate_pstate.pstate_change_ns,
589 refclk_mhz, 0x1fffff); 608 refclk_mhz, 0x1fffff);
590 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); 609 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
591 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 610 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
592 "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" 611 "DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
593 "HW register value = 0x%x\n", 612 "HW register value = 0x%x\n",
594 watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); 613 watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -597,7 +616,7 @@ static void program_watermarks(
597 prog_wm_value = convert_and_clamp( 616 prog_wm_value = convert_and_clamp(
598 watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); 617 watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
599 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); 618 REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
600 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 619 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
601 "URGENCY_WATERMARK_D calculated =%d\n" 620 "URGENCY_WATERMARK_D calculated =%d\n"
602 "HW register value = 0x%x\n", 621 "HW register value = 0x%x\n",
603 watermarks->d.urgent_ns, prog_wm_value); 622 watermarks->d.urgent_ns, prog_wm_value);
@@ -606,37 +625,39 @@ static void program_watermarks(
606 watermarks->d.pte_meta_urgent_ns, 625 watermarks->d.pte_meta_urgent_ns,
607 refclk_mhz, 0x1fffff); 626 refclk_mhz, 0x1fffff);
608 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); 627 REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
609 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 628 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
610 "PTE_META_URGENCY_WATERMARK_D calculated =%d\n" 629 "PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
611 "HW register value = 0x%x\n", 630 "HW register value = 0x%x\n",
612 watermarks->d.pte_meta_urgent_ns, prog_wm_value); 631 watermarks->d.pte_meta_urgent_ns, prog_wm_value);
613 632
614 633
615 prog_wm_value = convert_and_clamp( 634 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
616 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, 635 prog_wm_value = convert_and_clamp(
617 refclk_mhz, 0x1fffff); 636 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
618 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); 637 refclk_mhz, 0x1fffff);
619 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 638 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
620 "SR_ENTER_WATERMARK_D calculated =%d\n" 639 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
621 "HW register value = 0x%x\n", 640 "SR_ENTER_WATERMARK_D calculated =%d\n"
622 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); 641 "HW register value = 0x%x\n",
642 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
623 643
624 644
625 prog_wm_value = convert_and_clamp( 645 prog_wm_value = convert_and_clamp(
626 watermarks->d.cstate_pstate.cstate_exit_ns, 646 watermarks->d.cstate_pstate.cstate_exit_ns,
627 refclk_mhz, 0x1fffff); 647 refclk_mhz, 0x1fffff);
628 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); 648 REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
629 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 649 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
630 "SR_EXIT_WATERMARK_D calculated =%d\n" 650 "SR_EXIT_WATERMARK_D calculated =%d\n"
631 "HW register value = 0x%x\n", 651 "HW register value = 0x%x\n",
632 watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); 652 watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
653 }
633 654
634 655
635 prog_wm_value = convert_and_clamp( 656 prog_wm_value = convert_and_clamp(
636 watermarks->d.cstate_pstate.pstate_change_ns, 657 watermarks->d.cstate_pstate.pstate_change_ns,
637 refclk_mhz, 0x1fffff); 658 refclk_mhz, 0x1fffff);
638 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); 659 REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
639 dm_logger_write(hws->ctx->logger, LOG_HW_MARKS, 660 dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
640 "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" 661 "DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
641 "HW register value = 0x%x\n\n", 662 "HW register value = 0x%x\n\n",
642 watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); 663 watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -771,20 +792,22 @@ static void power_on_plane(
771 struct dce_hwseq *hws, 792 struct dce_hwseq *hws,
772 int plane_id) 793 int plane_id)
773{ 794{
774 REG_SET(DC_IP_REQUEST_CNTL, 0, 795 if (REG(DC_IP_REQUEST_CNTL)) {
775 IP_REQUEST_EN, 1); 796 REG_SET(DC_IP_REQUEST_CNTL, 0,
776 dpp_pg_control(hws, plane_id, true); 797 IP_REQUEST_EN, 1);
777 hubp_pg_control(hws, plane_id, true); 798 dpp_pg_control(hws, plane_id, true);
778 REG_SET(DC_IP_REQUEST_CNTL, 0, 799 hubp_pg_control(hws, plane_id, true);
779 IP_REQUEST_EN, 0); 800 REG_SET(DC_IP_REQUEST_CNTL, 0,
780 dm_logger_write(hws->ctx->logger, LOG_DEBUG, 801 IP_REQUEST_EN, 0);
781 "Un-gated front end for pipe %d\n", plane_id); 802 dm_logger_write(hws->ctx->logger, LOG_DEBUG,
803 "Un-gated front end for pipe %d\n", plane_id);
804 }
782} 805}
783 806
784static void undo_DEGVIDCN10_253_wa(struct dc *dc) 807static void undo_DEGVIDCN10_253_wa(struct dc *dc)
785{ 808{
786 struct dce_hwseq *hws = dc->hwseq; 809 struct dce_hwseq *hws = dc->hwseq;
787 struct mem_input *mi = dc->res_pool->mis[0]; 810 struct hubp *hubp = dc->res_pool->hubps[0];
788 int pwr_status = 0; 811 int pwr_status = 0;
789 812
790 REG_GET(DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, &pwr_status); 813 REG_GET(DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, &pwr_status);
@@ -792,7 +815,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
792 if (pwr_status == 2) 815 if (pwr_status == 2)
793 return; 816 return;
794 817
795 mi->funcs->set_blank(mi, true); 818 hubp->funcs->set_blank(hubp, true);
796 819
797 REG_SET(DC_IP_REQUEST_CNTL, 0, 820 REG_SET(DC_IP_REQUEST_CNTL, 0,
798 IP_REQUEST_EN, 1); 821 IP_REQUEST_EN, 1);
@@ -802,17 +825,13 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
802 IP_REQUEST_EN, 0); 825 IP_REQUEST_EN, 0);
803} 826}
804 827
805static void ready_shared_resources(struct dc *dc)
806{
807 if (dc->current_state->stream_count == 0 &&
808 !dc->debug.disable_stutter)
809 undo_DEGVIDCN10_253_wa(dc);
810}
811
812static void apply_DEGVIDCN10_253_wa(struct dc *dc) 828static void apply_DEGVIDCN10_253_wa(struct dc *dc)
813{ 829{
814 struct dce_hwseq *hws = dc->hwseq; 830 struct dce_hwseq *hws = dc->hwseq;
815 struct mem_input *mi = dc->res_pool->mis[0]; 831 struct hubp *hubp = dc->res_pool->hubps[0];
832
833 if (dc->debug.disable_stutter)
834 return;
816 835
817 REG_SET(DC_IP_REQUEST_CNTL, 0, 836 REG_SET(DC_IP_REQUEST_CNTL, 0,
818 IP_REQUEST_EN, 1); 837 IP_REQUEST_EN, 1);
@@ -821,14 +840,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
821 REG_SET(DC_IP_REQUEST_CNTL, 0, 840 REG_SET(DC_IP_REQUEST_CNTL, 0,
822 IP_REQUEST_EN, 0); 841 IP_REQUEST_EN, 0);
823 842
824 mi->funcs->set_hubp_blank_en(mi, false); 843 hubp->funcs->set_hubp_blank_en(hubp, false);
825}
826
827static void optimize_shared_resources(struct dc *dc)
828{
829 if (dc->current_state->stream_count == 0 &&
830 !dc->debug.disable_stutter)
831 apply_DEGVIDCN10_253_wa(dc);
832} 844}
833 845
834static void bios_golden_init(struct dc *dc) 846static void bios_golden_init(struct dc *dc)
@@ -887,12 +899,13 @@ static void dcn10_init_hw(struct dc *dc)
887 } 899 }
888 900
889 for (i = 0; i < dc->res_pool->pipe_count; i++) { 901 for (i = 0; i < dc->res_pool->pipe_count; i++) {
890 struct transform *xfm = dc->res_pool->transforms[i]; 902 struct dpp *dpp = dc->res_pool->dpps[i];
891 struct timing_generator *tg = dc->res_pool->timing_generators[i]; 903 struct timing_generator *tg = dc->res_pool->timing_generators[i];
892 904
893 xfm->funcs->transform_reset(xfm); 905 dpp->funcs->dpp_reset(dpp);
894 dc->res_pool->mpc->funcs->remove( 906 dc->res_pool->mpc->funcs->remove(
895 dc->res_pool->mpc, dc->res_pool->opps[i], i); 907 dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree),
908 dc->res_pool->opps[i]->inst, i);
896 909
897 /* Blank controller using driver code instead of 910 /* Blank controller using driver code instead of
898 * command table. 911 * command table.
@@ -1028,12 +1041,11 @@ static void reset_back_end_for_pipe(
1028 return; 1041 return;
1029 } 1042 }
1030 1043
1031 /* TODOFPGA break core_link_disable_stream into 2 functions: 1044 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
1032 * disable_stream and disable_link. disable_link will disable PHYPLL 1045 /* DPMS may already disable */
1033 * which is used by otg. Move disable_link after disable_crtc 1046 if (!pipe_ctx->stream->dpms_off)
1034 */ 1047 core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
1035 if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) 1048 }
1036 core_link_disable_stream(pipe_ctx);
1037 1049
1038 /* by upper caller loop, parent pipe: pipe0, will be reset last. 1050 /* by upper caller loop, parent pipe: pipe0, will be reset last.
1039 * back end share by all pipes and will be disable only when disable 1051 * back end share by all pipes and will be disable only when disable
@@ -1062,7 +1074,7 @@ static void reset_back_end_for_pipe(
1062static void plane_atomic_disconnect(struct dc *dc, 1074static void plane_atomic_disconnect(struct dc *dc,
1063 int fe_idx) 1075 int fe_idx)
1064{ 1076{
1065 struct mem_input *mi = dc->res_pool->mis[fe_idx]; 1077 struct hubp *hubp = dc->res_pool->hubps[fe_idx];
1066 struct mpc *mpc = dc->res_pool->mpc; 1078 struct mpc *mpc = dc->res_pool->mpc;
1067 int opp_id, z_idx; 1079 int opp_id, z_idx;
1068 int mpcc_id = -1; 1080 int mpcc_id = -1;
@@ -1086,11 +1098,12 @@ static void plane_atomic_disconnect(struct dc *dc,
1086 1098
1087 if (dc->debug.sanity_checks) 1099 if (dc->debug.sanity_checks)
1088 verify_allow_pstate_change_high(dc->hwseq); 1100 verify_allow_pstate_change_high(dc->hwseq);
1089 mi->funcs->dcc_control(mi, false, false); 1101 hubp->funcs->dcc_control(hubp, false, false);
1090 if (dc->debug.sanity_checks) 1102 if (dc->debug.sanity_checks)
1091 verify_allow_pstate_change_high(dc->hwseq); 1103 verify_allow_pstate_change_high(dc->hwseq);
1092 1104
1093 mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx); 1105 mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree),
1106 dc->res_pool->opps[opp_id]->inst, fe_idx);
1094} 1107}
1095 1108
1096/* disable HW used by plane. 1109/* disable HW used by plane.
@@ -1099,20 +1112,20 @@ static void plane_atomic_disable(struct dc *dc,
1099 int fe_idx) 1112 int fe_idx)
1100{ 1113{
1101 struct dce_hwseq *hws = dc->hwseq; 1114 struct dce_hwseq *hws = dc->hwseq;
1102 struct mem_input *mi = dc->res_pool->mis[fe_idx]; 1115 struct hubp *hubp = dc->res_pool->hubps[fe_idx];
1103 struct mpc *mpc = dc->res_pool->mpc; 1116 struct mpc *mpc = dc->res_pool->mpc;
1104 int opp_id = mi->opp_id; 1117 int opp_id = hubp->opp_id;
1105 1118
1106 if (opp_id == 0xf) 1119 if (opp_id == 0xf)
1107 return; 1120 return;
1108 1121
1109 mpc->funcs->wait_for_idle(mpc, mi->mpcc_id); 1122 mpc->funcs->wait_for_idle(mpc, hubp->mpcc_id);
1110 dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false; 1123 dc->res_pool->opps[hubp->opp_id]->mpcc_disconnect_pending[hubp->mpcc_id] = false;
1111 /*dm_logger_write(dc->ctx->logger, LOG_ERROR, 1124 /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
1112 "[debug_mpo: atomic disable finished on mpcc %d]\n", 1125 "[debug_mpo: atomic disable finished on mpcc %d]\n",
1113 fe_idx);*/ 1126 fe_idx);*/
1114 1127
1115 mi->funcs->set_blank(mi, true); 1128 hubp->funcs->set_blank(hubp, true);
1116 1129
1117 if (dc->debug.sanity_checks) 1130 if (dc->debug.sanity_checks)
1118 verify_allow_pstate_change_high(dc->hwseq); 1131 verify_allow_pstate_change_high(dc->hwseq);
@@ -1137,20 +1150,22 @@ static void plane_atomic_disable(struct dc *dc,
1137static void plane_atomic_power_down(struct dc *dc, int fe_idx) 1150static void plane_atomic_power_down(struct dc *dc, int fe_idx)
1138{ 1151{
1139 struct dce_hwseq *hws = dc->hwseq; 1152 struct dce_hwseq *hws = dc->hwseq;
1140 struct transform *xfm = dc->res_pool->transforms[fe_idx]; 1153 struct dpp *dpp = dc->res_pool->dpps[fe_idx];
1141 1154
1142 REG_SET(DC_IP_REQUEST_CNTL, 0, 1155 if (REG(DC_IP_REQUEST_CNTL)) {
1143 IP_REQUEST_EN, 1); 1156 REG_SET(DC_IP_REQUEST_CNTL, 0,
1144 dpp_pg_control(hws, fe_idx, false); 1157 IP_REQUEST_EN, 1);
1145 hubp_pg_control(hws, fe_idx, false); 1158 dpp_pg_control(hws, fe_idx, false);
1146 xfm->funcs->transform_reset(xfm); 1159 hubp_pg_control(hws, fe_idx, false);
1147 REG_SET(DC_IP_REQUEST_CNTL, 0, 1160 dpp->funcs->dpp_reset(dpp);
1148 IP_REQUEST_EN, 0); 1161 REG_SET(DC_IP_REQUEST_CNTL, 0,
1149 dm_logger_write(dc->ctx->logger, LOG_DEBUG, 1162 IP_REQUEST_EN, 0);
1150 "Power gated front end %d\n", fe_idx); 1163 dm_logger_write(dc->ctx->logger, LOG_DEBUG,
1151 1164 "Power gated front end %d\n", fe_idx);
1152 if (dc->debug.sanity_checks) 1165
1153 verify_allow_pstate_change_high(dc->hwseq); 1166 if (dc->debug.sanity_checks)
1167 verify_allow_pstate_change_high(dc->hwseq);
1168 }
1154} 1169}
1155 1170
1156 1171
@@ -1160,7 +1175,7 @@ static void reset_front_end(
1160{ 1175{
1161 struct dce_hwseq *hws = dc->hwseq; 1176 struct dce_hwseq *hws = dc->hwseq;
1162 struct timing_generator *tg; 1177 struct timing_generator *tg;
1163 int opp_id = dc->res_pool->mis[fe_idx]->opp_id; 1178 int opp_id = dc->res_pool->hubps[fe_idx]->opp_id;
1164 1179
1165 /*Already reset*/ 1180 /*Already reset*/
1166 if (opp_id == 0xf) 1181 if (opp_id == 0xf)
@@ -1192,7 +1207,7 @@ static void reset_front_end(
1192static void dcn10_power_down_fe(struct dc *dc, int fe_idx) 1207static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
1193{ 1208{
1194 struct dce_hwseq *hws = dc->hwseq; 1209 struct dce_hwseq *hws = dc->hwseq;
1195 struct transform *xfm = dc->res_pool->transforms[fe_idx]; 1210 struct dpp *dpp = dc->res_pool->dpps[fe_idx];
1196 1211
1197 reset_front_end(dc, fe_idx); 1212 reset_front_end(dc, fe_idx);
1198 1213
@@ -1200,7 +1215,7 @@ static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
1200 IP_REQUEST_EN, 1); 1215 IP_REQUEST_EN, 1);
1201 dpp_pg_control(hws, fe_idx, false); 1216 dpp_pg_control(hws, fe_idx, false);
1202 hubp_pg_control(hws, fe_idx, false); 1217 hubp_pg_control(hws, fe_idx, false);
1203 xfm->funcs->transform_reset(xfm); 1218 dpp->funcs->dpp_reset(dpp);
1204 REG_SET(DC_IP_REQUEST_CNTL, 0, 1219 REG_SET(DC_IP_REQUEST_CNTL, 0,
1205 IP_REQUEST_EN, 0); 1220 IP_REQUEST_EN, 0);
1206 dm_logger_write(dc->ctx->logger, LOG_DEBUG, 1221 dm_logger_write(dc->ctx->logger, LOG_DEBUG,
@@ -1275,6 +1290,9 @@ static void reset_hw_ctx_wrap(
1275 if (!pipe_ctx_old->stream) 1290 if (!pipe_ctx_old->stream)
1276 continue; 1291 continue;
1277 1292
1293 if (pipe_ctx_old->top_pipe)
1294 continue;
1295
1278 if (!pipe_ctx->stream || 1296 if (!pipe_ctx->stream ||
1279 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 1297 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
1280 struct clock_source *old_clk = pipe_ctx_old->clock_source; 1298 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
1339 if (plane_state == NULL) 1357 if (plane_state == NULL)
1340 return; 1358 return;
1341 addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr); 1359 addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
1342 pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 1360 pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
1343 pipe_ctx->plane_res.mi, 1361 pipe_ctx->plane_res.hubp,
1344 &plane_state->address, 1362 &plane_state->address,
1345 plane_state->flip_immediate); 1363 plane_state->flip_immediate);
1346 plane_state->status.requested_address = plane_state->address; 1364 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
1351static bool dcn10_set_input_transfer_func( 1369static bool dcn10_set_input_transfer_func(
1352 struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state) 1370 struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
1353{ 1371{
1354 struct transform *xfm_base = pipe_ctx->plane_res.xfm; 1372 struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
1355 const struct dc_transfer_func *tf = NULL; 1373 const struct dc_transfer_func *tf = NULL;
1356 bool result = true; 1374 bool result = true;
1357 1375
1358 if (xfm_base == NULL) 1376 if (dpp_base == NULL)
1359 return false; 1377 return false;
1360 1378
1361 if (plane_state->in_transfer_func) 1379 if (plane_state->in_transfer_func)
1362 tf = plane_state->in_transfer_func; 1380 tf = plane_state->in_transfer_func;
1363 1381
1364 if (plane_state->gamma_correction && dce_use_lut(plane_state)) 1382 if (plane_state->gamma_correction && dce_use_lut(plane_state))
1365 xfm_base->funcs->ipp_program_input_lut(xfm_base, 1383 dpp_base->funcs->ipp_program_input_lut(dpp_base,
1366 plane_state->gamma_correction); 1384 plane_state->gamma_correction);
1367 1385
1368 if (tf == NULL) 1386 if (tf == NULL)
1369 xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS); 1387 dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
1370 else if (tf->type == TF_TYPE_PREDEFINED) { 1388 else if (tf->type == TF_TYPE_PREDEFINED) {
1371 switch (tf->tf) { 1389 switch (tf->tf) {
1372 case TRANSFER_FUNCTION_SRGB: 1390 case TRANSFER_FUNCTION_SRGB:
1373 xfm_base->funcs->ipp_set_degamma(xfm_base, 1391 dpp_base->funcs->ipp_set_degamma(dpp_base,
1374 IPP_DEGAMMA_MODE_HW_sRGB); 1392 IPP_DEGAMMA_MODE_HW_sRGB);
1375 break; 1393 break;
1376 case TRANSFER_FUNCTION_BT709: 1394 case TRANSFER_FUNCTION_BT709:
1377 xfm_base->funcs->ipp_set_degamma(xfm_base, 1395 dpp_base->funcs->ipp_set_degamma(dpp_base,
1378 IPP_DEGAMMA_MODE_HW_xvYCC); 1396 IPP_DEGAMMA_MODE_HW_xvYCC);
1379 break; 1397 break;
1380 case TRANSFER_FUNCTION_LINEAR: 1398 case TRANSFER_FUNCTION_LINEAR:
1381 xfm_base->funcs->ipp_set_degamma(xfm_base, 1399 dpp_base->funcs->ipp_set_degamma(dpp_base,
1382 IPP_DEGAMMA_MODE_BYPASS); 1400 IPP_DEGAMMA_MODE_BYPASS);
1383 break; 1401 break;
1384 case TRANSFER_FUNCTION_PQ: 1402 case TRANSFER_FUNCTION_PQ:
@@ -1389,7 +1407,7 @@ static bool dcn10_set_input_transfer_func(
1389 break; 1407 break;
1390 } 1408 }
1391 } else if (tf->type == TF_TYPE_BYPASS) { 1409 } else if (tf->type == TF_TYPE_BYPASS) {
1392 xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS); 1410 dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
1393 } else { 1411 } else {
1394 /*TF_TYPE_DISTRIBUTED_POINTS*/ 1412 /*TF_TYPE_DISTRIBUTED_POINTS*/
1395 result = false; 1413 result = false;
@@ -1716,25 +1734,25 @@ static bool dcn10_set_output_transfer_func(
1716 struct pipe_ctx *pipe_ctx, 1734 struct pipe_ctx *pipe_ctx,
1717 const struct dc_stream_state *stream) 1735 const struct dc_stream_state *stream)
1718{ 1736{
1719 struct transform *xfm = pipe_ctx->plane_res.xfm; 1737 struct dpp *dpp = pipe_ctx->plane_res.dpp;
1720 1738
1721 if (xfm == NULL) 1739 if (dpp == NULL)
1722 return false; 1740 return false;
1723 1741
1724 xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 1742 dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
1725 1743
1726 if (stream->out_transfer_func && 1744 if (stream->out_transfer_func &&
1727 stream->out_transfer_func->type == 1745 stream->out_transfer_func->type ==
1728 TF_TYPE_PREDEFINED && 1746 TF_TYPE_PREDEFINED &&
1729 stream->out_transfer_func->tf == 1747 stream->out_transfer_func->tf ==
1730 TRANSFER_FUNCTION_SRGB) { 1748 TRANSFER_FUNCTION_SRGB) {
1731 xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 1749 dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_SRGB);
1732 } else if (dcn10_translate_regamma_to_hw_format( 1750 } else if (dcn10_translate_regamma_to_hw_format(
1733 stream->out_transfer_func, &xfm->regamma_params)) { 1751 stream->out_transfer_func, &dpp->regamma_params)) {
1734 xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 1752 dpp->funcs->opp_program_regamma_pwl(dpp, &dpp->regamma_params);
1735 xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 1753 dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_USER);
1736 } else { 1754 } else {
1737 xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 1755 dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_BYPASS);
1738 } 1756 }
1739 1757
1740 return true; 1758 return true;
@@ -1745,8 +1763,8 @@ static void dcn10_pipe_control_lock(
1745 struct pipe_ctx *pipe, 1763 struct pipe_ctx *pipe,
1746 bool lock) 1764 bool lock)
1747{ 1765{
1748 struct mem_input *mi = NULL; 1766 struct hubp *hubp = NULL;
1749 mi = dc->res_pool->mis[pipe->pipe_idx]; 1767 hubp = dc->res_pool->hubps[pipe->pipe_idx];
1750 /* use TG master update lock to lock everything on the TG 1768 /* use TG master update lock to lock everything on the TG
1751 * therefore only top pipe need to lock 1769 * therefore only top pipe need to lock
1752 */ 1770 */
@@ -1997,10 +2015,11 @@ static void dcn10_power_on_fe(
1997 plane_state->dst_rect.height); 2015 plane_state->dst_rect.height);
1998 2016
1999 dm_logger_write(dc->ctx->logger, LOG_DC, 2017 dm_logger_write(dc->ctx->logger, LOG_DC,
2000 "Pipe %d: width, height, x, y\n" 2018 "Pipe %d: width, height, x, y format:%d\n"
2001 "viewport:%d, %d, %d, %d\n" 2019 "viewport:%d, %d, %d, %d\n"
2002 "recout: %d, %d, %d, %d\n", 2020 "recout: %d, %d, %d, %d\n",
2003 pipe_ctx->pipe_idx, 2021 pipe_ctx->pipe_idx,
2022 plane_state->format,
2004 pipe_ctx->plane_res.scl_data.viewport.width, 2023 pipe_ctx->plane_res.scl_data.viewport.width,
2005 pipe_ctx->plane_res.scl_data.viewport.height, 2024 pipe_ctx->plane_res.scl_data.viewport.height,
2006 pipe_ctx->plane_res.scl_data.viewport.x, 2025 pipe_ctx->plane_res.scl_data.viewport.x,
@@ -2019,7 +2038,7 @@ static void dcn10_power_on_fe(
2019 2038
2020static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 2039static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
2021{ 2040{
2022 struct xfm_grph_csc_adjustment adjust; 2041 struct dpp_grph_csc_adjustment adjust;
2023 memset(&adjust, 0, sizeof(adjust)); 2042 memset(&adjust, 0, sizeof(adjust));
2024 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 2043 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
2025 2044
@@ -2055,7 +2074,7 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
2055 gamut_remap_matrix.matrix[10]; 2074 gamut_remap_matrix.matrix[10];
2056 } 2075 }
2057 2076
2058 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 2077 pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
2059} 2078}
2060 2079
2061 2080
@@ -2077,7 +2096,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
2077 2096
2078 tbl_entry.color_space = color_space; 2097 tbl_entry.color_space = color_space;
2079 //tbl_entry.regval = matrix; 2098 //tbl_entry.regval = matrix;
2080 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry); 2099 pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry);
2081 } 2100 }
2082} 2101}
2083static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) 2102static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
@@ -2167,7 +2186,7 @@ static void dcn10_get_surface_visual_confirm_color(
2167 } 2186 }
2168} 2187}
2169 2188
2170static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi, 2189static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1,
2171 struct vm_system_aperture_param *apt, 2190 struct vm_system_aperture_param *apt,
2172 struct dce_hwseq *hws) 2191 struct dce_hwseq *hws)
2173{ 2192{
@@ -2192,7 +2211,7 @@ static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
2192} 2211}
2193 2212
2194/* Temporary read settings, future will get values from kmd directly */ 2213/* Temporary read settings, future will get values from kmd directly */
2195static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi, 2214static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
2196 struct vm_context0_param *vm0, 2215 struct vm_context0_param *vm0,
2197 struct dce_hwseq *hws) 2216 struct dce_hwseq *hws)
2198{ 2217{
@@ -2236,22 +2255,22 @@ static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
2236 vm0->pte_base.quad_part -= fb_offset.quad_part; 2255 vm0->pte_base.quad_part -= fb_offset.quad_part;
2237} 2256}
2238 2257
2239static void dcn10_program_pte_vm(struct mem_input *mem_input, 2258static void dcn10_program_pte_vm(struct hubp *hubp,
2240 enum surface_pixel_format format, 2259 enum surface_pixel_format format,
2241 union dc_tiling_info *tiling_info, 2260 union dc_tiling_info *tiling_info,
2242 enum dc_rotation_angle rotation, 2261 enum dc_rotation_angle rotation,
2243 struct dce_hwseq *hws) 2262 struct dce_hwseq *hws)
2244{ 2263{
2245 struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input); 2264 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
2246 struct vm_system_aperture_param apt = { {{ 0 } } }; 2265 struct vm_system_aperture_param apt = { {{ 0 } } };
2247 struct vm_context0_param vm0 = { { { 0 } } }; 2266 struct vm_context0_param vm0 = { { { 0 } } };
2248 2267
2249 2268
2250 mmhub_read_vm_system_aperture_settings(mi, &apt, hws); 2269 mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
2251 mmhub_read_vm_context0_settings(mi, &vm0, hws); 2270 mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
2252 2271
2253 mem_input->funcs->mem_input_set_vm_system_aperture_settings(mem_input, &apt); 2272 hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt);
2254 mem_input->funcs->mem_input_set_vm_context0_settings(mem_input, &vm0); 2273 hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0);
2255} 2274}
2256 2275
2257static void update_dchubp_dpp( 2276static void update_dchubp_dpp(
@@ -2260,11 +2279,10 @@ static void update_dchubp_dpp(
2260 struct dc_state *context) 2279 struct dc_state *context)
2261{ 2280{
2262 struct dce_hwseq *hws = dc->hwseq; 2281 struct dce_hwseq *hws = dc->hwseq;
2263 struct mem_input *mi = pipe_ctx->plane_res.mi; 2282 struct hubp *hubp = pipe_ctx->plane_res.hubp;
2264 struct transform *xfm = pipe_ctx->plane_res.xfm; 2283 struct dpp *dpp = pipe_ctx->plane_res.dpp;
2265 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2284 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
2266 union plane_size size = plane_state->plane_size; 2285 union plane_size size = plane_state->plane_size;
2267 struct default_adjustment ocsc = {0};
2268 struct mpcc_cfg mpcc_cfg = {0}; 2286 struct mpcc_cfg mpcc_cfg = {0};
2269 struct pipe_ctx *top_pipe; 2287 struct pipe_ctx *top_pipe;
2270 bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; 2288 bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
@@ -2286,10 +2304,8 @@ static void update_dchubp_dpp(
2286 */ 2304 */
2287 REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst); 2305 REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst);
2288 2306
2289 dc->hwss.update_plane_addr(dc, pipe_ctx); 2307 hubp->funcs->hubp_setup(
2290 2308 hubp,
2291 mi->funcs->mem_input_setup(
2292 mi,
2293 &pipe_ctx->dlg_regs, 2309 &pipe_ctx->dlg_regs,
2294 &pipe_ctx->ttu_regs, 2310 &pipe_ctx->ttu_regs,
2295 &pipe_ctx->rq_regs, 2311 &pipe_ctx->rq_regs,
@@ -2299,19 +2315,20 @@ static void update_dchubp_dpp(
2299 2315
2300 if (dc->config.gpu_vm_support) 2316 if (dc->config.gpu_vm_support)
2301 dcn10_program_pte_vm( 2317 dcn10_program_pte_vm(
2302 pipe_ctx->plane_res.mi, 2318 pipe_ctx->plane_res.hubp,
2303 plane_state->format, 2319 plane_state->format,
2304 &plane_state->tiling_info, 2320 &plane_state->tiling_info,
2305 plane_state->rotation, 2321 plane_state->rotation,
2306 hws 2322 hws
2307 ); 2323 );
2308 2324
2309 xfm->funcs->ipp_setup(xfm, 2325 dpp->funcs->ipp_setup(dpp,
2310 plane_state->format, 2326 plane_state->format,
2311 EXPANSION_MODE_ZERO); 2327 EXPANSION_MODE_ZERO);
2312 2328
2313 mpcc_cfg.mi = mi; 2329 mpcc_cfg.dpp_id = hubp->inst;
2314 mpcc_cfg.opp = pipe_ctx->stream_res.opp; 2330 mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst;
2331 mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree);
2315 for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe) 2332 for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
2316 mpcc_cfg.z_index++; 2333 mpcc_cfg.z_index++;
2317 if (dc->debug.surface_visual_confirm) 2334 if (dc->debug.surface_visual_confirm)
@@ -2328,25 +2345,27 @@ static void update_dchubp_dpp(
2328 mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace( 2345 mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
2329 pipe_ctx->stream->output_color_space) 2346 pipe_ctx->stream->output_color_space)
2330 && per_pixel_alpha; 2347 && per_pixel_alpha;
2331 dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg); 2348 hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
2349 hubp->opp_id = mpcc_cfg.opp_id;
2332 2350
2333 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha; 2351 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
2334 pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP; 2352 pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
2335 /* scaler configuration */ 2353 /* scaler configuration */
2336 pipe_ctx->plane_res.xfm->funcs->transform_set_scaler( 2354 pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
2337 pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data); 2355 pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
2338 mi->funcs->mem_program_viewport(mi, 2356
2357 hubp->funcs->mem_program_viewport(hubp,
2339 &pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c); 2358 &pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c);
2340 2359
2341 /*gamut remap*/ 2360 /*gamut remap*/
2342 program_gamut_remap(pipe_ctx); 2361 program_gamut_remap(pipe_ctx);
2343 2362
2344 /*TODO add adjustments parameters*/ 2363 program_csc_matrix(pipe_ctx,
2345 ocsc.out_color_space = pipe_ctx->stream->output_color_space; 2364 pipe_ctx->stream->output_color_space,
2346 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(pipe_ctx->plane_res.xfm, &ocsc); 2365 pipe_ctx->stream->csc_color_matrix.matrix);
2347 2366
2348 mi->funcs->mem_input_program_surface_config( 2367 hubp->funcs->hubp_program_surface_config(
2349 mi, 2368 hubp,
2350 plane_state->format, 2369 plane_state->format,
2351 &plane_state->tiling_info, 2370 &plane_state->tiling_info,
2352 &size, 2371 &size,
@@ -2354,8 +2373,10 @@ static void update_dchubp_dpp(
2354 &plane_state->dcc, 2373 &plane_state->dcc,
2355 plane_state->horizontal_mirror); 2374 plane_state->horizontal_mirror);
2356 2375
2376 dc->hwss.update_plane_addr(dc, pipe_ctx);
2377
2357 if (is_pipe_tree_visible(pipe_ctx)) 2378 if (is_pipe_tree_visible(pipe_ctx))
2358 mi->funcs->set_blank(mi, false); 2379 hubp->funcs->set_blank(hubp, false);
2359} 2380}
2360 2381
2361 2382
@@ -2393,6 +2414,10 @@ static void program_all_pipe_in_tree(
2393 } 2414 }
2394 2415
2395 if (pipe_ctx->plane_state != NULL) { 2416 if (pipe_ctx->plane_state != NULL) {
2417 struct dc_cursor_position position = { 0 };
2418 struct pipe_ctx *cur_pipe_ctx =
2419 &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
2420
2396 dcn10_power_on_fe(dc, pipe_ctx, context); 2421 dcn10_power_on_fe(dc, pipe_ctx, context);
2397 2422
2398 /* temporary dcn1 wa: 2423 /* temporary dcn1 wa:
@@ -2407,6 +2432,19 @@ static void program_all_pipe_in_tree(
2407 toggle_watermark_change_req(dc->hwseq); 2432 toggle_watermark_change_req(dc->hwseq);
2408 2433
2409 update_dchubp_dpp(dc, pipe_ctx, context); 2434 update_dchubp_dpp(dc, pipe_ctx, context);
2435
2436 /* TODO: this is a hack w/a for switching from mpo to pipe split */
2437 dc_stream_set_cursor_position(pipe_ctx->stream, &position);
2438
2439 dc_stream_set_cursor_attributes(pipe_ctx->stream,
2440 &pipe_ctx->stream->cursor_attributes);
2441
2442 if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
2443 dc->hwss.set_input_transfer_func(
2444 pipe_ctx, pipe_ctx->plane_state);
2445 dc->hwss.set_output_transfer_func(
2446 pipe_ctx, pipe_ctx->stream);
2447 }
2410 } 2448 }
2411 2449
2412 if (dc->debug.sanity_checks) { 2450 if (dc->debug.sanity_checks) {
@@ -2445,6 +2483,30 @@ static void dcn10_pplib_apply_display_requirements(
2445 dc->prev_display_config = *pp_display_cfg; 2483 dc->prev_display_config = *pp_display_cfg;
2446} 2484}
2447 2485
2486static void optimize_shared_resources(struct dc *dc)
2487{
2488 if (dc->current_state->stream_count == 0) {
2489 apply_DEGVIDCN10_253_wa(dc);
2490 /* S0i2 message */
2491 dcn10_pplib_apply_display_requirements(dc, dc->current_state);
2492 }
2493
2494 if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
2495 dcn_bw_notify_pplib_of_wm_ranges(dc);
2496}
2497
2498static void ready_shared_resources(struct dc *dc, struct dc_state *context)
2499{
2500 if (dc->current_state->stream_count == 0 &&
2501 !dc->debug.disable_stutter)
2502 undo_DEGVIDCN10_253_wa(dc);
2503
2504 /* S0i2 message */
2505 if (dc->current_state->stream_count == 0 &&
2506 context->stream_count != 0)
2507 dcn10_pplib_apply_display_requirements(dc, context);
2508}
2509
2448static void dcn10_apply_ctx_for_surface( 2510static void dcn10_apply_ctx_for_surface(
2449 struct dc *dc, 2511 struct dc *dc,
2450 const struct dc_stream_state *stream, 2512 const struct dc_stream_state *stream,
@@ -2494,7 +2556,7 @@ static void dcn10_apply_ctx_for_surface(
2494 */ 2556 */
2495 2557
2496 if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) { 2558 if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
2497 if (pipe_ctx->plane_res.mi->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) { 2559 if (pipe_ctx->plane_res.hubp->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
2498 dcn10_power_down_fe(dc, pipe_ctx->pipe_idx); 2560 dcn10_power_down_fe(dc, pipe_ctx->pipe_idx);
2499 /* 2561 /*
2500 * power down fe will unlock when calling reset, need 2562 * power down fe will unlock when calling reset, need
@@ -2518,9 +2580,10 @@ static void dcn10_apply_ctx_for_surface(
2518 /* reset mpc */ 2580 /* reset mpc */
2519 dc->res_pool->mpc->funcs->remove( 2581 dc->res_pool->mpc->funcs->remove(
2520 dc->res_pool->mpc, 2582 dc->res_pool->mpc,
2521 old_pipe_ctx->stream_res.opp, 2583 &(old_pipe_ctx->stream_res.opp->mpc_tree),
2584 old_pipe_ctx->stream_res.opp->inst,
2522 old_pipe_ctx->pipe_idx); 2585 old_pipe_ctx->pipe_idx);
2523 old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true; 2586 old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.hubp->mpcc_id] = true;
2524 2587
2525 /*dm_logger_write(dc->ctx->logger, LOG_ERROR, 2588 /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
2526 "[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n", 2589 "[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n",
@@ -2532,6 +2595,7 @@ static void dcn10_apply_ctx_for_surface(
2532 old_pipe_ctx->top_pipe = NULL; 2595 old_pipe_ctx->top_pipe = NULL;
2533 old_pipe_ctx->bottom_pipe = NULL; 2596 old_pipe_ctx->bottom_pipe = NULL;
2534 old_pipe_ctx->plane_state = NULL; 2597 old_pipe_ctx->plane_state = NULL;
2598 old_pipe_ctx->stream = NULL;
2535 2599
2536 dm_logger_write(dc->ctx->logger, LOG_DC, 2600 dm_logger_write(dc->ctx->logger, LOG_DC,
2537 "Reset mpcc for pipe %d\n", 2601 "Reset mpcc for pipe %d\n",
@@ -2803,7 +2867,7 @@ static void dcn10_wait_for_mpcc_disconnect(
2803 if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) { 2867 if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
2804 res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i); 2868 res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
2805 pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false; 2869 pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
2806 res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true); 2870 res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
2807 /*dm_logger_write(dc->ctx->logger, LOG_ERROR, 2871 /*dm_logger_write(dc->ctx->logger, LOG_ERROR,
2808 "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n", 2872 "[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
2809 i);*/ 2873 i);*/
@@ -2834,11 +2898,11 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
2834 return; 2898 return;
2835 2899
2836 plane_state->status.is_flip_pending = 2900 plane_state->status.is_flip_pending =
2837 pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 2901 pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending(
2838 pipe_ctx->plane_res.mi); 2902 pipe_ctx->plane_res.hubp);
2839 2903
2840 plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 2904 plane_state->status.current_address = pipe_ctx->plane_res.hubp->current_address;
2841 if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 2905 if (pipe_ctx->plane_res.hubp->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
2842 tg->funcs->is_stereo_left_eye) { 2906 tg->funcs->is_stereo_left_eye) {
2843 plane_state->status.is_right_eye = 2907 plane_state->status.is_right_eye =
2844 !tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 2908 !tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
@@ -2882,6 +2946,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
2882 .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, 2946 .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
2883 .ready_shared_resources = ready_shared_resources, 2947 .ready_shared_resources = ready_shared_resources,
2884 .optimize_shared_resources = optimize_shared_resources, 2948 .optimize_shared_resources = optimize_shared_resources,
2949 .edp_backlight_control = hwss_edp_backlight_control,
2950 .edp_power_control = hwss_edp_power_control
2885}; 2951};
2886 2952
2887 2953
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
index 67bd6a738fe9..08db1e6b5166 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
@@ -37,188 +37,6 @@
37#define CTX \ 37#define CTX \
38 ippn10->base.ctx 38 ippn10->base.ctx
39 39
40static bool ippn10_cursor_program_control(
41 struct dcn10_ipp *ippn10,
42 bool pixel_data_invert,
43 enum dc_cursor_color_format color_format)
44{
45 if (REG(CURSOR_SETTINS))
46 REG_SET_2(CURSOR_SETTINS, 0,
47 /* no shift of the cursor HDL schedule */
48 CURSOR0_DST_Y_OFFSET, 0,
49 /* used to shift the cursor chunk request deadline */
50 CURSOR0_CHUNK_HDL_ADJUST, 3);
51 else
52 REG_SET_2(CURSOR_SETTINGS, 0,
53 /* no shift of the cursor HDL schedule */
54 CURSOR0_DST_Y_OFFSET, 0,
55 /* used to shift the cursor chunk request deadline */
56 CURSOR0_CHUNK_HDL_ADJUST, 3);
57
58 REG_UPDATE_2(CURSOR0_CONTROL,
59 CUR0_MODE, color_format,
60 CUR0_EXPANSION_MODE, 0);
61
62 if (color_format == CURSOR_MODE_MONO) {
63 /* todo: clarify what to program these to */
64 REG_UPDATE(CURSOR0_COLOR0,
65 CUR0_COLOR0, 0x00000000);
66 REG_UPDATE(CURSOR0_COLOR1,
67 CUR0_COLOR1, 0xFFFFFFFF);
68 }
69
70 /* TODO: Fixed vs float */
71
72 REG_UPDATE_3(FORMAT_CONTROL,
73 CNVC_BYPASS, 0,
74 ALPHA_EN, 1,
75 FORMAT_EXPANSION_MODE, 0);
76
77 return true;
78}
79
80enum cursor_pitch {
81 CURSOR_PITCH_64_PIXELS = 0,
82 CURSOR_PITCH_128_PIXELS,
83 CURSOR_PITCH_256_PIXELS
84};
85
86enum cursor_lines_per_chunk {
87 CURSOR_LINE_PER_CHUNK_2 = 1,
88 CURSOR_LINE_PER_CHUNK_4,
89 CURSOR_LINE_PER_CHUNK_8,
90 CURSOR_LINE_PER_CHUNK_16
91};
92
93static enum cursor_pitch ippn10_get_cursor_pitch(
94 unsigned int pitch)
95{
96 enum cursor_pitch hw_pitch;
97
98 switch (pitch) {
99 case 64:
100 hw_pitch = CURSOR_PITCH_64_PIXELS;
101 break;
102 case 128:
103 hw_pitch = CURSOR_PITCH_128_PIXELS;
104 break;
105 case 256:
106 hw_pitch = CURSOR_PITCH_256_PIXELS;
107 break;
108 default:
109 DC_ERR("Invalid cursor pitch of %d. "
110 "Only 64/128/256 is supported on DCN.\n", pitch);
111 hw_pitch = CURSOR_PITCH_64_PIXELS;
112 break;
113 }
114 return hw_pitch;
115}
116
117static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
118 unsigned int cur_width,
119 enum dc_cursor_color_format format)
120{
121 enum cursor_lines_per_chunk line_per_chunk;
122
123 if (format == CURSOR_MODE_MONO)
124 /* impl B. expansion in CUR Buffer reader */
125 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
126 else if (cur_width <= 32)
127 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
128 else if (cur_width <= 64)
129 line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
130 else if (cur_width <= 128)
131 line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
132 else
133 line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
134
135 return line_per_chunk;
136}
137
138static void ippn10_cursor_set_attributes(
139 struct input_pixel_processor *ipp,
140 const struct dc_cursor_attributes *attr)
141{
142 struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
143 enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
144 enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
145 attr->width, attr->color_format);
146
147 ippn10->curs_attr = *attr;
148
149 REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
150 CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
151 REG_UPDATE(CURSOR_SURFACE_ADDRESS,
152 CURSOR_SURFACE_ADDRESS, attr->address.low_part);
153
154 REG_UPDATE_2(CURSOR_SIZE,
155 CURSOR_WIDTH, attr->width,
156 CURSOR_HEIGHT, attr->height);
157 REG_UPDATE_3(CURSOR_CONTROL,
158 CURSOR_MODE, attr->color_format,
159 CURSOR_PITCH, hw_pitch,
160 CURSOR_LINES_PER_CHUNK, lpc);
161 ippn10_cursor_program_control(ippn10,
162 attr->attribute_flags.bits.INVERT_PIXEL_DATA,
163 attr->color_format);
164}
165
166static void ippn10_cursor_set_position(
167 struct input_pixel_processor *ipp,
168 const struct dc_cursor_position *pos,
169 const struct dc_cursor_mi_param *param)
170{
171 struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
172 int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
173 uint32_t cur_en = pos->enable ? 1 : 0;
174 uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
175
176 /*
177 * Guard aganst cursor_set_position() from being called with invalid
178 * attributes
179 *
180 * TODO: Look at combining cursor_set_position() and
181 * cursor_set_attributes() into cursor_update()
182 */
183 if (ippn10->curs_attr.address.quad_part == 0)
184 return;
185
186 dst_x_offset *= param->ref_clk_khz;
187 dst_x_offset /= param->pixel_clk_khz;
188
189 ASSERT(param->h_scale_ratio.value);
190
191 if (param->h_scale_ratio.value)
192 dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
193 dal_fixed31_32_from_int(dst_x_offset),
194 param->h_scale_ratio));
195
196 if (src_x_offset >= (int)param->viewport_width)
197 cur_en = 0; /* not visible beyond right edge*/
198
199 if (src_x_offset + (int)ippn10->curs_attr.width < 0)
200 cur_en = 0; /* not visible beyond left edge*/
201
202 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
203 ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
204 REG_UPDATE(CURSOR_CONTROL,
205 CURSOR_ENABLE, cur_en);
206 REG_UPDATE(CURSOR0_CONTROL,
207 CUR0_ENABLE, cur_en);
208
209 REG_SET_2(CURSOR_POSITION, 0,
210 CURSOR_X_POSITION, pos->x,
211 CURSOR_Y_POSITION, pos->y);
212
213 REG_SET_2(CURSOR_HOT_SPOT, 0,
214 CURSOR_HOT_SPOT_X, pos->x_hotspot,
215 CURSOR_HOT_SPOT_Y, pos->y_hotspot);
216
217 REG_SET(CURSOR_DST_OFFSET, 0,
218 CURSOR_DST_X_OFFSET, dst_x_offset);
219 /* TODO Handle surface pixel formats other than 4:4:4 */
220}
221
222/*****************************************/ 40/*****************************************/
223/* Constructor, Destructor */ 41/* Constructor, Destructor */
224/*****************************************/ 42/*****************************************/
@@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
230} 48}
231 49
232static const struct ipp_funcs dcn10_ipp_funcs = { 50static const struct ipp_funcs dcn10_ipp_funcs = {
233 .ipp_cursor_set_attributes = ippn10_cursor_set_attributes,
234 .ipp_cursor_set_position = ippn10_cursor_set_position,
235 .ipp_set_degamma = NULL,
236 .ipp_program_input_lut = NULL,
237 .ipp_full_bypass = NULL,
238 .ipp_setup = NULL,
239 .ipp_program_degamma_pwl = NULL,
240 .ipp_destroy = dcn10_ipp_destroy 51 .ipp_destroy = dcn10_ipp_destroy
241}; 52};
242 53
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
index 082b39a65e6a..76573e1f5b01 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c
@@ -65,7 +65,7 @@ static void mpc10_set_bg_color(
65 MPCC_BG_B_CB, bg_b_cb); 65 MPCC_BG_B_CB, bg_b_cb);
66} 66}
67 67
68static void mpc10_assert_idle_mpcc(struct mpc *mpc, int id) 68void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
69{ 69{
70 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); 70 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
71 71
@@ -116,19 +116,21 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i
116 } 116 }
117} 117}
118 118
119static void mpc10_mpcc_remove( 119void mpc10_mpcc_remove(
120 struct mpc *mpc, 120 struct mpc *mpc,
121 struct output_pixel_processor *opp, 121 struct mpc_tree_cfg *tree_cfg,
122 int opp_id,
122 int dpp_id) 123 int dpp_id)
123{ 124{
124 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); 125 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
125 int mpcc_id, z_idx; 126 int mpcc_id, z_idx;
126 127
127 for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++) 128 /* find z_idx for the dpp to be removed */
128 if (opp->mpc_tree.dpp[z_idx] == dpp_id) 129 for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++)
130 if (tree_cfg->dpp[z_idx] == dpp_id)
129 break; 131 break;
130 132
131 if (z_idx == opp->mpc_tree.num_pipes) { 133 if (z_idx == tree_cfg->num_pipes) {
132 /* In case of resume from S3/S4, remove mpcc from bios left over */ 134 /* In case of resume from S3/S4, remove mpcc from bios left over */
133 REG_SET(MPCC_OPP_ID[dpp_id], 0, 135 REG_SET(MPCC_OPP_ID[dpp_id], 0,
134 MPCC_OPP_ID, 0xf); 136 MPCC_OPP_ID, 0xf);
@@ -139,7 +141,7 @@ static void mpc10_mpcc_remove(
139 return; 141 return;
140 } 142 }
141 143
142 mpcc_id = opp->mpc_tree.mpcc[z_idx]; 144 mpcc_id = tree_cfg->mpcc[z_idx];
143 145
144 REG_SET(MPCC_OPP_ID[mpcc_id], 0, 146 REG_SET(MPCC_OPP_ID[mpcc_id], 0,
145 MPCC_OPP_ID, 0xf); 147 MPCC_OPP_ID, 0xf);
@@ -149,82 +151,101 @@ static void mpc10_mpcc_remove(
149 MPCC_BOT_SEL, 0xf); 151 MPCC_BOT_SEL, 0xf);
150 152
151 if (z_idx > 0) { 153 if (z_idx > 0) {
152 int top_mpcc_id = opp->mpc_tree.mpcc[z_idx - 1]; 154 int top_mpcc_id = tree_cfg->mpcc[z_idx - 1];
153 155
154 if (z_idx + 1 < opp->mpc_tree.num_pipes) 156 if (z_idx + 1 < tree_cfg->num_pipes)
157 /* mpcc to be removed is in the middle of the tree */
155 REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, 158 REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
156 MPCC_BOT_SEL, opp->mpc_tree.mpcc[z_idx + 1]); 159 MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]);
157 else { 160 else {
161 /* mpcc to be removed is at the bottom of the tree */
158 REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, 162 REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
159 MPCC_BOT_SEL, 0xf); 163 MPCC_BOT_SEL, 0xf);
160 REG_UPDATE(MPCC_CONTROL[top_mpcc_id], 164 REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
161 MPCC_MODE, MODE_TOP_ONLY); 165 MPCC_MODE, MODE_TOP_ONLY);
162 } 166 }
163 } else if (opp->mpc_tree.num_pipes > 1) 167 } else if (tree_cfg->num_pipes > 1)
164 REG_SET(MUX[opp->inst], 0, 168 /* mpcc to be removed is at the top of the tree */
165 MPC_OUT_MUX, opp->mpc_tree.mpcc[z_idx + 1]); 169 REG_SET(MUX[opp_id], 0,
170 MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]);
166 else 171 else
167 REG_SET(MUX[opp->inst], 0, MPC_OUT_MUX, 0xf); 172 /* mpcc to be removed is the only one in the tree */
173 REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf);
168 174
175 /* mark this mpcc as not in use */
169 mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); 176 mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
170 opp->mpc_tree.num_pipes--; 177 tree_cfg->num_pipes--;
171 for (; z_idx < opp->mpc_tree.num_pipes; z_idx++) { 178 for (; z_idx < tree_cfg->num_pipes; z_idx++) {
172 opp->mpc_tree.dpp[z_idx] = opp->mpc_tree.dpp[z_idx + 1]; 179 tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1];
173 opp->mpc_tree.mpcc[z_idx] = opp->mpc_tree.mpcc[z_idx + 1]; 180 tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1];
174 } 181 }
175 opp->mpc_tree.dpp[opp->mpc_tree.num_pipes] = 0xdeadbeef; 182 tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef;
176 opp->mpc_tree.mpcc[opp->mpc_tree.num_pipes] = 0xdeadbeef; 183 tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef;
177} 184}
178 185
179static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg) 186static void mpc10_add_to_tree_cfg(
187 struct mpc *mpc,
188 struct mpcc_cfg *cfg,
189 int mpcc_id)
180{ 190{
181 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); 191 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
192 int mpcc_mode = MODE_TOP_ONLY;
193 int position = cfg->z_index;
194 struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg;
182 int alpha_blnd_mode = cfg->per_pixel_alpha ? 195 int alpha_blnd_mode = cfg->per_pixel_alpha ?
183 BLND_PP_ALPHA : BLND_GLOBAL_ALPHA; 196 BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
184 int mpcc_mode = MODE_TOP_ONLY; 197 int z_idx;
185 int mpcc_id, z_idx;
186 198
187 ASSERT(cfg->z_index < mpc10->num_mpcc); 199 REG_SET(MPCC_OPP_ID[mpcc_id], 0,
200 MPCC_OPP_ID, cfg->opp_id);
188 201
189 for (z_idx = 0; z_idx < cfg->opp->mpc_tree.num_pipes; z_idx++) 202 REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
190 if (cfg->opp->mpc_tree.dpp[z_idx] == cfg->mi->inst) 203 MPCC_TOP_SEL, cfg->dpp_id);
191 break;
192 if (z_idx == cfg->opp->mpc_tree.num_pipes) {
193 ASSERT(cfg->z_index <= cfg->opp->mpc_tree.num_pipes);
194 mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
195 /*todo: remove hack*/
196 mpcc_id = cfg->mi->inst;
197 ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
198 204
199 if (mpc->ctx->dc->debug.sanity_checks) 205 if (position == 0) {
200 mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id); 206 /* idle dpp/mpcc is added to the top layer of tree */
201 } else {
202 ASSERT(cfg->z_index < cfg->opp->mpc_tree.num_pipes);
203 mpcc_id = cfg->opp->mpc_tree.mpcc[z_idx];
204 mpc10_mpcc_remove(mpc, cfg->opp, cfg->mi->inst);
205 }
206 207
207 REG_SET(MPCC_OPP_ID[mpcc_id], 0, 208 if (tree_cfg->num_pipes > 0) {
208 MPCC_OPP_ID, cfg->opp->inst); 209 /* get instance of previous top mpcc */
210 int prev_top_mpcc_id = tree_cfg->mpcc[0];
209 211
210 REG_SET(MPCC_TOP_SEL[mpcc_id], 0, 212 REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
211 MPCC_TOP_SEL, cfg->mi->inst); 213 MPCC_BOT_SEL, prev_top_mpcc_id);
214 mpcc_mode = MODE_BLEND;
215 }
212 216
213 if (cfg->z_index > 0) { 217 /* opp will get new output. from new added mpcc */
214 int top_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index - 1]; 218 REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id);
215 219
216 REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0, 220 } else if (position == tree_cfg->num_pipes) {
221 /* idle dpp/mpcc is added to the bottom layer of tree */
222
223 /* get instance of previous bottom mpcc, set to middle layer */
224 int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1];
225
226 REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0,
217 MPCC_BOT_SEL, mpcc_id); 227 MPCC_BOT_SEL, mpcc_id);
218 REG_UPDATE(MPCC_CONTROL[top_mpcc_id], 228 REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id],
219 MPCC_MODE, MODE_BLEND); 229 MPCC_MODE, MODE_BLEND);
220 } else
221 REG_SET(MUX[cfg->opp->inst], 0, MPC_OUT_MUX, mpcc_id);
222 230
223 if (cfg->z_index < cfg->opp->mpc_tree.num_pipes) { 231 /* mpcc_id become new bottom mpcc*/
224 int bot_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index]; 232 REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
233 MPCC_BOT_SEL, 0xf);
234
235 } else {
236 /* idle dpp/mpcc is added to middle of tree */
237 int above_mpcc_id = tree_cfg->mpcc[position - 1];
238 int below_mpcc_id = tree_cfg->mpcc[position];
225 239
240 /* mpcc above new mpcc_id has new bottom mux*/
241 REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0,
242 MPCC_BOT_SEL, mpcc_id);
243 REG_UPDATE(MPCC_CONTROL[above_mpcc_id],
244 MPCC_MODE, MODE_BLEND);
245
246 /* mpcc_id bottom mux is from below mpcc*/
226 REG_SET(MPCC_BOT_SEL[mpcc_id], 0, 247 REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
227 MPCC_BOT_SEL, bot_mpcc_id); 248 MPCC_BOT_SEL, below_mpcc_id);
228 mpcc_mode = MODE_BLEND; 249 mpcc_mode = MODE_BLEND;
229 } 250 }
230 251
@@ -234,24 +255,91 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
234 MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha, 255 MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
235 MPCC_BLND_ACTIVE_OVERLAP_ONLY, false); 256 MPCC_BLND_ACTIVE_OVERLAP_ONLY, false);
236 257
258 /* update mpc_tree_cfg with new mpcc */
259 for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) {
260 tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1];
261 tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1];
262 }
263 tree_cfg->dpp[position] = cfg->dpp_id;
264 tree_cfg->mpcc[position] = mpcc_id;
265 tree_cfg->num_pipes++;
266}
267
268int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
269{
270 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
271 int mpcc_id, z_idx;
272
273 ASSERT(cfg->z_index < mpc10->num_mpcc);
274
275 /* check in dpp already exists in mpc tree */
276 for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
277 if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
278 break;
279 if (z_idx == cfg->tree_cfg->num_pipes) {
280 ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes);
281 mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
282
283 /*
284 * TODO: remove hack
285 * Note: currently there is a bug in init_hw such that
286 * on resume from hibernate, BIOS sets up MPCC0, and
287 * we do mpcc_remove but the mpcc cannot go to idle
288 * after remove. This cause us to pick mpcc1 here,
289 * which causes a pstate hang for yet unknown reason.
290 */
291 mpcc_id = cfg->dpp_id;
292 /* end hack*/
293
294 ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
295
296 if (mpc->ctx->dc->debug.sanity_checks)
297 mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
298 } else {
299 ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes);
300 mpcc_id = cfg->tree_cfg->mpcc[z_idx];
301 mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id);
302 }
303
304 /* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */
305 mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id);
306
307 /* set background color */
237 mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id); 308 mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id);
238 309
310 /* mark this mpcc as in use */
239 mpc10->mpcc_in_use_mask |= 1 << mpcc_id; 311 mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
240 for (z_idx = cfg->opp->mpc_tree.num_pipes; z_idx > cfg->z_index; z_idx--) { 312
241 cfg->opp->mpc_tree.dpp[z_idx] = cfg->opp->mpc_tree.dpp[z_idx - 1]; 313 return mpcc_id;
242 cfg->opp->mpc_tree.mpcc[z_idx] = cfg->opp->mpc_tree.mpcc[z_idx - 1]; 314}
243 } 315
244 cfg->opp->mpc_tree.dpp[cfg->z_index] = cfg->mi->inst; 316void mpc10_update_blend_mode(
245 cfg->opp->mpc_tree.mpcc[cfg->z_index] = mpcc_id; 317 struct mpc *mpc,
246 cfg->opp->mpc_tree.num_pipes++; 318 struct mpcc_cfg *cfg)
247 cfg->mi->opp_id = cfg->opp->inst; 319{
248 cfg->mi->mpcc_id = mpcc_id; 320 struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
321 int mpcc_id, z_idx;
322 int alpha_blnd_mode = cfg->per_pixel_alpha ?
323 BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
324
325 /* find z_idx for the dpp that requires blending mode update*/
326 for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
327 if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
328 break;
329
330 ASSERT(z_idx < cfg->tree_cfg->num_pipes);
331 mpcc_id = cfg->tree_cfg->mpcc[z_idx];
332
333 REG_UPDATE_2(MPCC_CONTROL[mpcc_id],
334 MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
335 MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha);
249} 336}
250 337
251const struct mpc_funcs dcn10_mpc_funcs = { 338const struct mpc_funcs dcn10_mpc_funcs = {
252 .add = mpc10_mpcc_add, 339 .add = mpc10_mpcc_add,
253 .remove = mpc10_mpcc_remove, 340 .remove = mpc10_mpcc_remove,
254 .wait_for_idle = mpc10_assert_idle_mpcc 341 .wait_for_idle = mpc10_assert_idle_mpcc,
342 .update_blend_mode = mpc10_update_blend_mode,
255}; 343};
256 344
257void dcn10_mpc_construct(struct dcn10_mpc *mpc10, 345void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
@@ -272,3 +360,4 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
272 mpc10->mpcc_in_use_mask = 0; 360 mpc10->mpcc_in_use_mask = 0;
273 mpc10->num_mpcc = num_mpcc; 361 mpc10->num_mpcc = num_mpcc;
274} 362}
363
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
index 94f890a0ad40..683ce4aaa76e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.h
@@ -34,7 +34,6 @@
34#define MAX_OPP 6 34#define MAX_OPP 6
35 35
36#define MPC_COMMON_REG_LIST_DCN1_0(inst) \ 36#define MPC_COMMON_REG_LIST_DCN1_0(inst) \
37 SRII(MUX, MPC_OUT, inst),\
38 SRII(MPCC_TOP_SEL, MPCC, inst),\ 37 SRII(MPCC_TOP_SEL, MPCC, inst),\
39 SRII(MPCC_BOT_SEL, MPCC, inst),\ 38 SRII(MPCC_BOT_SEL, MPCC, inst),\
40 SRII(MPCC_CONTROL, MPCC, inst),\ 39 SRII(MPCC_CONTROL, MPCC, inst),\
@@ -45,17 +44,19 @@
45 SRII(MPCC_BG_B_CB, MPCC, inst),\ 44 SRII(MPCC_BG_B_CB, MPCC, inst),\
46 SRII(MPCC_BG_B_CB, MPCC, inst) 45 SRII(MPCC_BG_B_CB, MPCC, inst)
47 46
48struct dcn_mpc_registers { 47#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
49 uint32_t MPCC_TOP_SEL[MAX_MPCC]; 48 SRII(MUX, MPC_OUT, inst)
50 uint32_t MPCC_BOT_SEL[MAX_MPCC]; 49
51 uint32_t MPCC_CONTROL[MAX_MPCC]; 50#define MPC_COMMON_REG_VARIABLE_LIST \
52 uint32_t MPCC_STATUS[MAX_MPCC]; 51 uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
53 uint32_t MPCC_OPP_ID[MAX_MPCC]; 52 uint32_t MPCC_BOT_SEL[MAX_MPCC]; \
54 uint32_t MPCC_BG_G_Y[MAX_MPCC]; 53 uint32_t MPCC_CONTROL[MAX_MPCC]; \
55 uint32_t MPCC_BG_R_CR[MAX_MPCC]; 54 uint32_t MPCC_STATUS[MAX_MPCC]; \
56 uint32_t MPCC_BG_B_CB[MAX_MPCC]; 55 uint32_t MPCC_OPP_ID[MAX_MPCC]; \
56 uint32_t MPCC_BG_G_Y[MAX_MPCC]; \
57 uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
58 uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
57 uint32_t MUX[MAX_OPP]; 59 uint32_t MUX[MAX_OPP];
58};
59 60
60#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ 61#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
61 SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ 62 SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
@@ -87,6 +88,10 @@ struct dcn_mpc_registers {
87 type MPCC_BG_B_CB;\ 88 type MPCC_BG_B_CB;\
88 type MPC_OUT_MUX; 89 type MPC_OUT_MUX;
89 90
91struct dcn_mpc_registers {
92 MPC_COMMON_REG_VARIABLE_LIST
93};
94
90struct dcn_mpc_shift { 95struct dcn_mpc_shift {
91 MPC_REG_FIELD_LIST(uint8_t) 96 MPC_REG_FIELD_LIST(uint8_t)
92}; 97};
@@ -112,4 +117,22 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10,
112 const struct dcn_mpc_mask *mpc_mask, 117 const struct dcn_mpc_mask *mpc_mask,
113 int num_mpcc); 118 int num_mpcc);
114 119
120int mpc10_mpcc_add(
121 struct mpc *mpc,
122 struct mpcc_cfg *cfg);
123
124void mpc10_mpcc_remove(
125 struct mpc *mpc,
126 struct mpc_tree_cfg *tree_cfg,
127 int opp_id,
128 int dpp_id);
129
130void mpc10_assert_idle_mpcc(
131 struct mpc *mpc,
132 int id);
133
134void mpc10_update_blend_mode(
135 struct mpc *mpc,
136 struct mpcc_cfg *cfg);
137
115#endif 138#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index dc878f77837b..d911590d08bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -42,12 +42,12 @@
42#include "dce/dce_stream_encoder.h" 42#include "dce/dce_stream_encoder.h"
43#include "dce/dce_clocks.h" 43#include "dce/dce_clocks.h"
44#include "dce/dce_clock_source.h" 44#include "dce/dce_clock_source.h"
45#include "dcn10/dcn10_mem_input.h"
46#include "dce/dce_audio.h" 45#include "dce/dce_audio.h"
47#include "dce/dce_hwseq.h" 46#include "dce/dce_hwseq.h"
48#include "../virtual/virtual_stream_encoder.h" 47#include "../virtual/virtual_stream_encoder.h"
49#include "dce110/dce110_resource.h" 48#include "dce110/dce110_resource.h"
50#include "dce112/dce112_resource.h" 49#include "dce112/dce112_resource.h"
50#include "dcn10_hubp.h"
51 51
52#include "vega10/soc15ip.h" 52#include "vega10/soc15ip.h"
53 53
@@ -329,7 +329,11 @@ static const struct dcn_mpc_registers mpc_regs = {
329 MPC_COMMON_REG_LIST_DCN1_0(0), 329 MPC_COMMON_REG_LIST_DCN1_0(0),
330 MPC_COMMON_REG_LIST_DCN1_0(1), 330 MPC_COMMON_REG_LIST_DCN1_0(1),
331 MPC_COMMON_REG_LIST_DCN1_0(2), 331 MPC_COMMON_REG_LIST_DCN1_0(2),
332 MPC_COMMON_REG_LIST_DCN1_0(3) 332 MPC_COMMON_REG_LIST_DCN1_0(3),
333 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
334 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
335 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
336 MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
333}; 337};
334 338
335static const struct dcn_mpc_shift mpc_shift = { 339static const struct dcn_mpc_shift mpc_shift = {
@@ -414,22 +418,24 @@ static const struct resource_caps res_cap = {
414}; 418};
415 419
416static const struct dc_debug debug_defaults_drv = { 420static const struct dc_debug debug_defaults_drv = {
417 .disable_dcc = false,
418 .sanity_checks = true, 421 .sanity_checks = true,
419 .disable_dmcu = true, 422 .disable_dmcu = true,
420 .force_abm_enable = false, 423 .force_abm_enable = false,
421 .timing_trace = false, 424 .timing_trace = false,
422 .clock_trace = true, 425 .clock_trace = true,
423 /* spread sheet doesn't handle taps_c is one properly, 426
424 * need to enable scaler for video surface to pass 427 .min_disp_clk_khz = 300000,
425 * bandwidth validation.*/ 428
426 .always_scale = true,
427 .disable_pplib_clock_request = true, 429 .disable_pplib_clock_request = true,
428 .disable_pplib_wm_range = false, 430 .disable_pplib_wm_range = false,
429#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 431 .pplib_wm_report_mode = WM_REPORT_DEFAULT,
430 .use_dml_wm = false, 432 .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
431 .disable_pipe_split = true 433 .force_single_disp_pipe_split = true,
432#endif 434 .disable_dcc = DCC_ENABLE,
435 .voltage_align_fclk = true,
436 .disable_stereo_support = true,
437 .vsr_support = true,
438 .performance_trace = false,
433}; 439};
434 440
435static const struct dc_debug debug_defaults_diags = { 441static const struct dc_debug debug_defaults_diags = {
@@ -438,21 +444,17 @@ static const struct dc_debug debug_defaults_diags = {
438 .timing_trace = true, 444 .timing_trace = true,
439 .clock_trace = true, 445 .clock_trace = true,
440 .disable_stutter = true, 446 .disable_stutter = true,
441#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
442 .disable_pplib_clock_request = true, 447 .disable_pplib_clock_request = true,
443 .disable_pplib_wm_range = true, 448 .disable_pplib_wm_range = true
444 .use_dml_wm = false,
445 .disable_pipe_split = false
446#endif
447}; 449};
448 450
449static void dcn10_dpp_destroy(struct transform **xfm) 451static void dcn10_dpp_destroy(struct dpp **dpp)
450{ 452{
451 kfree(TO_DCN10_DPP(*xfm)); 453 kfree(TO_DCN10_DPP(*dpp));
452 *xfm = NULL; 454 *dpp = NULL;
453} 455}
454 456
455static struct transform *dcn10_dpp_create( 457static struct dpp *dcn10_dpp_create(
456 struct dc_context *ctx, 458 struct dc_context *ctx,
457 uint32_t inst) 459 uint32_t inst)
458{ 460{
@@ -462,8 +464,8 @@ static struct transform *dcn10_dpp_create(
462 if (!dpp) 464 if (!dpp)
463 return NULL; 465 return NULL;
464 466
465 dcn10_dpp_construct(dpp, ctx, inst, 467 dpp1_construct(dpp, ctx, inst,
466 &tf_regs[inst], &tf_shift, &tf_mask); 468 &tf_regs[inst], &tf_shift, &tf_mask);
467 return &dpp->base; 469 return &dpp->base;
468} 470}
469 471
@@ -702,15 +704,15 @@ static void destruct(struct dcn10_resource_pool *pool)
702 if (pool->base.opps[i] != NULL) 704 if (pool->base.opps[i] != NULL)
703 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]); 705 pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
704 706
705 if (pool->base.transforms[i] != NULL) 707 if (pool->base.dpps[i] != NULL)
706 dcn10_dpp_destroy(&pool->base.transforms[i]); 708 dcn10_dpp_destroy(&pool->base.dpps[i]);
707 709
708 if (pool->base.ipps[i] != NULL) 710 if (pool->base.ipps[i] != NULL)
709 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]); 711 pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
710 712
711 if (pool->base.mis[i] != NULL) { 713 if (pool->base.hubps[i] != NULL) {
712 kfree(TO_DCN10_MEM_INPUT(pool->base.mis[i])); 714 kfree(TO_DCN10_HUBP(pool->base.hubps[i]));
713 pool->base.mis[i] = NULL; 715 pool->base.hubps[i] = NULL;
714 } 716 }
715 717
716 if (pool->base.irqs != NULL) { 718 if (pool->base.irqs != NULL) {
@@ -757,19 +759,19 @@ static void destruct(struct dcn10_resource_pool *pool)
757 kfree(pool->base.pp_smu); 759 kfree(pool->base.pp_smu);
758} 760}
759 761
760static struct mem_input *dcn10_mem_input_create( 762static struct hubp *dcn10_hubp_create(
761 struct dc_context *ctx, 763 struct dc_context *ctx,
762 uint32_t inst) 764 uint32_t inst)
763{ 765{
764 struct dcn10_mem_input *mem_inputn10 = 766 struct dcn10_hubp *hubp1 =
765 kzalloc(sizeof(struct dcn10_mem_input), GFP_KERNEL); 767 kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL);
766 768
767 if (!mem_inputn10) 769 if (!hubp1)
768 return NULL; 770 return NULL;
769 771
770 dcn10_mem_input_construct(mem_inputn10, ctx, inst, 772 dcn10_hubp_construct(hubp1, ctx, inst,
771 &mi_regs[inst], &mi_shift, &mi_mask); 773 &mi_regs[inst], &mi_shift, &mi_mask);
772 return &mem_inputn10->base; 774 return &hubp1->base;
773} 775}
774 776
775static void get_pixel_clock_parameters( 777static void get_pixel_clock_parameters(
@@ -922,9 +924,9 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
922 idle_pipe->stream_res.tg = head_pipe->stream_res.tg; 924 idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
923 idle_pipe->stream_res.opp = head_pipe->stream_res.opp; 925 idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
924 926
925 idle_pipe->plane_res.mi = pool->mis[idle_pipe->pipe_idx]; 927 idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
926 idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx]; 928 idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
927 idle_pipe->plane_res.xfm = pool->transforms[idle_pipe->pipe_idx]; 929 idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
928 930
929 return idle_pipe; 931 return idle_pipe;
930} 932}
@@ -1085,7 +1087,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
1085 1087
1086 memset(output, 0, sizeof(*output)); 1088 memset(output, 0, sizeof(*output));
1087 1089
1088 if (dc->debug.disable_dcc) 1090 if (dc->debug.disable_dcc == DCC_DISABLE)
1089 return false; 1091 return false;
1090 1092
1091 if (!dcc_support_pixel_format(input->format, 1093 if (!dcc_support_pixel_format(input->format,
@@ -1129,6 +1131,10 @@ static bool get_dcc_compression_cap(const struct dc *dc,
1129 dcc_control = dcc_control__128_128_xxx; 1131 dcc_control = dcc_control__128_128_xxx;
1130 } 1132 }
1131 1133
1134 if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
1135 dcc_control != dcc_control__256_256_xxx)
1136 return false;
1137
1132 switch (dcc_control) { 1138 switch (dcc_control) {
1133 case dcc_control__256_256_xxx: 1139 case dcc_control__256_256_xxx:
1134 output->grph.rgb.max_uncompressed_blk_size = 256; 1140 output->grph.rgb.max_uncompressed_blk_size = 256;
@@ -1146,6 +1152,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
1146 output->grph.rgb.independent_64b_blks = true; 1152 output->grph.rgb.independent_64b_blks = true;
1147 break; 1153 break;
1148 } 1154 }
1155
1149 output->capable = true; 1156 output->capable = true;
1150 output->const_color_support = false; 1157 output->const_color_support = false;
1151 1158
@@ -1162,6 +1169,15 @@ static void dcn10_destroy_resource_pool(struct resource_pool **pool)
1162 *pool = NULL; 1169 *pool = NULL;
1163} 1170}
1164 1171
1172static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
1173{
1174 if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
1175 && caps->max_video_width != 0
1176 && plane_state->src_rect.width > caps->max_video_width)
1177 return DC_FAIL_SURFACE_VALIDATE;
1178
1179 return DC_OK;
1180}
1165 1181
1166static struct dc_cap_funcs cap_funcs = { 1182static struct dc_cap_funcs cap_funcs = {
1167 .get_dcc_compression_cap = get_dcc_compression_cap 1183 .get_dcc_compression_cap = get_dcc_compression_cap
@@ -1173,6 +1189,7 @@ static struct resource_funcs dcn10_res_pool_funcs = {
1173 .validate_guaranteed = dcn10_validate_guaranteed, 1189 .validate_guaranteed = dcn10_validate_guaranteed,
1174 .validate_bandwidth = dcn_validate_bandwidth, 1190 .validate_bandwidth = dcn_validate_bandwidth,
1175 .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer, 1191 .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
1192 .validate_plane = dcn10_validate_plane,
1176 .add_stream_to_ctx = dcn10_add_stream_to_ctx 1193 .add_stream_to_ctx = dcn10_add_stream_to_ctx
1177}; 1194};
1178 1195
@@ -1212,6 +1229,7 @@ static bool construct(
1212 /* max pipe num for ASIC before check pipe fuses */ 1229 /* max pipe num for ASIC before check pipe fuses */
1213 pool->base.pipe_count = pool->base.res_cap->num_timing_generator; 1230 pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1214 1231
1232 dc->caps.max_video_width = 3840;
1215 dc->caps.max_downscale_ratio = 200; 1233 dc->caps.max_downscale_ratio = 200;
1216 dc->caps.i2c_speed_in_khz = 100; 1234 dc->caps.i2c_speed_in_khz = 100;
1217 dc->caps.max_cursor_size = 256; 1235 dc->caps.max_cursor_size = 256;
@@ -1345,8 +1363,8 @@ static bool construct(
1345 if ((pipe_fuses & (1 << i)) != 0) 1363 if ((pipe_fuses & (1 << i)) != 0)
1346 continue; 1364 continue;
1347 1365
1348 pool->base.mis[j] = dcn10_mem_input_create(ctx, i); 1366 pool->base.hubps[j] = dcn10_hubp_create(ctx, i);
1349 if (pool->base.mis[j] == NULL) { 1367 if (pool->base.hubps[j] == NULL) {
1350 BREAK_TO_DEBUGGER(); 1368 BREAK_TO_DEBUGGER();
1351 dm_error( 1369 dm_error(
1352 "DC: failed to create memory input!\n"); 1370 "DC: failed to create memory input!\n");
@@ -1361,8 +1379,8 @@ static bool construct(
1361 goto ipp_create_fail; 1379 goto ipp_create_fail;
1362 } 1380 }
1363 1381
1364 pool->base.transforms[j] = dcn10_dpp_create(ctx, i); 1382 pool->base.dpps[j] = dcn10_dpp_create(ctx, i);
1365 if (pool->base.transforms[j] == NULL) { 1383 if (pool->base.dpps[j] == NULL) {
1366 BREAK_TO_DEBUGGER(); 1384 BREAK_TO_DEBUGGER();
1367 dm_error( 1385 dm_error(
1368 "DC: failed to create dpp!\n"); 1386 "DC: failed to create dpp!\n");
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
index 7cd10cbc5497..1994865d4351 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.c
@@ -25,6 +25,7 @@
25 25
26#include "reg_helper.h" 26#include "reg_helper.h"
27#include "dcn10_timing_generator.h" 27#include "dcn10_timing_generator.h"
28#include "dc.h"
28 29
29#define REG(reg)\ 30#define REG(reg)\
30 tgn10->tg_regs->reg 31 tgn10->tg_regs->reg
@@ -299,6 +300,17 @@ static void tgn10_program_timing(
299static void tgn10_unblank_crtc(struct timing_generator *tg) 300static void tgn10_unblank_crtc(struct timing_generator *tg)
300{ 301{
301 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg); 302 struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
303 uint32_t vertical_interrupt_enable = 0;
304
305 REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
306 OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
307
308 /* temporary work around for vertical interrupt, once vertical interrupt enabled,
309 * this check will be removed.
310 */
311 if (vertical_interrupt_enable)
312 REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
313 OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 1);
302 314
303 REG_UPDATE_2(OTG_BLANK_CONTROL, 315 REG_UPDATE_2(OTG_BLANK_CONTROL,
304 OTG_BLANK_DATA_EN, 0, 316 OTG_BLANK_DATA_EN, 0,
@@ -487,6 +499,9 @@ static bool tgn10_validate_timing(
487 timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA) 499 timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
488 return false; 500 return false;
489 501
502 if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
503 tg->ctx->dc->debug.disable_stereo_support)
504 return false;
490 /* Temporarily blocking interlacing mode until it's supported */ 505 /* Temporarily blocking interlacing mode until it's supported */
491 if (timing->flags.INTERLACE == 1) 506 if (timing->flags.INTERLACE == 1)
492 return false; 507 return false;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
index 69da293e9b4a..7d4818d7aa31 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_timing_generator.h
@@ -65,17 +65,14 @@
65 SRI(OTG_NOM_VERT_POSITION, OTG, inst),\ 65 SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
66 SRI(OTG_BLACK_COLOR, OTG, inst),\ 66 SRI(OTG_BLACK_COLOR, OTG, inst),\
67 SRI(OTG_CLOCK_CONTROL, OTG, inst),\ 67 SRI(OTG_CLOCK_CONTROL, OTG, inst),\
68 SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
68 SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\ 69 SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
69 SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ 70 SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
70 SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\ 71 SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
71 SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\ 72 SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
72 SRI(OPPBUF_CONTROL, OPPBUF, inst),\ 73 SRI(OPPBUF_CONTROL, OPPBUF, inst),\
73 SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\ 74 SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\
74 SRI(CONTROL, VTG, inst),\ 75 SRI(CONTROL, VTG, inst)
75 SR(D1VGA_CONTROL),\
76 SR(D2VGA_CONTROL),\
77 SR(D3VGA_CONTROL),\
78 SR(D4VGA_CONTROL)
79 76
80#define TG_COMMON_REG_LIST_DCN1_0(inst) \ 77#define TG_COMMON_REG_LIST_DCN1_0(inst) \
81 TG_COMMON_REG_LIST_DCN(inst),\ 78 TG_COMMON_REG_LIST_DCN(inst),\
@@ -121,6 +118,7 @@ struct dcn_tg_registers {
121 uint32_t OTG_TEST_PATTERN_CONTROL; 118 uint32_t OTG_TEST_PATTERN_CONTROL;
122 uint32_t OTG_TEST_PATTERN_COLOR; 119 uint32_t OTG_TEST_PATTERN_COLOR;
123 uint32_t OTG_CLOCK_CONTROL; 120 uint32_t OTG_CLOCK_CONTROL;
121 uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
124 uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; 122 uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
125 uint32_t OPTC_INPUT_CLOCK_CONTROL; 123 uint32_t OPTC_INPUT_CLOCK_CONTROL;
126 uint32_t OPTC_DATA_SOURCE_SELECT; 124 uint32_t OPTC_DATA_SOURCE_SELECT;
@@ -128,11 +126,6 @@ struct dcn_tg_registers {
128 uint32_t OPPBUF_CONTROL; 126 uint32_t OPPBUF_CONTROL;
129 uint32_t OPPBUF_3D_PARAMETERS_0; 127 uint32_t OPPBUF_3D_PARAMETERS_0;
130 uint32_t CONTROL; 128 uint32_t CONTROL;
131 /*todo: move VGA to HWSS */
132 uint32_t D1VGA_CONTROL;
133 uint32_t D2VGA_CONTROL;
134 uint32_t D3VGA_CONTROL;
135 uint32_t D4VGA_CONTROL;
136}; 129};
137 130
138#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ 131#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -205,6 +198,7 @@ struct dcn_tg_registers {
205 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\ 198 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
206 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\ 199 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
207 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\ 200 SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
201 SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
208 SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\ 202 SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
209 SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\ 203 SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
210 SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\ 204 SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
@@ -311,6 +305,7 @@ struct dcn_tg_registers {
311 type OTG_CLOCK_EN;\ 305 type OTG_CLOCK_EN;\
312 type OTG_CLOCK_ON;\ 306 type OTG_CLOCK_ON;\
313 type OTG_CLOCK_GATE_DIS;\ 307 type OTG_CLOCK_GATE_DIS;\
308 type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
314 type OTG_VERTICAL_INTERRUPT2_LINE_START;\ 309 type OTG_VERTICAL_INTERRUPT2_LINE_START;\
315 type OPTC_INPUT_CLK_EN;\ 310 type OPTC_INPUT_CLK_EN;\
316 type OPTC_INPUT_CLK_ON;\ 311 type OPTC_INPUT_CLK_ON;\
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h
index a11991c382de..c8190c38a644 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services.h
@@ -38,51 +38,6 @@
38 38
39#undef DEPRECATED 39#undef DEPRECATED
40 40
41/*
42 *
43 * general debug capabilities
44 *
45 */
46#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
47
48#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
49#define ASSERT_CRITICAL(expr) do { \
50 if (WARN_ON(!(expr))) { \
51 kgdb_breakpoint(); \
52 } \
53} while (0)
54#else
55#define ASSERT_CRITICAL(expr) do { \
56 if (WARN_ON(!(expr))) { \
57 ; \
58 } \
59} while (0)
60#endif
61
62#if defined(CONFIG_DEBUG_KERNEL_DC)
63#define ASSERT(expr) ASSERT_CRITICAL(expr)
64
65#else
66#define ASSERT(expr) WARN_ON(!(expr))
67#endif
68
69#define BREAK_TO_DEBUGGER() ASSERT(0)
70
71#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
72
73#define DC_ERR(...) do { \
74 dm_error(__VA_ARGS__); \
75 BREAK_TO_DEBUGGER(); \
76} while (0)
77
78#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
79#include <asm/fpu/api.h>
80#endif
81
82#define dm_alloc(size) kzalloc(size, GFP_KERNEL)
83#define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
84#define dm_free(ptr) kfree(ptr)
85
86irq_handler_idx dm_register_interrupt( 41irq_handler_idx dm_register_interrupt(
87 struct dc_context *ctx, 42 struct dc_context *ctx,
88 struct dc_interrupt_params *int_params, 43 struct dc_interrupt_params *int_params,
@@ -418,6 +373,8 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
418#define dm_log_to_buffer(buffer, size, fmt, args)\ 373#define dm_log_to_buffer(buffer, size, fmt, args)\
419 vsnprintf(buffer, size, fmt, args) 374 vsnprintf(buffer, size, fmt, args)
420 375
376unsigned long long dm_get_timestamp(struct dc_context *ctx);
377
421/* 378/*
422 * Debug and verification hooks 379 * Debug and verification hooks
423 */ 380 */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index ec712d727665..87bab8e8139f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -3,17 +3,19 @@
3# It provides the general basic services required by other DAL 3# It provides the general basic services required by other DAL
4# subcomponents. 4# subcomponents.
5 5
6CFLAGS_display_mode_vba.o := -mhard-float -msse -mpreferred-stack-boundary=4
6CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4 7CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4
7CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4 8CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4
8CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4 9CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
10CFLAGS_dml1_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
9CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4 11CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4
10CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4
11CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4 12CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4
12CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4 13CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4
13 14
15
14DML = display_mode_lib.o display_rq_dlg_calc.o \ 16DML = display_mode_lib.o display_rq_dlg_calc.o \
15 display_rq_dlg_helpers.o display_watermark.o \ 17 display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
16 soc_bounding_box.o dml_common_defs.o 18 soc_bounding_box.o dml_common_defs.o display_mode_vba.o
17 19
18AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML)) 20AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
19 21
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
index 745c04cb764a..ea4cde952f4f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dc_features.h
@@ -25,9 +25,11 @@
25#ifndef __DC_FEATURES_H__ 25#ifndef __DC_FEATURES_H__
26#define __DC_FEATURES_H__ 26#define __DC_FEATURES_H__
27 27
28// local features
28#define DC__PRESENT 1 29#define DC__PRESENT 1
29#define DC__PRESENT__1 1 30#define DC__PRESENT__1 1
30#define DC__NUM_DPP 4 31#define DC__NUM_DPP 4
32#define DC__VOLTAGE_STATES 7
31#define DC__NUM_DPP__4 1 33#define DC__NUM_DPP__4 1
32#define DC__NUM_DPP__0_PRESENT 1 34#define DC__NUM_DPP__0_PRESENT 1
33#define DC__NUM_DPP__1_PRESENT 1 35#define DC__NUM_DPP__1_PRESENT 1
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
index 143a3d418de0..b1ad3553f900 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h
@@ -24,14 +24,12 @@
24 */ 24 */
25#ifndef __DISPLAY_MODE_ENUMS_H__ 25#ifndef __DISPLAY_MODE_ENUMS_H__
26#define __DISPLAY_MODE_ENUMS_H__ 26#define __DISPLAY_MODE_ENUMS_H__
27
27enum output_encoder_class { 28enum output_encoder_class {
28 dm_dp = 0, 29 dm_dp = 0, dm_hdmi = 1, dm_wb = 2, dm_edp
29 dm_hdmi = 1,
30 dm_wb = 2
31}; 30};
32enum output_format_class { 31enum output_format_class {
33 dm_444 = 0, 32 dm_444 = 0, dm_420 = 1, dm_n422, dm_s422
34 dm_420 = 1
35}; 33};
36enum source_format_class { 34enum source_format_class {
37 dm_444_16 = 0, 35 dm_444_16 = 0,
@@ -40,18 +38,16 @@ enum source_format_class {
40 dm_420_8 = 3, 38 dm_420_8 = 3,
41 dm_420_10 = 4, 39 dm_420_10 = 4,
42 dm_422_8 = 5, 40 dm_422_8 = 5,
43 dm_422_10 = 6 41 dm_422_10 = 6,
42 dm_444_8 = 7,
43 dm_mono_8,
44 dm_mono_16
44}; 45};
45enum output_bpc_class { 46enum output_bpc_class {
46 dm_out_6 = 0, 47 dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4
47 dm_out_8 = 1,
48 dm_out_10 = 2,
49 dm_out_12 = 3,
50 dm_out_16 = 4
51}; 48};
52enum scan_direction_class { 49enum scan_direction_class {
53 dm_horz = 0, 50 dm_horz = 0, dm_vert = 1
54 dm_vert = 1
55}; 51};
56enum dm_swizzle_mode { 52enum dm_swizzle_mode {
57 dm_sw_linear = 0, 53 dm_sw_linear = 0,
@@ -84,28 +80,32 @@ enum dm_swizzle_mode {
84 dm_sw_SPARE_14 = 27, 80 dm_sw_SPARE_14 = 27,
85 dm_sw_SPARE_15 = 28, 81 dm_sw_SPARE_15 = 28,
86 dm_sw_var_s_x = 29, 82 dm_sw_var_s_x = 29,
87 dm_sw_var_d_x = 30 83 dm_sw_var_d_x = 30,
84 dm_sw_64kb_r_x,
85 dm_sw_gfx7_2d_thin_lvp,
86 dm_sw_gfx7_2d_thin_gl
88}; 87};
89enum lb_depth { 88enum lb_depth {
90 dm_lb_10 = 30, 89 dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16
91 dm_lb_8 = 24,
92 dm_lb_6 = 18,
93 dm_lb_12 = 36
94}; 90};
95enum voltage_state { 91enum voltage_state {
96 dm_vmin = 0, 92 dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3
97 dm_vmid = 1,
98 dm_vnom = 2,
99 dm_vmax = 3,
100 dm_vmax_exceeded = 4
101}; 93};
102enum source_macro_tile_size { 94enum source_macro_tile_size {
103 dm_4k_tile = 0, 95 dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2
104 dm_64k_tile = 1,
105 dm_256k_tile = 2
106}; 96};
107enum cursor_bpp { 97enum cursor_bpp {
108 dm_cur_2bit = 0, 98 dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2
109 dm_cur_32bit = 1
110}; 99};
100enum clock_change_support {
101 dm_dram_clock_change_uninitialized = 0,
102 dm_dram_clock_change_vactive,
103 dm_dram_clock_change_vblank,
104 dm_dram_clock_change_unsupported
105};
106
107enum output_standard {
108 dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt
109};
110
111#endif 111#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
index c02c5522613b..4c31fa54af39 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c
@@ -24,6 +24,7 @@
24 */ 24 */
25 25
26#include "display_mode_lib.h" 26#include "display_mode_lib.h"
27#include "dc_features.h"
27 28
28static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project) 29static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project)
29{ 30{
@@ -126,21 +127,11 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro
126 } 127 }
127} 128}
128 129
129static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project)
130{
131 if (project == DML_PROJECT_RAVEN1) {
132 me->voltage_override = dm_vmin;
133 } else {
134 BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
135 }
136}
137
138void dml_init_instance(struct display_mode_lib *lib, enum dml_project project) 130void dml_init_instance(struct display_mode_lib *lib, enum dml_project project)
139{ 131{
140 if (lib->project != project) { 132 if (lib->project != project) {
141 set_soc_bounding_box(&lib->soc, project); 133 set_soc_bounding_box(&lib->soc, project);
142 set_ip_params(&lib->ip, project); 134 set_ip_params(&lib->ip, project);
143 set_mode_evaluation(&lib->me, project);
144 lib->project = project; 135 lib->project = project;
145 } 136 }
146} 137}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
index eb1c8e6e7f23..26f4f2a3d90d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h
@@ -25,11 +25,12 @@
25#ifndef __DISPLAY_MODE_LIB_H__ 25#ifndef __DISPLAY_MODE_LIB_H__
26#define __DISPLAY_MODE_LIB_H__ 26#define __DISPLAY_MODE_LIB_H__
27 27
28
28#include "dml_common_defs.h" 29#include "dml_common_defs.h"
29#include "soc_bounding_box.h" 30#include "soc_bounding_box.h"
30#include "display_watermark.h" 31#include "display_mode_vba.h"
31#include "display_rq_dlg_calc.h" 32#include "display_rq_dlg_calc.h"
32#include "display_mode_support.h" 33#include "dml1_display_rq_dlg_calc.h"
33 34
34enum dml_project { 35enum dml_project {
35 DML_PROJECT_UNDEFINED, 36 DML_PROJECT_UNDEFINED,
@@ -39,10 +40,8 @@ enum dml_project {
39struct display_mode_lib { 40struct display_mode_lib {
40 struct _vcs_dpi_ip_params_st ip; 41 struct _vcs_dpi_ip_params_st ip;
41 struct _vcs_dpi_soc_bounding_box_st soc; 42 struct _vcs_dpi_soc_bounding_box_st soc;
42 struct _vcs_dpi_mode_evaluation_st me;
43 enum dml_project project; 43 enum dml_project project;
44 struct dml_ms_internal_vars vars; 44 struct vba_vars_st vba;
45 struct _vcs_dpi_wm_calc_pipe_params_st wm_param[DC__NUM_PIPES__MAX];
46 struct dal_logger *logger; 45 struct dal_logger *logger;
47}; 46};
48 47
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
index e589a5eadb6a..baf182177736 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
@@ -25,405 +25,533 @@
25#ifndef __DISPLAY_MODE_STRUCTS_H__ 25#ifndef __DISPLAY_MODE_STRUCTS_H__
26#define __DISPLAY_MODE_STRUCTS_H__ 26#define __DISPLAY_MODE_STRUCTS_H__
27 27
28typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
29typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
30typedef struct _vcs_dpi_ip_params_st ip_params_st;
31typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st;
32typedef struct _vcs_dpi_display_output_params_st display_output_params_st;
33typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st;
34typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st;
35typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st;
36typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st;
37typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st;
38typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st;
39typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st;
40typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st;
41typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st;
42typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st;
43typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st;
44typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st;
45typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st;
46typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st;
47typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st;
48typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st;
49typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st;
50typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st;
51typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st;
52typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st;
53typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st;
54typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st;
55typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st;
56typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st;
57typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st;
58typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st;
59typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st;
60typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st;
61
28struct _vcs_dpi_voltage_scaling_st { 62struct _vcs_dpi_voltage_scaling_st {
63 int state;
64 double dscclk_mhz;
29 double dcfclk_mhz; 65 double dcfclk_mhz;
66 double socclk_mhz;
67 double dram_speed_mhz;
68 double fabricclk_mhz;
30 double dispclk_mhz; 69 double dispclk_mhz;
31 double dppclk_mhz;
32 double dram_bw_per_chan_gbps; 70 double dram_bw_per_chan_gbps;
33 double phyclk_mhz; 71 double phyclk_mhz;
34 double socclk_mhz; 72 double dppclk_mhz;
35}; 73};
36 74
37struct _vcs_dpi_soc_bounding_box_st { 75struct _vcs_dpi_soc_bounding_box_st {
38 double sr_exit_time_us; 76 double sr_exit_time_us;
39 double sr_enter_plus_exit_time_us; 77 double sr_enter_plus_exit_time_us;
40 double urgent_latency_us; 78 double urgent_latency_us;
41 double writeback_latency_us; 79 double writeback_latency_us;
42 double ideal_dram_bw_after_urgent_percent; 80 double ideal_dram_bw_after_urgent_percent;
43 unsigned int max_request_size_bytes; 81 unsigned int max_request_size_bytes;
44 struct _vcs_dpi_voltage_scaling_st vmin; 82 struct _vcs_dpi_voltage_scaling_st vmin;
45 struct _vcs_dpi_voltage_scaling_st vmid; 83 struct _vcs_dpi_voltage_scaling_st vmid;
46 struct _vcs_dpi_voltage_scaling_st vnom; 84 struct _vcs_dpi_voltage_scaling_st vnom;
47 struct _vcs_dpi_voltage_scaling_st vmax; 85 struct _vcs_dpi_voltage_scaling_st vmax;
48 double downspread_percent; 86 double downspread_percent;
49 double dram_page_open_time_ns; 87 double dram_page_open_time_ns;
50 double dram_rw_turnaround_time_ns; 88 double dram_rw_turnaround_time_ns;
51 double dram_return_buffer_per_channel_bytes; 89 double dram_return_buffer_per_channel_bytes;
52 unsigned int round_trip_ping_latency_dcfclk_cycles; 90 double dram_channel_width_bytes;
53 unsigned int urgent_out_of_order_return_per_channel_bytes; 91 double fabric_datapath_to_dcn_data_return_bytes;
54 unsigned int channel_interleave_bytes; 92 double dcn_downspread_percent;
55 unsigned int num_banks; 93 double dispclk_dppclk_vco_speed_mhz;
56 unsigned int num_chans; 94 double dfs_vco_period_ps;
57 unsigned int vmm_page_size_bytes; 95 unsigned int round_trip_ping_latency_dcfclk_cycles;
58 double dram_clock_change_latency_us; 96 unsigned int urgent_out_of_order_return_per_channel_bytes;
59 double writeback_dram_clock_change_latency_us; 97 unsigned int channel_interleave_bytes;
60 unsigned int return_bus_width_bytes; 98 unsigned int num_banks;
61}; 99 unsigned int num_chans;
62 100 unsigned int vmm_page_size_bytes;
63struct _vcs_dpi_ip_params_st { 101 double dram_clock_change_latency_us;
64 unsigned int rob_buffer_size_kbytes; 102 double writeback_dram_clock_change_latency_us;
65 unsigned int det_buffer_size_kbytes; 103 unsigned int return_bus_width_bytes;
66 unsigned int dpte_buffer_size_in_pte_reqs; 104 unsigned int voltage_override;
67 unsigned int dpp_output_buffer_pixels; 105 double xfc_bus_transport_time_us;
68 unsigned int opp_output_buffer_lines; 106 double xfc_xbuf_latency_tolerance_us;
69 unsigned int pixel_chunk_size_kbytes; 107 struct _vcs_dpi_voltage_scaling_st clock_limits[7];
70 unsigned char pte_enable; 108};
71 unsigned int pte_chunk_size_kbytes; 109
72 unsigned int meta_chunk_size_kbytes; 110struct _vcs_dpi_ip_params_st {
73 unsigned int writeback_chunk_size_kbytes; 111 unsigned int max_inter_dcn_tile_repeaters;
74 unsigned int line_buffer_size_bits; 112 unsigned int num_dsc;
75 unsigned int max_line_buffer_lines; 113 unsigned int odm_capable;
114 unsigned int rob_buffer_size_kbytes;
115 unsigned int det_buffer_size_kbytes;
116 unsigned int dpte_buffer_size_in_pte_reqs;
117 unsigned int pde_proc_buffer_size_64k_reqs;
118 unsigned int dpp_output_buffer_pixels;
119 unsigned int opp_output_buffer_lines;
120 unsigned int pixel_chunk_size_kbytes;
121 unsigned char pte_enable;
122 unsigned int pte_chunk_size_kbytes;
123 unsigned int meta_chunk_size_kbytes;
124 unsigned int writeback_chunk_size_kbytes;
125 unsigned int line_buffer_size_bits;
126 unsigned int max_line_buffer_lines;
127 unsigned int writeback_luma_buffer_size_kbytes;
128 unsigned int writeback_chroma_buffer_size_kbytes;
129 unsigned int writeback_chroma_line_buffer_width_pixels;
130 unsigned int max_page_table_levels;
131 unsigned int max_num_dpp;
132 unsigned int max_num_otg;
133 unsigned int cursor_chunk_size;
134 unsigned int cursor_buffer_size;
135 unsigned int max_num_wb;
136 unsigned int max_dchub_pscl_bw_pix_per_clk;
137 unsigned int max_pscl_lb_bw_pix_per_clk;
138 unsigned int max_lb_vscl_bw_pix_per_clk;
139 unsigned int max_vscl_hscl_bw_pix_per_clk;
140 double max_hscl_ratio;
141 double max_vscl_ratio;
142 unsigned int hscl_mults;
143 unsigned int vscl_mults;
144 unsigned int max_hscl_taps;
145 unsigned int max_vscl_taps;
146 unsigned int xfc_supported;
147 unsigned int ptoi_supported;
148 unsigned int xfc_fill_constant_bytes;
149 double dispclk_ramp_margin_percent;
150 double xfc_fill_bw_overhead_percent;
151 double underscan_factor;
152 unsigned int min_vblank_lines;
153 unsigned int dppclk_delay_subtotal;
154 unsigned int dispclk_delay_subtotal;
155 unsigned int dcfclk_cstate_latency;
156 unsigned int dppclk_delay_scl;
157 unsigned int dppclk_delay_scl_lb_only;
158 unsigned int dppclk_delay_cnvc_formatter;
159 unsigned int dppclk_delay_cnvc_cursor;
160 unsigned int is_line_buffer_bpp_fixed;
161 unsigned int line_buffer_fixed_bpp;
162 unsigned int dcc_supported;
163
76 unsigned int IsLineBufferBppFixed; 164 unsigned int IsLineBufferBppFixed;
77 unsigned int LineBufferFixedBpp; 165 unsigned int LineBufferFixedBpp;
78 unsigned int writeback_luma_buffer_size_kbytes;
79 unsigned int writeback_chroma_buffer_size_kbytes;
80 unsigned int max_num_dpp;
81 unsigned int max_num_wb;
82 unsigned int max_dchub_pscl_bw_pix_per_clk;
83 unsigned int max_pscl_lb_bw_pix_per_clk;
84 unsigned int max_lb_vscl_bw_pix_per_clk;
85 unsigned int max_vscl_hscl_bw_pix_per_clk;
86 double max_hscl_ratio;
87 double max_vscl_ratio;
88 unsigned int hscl_mults;
89 unsigned int vscl_mults;
90 unsigned int max_hscl_taps;
91 unsigned int max_vscl_taps;
92 double dispclk_ramp_margin_percent;
93 double underscan_factor;
94 unsigned int min_vblank_lines;
95 unsigned int dppclk_delay_subtotal;
96 unsigned int dispclk_delay_subtotal;
97 unsigned int dcfclk_cstate_latency;
98 unsigned int max_inter_dcn_tile_repeaters;
99 unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; 166 unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
100 unsigned int bug_forcing_LC_req_same_size_fixed; 167 unsigned int bug_forcing_LC_req_same_size_fixed;
101}; 168};
102 169
103struct _vcs_dpi_display_pipe_source_params_st { 170struct _vcs_dpi_display_xfc_params_st {
104 int source_format; 171 double xfc_tslv_vready_offset_us;
105 unsigned char dcc; 172 double xfc_tslv_vupdate_width_us;
106 unsigned int dcc_rate; 173 double xfc_tslv_vupdate_offset_us;
107 unsigned char vm; 174 int xfc_slv_chunk_size_bytes;
108 int source_scan; 175};
109 int sw_mode; 176
110 int macro_tile_size; 177struct _vcs_dpi_display_pipe_source_params_st {
111 unsigned char is_display_sw; 178 int source_format;
112 unsigned int viewport_width; 179 unsigned char dcc;
113 unsigned int viewport_height; 180 unsigned int dcc_override;
114 unsigned int viewport_width_c; 181 unsigned int dcc_rate;
115 unsigned int viewport_height_c; 182 unsigned char dcc_use_global;
116 unsigned int data_pitch; 183 unsigned char vm;
117 unsigned int data_pitch_c; 184 unsigned char vm_levels_force_en;
118 unsigned int meta_pitch; 185 unsigned int vm_levels_force;
119 unsigned int meta_pitch_c; 186 int source_scan;
120 unsigned int cur0_src_width; 187 int sw_mode;
121 int cur0_bpp; 188 int macro_tile_size;
122 unsigned char is_hsplit; 189 unsigned char is_display_sw;
123 unsigned int hsplit_grp; 190 unsigned int viewport_width;
124}; 191 unsigned int viewport_height;
125 192 unsigned int viewport_y_y;
126struct _vcs_dpi_display_output_params_st { 193 unsigned int viewport_y_c;
127 int output_bpc; 194 unsigned int viewport_width_c;
128 int output_type; 195 unsigned int viewport_height_c;
129 int output_format; 196 unsigned int data_pitch;
130 int output_standard; 197 unsigned int data_pitch_c;
131}; 198 unsigned int meta_pitch;
132 199 unsigned int meta_pitch_c;
133struct _vcs_dpi_display_bandwidth_st { 200 unsigned int cur0_src_width;
134 double total_bw_consumed_gbps; 201 int cur0_bpp;
135 double guaranteed_urgent_return_bw_gbps; 202 unsigned int cur1_src_width;
136}; 203 int cur1_bpp;
137 204 int num_cursors;
138struct _vcs_dpi_scaler_ratio_depth_st { 205 unsigned char is_hsplit;
139 double hscl_ratio; 206 unsigned char dynamic_metadata_enable;
140 double vscl_ratio; 207 unsigned int dynamic_metadata_lines_before_active;
141 double hscl_ratio_c; 208 unsigned int dynamic_metadata_xmit_bytes;
142 double vscl_ratio_c; 209 unsigned int hsplit_grp;
143 double vinit; 210 unsigned char xfc_enable;
144 double vinit_c; 211 unsigned char xfc_slave;
145 double vinit_bot; 212 struct _vcs_dpi_display_xfc_params_st xfc_params;
146 double vinit_bot_c; 213};
147 int lb_depth; 214struct writeback_st {
148}; 215 int wb_src_height;
149 216 int wb_dst_width;
150struct _vcs_dpi_scaler_taps_st { 217 int wb_dst_height;
151 unsigned int htaps; 218 int wb_pixel_format;
152 unsigned int vtaps; 219 int wb_htaps_luma;
153 unsigned int htaps_c; 220 int wb_vtaps_luma;
154 unsigned int vtaps_c; 221 int wb_htaps_chroma;
155}; 222 int wb_vtaps_chroma;
156 223 int wb_hratio;
157struct _vcs_dpi_display_pipe_dest_params_st { 224 int wb_vratio;
158 unsigned int recout_width; 225};
159 unsigned int recout_height; 226
160 unsigned int full_recout_width; 227struct _vcs_dpi_display_output_params_st {
161 unsigned int full_recout_height; 228 int dp_lanes;
162 unsigned int hblank_start; 229 int output_bpp;
163 unsigned int hblank_end; 230 int dsc_enable;
164 unsigned int vblank_start; 231 int wb_enable;
165 unsigned int vblank_end; 232 int output_bpc;
166 unsigned int htotal; 233 int output_type;
167 unsigned int vtotal; 234 int output_format;
168 unsigned int vactive; 235 int output_standard;
169 unsigned int vstartup_start; 236 int dsc_slices;
170 unsigned int vupdate_offset; 237 struct writeback_st wb;
171 unsigned int vupdate_width; 238};
172 unsigned int vready_offset; 239
173 unsigned int vsync_plus_back_porch; 240struct _vcs_dpi_display_bandwidth_st {
174 unsigned char interlaced; 241 double total_bw_consumed_gbps;
175 unsigned char underscan; 242 double guaranteed_urgent_return_bw_gbps;
176 double pixel_rate_mhz; 243};
177 unsigned char syncronized_vblank_all_planes; 244
178}; 245struct _vcs_dpi_scaler_ratio_depth_st {
179 246 double hscl_ratio;
180struct _vcs_dpi_display_pipe_params_st { 247 double vscl_ratio;
181 struct _vcs_dpi_display_pipe_source_params_st src; 248 double hscl_ratio_c;
182 struct _vcs_dpi_display_pipe_dest_params_st dest; 249 double vscl_ratio_c;
183 struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth; 250 double vinit;
184 struct _vcs_dpi_scaler_taps_st scale_taps; 251 double vinit_c;
185}; 252 double vinit_bot;
186 253 double vinit_bot_c;
187struct _vcs_dpi_display_clocks_and_cfg_st { 254 int lb_depth;
188 int voltage; 255 int scl_enable;
189 double dppclk_mhz; 256};
190 double refclk_mhz; 257
191 double dispclk_mhz; 258struct _vcs_dpi_scaler_taps_st {
192 double dcfclk_mhz; 259 unsigned int htaps;
193 double socclk_mhz; 260 unsigned int vtaps;
194}; 261 unsigned int htaps_c;
195 262 unsigned int vtaps_c;
196struct _vcs_dpi_display_e2e_pipe_params_st { 263};
197 struct _vcs_dpi_display_pipe_params_st pipe; 264
198 struct _vcs_dpi_display_output_params_st dout; 265struct _vcs_dpi_display_pipe_dest_params_st {
199 struct _vcs_dpi_display_clocks_and_cfg_st clks_cfg; 266 unsigned int recout_width;
200}; 267 unsigned int recout_height;
201 268 unsigned int full_recout_width;
202struct _vcs_dpi_dchub_buffer_sizing_st { 269 unsigned int full_recout_height;
203 unsigned int swath_width_y; 270 unsigned int hblank_start;
204 unsigned int swath_height_y; 271 unsigned int hblank_end;
205 unsigned int swath_height_c; 272 unsigned int vblank_start;
206 unsigned int detail_buffer_size_y; 273 unsigned int vblank_end;
207}; 274 unsigned int htotal;
208 275 unsigned int vtotal;
209struct _vcs_dpi_watermarks_perf_st { 276 unsigned int vactive;
210 double stutter_eff_in_active_region_percent; 277 unsigned int hactive;
211 double urgent_latency_supported_us; 278 unsigned int vstartup_start;
212 double non_urgent_latency_supported_us; 279 unsigned int vupdate_offset;
213 double dram_clock_change_margin_us; 280 unsigned int vupdate_width;
214 double dram_access_eff_percent; 281 unsigned int vready_offset;
215}; 282 unsigned char interlaced;
216 283 unsigned char underscan;
217struct _vcs_dpi_cstate_pstate_watermarks_st { 284 double pixel_rate_mhz;
218 double cstate_exit_us; 285 unsigned char synchronized_vblank_all_planes;
219 double cstate_enter_plus_exit_us; 286 unsigned char otg_inst;
220 double pstate_change_us; 287 unsigned char odm_split_cnt;
221}; 288 unsigned char odm_combine;
222 289};
223struct _vcs_dpi_wm_calc_pipe_params_st { 290
224 unsigned int num_dpp; 291struct _vcs_dpi_display_pipe_params_st {
225 int voltage; 292 display_pipe_source_params_st src;
226 int output_type; 293 display_pipe_dest_params_st dest;
227 double dcfclk_mhz; 294 scaler_ratio_depth_st scale_ratio_depth;
228 double socclk_mhz; 295 scaler_taps_st scale_taps;
229 double dppclk_mhz; 296};
230 double pixclk_mhz; 297
231 unsigned char interlace_en; 298struct _vcs_dpi_display_clocks_and_cfg_st {
232 unsigned char pte_enable; 299 int voltage;
233 unsigned char dcc_enable; 300 double dppclk_mhz;
234 double dcc_rate; 301 double refclk_mhz;
235 double bytes_per_pixel_c; 302 double dispclk_mhz;
236 double bytes_per_pixel_y; 303 double dcfclk_mhz;
237 unsigned int swath_width_y; 304 double socclk_mhz;
238 unsigned int swath_height_y; 305};
239 unsigned int swath_height_c; 306
240 unsigned int det_buffer_size_y; 307struct _vcs_dpi_display_e2e_pipe_params_st {
241 double h_ratio; 308 display_pipe_params_st pipe;
242 double v_ratio; 309 display_output_params_st dout;
243 unsigned int h_taps; 310 display_clocks_and_cfg_st clks_cfg;
244 unsigned int h_total; 311};
245 unsigned int v_total; 312
246 unsigned int v_active; 313struct _vcs_dpi_dchub_buffer_sizing_st {
247 unsigned int e2e_index; 314 unsigned int swath_width_y;
248 double display_pipe_line_delivery_time; 315 unsigned int swath_height_y;
249 double read_bw; 316 unsigned int swath_height_c;
250 unsigned int lines_in_det_y; 317 unsigned int detail_buffer_size_y;
251 unsigned int lines_in_det_y_rounded_down_to_swath; 318};
252 double full_det_buffering_time; 319
253 double dcfclk_deepsleep_mhz_per_plane; 320struct _vcs_dpi_watermarks_perf_st {
254}; 321 double stutter_eff_in_active_region_percent;
255 322 double urgent_latency_supported_us;
256struct _vcs_dpi_vratio_pre_st { 323 double non_urgent_latency_supported_us;
257 double vratio_pre_l; 324 double dram_clock_change_margin_us;
258 double vratio_pre_c; 325 double dram_access_eff_percent;
259}; 326};
260 327
261struct _vcs_dpi_display_data_rq_misc_params_st { 328struct _vcs_dpi_cstate_pstate_watermarks_st {
262 unsigned int full_swath_bytes; 329 double cstate_exit_us;
263 unsigned int stored_swath_bytes; 330 double cstate_enter_plus_exit_us;
264 unsigned int blk256_height; 331 double pstate_change_us;
265 unsigned int blk256_width; 332};
266 unsigned int req_height; 333
267 unsigned int req_width; 334struct _vcs_dpi_wm_calc_pipe_params_st {
268}; 335 unsigned int num_dpp;
269 336 int voltage;
270struct _vcs_dpi_display_data_rq_sizing_params_st { 337 int output_type;
271 unsigned int chunk_bytes; 338 double dcfclk_mhz;
272 unsigned int min_chunk_bytes; 339 double socclk_mhz;
273 unsigned int meta_chunk_bytes; 340 double dppclk_mhz;
274 unsigned int min_meta_chunk_bytes; 341 double pixclk_mhz;
275 unsigned int mpte_group_bytes; 342 unsigned char interlace_en;
276 unsigned int dpte_group_bytes; 343 unsigned char pte_enable;
277}; 344 unsigned char dcc_enable;
278 345 double dcc_rate;
279struct _vcs_dpi_display_data_rq_dlg_params_st { 346 double bytes_per_pixel_c;
280 unsigned int swath_width_ub; 347 double bytes_per_pixel_y;
281 unsigned int swath_height; 348 unsigned int swath_width_y;
282 unsigned int req_per_swath_ub; 349 unsigned int swath_height_y;
283 unsigned int meta_pte_bytes_per_frame_ub; 350 unsigned int swath_height_c;
284 unsigned int dpte_req_per_row_ub; 351 unsigned int det_buffer_size_y;
285 unsigned int dpte_groups_per_row_ub; 352 double h_ratio;
286 unsigned int dpte_row_height; 353 double v_ratio;
287 unsigned int dpte_bytes_per_row_ub; 354 unsigned int h_taps;
288 unsigned int meta_chunks_per_row_ub; 355 unsigned int h_total;
289 unsigned int meta_req_per_row_ub; 356 unsigned int v_total;
290 unsigned int meta_row_height; 357 unsigned int v_active;
291 unsigned int meta_bytes_per_row_ub; 358 unsigned int e2e_index;
292}; 359 double display_pipe_line_delivery_time;
293 360 double read_bw;
294struct _vcs_dpi_display_cur_rq_dlg_params_st { 361 unsigned int lines_in_det_y;
295 unsigned char enable; 362 unsigned int lines_in_det_y_rounded_down_to_swath;
296 unsigned int swath_height; 363 double full_det_buffering_time;
297 unsigned int req_per_line; 364 double dcfclk_deepsleep_mhz_per_plane;
298}; 365};
299 366
300struct _vcs_dpi_display_rq_dlg_params_st { 367struct _vcs_dpi_vratio_pre_st {
301 struct _vcs_dpi_display_data_rq_dlg_params_st rq_l; 368 double vratio_pre_l;
302 struct _vcs_dpi_display_data_rq_dlg_params_st rq_c; 369 double vratio_pre_c;
303 struct _vcs_dpi_display_cur_rq_dlg_params_st rq_cur0; 370};
304}; 371
305 372struct _vcs_dpi_display_data_rq_misc_params_st {
306struct _vcs_dpi_display_rq_sizing_params_st { 373 unsigned int full_swath_bytes;
307 struct _vcs_dpi_display_data_rq_sizing_params_st rq_l; 374 unsigned int stored_swath_bytes;
308 struct _vcs_dpi_display_data_rq_sizing_params_st rq_c; 375 unsigned int blk256_height;
309}; 376 unsigned int blk256_width;
310 377 unsigned int req_height;
311struct _vcs_dpi_display_rq_misc_params_st { 378 unsigned int req_width;
312 struct _vcs_dpi_display_data_rq_misc_params_st rq_l; 379};
313 struct _vcs_dpi_display_data_rq_misc_params_st rq_c; 380
314}; 381struct _vcs_dpi_display_data_rq_sizing_params_st {
315 382 unsigned int chunk_bytes;
316struct _vcs_dpi_display_rq_params_st { 383 unsigned int min_chunk_bytes;
317 unsigned char yuv420; 384 unsigned int meta_chunk_bytes;
318 unsigned char yuv420_10bpc; 385 unsigned int min_meta_chunk_bytes;
319 struct _vcs_dpi_display_rq_misc_params_st misc; 386 unsigned int mpte_group_bytes;
320 struct _vcs_dpi_display_rq_sizing_params_st sizing; 387 unsigned int dpte_group_bytes;
321 struct _vcs_dpi_display_rq_dlg_params_st dlg; 388};
322}; 389
323 390struct _vcs_dpi_display_data_rq_dlg_params_st {
324struct _vcs_dpi_display_dlg_regs_st { 391 unsigned int swath_width_ub;
325 unsigned int refcyc_h_blank_end; 392 unsigned int swath_height;
326 unsigned int dlg_vblank_end; 393 unsigned int req_per_swath_ub;
327 unsigned int min_dst_y_next_start; 394 unsigned int meta_pte_bytes_per_frame_ub;
328 unsigned int refcyc_per_htotal; 395 unsigned int dpte_req_per_row_ub;
329 unsigned int refcyc_x_after_scaler; 396 unsigned int dpte_groups_per_row_ub;
330 unsigned int dst_y_after_scaler; 397 unsigned int dpte_row_height;
331 unsigned int dst_y_prefetch; 398 unsigned int dpte_bytes_per_row_ub;
332 unsigned int dst_y_per_vm_vblank; 399 unsigned int meta_chunks_per_row_ub;
333 unsigned int dst_y_per_row_vblank; 400 unsigned int meta_req_per_row_ub;
334 unsigned int ref_freq_to_pix_freq; 401 unsigned int meta_row_height;
335 unsigned int vratio_prefetch; 402 unsigned int meta_bytes_per_row_ub;
336 unsigned int vratio_prefetch_c; 403};
337 unsigned int refcyc_per_pte_group_vblank_l; 404
338 unsigned int refcyc_per_pte_group_vblank_c; 405struct _vcs_dpi_display_cur_rq_dlg_params_st {
339 unsigned int refcyc_per_meta_chunk_vblank_l; 406 unsigned char enable;
340 unsigned int refcyc_per_meta_chunk_vblank_c; 407 unsigned int swath_height;
341 unsigned int dst_y_per_pte_row_nom_l; 408 unsigned int req_per_line;
342 unsigned int dst_y_per_pte_row_nom_c; 409};
343 unsigned int refcyc_per_pte_group_nom_l; 410
344 unsigned int refcyc_per_pte_group_nom_c; 411struct _vcs_dpi_display_rq_dlg_params_st {
345 unsigned int dst_y_per_meta_row_nom_l; 412 display_data_rq_dlg_params_st rq_l;
346 unsigned int dst_y_per_meta_row_nom_c; 413 display_data_rq_dlg_params_st rq_c;
347 unsigned int refcyc_per_meta_chunk_nom_l; 414 display_cur_rq_dlg_params_st rq_cur0;
348 unsigned int refcyc_per_meta_chunk_nom_c; 415};
349 unsigned int refcyc_per_line_delivery_pre_l; 416
350 unsigned int refcyc_per_line_delivery_pre_c; 417struct _vcs_dpi_display_rq_sizing_params_st {
351 unsigned int refcyc_per_line_delivery_l; 418 display_data_rq_sizing_params_st rq_l;
352 unsigned int refcyc_per_line_delivery_c; 419 display_data_rq_sizing_params_st rq_c;
353 unsigned int chunk_hdl_adjust_cur0; 420};
354}; 421
355 422struct _vcs_dpi_display_rq_misc_params_st {
356struct _vcs_dpi_display_ttu_regs_st { 423 display_data_rq_misc_params_st rq_l;
357 unsigned int qos_level_low_wm; 424 display_data_rq_misc_params_st rq_c;
358 unsigned int qos_level_high_wm; 425};
359 unsigned int min_ttu_vblank; 426
360 unsigned int qos_level_flip; 427struct _vcs_dpi_display_rq_params_st {
361 unsigned int refcyc_per_req_delivery_l; 428 unsigned char yuv420;
362 unsigned int refcyc_per_req_delivery_c; 429 unsigned char yuv420_10bpc;
363 unsigned int refcyc_per_req_delivery_cur0; 430 display_rq_misc_params_st misc;
364 unsigned int refcyc_per_req_delivery_pre_l; 431 display_rq_sizing_params_st sizing;
365 unsigned int refcyc_per_req_delivery_pre_c; 432 display_rq_dlg_params_st dlg;
366 unsigned int refcyc_per_req_delivery_pre_cur0; 433};
367 unsigned int qos_level_fixed_l; 434
368 unsigned int qos_level_fixed_c; 435struct _vcs_dpi_display_dlg_regs_st {
369 unsigned int qos_level_fixed_cur0; 436 unsigned int refcyc_h_blank_end;
370 unsigned int qos_ramp_disable_l; 437 unsigned int dlg_vblank_end;
371 unsigned int qos_ramp_disable_c; 438 unsigned int min_dst_y_next_start;
372 unsigned int qos_ramp_disable_cur0; 439 unsigned int refcyc_per_htotal;
373}; 440 unsigned int refcyc_x_after_scaler;
374 441 unsigned int dst_y_after_scaler;
375struct _vcs_dpi_display_data_rq_regs_st { 442 unsigned int dst_y_prefetch;
376 unsigned int chunk_size; 443 unsigned int dst_y_per_vm_vblank;
377 unsigned int min_chunk_size; 444 unsigned int dst_y_per_row_vblank;
378 unsigned int meta_chunk_size; 445 unsigned int dst_y_per_vm_flip;
379 unsigned int min_meta_chunk_size; 446 unsigned int dst_y_per_row_flip;
380 unsigned int dpte_group_size; 447 unsigned int ref_freq_to_pix_freq;
381 unsigned int mpte_group_size; 448 unsigned int vratio_prefetch;
382 unsigned int swath_height; 449 unsigned int vratio_prefetch_c;
383 unsigned int pte_row_height_linear; 450 unsigned int refcyc_per_pte_group_vblank_l;
384}; 451 unsigned int refcyc_per_pte_group_vblank_c;
385 452 unsigned int refcyc_per_meta_chunk_vblank_l;
386struct _vcs_dpi_display_rq_regs_st { 453 unsigned int refcyc_per_meta_chunk_vblank_c;
387 struct _vcs_dpi_display_data_rq_regs_st rq_regs_l; 454 unsigned int refcyc_per_pte_group_flip_l;
388 struct _vcs_dpi_display_data_rq_regs_st rq_regs_c; 455 unsigned int refcyc_per_pte_group_flip_c;
389 unsigned int drq_expansion_mode; 456 unsigned int refcyc_per_meta_chunk_flip_l;
390 unsigned int prq_expansion_mode; 457 unsigned int refcyc_per_meta_chunk_flip_c;
391 unsigned int mrq_expansion_mode; 458 unsigned int dst_y_per_pte_row_nom_l;
392 unsigned int crq_expansion_mode; 459 unsigned int dst_y_per_pte_row_nom_c;
393 unsigned int plane1_base_address; 460 unsigned int refcyc_per_pte_group_nom_l;
394}; 461 unsigned int refcyc_per_pte_group_nom_c;
395 462 unsigned int dst_y_per_meta_row_nom_l;
396struct _vcs_dpi_display_dlg_sys_params_st { 463 unsigned int dst_y_per_meta_row_nom_c;
397 double t_mclk_wm_us; 464 unsigned int refcyc_per_meta_chunk_nom_l;
398 double t_urg_wm_us; 465 unsigned int refcyc_per_meta_chunk_nom_c;
399 double t_sr_wm_us; 466 unsigned int refcyc_per_line_delivery_pre_l;
400 double t_extra_us; 467 unsigned int refcyc_per_line_delivery_pre_c;
401 double t_srx_delay_us; 468 unsigned int refcyc_per_line_delivery_l;
402 double deepsleep_dcfclk_mhz; 469 unsigned int refcyc_per_line_delivery_c;
403 double total_flip_bw; 470 unsigned int chunk_hdl_adjust_cur0;
404 unsigned int total_flip_bytes; 471 unsigned int chunk_hdl_adjust_cur1;
405}; 472 unsigned int vready_after_vcount0;
406 473 unsigned int dst_y_offset_cur0;
407struct _vcs_dpi_display_dlg_prefetch_param_st { 474 unsigned int dst_y_offset_cur1;
408 double prefetch_bw; 475 unsigned int xfc_reg_transfer_delay;
409 unsigned int flip_bytes; 476 unsigned int xfc_reg_precharge_delay;
410}; 477 unsigned int xfc_reg_remote_surface_flip_latency;
411 478 unsigned int xfc_reg_prefetch_margin;
412struct _vcs_dpi_display_pipe_clock_st { 479 unsigned int dst_y_delta_drq_limit;
413 double dcfclk_mhz; 480};
414 double dispclk_mhz; 481
415 double dppclk_mhz[4]; 482struct _vcs_dpi_display_ttu_regs_st {
416 unsigned char dppclk_div[4]; 483 unsigned int qos_level_low_wm;
417}; 484 unsigned int qos_level_high_wm;
418 485 unsigned int min_ttu_vblank;
419struct _vcs_dpi_display_arb_params_st { 486 unsigned int qos_level_flip;
420 int max_req_outstanding; 487 unsigned int refcyc_per_req_delivery_l;
421 int min_req_outstanding; 488 unsigned int refcyc_per_req_delivery_c;
422 int sat_level_us; 489 unsigned int refcyc_per_req_delivery_cur0;
423}; 490 unsigned int refcyc_per_req_delivery_cur1;
424 491 unsigned int refcyc_per_req_delivery_pre_l;
425struct _vcs_dpi_mode_evaluation_st { 492 unsigned int refcyc_per_req_delivery_pre_c;
426 int voltage_override; 493 unsigned int refcyc_per_req_delivery_pre_cur0;
494 unsigned int refcyc_per_req_delivery_pre_cur1;
495 unsigned int qos_level_fixed_l;
496 unsigned int qos_level_fixed_c;
497 unsigned int qos_level_fixed_cur0;
498 unsigned int qos_level_fixed_cur1;
499 unsigned int qos_ramp_disable_l;
500 unsigned int qos_ramp_disable_c;
501 unsigned int qos_ramp_disable_cur0;
502 unsigned int qos_ramp_disable_cur1;
503};
504
505struct _vcs_dpi_display_data_rq_regs_st {
506 unsigned int chunk_size;
507 unsigned int min_chunk_size;
508 unsigned int meta_chunk_size;
509 unsigned int min_meta_chunk_size;
510 unsigned int dpte_group_size;
511 unsigned int mpte_group_size;
512 unsigned int swath_height;
513 unsigned int pte_row_height_linear;
514};
515
516struct _vcs_dpi_display_rq_regs_st {
517 display_data_rq_regs_st rq_regs_l;
518 display_data_rq_regs_st rq_regs_c;
519 unsigned int drq_expansion_mode;
520 unsigned int prq_expansion_mode;
521 unsigned int mrq_expansion_mode;
522 unsigned int crq_expansion_mode;
523 unsigned int plane1_base_address;
524};
525
526struct _vcs_dpi_display_dlg_sys_params_st {
527 double t_mclk_wm_us;
528 double t_urg_wm_us;
529 double t_sr_wm_us;
530 double t_extra_us;
531 double mem_trip_us;
532 double t_srx_delay_us;
533 double deepsleep_dcfclk_mhz;
534 double total_flip_bw;
535 unsigned int total_flip_bytes;
536};
537
538struct _vcs_dpi_display_dlg_prefetch_param_st {
539 double prefetch_bw;
540 unsigned int flip_bytes;
541};
542
543struct _vcs_dpi_display_pipe_clock_st {
544 double dcfclk_mhz;
545 double dispclk_mhz;
546 double socclk_mhz;
547 double dscclk_mhz[6];
548 double dppclk_mhz[6];
549};
550
551struct _vcs_dpi_display_arb_params_st {
552 int max_req_outstanding;
553 int min_req_outstanding;
554 int sat_level_us;
427}; 555};
428 556
429#endif /*__DISPLAY_MODE_STRUCTS_H__*/ 557#endif /*__DISPLAY_MODE_STRUCTS_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h
deleted file mode 100644
index d4ea0371cde2..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_support.h
+++ /dev/null
@@ -1,194 +0,0 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25#ifndef __DISPLAY_MODE_SUPPORT_H__
26#define __DISPLAY_MODE_SUPPORT_H__
27
28#include "dml_common_defs.h"
29
30struct display_mode_lib;
31
32#define NumberOfStates 4
33#define NumberOfStatesPlusTwo (NumberOfStates+2)
34
35struct dml_ms_internal_vars {
36 double ScaleRatioSupport;
37 double SourceFormatPixelAndScanSupport;
38 double TotalReadBandwidthConsumedGBytePerSecond;
39 double TotalWriteBandwidthConsumedGBytePerSecond;
40 double TotalBandwidthConsumedGBytePerSecond;
41 double DCCEnabledInAnyPlane;
42 double ReturnBWToDCNPerState;
43 double CriticalPoint;
44 double WritebackLatencySupport;
45 double RequiredOutputBW;
46 double TotalNumberOfActiveWriteback;
47 double TotalAvailableWritebackSupport;
48 double MaximumSwathWidth;
49 double NumberOfDPPRequiredForDETSize;
50 double NumberOfDPPRequiredForLBSize;
51 double MinDispclkUsingSingleDPP;
52 double MinDispclkUsingDualDPP;
53 double ViewportSizeSupport;
54 double SwathWidthGranularityY;
55 double RoundedUpMaxSwathSizeBytesY;
56 double SwathWidthGranularityC;
57 double RoundedUpMaxSwathSizeBytesC;
58 double LinesInDETLuma;
59 double LinesInDETChroma;
60 double EffectiveLBLatencyHidingSourceLinesLuma;
61 double EffectiveLBLatencyHidingSourceLinesChroma;
62 double EffectiveDETLBLinesLuma;
63 double EffectiveDETLBLinesChroma;
64 double ProjectedDCFCLKDeepSleep;
65 double MetaReqHeightY;
66 double MetaReqWidthY;
67 double MetaSurfaceWidthY;
68 double MetaSurfaceHeightY;
69 double MetaPteBytesPerFrameY;
70 double MetaRowBytesY;
71 double MacroTileBlockSizeBytesY;
72 double MacroTileBlockHeightY;
73 double DataPTEReqHeightY;
74 double DataPTEReqWidthY;
75 double DPTEBytesPerRowY;
76 double MetaReqHeightC;
77 double MetaReqWidthC;
78 double MetaSurfaceWidthC;
79 double MetaSurfaceHeightC;
80 double MetaPteBytesPerFrameC;
81 double MetaRowBytesC;
82 double MacroTileBlockSizeBytesC;
83 double MacroTileBlockHeightC;
84 double MacroTileBlockWidthC;
85 double DataPTEReqHeightC;
86 double DataPTEReqWidthC;
87 double DPTEBytesPerRowC;
88 double VInitY;
89 double MaxPartialSwY;
90 double VInitC;
91 double MaxPartialSwC;
92 double dst_x_after_scaler;
93 double dst_y_after_scaler;
94 double TimeCalc;
95 double VUpdateOffset;
96 double TotalRepeaterDelay;
97 double VUpdateWidth;
98 double VReadyOffset;
99 double TimeSetup;
100 double ExtraLatency;
101 double MaximumVStartup;
102 double BWAvailableForImmediateFlip;
103 double TotalImmediateFlipBytes;
104 double TimeForMetaPTEWithImmediateFlip;
105 double TimeForMetaPTEWithoutImmediateFlip;
106 double TimeForMetaAndDPTERowWithImmediateFlip;
107 double TimeForMetaAndDPTERowWithoutImmediateFlip;
108 double LineTimesToRequestPrefetchPixelDataWithImmediateFlip;
109 double LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip;
110 double MaximumReadBandwidthWithPrefetchWithImmediateFlip;
111 double MaximumReadBandwidthWithPrefetchWithoutImmediateFlip;
112 double VoltageOverrideLevel;
113 double VoltageLevelWithImmediateFlip;
114 double VoltageLevelWithoutImmediateFlip;
115 double ImmediateFlipSupported;
116 double VoltageLevel;
117 double DCFCLK;
118 double FabricAndDRAMBandwidth;
119 double SwathWidthYSingleDPP[DC__NUM_PIPES__MAX];
120 double BytePerPixelInDETY[DC__NUM_PIPES__MAX];
121 double BytePerPixelInDETC[DC__NUM_PIPES__MAX];
122 double ReadBandwidth[DC__NUM_PIPES__MAX];
123 double WriteBandwidth[DC__NUM_PIPES__MAX];
124 double DCFCLKPerState[NumberOfStatesPlusTwo];
125 double FabricAndDRAMBandwidthPerState[NumberOfStatesPlusTwo];
126 double ReturnBWPerState[NumberOfStatesPlusTwo];
127 double BandwidthSupport[NumberOfStatesPlusTwo];
128 double UrgentRoundTripAndOutOfOrderLatencyPerState[NumberOfStatesPlusTwo];
129 double ROBSupport[NumberOfStatesPlusTwo];
130 double RequiredPHYCLK[DC__NUM_PIPES__MAX];
131 double DIOSupport[NumberOfStatesPlusTwo];
132 double PHYCLKPerState[NumberOfStatesPlusTwo];
133 double PSCL_FACTOR[DC__NUM_PIPES__MAX];
134 double PSCL_FACTOR_CHROMA[DC__NUM_PIPES__MAX];
135 double MinDPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX];
136 double Read256BlockHeightY[DC__NUM_PIPES__MAX];
137 double Read256BlockWidthY[DC__NUM_PIPES__MAX];
138 double Read256BlockHeightC[DC__NUM_PIPES__MAX];
139 double Read256BlockWidthC[DC__NUM_PIPES__MAX];
140 double MaxSwathHeightY[DC__NUM_PIPES__MAX];
141 double MaxSwathHeightC[DC__NUM_PIPES__MAX];
142 double MinSwathHeightY[DC__NUM_PIPES__MAX];
143 double MinSwathHeightC[DC__NUM_PIPES__MAX];
144 double NumberOfDPPRequiredForDETAndLBSize[DC__NUM_PIPES__MAX];
145 double TotalNumberOfActiveDPP[NumberOfStatesPlusTwo * 2];
146 double RequiredDISPCLK[NumberOfStatesPlusTwo * 2];
147 double DISPCLK_DPPCLK_Support[NumberOfStatesPlusTwo * 2];
148 double MaxDispclk[NumberOfStatesPlusTwo];
149 double MaxDppclk[NumberOfStatesPlusTwo];
150 double NoOfDPP[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
151 double TotalAvailablePipesSupport[NumberOfStatesPlusTwo * 2];
152 double SwathWidthYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
153 double SwathHeightYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
154 double SwathHeightCPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
155 double DETBufferSizeYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
156 double UrgentLatencySupportUsPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
157 double UrgentLatencySupport[NumberOfStatesPlusTwo * 2];
158 double TotalNumberOfDCCActiveDPP[NumberOfStatesPlusTwo * 2];
159 double DPTEBytesPerRow[DC__NUM_PIPES__MAX];
160 double MetaPTEBytesPerFrame[DC__NUM_PIPES__MAX];
161 double MetaRowBytes[DC__NUM_PIPES__MAX];
162 double PrefillY[DC__NUM_PIPES__MAX];
163 double MaxNumSwY[DC__NUM_PIPES__MAX];
164 double PrefetchLinesY[DC__NUM_PIPES__MAX];
165 double PrefillC[DC__NUM_PIPES__MAX];
166 double MaxNumSwC[DC__NUM_PIPES__MAX];
167 double PrefetchLinesC[DC__NUM_PIPES__MAX];
168 double LineTimesForPrefetch[DC__NUM_PIPES__MAX];
169 double PrefetchBW[DC__NUM_PIPES__MAX];
170 double LinesForMetaPTEWithImmediateFlip[DC__NUM_PIPES__MAX];
171 double LinesForMetaPTEWithoutImmediateFlip[DC__NUM_PIPES__MAX];
172 double LinesForMetaAndDPTERowWithImmediateFlip[DC__NUM_PIPES__MAX];
173 double LinesForMetaAndDPTERowWithoutImmediateFlip[DC__NUM_PIPES__MAX];
174 double VRatioPreYWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
175 double VRatioPreCWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
176 double RequiredPrefetchPixelDataBWWithImmediateFlip[NumberOfStatesPlusTwo * 2
177 * DC__NUM_PIPES__MAX];
178 double VRatioPreYWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
179 double VRatioPreCWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
180 double RequiredPrefetchPixelDataBWWithoutImmediateFlip[NumberOfStatesPlusTwo * 2
181 * DC__NUM_PIPES__MAX];
182 double PrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
183 double PrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
184 double VRatioInPrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
185 double VRatioInPrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
186 double ModeSupportWithImmediateFlip[NumberOfStatesPlusTwo * 2];
187 double ModeSupportWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
188 double RequiredDISPCLKPerRatio[2];
189 double DPPPerPlanePerRatio[2 * DC__NUM_PIPES__MAX];
190 double DISPCLK_DPPCLK_SupportPerRatio[2];
191 struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX];
192};
193
194#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
new file mode 100644
index 000000000000..ea661ee44674
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
@@ -0,0 +1,6124 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "display_mode_lib.h"
27#include "display_mode_vba.h"
28
29#include "dml_inline_defs.h"
30
31static const unsigned int NumberOfStates = DC__VOLTAGE_STATES;
32
33static void fetch_socbb_params(struct display_mode_lib *mode_lib);
34static void fetch_ip_params(struct display_mode_lib *mode_lib);
35static void fetch_pipe_params(struct display_mode_lib *mode_lib);
36static void recalculate_params(
37 struct display_mode_lib *mode_lib,
38 const display_e2e_pipe_params_st *pipes,
39 unsigned int num_pipes);
40static void recalculate(struct display_mode_lib *mode_lib);
41static double adjust_ReturnBW(
42 struct display_mode_lib *mode_lib,
43 double ReturnBW,
44 bool DCCEnabledAnyPlane,
45 double ReturnBandwidthToDCN);
46static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
47static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
48static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
49 struct display_mode_lib *mode_lib);
50static unsigned int dscceComputeDelay(
51 unsigned int bpc,
52 double bpp,
53 unsigned int sliceWidth,
54 unsigned int numSlices,
55 enum output_format_class pixelFormat);
56static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
57// Super monster function with some 45 argument
58static bool CalculatePrefetchSchedule(
59 struct display_mode_lib *mode_lib,
60 double DPPCLK,
61 double DISPCLK,
62 double PixelClock,
63 double DCFClkDeepSleep,
64 unsigned int DSCDelay,
65 unsigned int DPPPerPlane,
66 bool ScalerEnabled,
67 unsigned int NumberOfCursors,
68 double DPPCLKDelaySubtotal,
69 double DPPCLKDelaySCL,
70 double DPPCLKDelaySCLLBOnly,
71 double DPPCLKDelayCNVCFormater,
72 double DPPCLKDelayCNVCCursor,
73 double DISPCLKDelaySubtotal,
74 unsigned int ScalerRecoutWidth,
75 enum output_format_class OutputFormat,
76 unsigned int VBlank,
77 unsigned int HTotal,
78 unsigned int MaxInterDCNTileRepeaters,
79 unsigned int VStartup,
80 unsigned int PageTableLevels,
81 bool VirtualMemoryEnable,
82 bool DynamicMetadataEnable,
83 unsigned int DynamicMetadataLinesBeforeActiveRequired,
84 unsigned int DynamicMetadataTransmittedBytes,
85 bool DCCEnable,
86 double UrgentLatency,
87 double UrgentExtraLatency,
88 double TCalc,
89 unsigned int PDEAndMetaPTEBytesFrame,
90 unsigned int MetaRowByte,
91 unsigned int PixelPTEBytesPerRow,
92 double PrefetchSourceLinesY,
93 unsigned int SwathWidthY,
94 double BytePerPixelDETY,
95 double VInitPreFillY,
96 unsigned int MaxNumSwathY,
97 double PrefetchSourceLinesC,
98 double BytePerPixelDETC,
99 double VInitPreFillC,
100 unsigned int MaxNumSwathC,
101 unsigned int SwathHeightY,
102 unsigned int SwathHeightC,
103 double TWait,
104 bool XFCEnabled,
105 double XFCRemoteSurfaceFlipDelay,
106 bool InterlaceEnable,
107 bool ProgressiveToInterlaceUnitInOPP,
108 double *DSTXAfterScaler,
109 double *DSTYAfterScaler,
110 double *DestinationLinesForPrefetch,
111 double *PrefetchBandwidth,
112 double *DestinationLinesToRequestVMInVBlank,
113 double *DestinationLinesToRequestRowInVBlank,
114 double *VRatioPrefetchY,
115 double *VRatioPrefetchC,
116 double *RequiredPrefetchPixDataBW,
117 unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
118 double *Tno_bw,
119 unsigned int *VUpdateOffsetPix,
120 unsigned int *VUpdateWidthPix,
121 unsigned int *VReadyOffsetPix);
122static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
123static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
124static double CalculatePrefetchSourceLines(
125 struct display_mode_lib *mode_lib,
126 double VRatio,
127 double vtaps,
128 bool Interlace,
129 bool ProgressiveToInterlaceUnitInOPP,
130 unsigned int SwathHeight,
131 unsigned int ViewportYStart,
132 double *VInitPreFill,
133 unsigned int *MaxNumSwath);
134static unsigned int CalculateVMAndRowBytes(
135 struct display_mode_lib *mode_lib,
136 bool DCCEnable,
137 unsigned int BlockHeight256Bytes,
138 unsigned int BlockWidth256Bytes,
139 enum source_format_class SourcePixelFormat,
140 unsigned int SurfaceTiling,
141 unsigned int BytePerPixel,
142 enum scan_direction_class ScanDirection,
143 unsigned int ViewportWidth,
144 unsigned int ViewportHeight,
145 unsigned int SwathWidthY,
146 bool VirtualMemoryEnable,
147 unsigned int VMMPageSize,
148 unsigned int PTEBufferSizeInRequests,
149 unsigned int PDEProcessingBufIn64KBReqs,
150 unsigned int Pitch,
151 unsigned int DCCMetaPitch,
152 unsigned int *MacroTileWidth,
153 unsigned int *MetaRowByte,
154 unsigned int *PixelPTEBytesPerRow,
155 bool *PTEBufferSizeNotExceeded,
156 unsigned int *dpte_row_height,
157 unsigned int *meta_row_height);
158static double CalculateTWait(
159 unsigned int PrefetchMode,
160 double DRAMClockChangeLatency,
161 double UrgentLatency,
162 double SREnterPlusExitTime);
163static double CalculateRemoteSurfaceFlipDelay(
164 struct display_mode_lib *mode_lib,
165 double VRatio,
166 double SwathWidth,
167 double Bpp,
168 double LineTime,
169 double XFCTSlvVupdateOffset,
170 double XFCTSlvVupdateWidth,
171 double XFCTSlvVreadyOffset,
172 double XFCXBUFLatencyTolerance,
173 double XFCFillBWOverhead,
174 double XFCSlvChunkSize,
175 double XFCBusTransportTime,
176 double TCalc,
177 double TWait,
178 double *SrcActiveDrainRate,
179 double *TInitXFill,
180 double *TslvChk);
181static double CalculateWriteBackDISPCLK(
182 enum source_format_class WritebackPixelFormat,
183 double PixelClock,
184 double WritebackHRatio,
185 double WritebackVRatio,
186 unsigned int WritebackLumaHTaps,
187 unsigned int WritebackLumaVTaps,
188 unsigned int WritebackChromaHTaps,
189 unsigned int WritebackChromaVTaps,
190 double WritebackDestinationWidth,
191 unsigned int HTotal,
192 unsigned int WritebackChromaLineBufferWidth);
193static void CalculateActiveRowBandwidth(
194 bool VirtualMemoryEnable,
195 enum source_format_class SourcePixelFormat,
196 double VRatio,
197 bool DCCEnable,
198 double LineTime,
199 unsigned int MetaRowByteLuma,
200 unsigned int MetaRowByteChroma,
201 unsigned int meta_row_height_luma,
202 unsigned int meta_row_height_chroma,
203 unsigned int PixelPTEBytesPerRowLuma,
204 unsigned int PixelPTEBytesPerRowChroma,
205 unsigned int dpte_row_height_luma,
206 unsigned int dpte_row_height_chroma,
207 double *meta_row_bw,
208 double *dpte_row_bw,
209 double *qual_row_bw);
210static void CalculateFlipSchedule(
211 struct display_mode_lib *mode_lib,
212 double UrgentExtraLatency,
213 double UrgentLatency,
214 unsigned int MaxPageTableLevels,
215 bool VirtualMemoryEnable,
216 double BandwidthAvailableForImmediateFlip,
217 unsigned int TotImmediateFlipBytes,
218 enum source_format_class SourcePixelFormat,
219 unsigned int ImmediateFlipBytes,
220 double LineTime,
221 double Tno_bw,
222 double VRatio,
223 double PDEAndMetaPTEBytesFrame,
224 unsigned int MetaRowByte,
225 unsigned int PixelPTEBytesPerRow,
226 bool DCCEnable,
227 unsigned int dpte_row_height,
228 unsigned int meta_row_height,
229 double qual_row_bw,
230 double *DestinationLinesToRequestVMInImmediateFlip,
231 double *DestinationLinesToRequestRowInImmediateFlip,
232 double *final_flip_bw,
233 bool *ImmediateFlipSupportedForPipe);
234static double CalculateWriteBackDelay(
235 enum source_format_class WritebackPixelFormat,
236 double WritebackHRatio,
237 double WritebackVRatio,
238 unsigned int WritebackLumaHTaps,
239 unsigned int WritebackLumaVTaps,
240 unsigned int WritebackChromaHTaps,
241 unsigned int WritebackChromaVTaps,
242 unsigned int WritebackDestinationWidth);
243static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib);
244static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
245static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
246
247void set_prefetch_mode(
248 struct display_mode_lib *mode_lib,
249 bool cstate_en,
250 bool pstate_en,
251 bool ignore_viewport_pos,
252 bool immediate_flip_support)
253{
254 unsigned int prefetch_mode;
255
256 if (cstate_en && pstate_en)
257 prefetch_mode = 0;
258 else if (cstate_en)
259 prefetch_mode = 1;
260 else
261 prefetch_mode = 2;
262 if (prefetch_mode != mode_lib->vba.PrefetchMode
263 || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning
264 || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) {
265 DTRACE(
266 " Prefetch mode has changed from %i to %i. Recalculating.",
267 prefetch_mode,
268 mode_lib->vba.PrefetchMode);
269 mode_lib->vba.PrefetchMode = prefetch_mode;
270 mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos;
271 mode_lib->vba.ImmediateFlipSupport = immediate_flip_support;
272 recalculate(mode_lib);
273 }
274}
275
276unsigned int dml_get_voltage_level(
277 struct display_mode_lib *mode_lib,
278 const display_e2e_pipe_params_st *pipes,
279 unsigned int num_pipes)
280{
281 bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
282 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
283 || num_pipes != mode_lib->vba.cache_num_pipes
284 || memcmp(pipes, mode_lib->vba.cache_pipes,
285 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
286
287 mode_lib->vba.soc = mode_lib->soc;
288 mode_lib->vba.ip = mode_lib->ip;
289 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
290 mode_lib->vba.cache_num_pipes = num_pipes;
291
292 if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
293 recalculate(mode_lib);
294 else {
295 fetch_socbb_params(mode_lib);
296 fetch_ip_params(mode_lib);
297 fetch_pipe_params(mode_lib);
298 }
299 ModeSupportAndSystemConfigurationFull(mode_lib);
300
301 return mode_lib->vba.VoltageLevel;
302}
303
304#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) \
305{ \
306 recalculate_params(mode_lib, pipes, num_pipes); \
307 return var; \
308}
309
310dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep);
311dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
312dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark);
313dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
314dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
315dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
316dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
317dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
318dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent
319dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
320dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
321dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs);
322dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
323dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
324dml_get_attr_func(
325 dram_clock_change_latency,
326 mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
327dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
328dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
329dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
330dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
331
332#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) \
333{\
334 unsigned int which_plane; \
335 recalculate_params(mode_lib, pipes, num_pipes); \
336 which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
337 return var[which_plane]; \
338}
339
340dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
341dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
342dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
343dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
344dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
345dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
346dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
347dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
348dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
349dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
350dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
351dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
352dml_get_pipe_attr_func(
353 dst_y_per_row_flip,
354 mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
355
356dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay);
357dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay);
358dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency);
359dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin);
360
361unsigned int get_vstartup_calculated(
362 struct display_mode_lib *mode_lib,
363 const display_e2e_pipe_params_st *pipes,
364 unsigned int num_pipes,
365 unsigned int which_pipe)
366{
367 unsigned int which_plane;
368
369 recalculate_params(mode_lib, pipes, num_pipes);
370 which_plane = mode_lib->vba.pipe_plane[which_pipe];
371 return mode_lib->vba.VStartup[which_plane];
372}
373
374double get_total_immediate_flip_bytes(
375 struct display_mode_lib *mode_lib,
376 const display_e2e_pipe_params_st *pipes,
377 unsigned int num_pipes)
378{
379 recalculate_params(mode_lib, pipes, num_pipes);
380 return mode_lib->vba.TotImmediateFlipBytes;
381}
382
383double get_total_immediate_flip_bw(
384 struct display_mode_lib *mode_lib,
385 const display_e2e_pipe_params_st *pipes,
386 unsigned int num_pipes)
387{
388 recalculate_params(mode_lib, pipes, num_pipes);
389 return mode_lib->vba.ImmediateFlipBW;
390}
391
392double get_total_prefetch_bw(
393 struct display_mode_lib *mode_lib,
394 const display_e2e_pipe_params_st *pipes,
395 unsigned int num_pipes)
396{
397 unsigned int k;
398 double total_prefetch_bw = 0.0;
399
400 recalculate_params(mode_lib, pipes, num_pipes);
401 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
402 total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
403 return total_prefetch_bw;
404}
405
406static void fetch_socbb_params(struct display_mode_lib *mode_lib)
407{
408 soc_bounding_box_st *soc = &mode_lib->vba.soc;
409 unsigned int i;
410
411 // SOC Bounding Box Parameters
412 mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
413 mode_lib->vba.NumberOfChannels = soc->num_chans;
414 mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency =
415 soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment!
416 mode_lib->vba.UrgentLatency = soc->urgent_latency_us;
417 mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
418 mode_lib->vba.UrgentOutOfOrderReturnPerChannel =
419 soc->urgent_out_of_order_return_per_channel_bytes;
420 mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
421 mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
422 mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
423 mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
424 mode_lib->vba.Downspreading = soc->downspread_percent;
425 mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new!
426 mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
427 mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new
428 mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new
429 mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
430 // Set the voltage scaling clocks as the defaults. Most of these will
431 // be set to different values by the test
432 for (i = 0; i < DC__VOLTAGE_STATES; i++)
433 if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
434 break;
435
436 mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
437 mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
438 mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz;
439 mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
440
441 mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
442 mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
443
444 mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
445 mode_lib->vba.MaxHSCLRatio = 4;
446 mode_lib->vba.MaxVSCLRatio = 4;
447 mode_lib->vba.MaxNumWriteback = 0; /*TODO*/
448 mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
449 mode_lib->vba.Cursor64BppSupport = true;
450 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
451 mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
452 mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
453 mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
454 mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
455 mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
456 mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
457 mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
458 mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
459 }
460}
461
462static void fetch_ip_params(struct display_mode_lib *mode_lib)
463{
464 ip_params_st *ip = &mode_lib->vba.ip;
465
466 // IP Parameters
467 mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
468 mode_lib->vba.MaxNumOTG = ip->max_num_otg;
469 mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
470 mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
471
472 mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
473 mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
474 mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
475 mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
476 mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
477 mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
478 mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes;
479 mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
480 mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
481 mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
482 mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs;
483 mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
484 mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
485 mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes;
486 mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes;
487 mode_lib->vba.WritebackChromaLineBufferWidth =
488 ip->writeback_chroma_line_buffer_width_pixels;
489 mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels;
490 mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
491 mode_lib->vba.NumberOfDSC = ip->num_dsc;
492 mode_lib->vba.ODMCapability = ip->odm_capable;
493 mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
494
495 mode_lib->vba.XFCSupported = ip->xfc_supported;
496 mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
497 mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
498 mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
499 mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
500 mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
501 mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
502 mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
503 mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
504
505 mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
506
507 mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
508}
509
510static void fetch_pipe_params(struct display_mode_lib *mode_lib)
511{
512 display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
513 ip_params_st *ip = &mode_lib->vba.ip;
514
515 unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
516 unsigned int j, k;
517 bool PlaneVisited[DC__NUM_DPP__MAX];
518 bool visited[DC__NUM_DPP__MAX];
519
520 // Convert Pipes to Planes
521 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
522 visited[k] = false;
523
524 mode_lib->vba.NumberOfActivePlanes = 0;
525 for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
526 display_pipe_source_params_st *src = &pipes[j].pipe.src;
527 display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
528 scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
529 scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
530 display_output_params_st *dout = &pipes[j].dout;
531 display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
532
533 if (visited[j])
534 continue;
535 visited[j] = true;
536
537 mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
538
539 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
540 mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
541 (enum scan_direction_class) (src->source_scan);
542 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
543 src->viewport_width;
544 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
545 src->viewport_height;
546 mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
547 src->viewport_y_y;
548 mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
549 src->viewport_y_c;
550 mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
551 mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
552 mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
553 mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
554 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
555 mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
556 mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
557 if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes])
558 mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
559 mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
560 mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
561 mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
562 mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
563 mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
564 mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
565 mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
566 src->dcc_use_global ?
567 ip->dcc_supported : src->dcc && ip->dcc_supported;
568 mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
569 mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] =
570 (enum source_format_class) (src->source_format);
571 mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
572 mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
573 mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
574 (enum dm_swizzle_mode) (src->sw_mode);
575 mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
576 dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
577 mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
578 dst->odm_combine;
579 mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
580 (enum output_format_class) (dout->output_format);
581 mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
582 (enum output_encoder_class) (dout->output_type);
583 mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
584 mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
585 dout->dp_lanes;
586 mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
587 mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
588 dout->dsc_slices;
589 mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
590 dout->output_bpc == 0 ? 12 : dout->output_bpc;
591 mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
592 mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
593 dout->wb.wb_src_height;
594 mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
595 dout->wb.wb_dst_width;
596 mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
597 dout->wb.wb_dst_height;
598 mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
599 (enum source_format_class) (dout->wb.wb_pixel_format);
600 mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
601 dout->wb.wb_htaps_luma;
602 mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
603 dout->wb.wb_vtaps_luma;
604 mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
605 dout->wb.wb_htaps_chroma;
606 mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
607 dout->wb.wb_vtaps_chroma;
608 mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
609 dout->wb.wb_hratio;
610 mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
611 dout->wb.wb_vratio;
612
613 mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
614 src->dynamic_metadata_enable;
615 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
616 src->dynamic_metadata_lines_before_active;
617 mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
618 src->dynamic_metadata_xmit_bytes;
619
620 mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
621 && ip->xfc_supported;
622 mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
623 mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
624 mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
625 mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
626 mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
627 mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
628 if (ip->is_line_buffer_bpp_fixed)
629 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
630 ip->line_buffer_fixed_bpp;
631 else {
632 unsigned int lb_depth;
633
634 switch (scl->lb_depth) {
635 case dm_lb_6:
636 lb_depth = 18;
637 break;
638 case dm_lb_8:
639 lb_depth = 24;
640 break;
641 case dm_lb_10:
642 lb_depth = 30;
643 break;
644 case dm_lb_12:
645 lb_depth = 36;
646 break;
647 case dm_lb_16:
648 lb_depth = 48;
649 break;
650 default:
651 lb_depth = 36;
652 }
653 mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
654 }
655 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
656 // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
657 // calculate things a little more accurately
658 for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
659 switch (k) {
660 case 0:
661 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
662 CursorBppEnumToBits(
663 (enum cursor_bpp) (src->cur0_bpp));
664 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
665 src->cur0_src_width;
666 if (src->cur0_src_width > 0)
667 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
668 break;
669 case 1:
670 mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
671 CursorBppEnumToBits(
672 (enum cursor_bpp) (src->cur1_bpp));
673 mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
674 src->cur1_src_width;
675 if (src->cur1_src_width > 0)
676 mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
677 break;
678 default:
679 dml_print(
680 "ERROR: Number of cursors specified exceeds supported maximum\n")
681 ;
682 }
683 }
684
685 OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
686
687 if (dst->odm_combine && !src->is_hsplit)
688 dml_print(
689 "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
690 j);
691
692 if (src->is_hsplit) {
693 for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
694 display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
695 display_output_params_st *dout_k = &pipes[k].dout;
696
697 if (src_k->is_hsplit && !visited[k]
698 && src->hsplit_grp == src_k->hsplit_grp) {
699 mode_lib->vba.pipe_plane[k] =
700 mode_lib->vba.NumberOfActivePlanes;
701 mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
702 if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
703 == dm_horz)
704 mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
705 src_k->viewport_width;
706 else
707 mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
708 src_k->viewport_height;
709
710 mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] +=
711 dout_k->dsc_slices;
712 visited[k] = true;
713 }
714 }
715 }
716
717 mode_lib->vba.NumberOfActivePlanes++;
718 }
719
720 // handle overlays through dml_ml->vba.BlendingAndTiming
721 // dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
722
723 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
724 PlaneVisited[j] = false;
725
726 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
727 for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
728 if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
729 // doesn't matter, so choose the smaller one
730 mode_lib->vba.BlendingAndTiming[j] = j;
731 PlaneVisited[j] = true;
732 mode_lib->vba.BlendingAndTiming[k] = j;
733 PlaneVisited[k] = true;
734 }
735 }
736
737 if (!PlaneVisited[j]) {
738 mode_lib->vba.BlendingAndTiming[j] = j;
739 PlaneVisited[j] = true;
740 }
741 }
742
743 // TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified
744 // Do we want the dscclk to automatically be halved? Guess not since the value is specified
745
746 mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
747 for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k)
748 ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
749
750 mode_lib->vba.VirtualMemoryEnable = false;
751 mode_lib->vba.OverridePageTableLevels = 0;
752
753 for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
754 mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable
755 || !!pipes[k].pipe.src.vm;
756 mode_lib->vba.OverridePageTableLevels =
757 (pipes[k].pipe.src.vm_levels_force_en
758 && mode_lib->vba.OverridePageTableLevels
759 < pipes[k].pipe.src.vm_levels_force) ?
760 pipes[k].pipe.src.vm_levels_force :
761 mode_lib->vba.OverridePageTableLevels;
762 }
763
764 if (mode_lib->vba.OverridePageTableLevels)
765 mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels;
766
767 mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable && !!ip->pte_enable;
768
769 mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
770 mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels
771 * mode_lib->vba.DRAMChannelWidth,
772 mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn)
773 / 1000.0;
774
775 // TODO: Must be consistent across all pipes
776 // DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown;
777}
778
779static void recalculate(struct display_mode_lib *mode_lib)
780{
781 ModeSupportAndSystemConfiguration(mode_lib);
782 PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
783 DisplayPipeConfiguration(mode_lib);
784 DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
785}
786
787// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
788// rather than working them out as in recalculate_ms
789static void recalculate_params(
790 struct display_mode_lib *mode_lib,
791 const display_e2e_pipe_params_st *pipes,
792 unsigned int num_pipes)
793{
794 // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
795 if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
796 || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
797 || num_pipes != mode_lib->vba.cache_num_pipes
798 || memcmp(
799 pipes,
800 mode_lib->vba.cache_pipes,
801 sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
802 mode_lib->vba.soc = mode_lib->soc;
803 mode_lib->vba.ip = mode_lib->ip;
804 memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
805 mode_lib->vba.cache_num_pipes = num_pipes;
806 recalculate(mode_lib);
807 }
808}
809
810static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
811{
812 soc_bounding_box_st *soc = &mode_lib->vba.soc;
813 unsigned int i, k;
814 unsigned int total_pipes = 0;
815
816 mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
817 for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i)
818 ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage);
819
820 mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
821 mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
822
823 if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
824 mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
825 else
826 mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
827
828 fetch_socbb_params(mode_lib);
829 fetch_ip_params(mode_lib);
830 fetch_pipe_params(mode_lib);
831
832 // Total Available Pipes Support Check
833 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
834 total_pipes += mode_lib->vba.DPPPerPlane[k];
835 ASSERT(total_pipes <= DC__NUM_DPP__MAX);
836}
837
838static double adjust_ReturnBW(
839 struct display_mode_lib *mode_lib,
840 double ReturnBW,
841 bool DCCEnabledAnyPlane,
842 double ReturnBandwidthToDCN)
843{
844 double CriticalCompression;
845
846 if (DCCEnabledAnyPlane
847 && ReturnBandwidthToDCN
848 > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
849 ReturnBW =
850 dml_min(
851 ReturnBW,
852 ReturnBandwidthToDCN * 4
853 * (1.0
854 - mode_lib->vba.UrgentLatency
855 / ((mode_lib->vba.ROBBufferSizeInKByte
856 - mode_lib->vba.PixelChunkSizeInKByte)
857 * 1024
858 / ReturnBandwidthToDCN
859 - mode_lib->vba.DCFCLK
860 * mode_lib->vba.ReturnBusWidth
861 / 4)
862 + mode_lib->vba.UrgentLatency));
863
864 CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
865 * mode_lib->vba.UrgentLatency
866 / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency
867 + (mode_lib->vba.ROBBufferSizeInKByte
868 - mode_lib->vba.PixelChunkSizeInKByte)
869 * 1024);
870
871 if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
872 ReturnBW =
873 dml_min(
874 ReturnBW,
875 4.0 * ReturnBandwidthToDCN
876 * (mode_lib->vba.ROBBufferSizeInKByte
877 - mode_lib->vba.PixelChunkSizeInKByte)
878 * 1024
879 * mode_lib->vba.ReturnBusWidth
880 * mode_lib->vba.DCFCLK
881 * mode_lib->vba.UrgentLatency
882 / dml_pow(
883 (ReturnBandwidthToDCN
884 * mode_lib->vba.UrgentLatency
885 + (mode_lib->vba.ROBBufferSizeInKByte
886 - mode_lib->vba.PixelChunkSizeInKByte)
887 * 1024),
888 2));
889
890 return ReturnBW;
891}
892
893static unsigned int dscceComputeDelay(
894 unsigned int bpc,
895 double bpp,
896 unsigned int sliceWidth,
897 unsigned int numSlices,
898 enum output_format_class pixelFormat)
899{
900 // valid bpc = source bits per component in the set of {8, 10, 12}
901 // valid bpp = increments of 1/16 of a bit
902 // min = 6/7/8 in N420/N422/444, respectively
903 // max = such that compression is 1:1
904 //valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
905 //valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
906 //valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
907
908 // fixed value
909 unsigned int rcModelSize = 8192;
910
911 // N422/N420 operate at 2 pixels per clock
912 unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
913 Delay, pixels;
914
915 if (pixelFormat == dm_n422 || pixelFormat == dm_420)
916 pixelsPerClock = 2;
917 // #all other modes operate at 1 pixel per clock
918 else
919 pixelsPerClock = 1;
920
921 //initial transmit delay as per PPS
922 initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
923
924 //compute ssm delay
925 if (bpc == 8)
926 D = 81;
927 else if (bpc == 10)
928 D = 89;
929 else
930 D = 113;
931
932 //divide by pixel per cycle to compute slice width as seen by DSC
933 w = sliceWidth / pixelsPerClock;
934
935 //422 mode has an additional cycle of delay
936 if (pixelFormat == dm_s422)
937 s = 1;
938 else
939 s = 0;
940
941 //main calculation for the dscce
942 ix = initalXmitDelay + 45;
943 wx = (w + 2) / 3;
944 p = 3 * wx - w;
945 l0 = ix / w;
946 a = ix + p * l0;
947 ax = (a + 2) / 3 + D + 6 + 1;
948 l = (ax + wx - 1) / wx;
949 if ((ix % w) == 0 && p != 0)
950 lstall = 1;
951 else
952 lstall = 0;
953 Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
954
955 //dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
956 pixels = Delay * 3 * pixelsPerClock;
957 return pixels;
958}
959
960static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
961{
962 unsigned int Delay = 0;
963
964 if (pixelFormat == dm_420) {
965 // sfr
966 Delay = Delay + 2;
967 // dsccif
968 Delay = Delay + 0;
969 // dscc - input deserializer
970 Delay = Delay + 3;
971 // dscc gets pixels every other cycle
972 Delay = Delay + 2;
973 // dscc - input cdc fifo
974 Delay = Delay + 12;
975 // dscc gets pixels every other cycle
976 Delay = Delay + 13;
977 // dscc - cdc uncertainty
978 Delay = Delay + 2;
979 // dscc - output cdc fifo
980 Delay = Delay + 7;
981 // dscc gets pixels every other cycle
982 Delay = Delay + 3;
983 // dscc - cdc uncertainty
984 Delay = Delay + 2;
985 // dscc - output serializer
986 Delay = Delay + 1;
987 // sft
988 Delay = Delay + 1;
989 } else if (pixelFormat == dm_n422) {
990 // sfr
991 Delay = Delay + 2;
992 // dsccif
993 Delay = Delay + 1;
994 // dscc - input deserializer
995 Delay = Delay + 5;
996 // dscc - input cdc fifo
997 Delay = Delay + 25;
998 // dscc - cdc uncertainty
999 Delay = Delay + 2;
1000 // dscc - output cdc fifo
1001 Delay = Delay + 10;
1002 // dscc - cdc uncertainty
1003 Delay = Delay + 2;
1004 // dscc - output serializer
1005 Delay = Delay + 1;
1006 // sft
1007 Delay = Delay + 1;
1008 } else {
1009 // sfr
1010 Delay = Delay + 2;
1011 // dsccif
1012 Delay = Delay + 0;
1013 // dscc - input deserializer
1014 Delay = Delay + 3;
1015 // dscc - input cdc fifo
1016 Delay = Delay + 12;
1017 // dscc - cdc uncertainty
1018 Delay = Delay + 2;
1019 // dscc - output cdc fifo
1020 Delay = Delay + 7;
1021 // dscc - output serializer
1022 Delay = Delay + 1;
1023 // dscc - cdc uncertainty
1024 Delay = Delay + 2;
1025 // sft
1026 Delay = Delay + 1;
1027 }
1028
1029 return Delay;
1030}
1031
1032static bool CalculatePrefetchSchedule(
1033 struct display_mode_lib *mode_lib,
1034 double DPPCLK,
1035 double DISPCLK,
1036 double PixelClock,
1037 double DCFClkDeepSleep,
1038 unsigned int DSCDelay,
1039 unsigned int DPPPerPlane,
1040 bool ScalerEnabled,
1041 unsigned int NumberOfCursors,
1042 double DPPCLKDelaySubtotal,
1043 double DPPCLKDelaySCL,
1044 double DPPCLKDelaySCLLBOnly,
1045 double DPPCLKDelayCNVCFormater,
1046 double DPPCLKDelayCNVCCursor,
1047 double DISPCLKDelaySubtotal,
1048 unsigned int ScalerRecoutWidth,
1049 enum output_format_class OutputFormat,
1050 unsigned int VBlank,
1051 unsigned int HTotal,
1052 unsigned int MaxInterDCNTileRepeaters,
1053 unsigned int VStartup,
1054 unsigned int PageTableLevels,
1055 bool VirtualMemoryEnable,
1056 bool DynamicMetadataEnable,
1057 unsigned int DynamicMetadataLinesBeforeActiveRequired,
1058 unsigned int DynamicMetadataTransmittedBytes,
1059 bool DCCEnable,
1060 double UrgentLatency,
1061 double UrgentExtraLatency,
1062 double TCalc,
1063 unsigned int PDEAndMetaPTEBytesFrame,
1064 unsigned int MetaRowByte,
1065 unsigned int PixelPTEBytesPerRow,
1066 double PrefetchSourceLinesY,
1067 unsigned int SwathWidthY,
1068 double BytePerPixelDETY,
1069 double VInitPreFillY,
1070 unsigned int MaxNumSwathY,
1071 double PrefetchSourceLinesC,
1072 double BytePerPixelDETC,
1073 double VInitPreFillC,
1074 unsigned int MaxNumSwathC,
1075 unsigned int SwathHeightY,
1076 unsigned int SwathHeightC,
1077 double TWait,
1078 bool XFCEnabled,
1079 double XFCRemoteSurfaceFlipDelay,
1080 bool InterlaceEnable,
1081 bool ProgressiveToInterlaceUnitInOPP,
1082 double *DSTXAfterScaler,
1083 double *DSTYAfterScaler,
1084 double *DestinationLinesForPrefetch,
1085 double *PrefetchBandwidth,
1086 double *DestinationLinesToRequestVMInVBlank,
1087 double *DestinationLinesToRequestRowInVBlank,
1088 double *VRatioPrefetchY,
1089 double *VRatioPrefetchC,
1090 double *RequiredPrefetchPixDataBW,
1091 unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
1092 double *Tno_bw,
1093 unsigned int *VUpdateOffsetPix,
1094 unsigned int *VUpdateWidthPix,
1095 unsigned int *VReadyOffsetPix)
1096{
1097 bool MyError = false;
1098 unsigned int DPPCycles, DISPCLKCycles;
1099 double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
1100 double Tdm, LineTime, Tsetup;
1101 double dst_y_prefetch_equ;
1102 double Tsw_oto;
1103 double prefetch_bw_oto;
1104 double Tvm_oto;
1105 double Tr0_oto;
1106 double Tpre_oto;
1107 double dst_y_prefetch_oto;
1108 double TimeForFetchingMetaPTE = 0;
1109 double TimeForFetchingRowInVBlank = 0;
1110 double LinesToRequestPrefetchPixelData = 0;
1111
1112 if (ScalerEnabled)
1113 DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
1114 else
1115 DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
1116
1117 DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
1118
1119 DISPCLKCycles = DISPCLKDelaySubtotal;
1120
1121 if (DPPCLK == 0.0 || DISPCLK == 0.0)
1122 return true;
1123
1124 *DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
1125 + DSCDelay;
1126
1127 if (DPPPerPlane > 1)
1128 *DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
1129
1130 if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
1131 *DSTYAfterScaler = 1;
1132 else
1133 *DSTYAfterScaler = 0;
1134
1135 DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
1136 *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
1137 *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
1138
1139 *VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
1140 TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
1141 *VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
1142 * PixelClock;
1143
1144 *VReadyOffsetPix = dml_max(
1145 150.0 / DPPCLK,
1146 TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK)
1147 * PixelClock;
1148
1149 Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
1150
1151 LineTime = (double) HTotal / PixelClock;
1152
1153 if (DynamicMetadataEnable) {
1154 double Tdmbf, Tdmec, Tdmsks;
1155
1156 Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
1157 Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
1158 Tdmec = LineTime;
1159 if (DynamicMetadataLinesBeforeActiveRequired == 0)
1160 Tdmsks = VBlank * LineTime / 2.0;
1161 else
1162 Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
1163 if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
1164 Tdmsks = Tdmsks / 2;
1165 if (VStartup * LineTime
1166 < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
1167 MyError = true;
1168 *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
1169 + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
1170 } else
1171 *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
1172 } else
1173 Tdm = 0;
1174
1175 if (VirtualMemoryEnable) {
1176 if (PageTableLevels == 4)
1177 *Tno_bw = UrgentExtraLatency + UrgentLatency;
1178 else if (PageTableLevels == 3)
1179 *Tno_bw = UrgentExtraLatency;
1180 else
1181 *Tno_bw = 0;
1182 } else if (DCCEnable)
1183 *Tno_bw = LineTime;
1184 else
1185 *Tno_bw = LineTime / 4;
1186
1187 dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
1188 - (Tsetup + Tdm) / LineTime
1189 - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal);
1190
1191 Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
1192
1193 prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
1194 + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
1195 + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
1196 / Tsw_oto;
1197
1198 if (VirtualMemoryEnable == true) {
1199 Tvm_oto =
1200 dml_max(
1201 *Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
1202 dml_max(
1203 UrgentExtraLatency
1204 + UrgentLatency
1205 * (PageTableLevels
1206 - 1),
1207 LineTime / 4.0));
1208 } else
1209 Tvm_oto = LineTime / 4.0;
1210
1211 if ((VirtualMemoryEnable == true || DCCEnable == true)) {
1212 Tr0_oto = dml_max(
1213 (MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
1214 dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4)));
1215 } else
1216 Tr0_oto = LineTime - Tvm_oto;
1217
1218 Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
1219
1220 dst_y_prefetch_oto = Tpre_oto / LineTime;
1221
1222 if (dst_y_prefetch_oto < dst_y_prefetch_equ)
1223 *DestinationLinesForPrefetch = dst_y_prefetch_oto;
1224 else
1225 *DestinationLinesForPrefetch = dst_y_prefetch_equ;
1226
1227 *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
1228 / 4;
1229
1230 dml_print("DML: VStartup: %d\n", VStartup);
1231 dml_print("DML: TCalc: %f\n", TCalc);
1232 dml_print("DML: TWait: %f\n", TWait);
1233 dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
1234 dml_print("DML: LineTime: %f\n", LineTime);
1235 dml_print("DML: Tsetup: %f\n", Tsetup);
1236 dml_print("DML: Tdm: %f\n", Tdm);
1237 dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler);
1238 dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler);
1239 dml_print("DML: HTotal: %d\n", HTotal);
1240
1241 *PrefetchBandwidth = 0;
1242 *DestinationLinesToRequestVMInVBlank = 0;
1243 *DestinationLinesToRequestRowInVBlank = 0;
1244 *VRatioPrefetchY = 0;
1245 *VRatioPrefetchC = 0;
1246 *RequiredPrefetchPixDataBW = 0;
1247 if (*DestinationLinesForPrefetch > 1) {
1248 *PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
1249 + 2 * PixelPTEBytesPerRow
1250 + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
1251 + PrefetchSourceLinesC * SwathWidthY / 2
1252 * dml_ceil(BytePerPixelDETC, 2))
1253 / (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
1254 if (VirtualMemoryEnable) {
1255 TimeForFetchingMetaPTE =
1256 dml_max(
1257 *Tno_bw
1258 + (double) PDEAndMetaPTEBytesFrame
1259 / *PrefetchBandwidth,
1260 dml_max(
1261 UrgentExtraLatency
1262 + UrgentLatency
1263 * (PageTableLevels
1264 - 1),
1265 LineTime / 4));
1266 } else {
1267 if (NumberOfCursors > 0 || XFCEnabled)
1268 TimeForFetchingMetaPTE = LineTime / 4;
1269 else
1270 TimeForFetchingMetaPTE = 0.0;
1271 }
1272
1273 if ((VirtualMemoryEnable == true || DCCEnable == true)) {
1274 TimeForFetchingRowInVBlank =
1275 dml_max(
1276 (MetaRowByte + PixelPTEBytesPerRow)
1277 / *PrefetchBandwidth,
1278 dml_max(
1279 UrgentLatency,
1280 dml_max(
1281 LineTime
1282 - TimeForFetchingMetaPTE,
1283 LineTime
1284 / 4.0)));
1285 } else {
1286 if (NumberOfCursors > 0 || XFCEnabled)
1287 TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
1288 else
1289 TimeForFetchingRowInVBlank = 0.0;
1290 }
1291
1292 *DestinationLinesToRequestVMInVBlank = dml_floor(
1293 4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
1294 1) / 4.0;
1295
1296 *DestinationLinesToRequestRowInVBlank = dml_floor(
1297 4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
1298 1) / 4.0;
1299
1300 LinesToRequestPrefetchPixelData =
1301 *DestinationLinesForPrefetch
1302 - ((NumberOfCursors > 0 || VirtualMemoryEnable
1303 || DCCEnable) ?
1304 (*DestinationLinesToRequestVMInVBlank
1305 + *DestinationLinesToRequestRowInVBlank) :
1306 0.0);
1307
1308 if (LinesToRequestPrefetchPixelData > 0) {
1309
1310 *VRatioPrefetchY = (double) PrefetchSourceLinesY
1311 / LinesToRequestPrefetchPixelData;
1312 *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1313 if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
1314 if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
1315 *VRatioPrefetchY =
1316 dml_max(
1317 (double) PrefetchSourceLinesY
1318 / LinesToRequestPrefetchPixelData,
1319 (double) MaxNumSwathY
1320 * SwathHeightY
1321 / (LinesToRequestPrefetchPixelData
1322 - (VInitPreFillY
1323 - 3.0)
1324 / 2.0));
1325 *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
1326 } else {
1327 MyError = true;
1328 *VRatioPrefetchY = 0;
1329 }
1330 }
1331
1332 *VRatioPrefetchC = (double) PrefetchSourceLinesC
1333 / LinesToRequestPrefetchPixelData;
1334 *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1335
1336 if ((SwathHeightC > 4)) {
1337 if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
1338 *VRatioPrefetchC =
1339 dml_max(
1340 *VRatioPrefetchC,
1341 (double) MaxNumSwathC
1342 * SwathHeightC
1343 / (LinesToRequestPrefetchPixelData
1344 - (VInitPreFillC
1345 - 3.0)
1346 / 2.0));
1347 *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
1348 } else {
1349 MyError = true;
1350 *VRatioPrefetchC = 0;
1351 }
1352 }
1353
1354 *RequiredPrefetchPixDataBW =
1355 DPPPerPlane
1356 * ((double) PrefetchSourceLinesY
1357 / LinesToRequestPrefetchPixelData
1358 * dml_ceil(
1359 BytePerPixelDETY,
1360 1)
1361 + (double) PrefetchSourceLinesC
1362 / LinesToRequestPrefetchPixelData
1363 * dml_ceil(
1364 BytePerPixelDETC,
1365 2)
1366 / 2)
1367 * SwathWidthY / LineTime;
1368 } else {
1369 MyError = true;
1370 *VRatioPrefetchY = 0;
1371 *VRatioPrefetchC = 0;
1372 *RequiredPrefetchPixDataBW = 0;
1373 }
1374
1375 } else {
1376 MyError = true;
1377 }
1378
1379 if (MyError) {
1380 *PrefetchBandwidth = 0;
1381 TimeForFetchingMetaPTE = 0;
1382 TimeForFetchingRowInVBlank = 0;
1383 *DestinationLinesToRequestVMInVBlank = 0;
1384 *DestinationLinesToRequestRowInVBlank = 0;
1385 *DestinationLinesForPrefetch = 0;
1386 LinesToRequestPrefetchPixelData = 0;
1387 *VRatioPrefetchY = 0;
1388 *VRatioPrefetchC = 0;
1389 *RequiredPrefetchPixDataBW = 0;
1390 }
1391
1392 return MyError;
1393}
1394
1395static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
1396{
1397 return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
1398}
1399
1400static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
1401{
1402 return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
1403}
1404
1405static double CalculatePrefetchSourceLines(
1406 struct display_mode_lib *mode_lib,
1407 double VRatio,
1408 double vtaps,
1409 bool Interlace,
1410 bool ProgressiveToInterlaceUnitInOPP,
1411 unsigned int SwathHeight,
1412 unsigned int ViewportYStart,
1413 double *VInitPreFill,
1414 unsigned int *MaxNumSwath)
1415{
1416 unsigned int MaxPartialSwath;
1417
1418 if (ProgressiveToInterlaceUnitInOPP)
1419 *VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
1420 else
1421 *VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
1422
1423 if (!mode_lib->vba.IgnoreViewportPositioning) {
1424
1425 *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
1426
1427 if (*VInitPreFill > 1.0)
1428 MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
1429 else
1430 MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
1431 % SwathHeight;
1432 MaxPartialSwath = dml_max(1U, MaxPartialSwath);
1433
1434 } else {
1435
1436 if (ViewportYStart != 0)
1437 dml_print(
1438 "WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
1439
1440 *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
1441
1442 if (*VInitPreFill > 1.0)
1443 MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
1444 else
1445 MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
1446 % SwathHeight;
1447 }
1448
1449 return *MaxNumSwath * SwathHeight + MaxPartialSwath;
1450}
1451
1452static unsigned int CalculateVMAndRowBytes(
1453 struct display_mode_lib *mode_lib,
1454 bool DCCEnable,
1455 unsigned int BlockHeight256Bytes,
1456 unsigned int BlockWidth256Bytes,
1457 enum source_format_class SourcePixelFormat,
1458 unsigned int SurfaceTiling,
1459 unsigned int BytePerPixel,
1460 enum scan_direction_class ScanDirection,
1461 unsigned int ViewportWidth,
1462 unsigned int ViewportHeight,
1463 unsigned int SwathWidth,
1464 bool VirtualMemoryEnable,
1465 unsigned int VMMPageSize,
1466 unsigned int PTEBufferSizeInRequests,
1467 unsigned int PDEProcessingBufIn64KBReqs,
1468 unsigned int Pitch,
1469 unsigned int DCCMetaPitch,
1470 unsigned int *MacroTileWidth,
1471 unsigned int *MetaRowByte,
1472 unsigned int *PixelPTEBytesPerRow,
1473 bool *PTEBufferSizeNotExceeded,
1474 unsigned int *dpte_row_height,
1475 unsigned int *meta_row_height)
1476{
1477 unsigned int MetaRequestHeight;
1478 unsigned int MetaRequestWidth;
1479 unsigned int MetaSurfWidth;
1480 unsigned int MetaSurfHeight;
1481 unsigned int MPDEBytesFrame;
1482 unsigned int MetaPTEBytesFrame;
1483 unsigned int DCCMetaSurfaceBytes;
1484
1485 unsigned int MacroTileSizeBytes;
1486 unsigned int MacroTileHeight;
1487 unsigned int DPDE0BytesFrame;
1488 unsigned int ExtraDPDEBytesFrame;
1489 unsigned int PDEAndMetaPTEBytesFrame;
1490
1491 if (DCCEnable == true) {
1492 MetaRequestHeight = 8 * BlockHeight256Bytes;
1493 MetaRequestWidth = 8 * BlockWidth256Bytes;
1494 if (ScanDirection == dm_horz) {
1495 *meta_row_height = MetaRequestHeight;
1496 MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
1497 + MetaRequestWidth;
1498 *MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
1499 } else {
1500 *meta_row_height = MetaRequestWidth;
1501 MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
1502 + MetaRequestHeight;
1503 *MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
1504 }
1505 if (ScanDirection == dm_horz) {
1506 DCCMetaSurfaceBytes = DCCMetaPitch
1507 * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
1508 + 64 * BlockHeight256Bytes) * BytePerPixel
1509 / 256;
1510 } else {
1511 DCCMetaSurfaceBytes = DCCMetaPitch
1512 * (dml_ceil(
1513 (double) ViewportHeight - 1,
1514 64 * BlockHeight256Bytes)
1515 + 64 * BlockHeight256Bytes) * BytePerPixel
1516 / 256;
1517 }
1518 if (VirtualMemoryEnable == true) {
1519 MetaPTEBytesFrame = (dml_ceil(
1520 (double) (DCCMetaSurfaceBytes - VMMPageSize)
1521 / (8 * VMMPageSize),
1522 1) + 1) * 64;
1523 MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1);
1524 } else {
1525 MetaPTEBytesFrame = 0;
1526 MPDEBytesFrame = 0;
1527 }
1528 } else {
1529 MetaPTEBytesFrame = 0;
1530 MPDEBytesFrame = 0;
1531 *MetaRowByte = 0;
1532 }
1533
1534 if (SurfaceTiling == dm_sw_linear) {
1535 MacroTileSizeBytes = 256;
1536 MacroTileHeight = 1;
1537 } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
1538 || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
1539 MacroTileSizeBytes = 4096;
1540 MacroTileHeight = 4 * BlockHeight256Bytes;
1541 } else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
1542 || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
1543 || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
1544 || SurfaceTiling == dm_sw_64kb_r_x) {
1545 MacroTileSizeBytes = 65536;
1546 MacroTileHeight = 16 * BlockHeight256Bytes;
1547 } else {
1548 MacroTileSizeBytes = 262144;
1549 MacroTileHeight = 32 * BlockHeight256Bytes;
1550 }
1551 *MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
1552
1553 if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) {
1554 if (ScanDirection == dm_horz) {
1555 DPDE0BytesFrame =
1556 64
1557 * (dml_ceil(
1558 ((Pitch
1559 * (dml_ceil(
1560 ViewportHeight
1561 - 1,
1562 MacroTileHeight)
1563 + MacroTileHeight)
1564 * BytePerPixel)
1565 - MacroTileSizeBytes)
1566 / (8
1567 * 2097152),
1568 1) + 1);
1569 } else {
1570 DPDE0BytesFrame =
1571 64
1572 * (dml_ceil(
1573 ((Pitch
1574 * (dml_ceil(
1575 (double) SwathWidth
1576 - 1,
1577 MacroTileHeight)
1578 + MacroTileHeight)
1579 * BytePerPixel)
1580 - MacroTileSizeBytes)
1581 / (8
1582 * 2097152),
1583 1) + 1);
1584 }
1585 ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2);
1586 } else {
1587 DPDE0BytesFrame = 0;
1588 ExtraDPDEBytesFrame = 0;
1589 }
1590
1591 PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
1592 + ExtraDPDEBytesFrame;
1593
1594 if (VirtualMemoryEnable == true) {
1595 unsigned int PTERequestSize;
1596 unsigned int PixelPTEReqHeight;
1597 unsigned int PixelPTEReqWidth;
1598 double FractionOfPTEReturnDrop;
1599 unsigned int EffectivePDEProcessingBufIn64KBReqs;
1600
1601 if (SurfaceTiling == dm_sw_linear) {
1602 PixelPTEReqHeight = 1;
1603 PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
1604 PTERequestSize = 64;
1605 FractionOfPTEReturnDrop = 0;
1606 } else if (MacroTileSizeBytes == 4096) {
1607 PixelPTEReqHeight = MacroTileHeight;
1608 PixelPTEReqWidth = 8 * *MacroTileWidth;
1609 PTERequestSize = 64;
1610 if (ScanDirection == dm_horz)
1611 FractionOfPTEReturnDrop = 0;
1612 else
1613 FractionOfPTEReturnDrop = 7 / 8;
1614 } else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
1615 PixelPTEReqHeight = 16 * BlockHeight256Bytes;
1616 PixelPTEReqWidth = 16 * BlockWidth256Bytes;
1617 PTERequestSize = 128;
1618 FractionOfPTEReturnDrop = 0;
1619 } else {
1620 PixelPTEReqHeight = MacroTileHeight;
1621 PixelPTEReqWidth = 8 * *MacroTileWidth;
1622 PTERequestSize = 64;
1623 FractionOfPTEReturnDrop = 0;
1624 }
1625
1626 if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
1627 EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
1628 else
1629 EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
1630
1631 if (SurfaceTiling == dm_sw_linear) {
1632 *dpte_row_height =
1633 dml_min(
1634 128,
1635 1
1636 << (unsigned int) dml_floor(
1637 dml_log2(
1638 dml_min(
1639 (double) PTEBufferSizeInRequests
1640 * PixelPTEReqWidth,
1641 EffectivePDEProcessingBufIn64KBReqs
1642 * 65536.0
1643 / BytePerPixel)
1644 / Pitch),
1645 1));
1646 *PixelPTEBytesPerRow = PTERequestSize
1647 * (dml_ceil(
1648 (double) (Pitch * *dpte_row_height - 1)
1649 / PixelPTEReqWidth,
1650 1) + 1);
1651 } else if (ScanDirection == dm_horz) {
1652 *dpte_row_height = PixelPTEReqHeight;
1653 *PixelPTEBytesPerRow = PTERequestSize
1654 * (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
1655 + 1);
1656 } else {
1657 *dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
1658 *PixelPTEBytesPerRow = PTERequestSize
1659 * (dml_ceil(
1660 ((double) SwathWidth - 1)
1661 / PixelPTEReqHeight,
1662 1) + 1);
1663 }
1664 if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
1665 <= 64 * PTEBufferSizeInRequests) {
1666 *PTEBufferSizeNotExceeded = true;
1667 } else {
1668 *PTEBufferSizeNotExceeded = false;
1669 }
1670 } else {
1671 *PixelPTEBytesPerRow = 0;
1672 *PTEBufferSizeNotExceeded = true;
1673 }
1674
1675 return PDEAndMetaPTEBytesFrame;
1676}
1677
1678static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
1679 struct display_mode_lib *mode_lib)
1680{
1681 unsigned int j, k;
1682
1683 mode_lib->vba.WritebackDISPCLK = 0.0;
1684 mode_lib->vba.DISPCLKWithRamping = 0;
1685 mode_lib->vba.DISPCLKWithoutRamping = 0;
1686 mode_lib->vba.GlobalDPPCLK = 0.0;
1687
1688 // dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
1689 //
1690 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1691 if (mode_lib->vba.WritebackEnable[k]) {
1692 mode_lib->vba.WritebackDISPCLK =
1693 dml_max(
1694 mode_lib->vba.WritebackDISPCLK,
1695 CalculateWriteBackDISPCLK(
1696 mode_lib->vba.WritebackPixelFormat[k],
1697 mode_lib->vba.PixelClock[k],
1698 mode_lib->vba.WritebackHRatio[k],
1699 mode_lib->vba.WritebackVRatio[k],
1700 mode_lib->vba.WritebackLumaHTaps[k],
1701 mode_lib->vba.WritebackLumaVTaps[k],
1702 mode_lib->vba.WritebackChromaHTaps[k],
1703 mode_lib->vba.WritebackChromaVTaps[k],
1704 mode_lib->vba.WritebackDestinationWidth[k],
1705 mode_lib->vba.HTotal[k],
1706 mode_lib->vba.WritebackChromaLineBufferWidth));
1707 }
1708 }
1709
1710 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1711 if (mode_lib->vba.HRatio[k] > 1) {
1712 mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
1713 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1714 mode_lib->vba.MaxPSCLToLBThroughput
1715 * mode_lib->vba.HRatio[k]
1716 / dml_ceil(
1717 mode_lib->vba.htaps[k]
1718 / 6.0,
1719 1));
1720 } else {
1721 mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
1722 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1723 mode_lib->vba.MaxPSCLToLBThroughput);
1724 }
1725
1726 mode_lib->vba.DPPCLKUsingSingleDPPLuma =
1727 mode_lib->vba.PixelClock[k]
1728 * dml_max(
1729 mode_lib->vba.vtaps[k] / 6.0
1730 * dml_min(
1731 1.0,
1732 mode_lib->vba.HRatio[k]),
1733 dml_max(
1734 mode_lib->vba.HRatio[k]
1735 * mode_lib->vba.VRatio[k]
1736 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
1737 1.0));
1738
1739 if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
1740 && mode_lib->vba.DPPCLKUsingSingleDPPLuma
1741 < 2 * mode_lib->vba.PixelClock[k]) {
1742 mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
1743 }
1744
1745 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
1746 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
1747 mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
1748 mode_lib->vba.DPPCLKUsingSingleDPP[k] =
1749 mode_lib->vba.DPPCLKUsingSingleDPPLuma;
1750 } else {
1751 if (mode_lib->vba.HRatio[k] > 1) {
1752 mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
1753 dml_min(
1754 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1755 mode_lib->vba.MaxPSCLToLBThroughput
1756 * mode_lib->vba.HRatio[k]
1757 / 2
1758 / dml_ceil(
1759 mode_lib->vba.HTAPsChroma[k]
1760 / 6.0,
1761 1.0));
1762 } else {
1763 mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
1764 mode_lib->vba.MaxDCHUBToPSCLThroughput,
1765 mode_lib->vba.MaxPSCLToLBThroughput);
1766 }
1767 mode_lib->vba.DPPCLKUsingSingleDPPChroma =
1768 mode_lib->vba.PixelClock[k]
1769 * dml_max(
1770 mode_lib->vba.VTAPsChroma[k]
1771 / 6.0
1772 * dml_min(
1773 1.0,
1774 mode_lib->vba.HRatio[k]
1775 / 2),
1776 dml_max(
1777 mode_lib->vba.HRatio[k]
1778 * mode_lib->vba.VRatio[k]
1779 / 4
1780 / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
1781 1.0));
1782
1783 if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
1784 && mode_lib->vba.DPPCLKUsingSingleDPPChroma
1785 < 2 * mode_lib->vba.PixelClock[k]) {
1786 mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
1787 * mode_lib->vba.PixelClock[k];
1788 }
1789
1790 mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
1791 mode_lib->vba.DPPCLKUsingSingleDPPLuma,
1792 mode_lib->vba.DPPCLKUsingSingleDPPChroma);
1793 }
1794 }
1795
1796 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1797 if (mode_lib->vba.BlendingAndTiming[k] != k)
1798 continue;
1799 if (mode_lib->vba.ODMCombineEnabled[k]) {
1800 mode_lib->vba.DISPCLKWithRamping =
1801 dml_max(
1802 mode_lib->vba.DISPCLKWithRamping,
1803 mode_lib->vba.PixelClock[k] / 2
1804 * (1
1805 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1806 / 100)
1807 * (1
1808 + mode_lib->vba.DISPCLKRampingMargin
1809 / 100));
1810 mode_lib->vba.DISPCLKWithoutRamping =
1811 dml_max(
1812 mode_lib->vba.DISPCLKWithoutRamping,
1813 mode_lib->vba.PixelClock[k] / 2
1814 * (1
1815 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1816 / 100));
1817 } else if (!mode_lib->vba.ODMCombineEnabled[k]) {
1818 mode_lib->vba.DISPCLKWithRamping =
1819 dml_max(
1820 mode_lib->vba.DISPCLKWithRamping,
1821 mode_lib->vba.PixelClock[k]
1822 * (1
1823 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1824 / 100)
1825 * (1
1826 + mode_lib->vba.DISPCLKRampingMargin
1827 / 100));
1828 mode_lib->vba.DISPCLKWithoutRamping =
1829 dml_max(
1830 mode_lib->vba.DISPCLKWithoutRamping,
1831 mode_lib->vba.PixelClock[k]
1832 * (1
1833 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
1834 / 100));
1835 }
1836 }
1837
1838 mode_lib->vba.DISPCLKWithRamping = dml_max(
1839 mode_lib->vba.DISPCLKWithRamping,
1840 mode_lib->vba.WritebackDISPCLK);
1841 mode_lib->vba.DISPCLKWithoutRamping = dml_max(
1842 mode_lib->vba.DISPCLKWithoutRamping,
1843 mode_lib->vba.WritebackDISPCLK);
1844
1845 ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
1846 mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
1847 mode_lib->vba.DISPCLKWithRamping,
1848 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1849 mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
1850 mode_lib->vba.DISPCLKWithoutRamping,
1851 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1852 mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
1853 mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz,
1854 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1855 if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
1856 > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
1857 mode_lib->vba.DISPCLK_calculated =
1858 mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
1859 } else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
1860 > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
1861 mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
1862 } else {
1863 mode_lib->vba.DISPCLK_calculated =
1864 mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
1865 }
1866 DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
1867
1868 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1869 mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
1870 / mode_lib->vba.DPPPerPlane[k]
1871 * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
1872 mode_lib->vba.GlobalDPPCLK = dml_max(
1873 mode_lib->vba.GlobalDPPCLK,
1874 mode_lib->vba.DPPCLK_calculated[k]);
1875 }
1876 mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
1877 mode_lib->vba.GlobalDPPCLK,
1878 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
1879 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1880 mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
1881 * dml_ceil(
1882 mode_lib->vba.DPPCLK_calculated[k] * 255
1883 / mode_lib->vba.GlobalDPPCLK,
1884 1);
1885 DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
1886 }
1887
1888 // Urgent Watermark
1889 mode_lib->vba.DCCEnabledAnyPlane = false;
1890 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
1891 if (mode_lib->vba.DCCEnable[k])
1892 mode_lib->vba.DCCEnabledAnyPlane = true;
1893
1894 mode_lib->vba.ReturnBandwidthToDCN = dml_min(
1895 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
1896 mode_lib->vba.FabricAndDRAMBandwidth * 1000)
1897 * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100;
1898
1899 mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
1900 mode_lib->vba.ReturnBW = adjust_ReturnBW(
1901 mode_lib,
1902 mode_lib->vba.ReturnBW,
1903 mode_lib->vba.DCCEnabledAnyPlane,
1904 mode_lib->vba.ReturnBandwidthToDCN);
1905
1906 // Let's do this calculation again??
1907 mode_lib->vba.ReturnBandwidthToDCN = dml_min(
1908 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
1909 mode_lib->vba.FabricAndDRAMBandwidth * 1000);
1910 mode_lib->vba.ReturnBW = adjust_ReturnBW(
1911 mode_lib,
1912 mode_lib->vba.ReturnBW,
1913 mode_lib->vba.DCCEnabledAnyPlane,
1914 mode_lib->vba.ReturnBandwidthToDCN);
1915
1916 DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK);
1917 DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN);
1918 DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW);
1919
1920 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1921 bool MainPlaneDoesODMCombine = false;
1922
1923 if (mode_lib->vba.SourceScan[k] == dm_horz)
1924 mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
1925 else
1926 mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
1927
1928 if (mode_lib->vba.ODMCombineEnabled[k] == true)
1929 MainPlaneDoesODMCombine = true;
1930 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
1931 if (mode_lib->vba.BlendingAndTiming[k] == j
1932 && mode_lib->vba.ODMCombineEnabled[j] == true)
1933 MainPlaneDoesODMCombine = true;
1934
1935 if (MainPlaneDoesODMCombine == true)
1936 mode_lib->vba.SwathWidthY[k] = dml_min(
1937 (double) mode_lib->vba.SwathWidthSingleDPPY[k],
1938 dml_round(
1939 mode_lib->vba.HActive[k] / 2.0
1940 * mode_lib->vba.HRatio[k]));
1941 else
1942 mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
1943 / mode_lib->vba.DPPPerPlane[k];
1944 }
1945
1946 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1947 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
1948 mode_lib->vba.BytePerPixelDETY[k] = 8;
1949 mode_lib->vba.BytePerPixelDETC[k] = 0;
1950 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
1951 mode_lib->vba.BytePerPixelDETY[k] = 4;
1952 mode_lib->vba.BytePerPixelDETC[k] = 0;
1953 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
1954 mode_lib->vba.BytePerPixelDETY[k] = 2;
1955 mode_lib->vba.BytePerPixelDETC[k] = 0;
1956 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
1957 mode_lib->vba.BytePerPixelDETY[k] = 1;
1958 mode_lib->vba.BytePerPixelDETC[k] = 0;
1959 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
1960 mode_lib->vba.BytePerPixelDETY[k] = 1;
1961 mode_lib->vba.BytePerPixelDETC[k] = 2;
1962 } else { // dm_420_10
1963 mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
1964 mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
1965 }
1966 }
1967
1968 mode_lib->vba.TotalDataReadBandwidth = 0.0;
1969 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1970 mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
1971 * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
1972 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
1973 * mode_lib->vba.VRatio[k];
1974 mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
1975 / 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
1976 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
1977 * mode_lib->vba.VRatio[k] / 2;
1978 DTRACE(
1979 " read_bw[%i] = %fBps",
1980 k,
1981 mode_lib->vba.ReadBandwidthPlaneLuma[k]
1982 + mode_lib->vba.ReadBandwidthPlaneChroma[k]);
1983 mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
1984 + mode_lib->vba.ReadBandwidthPlaneChroma[k];
1985 }
1986
1987 mode_lib->vba.TotalDCCActiveDPP = 0;
1988 mode_lib->vba.TotalActiveDPP = 0;
1989 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
1990 mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
1991 + mode_lib->vba.DPPPerPlane[k];
1992 if (mode_lib->vba.DCCEnable[k])
1993 mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
1994 + mode_lib->vba.DPPPerPlane[k];
1995 }
1996
1997 mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
1998 (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
1999 + mode_lib->vba.UrgentOutOfOrderReturnPerChannel
2000 * mode_lib->vba.NumberOfChannels
2001 / mode_lib->vba.ReturnBW;
2002
2003 mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
2004 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2005 double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma;
2006
2007 if (mode_lib->vba.VRatio[k] <= 1.0)
2008 mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
2009 (double) mode_lib->vba.SwathWidthY[k]
2010 * mode_lib->vba.DPPPerPlane[k]
2011 / mode_lib->vba.HRatio[k]
2012 / mode_lib->vba.PixelClock[k];
2013 else
2014 mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
2015 (double) mode_lib->vba.SwathWidthY[k]
2016 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2017 / mode_lib->vba.DPPCLK[k];
2018
2019 DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k]
2020 * mode_lib->vba.SwathHeightY[k]
2021 * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
2022 / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k]
2023 / mode_lib->vba.TotalDataReadBandwidth);
2024 mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(
2025 mode_lib->vba.LastPixelOfLineExtraWatermark,
2026 DataFabricLineDeliveryTimeLuma
2027 - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]);
2028
2029 if (mode_lib->vba.BytePerPixelDETC[k] == 0)
2030 mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0;
2031 else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0)
2032 mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
2033 mode_lib->vba.SwathWidthY[k] / 2.0
2034 * mode_lib->vba.DPPPerPlane[k]
2035 / (mode_lib->vba.HRatio[k] / 2.0)
2036 / mode_lib->vba.PixelClock[k];
2037 else
2038 mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
2039 mode_lib->vba.SwathWidthY[k] / 2.0
2040 / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
2041 / mode_lib->vba.DPPCLK[k];
2042
2043 DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0
2044 * mode_lib->vba.SwathHeightC[k]
2045 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
2046 / (mode_lib->vba.ReturnBW
2047 * mode_lib->vba.ReadBandwidthPlaneChroma[k]
2048 / mode_lib->vba.TotalDataReadBandwidth);
2049 mode_lib->vba.LastPixelOfLineExtraWatermark =
2050 dml_max(
2051 mode_lib->vba.LastPixelOfLineExtraWatermark,
2052 DataFabricLineDeliveryTimeChroma
2053 - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
2054 }
2055
2056 mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
2057 + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
2058 + mode_lib->vba.TotalDCCActiveDPP
2059 * mode_lib->vba.MetaChunkSize) * 1024.0
2060 / mode_lib->vba.ReturnBW;
2061
2062 if (mode_lib->vba.VirtualMemoryEnable)
2063 mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
2064 * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW;
2065
2066 mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency
2067 + mode_lib->vba.LastPixelOfLineExtraWatermark
2068 + mode_lib->vba.UrgentExtraLatency;
2069
2070 DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
2071 DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
2072
2073 mode_lib->vba.MemoryTripWatermark = mode_lib->vba.UrgentLatency;
2074
2075 mode_lib->vba.TotalActiveWriteback = 0;
2076 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2077 if (mode_lib->vba.WritebackEnable[k])
2078 mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
2079 }
2080
2081 if (mode_lib->vba.TotalActiveWriteback <= 1)
2082 mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
2083 else
2084 mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
2085 + mode_lib->vba.WritebackChunkSize * 1024.0 / 32
2086 / mode_lib->vba.SOCCLK;
2087
2088 DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
2089
2090 // NB P-State/DRAM Clock Change Watermark
2091 mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
2092 + mode_lib->vba.UrgentWatermark;
2093
2094 DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
2095
2096 DTRACE(" calculating wb pstate watermark");
2097 DTRACE(" total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
2098 DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
2099
2100 if (mode_lib->vba.TotalActiveWriteback <= 1)
2101 mode_lib->vba.WritebackDRAMClockChangeWatermark =
2102 mode_lib->vba.DRAMClockChangeLatency
2103 + mode_lib->vba.WritebackLatency;
2104 else
2105 mode_lib->vba.WritebackDRAMClockChangeWatermark =
2106 mode_lib->vba.DRAMClockChangeLatency
2107 + mode_lib->vba.WritebackLatency
2108 + mode_lib->vba.WritebackChunkSize * 1024.0 / 32
2109 / mode_lib->vba.SOCCLK;
2110
2111 DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
2112
2113 // Stutter Efficiency
2114 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2115 mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
2116 / mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
2117 mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
2118 mode_lib->vba.LinesInDETY[k],
2119 mode_lib->vba.SwathHeightY[k]);
2120 mode_lib->vba.FullDETBufferingTimeY[k] =
2121 mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
2122 * (mode_lib->vba.HTotal[k]
2123 / mode_lib->vba.PixelClock[k])
2124 / mode_lib->vba.VRatio[k];
2125 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
2126 mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k]
2127 / mode_lib->vba.BytePerPixelDETC[k]
2128 / (mode_lib->vba.SwathWidthY[k] / 2);
2129 mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(
2130 mode_lib->vba.LinesInDETC[k],
2131 mode_lib->vba.SwathHeightC[k]);
2132 mode_lib->vba.FullDETBufferingTimeC[k] =
2133 mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
2134 * (mode_lib->vba.HTotal[k]
2135 / mode_lib->vba.PixelClock[k])
2136 / (mode_lib->vba.VRatio[k] / 2);
2137 } else {
2138 mode_lib->vba.LinesInDETC[k] = 0;
2139 mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
2140 mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
2141 }
2142 }
2143
2144 mode_lib->vba.MinFullDETBufferingTime = 999999.0;
2145 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2146 if (mode_lib->vba.FullDETBufferingTimeY[k]
2147 < mode_lib->vba.MinFullDETBufferingTime) {
2148 mode_lib->vba.MinFullDETBufferingTime =
2149 mode_lib->vba.FullDETBufferingTimeY[k];
2150 mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
2151 (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
2152 / mode_lib->vba.PixelClock[k];
2153 }
2154 if (mode_lib->vba.FullDETBufferingTimeC[k]
2155 < mode_lib->vba.MinFullDETBufferingTime) {
2156 mode_lib->vba.MinFullDETBufferingTime =
2157 mode_lib->vba.FullDETBufferingTimeC[k];
2158 mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
2159 (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
2160 / mode_lib->vba.PixelClock[k];
2161 }
2162 }
2163
2164 mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
2165 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2166 if (mode_lib->vba.DCCEnable[k]) {
2167 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2168 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2169 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2170 / mode_lib->vba.DCCRate[k]
2171 / 1000
2172 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2173 / mode_lib->vba.DCCRate[k]
2174 / 1000;
2175 } else {
2176 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2177 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2178 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2179 / 1000
2180 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2181 / 1000;
2182 }
2183 if (mode_lib->vba.DCCEnable[k]) {
2184 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2185 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2186 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2187 / 1000 / 256
2188 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2189 / 1000 / 256;
2190 }
2191 if (mode_lib->vba.VirtualMemoryEnable) {
2192 mode_lib->vba.AverageReadBandwidthGBytePerSecond =
2193 mode_lib->vba.AverageReadBandwidthGBytePerSecond
2194 + mode_lib->vba.ReadBandwidthPlaneLuma[k]
2195 / 1000 / 512
2196 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2197 / 1000 / 512;
2198 }
2199 }
2200
2201 mode_lib->vba.PartOfBurstThatFitsInROB =
2202 dml_min(
2203 mode_lib->vba.MinFullDETBufferingTime
2204 * mode_lib->vba.TotalDataReadBandwidth,
2205 mode_lib->vba.ROBBufferSizeInKByte * 1024
2206 * mode_lib->vba.TotalDataReadBandwidth
2207 / (mode_lib->vba.AverageReadBandwidthGBytePerSecond
2208 * 1000));
2209 mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
2210 * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
2211 / mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
2212 + (mode_lib->vba.MinFullDETBufferingTime
2213 * mode_lib->vba.TotalDataReadBandwidth
2214 - mode_lib->vba.PartOfBurstThatFitsInROB)
2215 / (mode_lib->vba.DCFCLK * 64);
2216 if (mode_lib->vba.TotalActiveWriteback == 0) {
2217 mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
2218 - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
2219 / mode_lib->vba.MinFullDETBufferingTime) * 100;
2220 } else {
2221 mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
2222 }
2223
2224 mode_lib->vba.SmallestVBlank = 999999;
2225 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2226 if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
2227 mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
2228 - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
2229 / mode_lib->vba.PixelClock[k];
2230 } else {
2231 mode_lib->vba.VBlankTime = 0;
2232 }
2233 mode_lib->vba.SmallestVBlank = dml_min(
2234 mode_lib->vba.SmallestVBlank,
2235 mode_lib->vba.VBlankTime);
2236 }
2237
2238 mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
2239 * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
2240 - mode_lib->vba.SmallestVBlank)
2241 + mode_lib->vba.SmallestVBlank)
2242 / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
2243
2244 // dml_ml->vba.DCFCLK Deep Sleep
2245 mode_lib->vba.DCFClkDeepSleep = 8.0;
2246
2247 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
2248 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
2249 mode_lib->vba.DCFCLKDeepSleepPerPlane =
2250 dml_max(
2251 1.1 * mode_lib->vba.SwathWidthY[k]
2252 * dml_ceil(
2253 mode_lib->vba.BytePerPixelDETY[k],
2254 1) / 32
2255 / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
2256 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
2257 * dml_ceil(
2258 mode_lib->vba.BytePerPixelDETC[k],
2259 2) / 32
2260 / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
2261 } else
2262 mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k]
2263 * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
2264 / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
2265 mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(
2266 mode_lib->vba.DCFCLKDeepSleepPerPlane,
2267 mode_lib->vba.PixelClock[k] / 16.0);
2268 mode_lib->vba.DCFClkDeepSleep = dml_max(
2269 mode_lib->vba.DCFClkDeepSleep,
2270 mode_lib->vba.DCFCLKDeepSleepPerPlane);
2271
2272 DTRACE(
2273 " dcfclk_deepsleep_per_plane[%i] = %fMHz",
2274 k,
2275 mode_lib->vba.DCFCLKDeepSleepPerPlane);
2276 }
2277
2278 DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep);
2279
2280 // Stutter Watermark
2281 mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
2282 + mode_lib->vba.LastPixelOfLineExtraWatermark
2283 + mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFClkDeepSleep;
2284 mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
2285 + mode_lib->vba.LastPixelOfLineExtraWatermark
2286 + mode_lib->vba.UrgentExtraLatency;
2287
2288 DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark);
2289 DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
2290
2291 // Urgent Latency Supported
2292 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2293 mode_lib->vba.EffectiveDETPlusLBLinesLuma =
2294 dml_floor(
2295 mode_lib->vba.LinesInDETY[k]
2296 + dml_min(
2297 mode_lib->vba.LinesInDETY[k]
2298 * mode_lib->vba.DPPCLK[k]
2299 * mode_lib->vba.BytePerPixelDETY[k]
2300 * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2301 / (mode_lib->vba.ReturnBW
2302 / mode_lib->vba.DPPPerPlane[k]),
2303 (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
2304 mode_lib->vba.SwathHeightY[k]);
2305
2306 mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
2307 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
2308 / mode_lib->vba.VRatio[k]
2309 - mode_lib->vba.EffectiveDETPlusLBLinesLuma
2310 * mode_lib->vba.SwathWidthY[k]
2311 * mode_lib->vba.BytePerPixelDETY[k]
2312 / (mode_lib->vba.ReturnBW
2313 / mode_lib->vba.DPPPerPlane[k]);
2314
2315 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
2316 mode_lib->vba.EffectiveDETPlusLBLinesChroma =
2317 dml_floor(
2318 mode_lib->vba.LinesInDETC[k]
2319 + dml_min(
2320 mode_lib->vba.LinesInDETC[k]
2321 * mode_lib->vba.DPPCLK[k]
2322 * mode_lib->vba.BytePerPixelDETC[k]
2323 * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
2324 / (mode_lib->vba.ReturnBW
2325 / mode_lib->vba.DPPPerPlane[k]),
2326 (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
2327 mode_lib->vba.SwathHeightC[k]);
2328 mode_lib->vba.UrgentLatencySupportUsChroma =
2329 mode_lib->vba.EffectiveDETPlusLBLinesChroma
2330 * (mode_lib->vba.HTotal[k]
2331 / mode_lib->vba.PixelClock[k])
2332 / (mode_lib->vba.VRatio[k] / 2)
2333 - mode_lib->vba.EffectiveDETPlusLBLinesChroma
2334 * (mode_lib->vba.SwathWidthY[k]
2335 / 2)
2336 * mode_lib->vba.BytePerPixelDETC[k]
2337 / (mode_lib->vba.ReturnBW
2338 / mode_lib->vba.DPPPerPlane[k]);
2339 mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
2340 mode_lib->vba.UrgentLatencySupportUsLuma,
2341 mode_lib->vba.UrgentLatencySupportUsChroma);
2342 } else {
2343 mode_lib->vba.UrgentLatencySupportUs[k] =
2344 mode_lib->vba.UrgentLatencySupportUsLuma;
2345 }
2346 }
2347
2348 mode_lib->vba.MinUrgentLatencySupportUs = 999999;
2349 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2350 mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
2351 mode_lib->vba.MinUrgentLatencySupportUs,
2352 mode_lib->vba.UrgentLatencySupportUs[k]);
2353 }
2354
2355 // Non-Urgent Latency Tolerance
2356 mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
2357 - mode_lib->vba.UrgentWatermark;
2358
2359 // DSCCLK
2360 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2361 if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
2362 mode_lib->vba.DSCCLK_calculated[k] = 0.0;
2363 } else {
2364 if (mode_lib->vba.OutputFormat[k] == dm_420
2365 || mode_lib->vba.OutputFormat[k] == dm_n422)
2366 mode_lib->vba.DSCFormatFactor = 2;
2367 else
2368 mode_lib->vba.DSCFormatFactor = 1;
2369 if (mode_lib->vba.ODMCombineEnabled[k])
2370 mode_lib->vba.DSCCLK_calculated[k] =
2371 mode_lib->vba.PixelClockBackEnd[k] / 6
2372 / mode_lib->vba.DSCFormatFactor
2373 / (1
2374 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
2375 / 100);
2376 else
2377 mode_lib->vba.DSCCLK_calculated[k] =
2378 mode_lib->vba.PixelClockBackEnd[k] / 3
2379 / mode_lib->vba.DSCFormatFactor
2380 / (1
2381 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
2382 / 100);
2383 }
2384 }
2385
2386 // DSC Delay
2387 // TODO
2388 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2389 double bpp = mode_lib->vba.OutputBpp[k];
2390 unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
2391
2392 if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
2393 if (!mode_lib->vba.ODMCombineEnabled[k]) {
2394 mode_lib->vba.DSCDelay[k] =
2395 dscceComputeDelay(
2396 mode_lib->vba.DSCInputBitPerComponent[k],
2397 bpp,
2398 dml_ceil(
2399 (double) mode_lib->vba.HActive[k]
2400 / mode_lib->vba.NumberOfDSCSlices[k],
2401 1),
2402 slices,
2403 mode_lib->vba.OutputFormat[k])
2404 + dscComputeDelay(
2405 mode_lib->vba.OutputFormat[k]);
2406 } else {
2407 mode_lib->vba.DSCDelay[k] =
2408 2
2409 * (dscceComputeDelay(
2410 mode_lib->vba.DSCInputBitPerComponent[k],
2411 bpp,
2412 dml_ceil(
2413 (double) mode_lib->vba.HActive[k]
2414 / mode_lib->vba.NumberOfDSCSlices[k],
2415 1),
2416 slices / 2.0,
2417 mode_lib->vba.OutputFormat[k])
2418 + dscComputeDelay(
2419 mode_lib->vba.OutputFormat[k]));
2420 }
2421 mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k]
2422 * mode_lib->vba.PixelClock[k]
2423 / mode_lib->vba.PixelClockBackEnd[k];
2424 } else {
2425 mode_lib->vba.DSCDelay[k] = 0;
2426 }
2427 }
2428
2429 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
2430 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes
2431 if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
2432 && mode_lib->vba.DSCEnabled[j])
2433 mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
2434
2435 // Prefetch
2436 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2437 unsigned int PDEAndMetaPTEBytesFrameY;
2438 unsigned int PixelPTEBytesPerRowY;
2439 unsigned int MetaRowByteY;
2440 unsigned int MetaRowByteC;
2441 unsigned int PDEAndMetaPTEBytesFrameC;
2442 unsigned int PixelPTEBytesPerRowC;
2443
2444 Calculate256BBlockSizes(
2445 mode_lib->vba.SourcePixelFormat[k],
2446 mode_lib->vba.SurfaceTiling[k],
2447 dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
2448 dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
2449 &mode_lib->vba.BlockHeight256BytesY[k],
2450 &mode_lib->vba.BlockHeight256BytesC[k],
2451 &mode_lib->vba.BlockWidth256BytesY[k],
2452 &mode_lib->vba.BlockWidth256BytesC[k]);
2453 PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
2454 mode_lib,
2455 mode_lib->vba.DCCEnable[k],
2456 mode_lib->vba.BlockHeight256BytesY[k],
2457 mode_lib->vba.BlockWidth256BytesY[k],
2458 mode_lib->vba.SourcePixelFormat[k],
2459 mode_lib->vba.SurfaceTiling[k],
2460 dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
2461 mode_lib->vba.SourceScan[k],
2462 mode_lib->vba.ViewportWidth[k],
2463 mode_lib->vba.ViewportHeight[k],
2464 mode_lib->vba.SwathWidthY[k],
2465 mode_lib->vba.VirtualMemoryEnable,
2466 mode_lib->vba.VMMPageSize,
2467 mode_lib->vba.PTEBufferSizeInRequests,
2468 mode_lib->vba.PDEProcessingBufIn64KBReqs,
2469 mode_lib->vba.PitchY[k],
2470 mode_lib->vba.DCCMetaPitchY[k],
2471 &mode_lib->vba.MacroTileWidthY[k],
2472 &MetaRowByteY,
2473 &PixelPTEBytesPerRowY,
2474 &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
2475 &mode_lib->vba.dpte_row_height[k],
2476 &mode_lib->vba.meta_row_height[k]);
2477 mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
2478 mode_lib,
2479 mode_lib->vba.VRatio[k],
2480 mode_lib->vba.vtaps[k],
2481 mode_lib->vba.Interlace[k],
2482 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
2483 mode_lib->vba.SwathHeightY[k],
2484 mode_lib->vba.ViewportYStartY[k],
2485 &mode_lib->vba.VInitPreFillY[k],
2486 &mode_lib->vba.MaxNumSwathY[k]);
2487
2488 if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
2489 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
2490 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
2491 && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
2492 PDEAndMetaPTEBytesFrameC =
2493 CalculateVMAndRowBytes(
2494 mode_lib,
2495 mode_lib->vba.DCCEnable[k],
2496 mode_lib->vba.BlockHeight256BytesC[k],
2497 mode_lib->vba.BlockWidth256BytesC[k],
2498 mode_lib->vba.SourcePixelFormat[k],
2499 mode_lib->vba.SurfaceTiling[k],
2500 dml_ceil(
2501 mode_lib->vba.BytePerPixelDETC[k],
2502 2),
2503 mode_lib->vba.SourceScan[k],
2504 mode_lib->vba.ViewportWidth[k] / 2,
2505 mode_lib->vba.ViewportHeight[k] / 2,
2506 mode_lib->vba.SwathWidthY[k] / 2,
2507 mode_lib->vba.VirtualMemoryEnable,
2508 mode_lib->vba.VMMPageSize,
2509 mode_lib->vba.PTEBufferSizeInRequests,
2510 mode_lib->vba.PDEProcessingBufIn64KBReqs,
2511 mode_lib->vba.PitchC[k],
2512 0,
2513 &mode_lib->vba.MacroTileWidthC[k],
2514 &MetaRowByteC,
2515 &PixelPTEBytesPerRowC,
2516 &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
2517 &mode_lib->vba.dpte_row_height_chroma[k],
2518 &mode_lib->vba.meta_row_height_chroma[k]);
2519 mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
2520 mode_lib,
2521 mode_lib->vba.VRatio[k] / 2,
2522 mode_lib->vba.VTAPsChroma[k],
2523 mode_lib->vba.Interlace[k],
2524 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
2525 mode_lib->vba.SwathHeightC[k],
2526 mode_lib->vba.ViewportYStartC[k],
2527 &mode_lib->vba.VInitPreFillC[k],
2528 &mode_lib->vba.MaxNumSwathC[k]);
2529 } else {
2530 PixelPTEBytesPerRowC = 0;
2531 PDEAndMetaPTEBytesFrameC = 0;
2532 MetaRowByteC = 0;
2533 mode_lib->vba.MaxNumSwathC[k] = 0;
2534 mode_lib->vba.PrefetchSourceLinesC[k] = 0;
2535 }
2536
2537 mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
2538 mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
2539 + PDEAndMetaPTEBytesFrameC;
2540 mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
2541
2542 CalculateActiveRowBandwidth(
2543 mode_lib->vba.VirtualMemoryEnable,
2544 mode_lib->vba.SourcePixelFormat[k],
2545 mode_lib->vba.VRatio[k],
2546 mode_lib->vba.DCCEnable[k],
2547 mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
2548 MetaRowByteY,
2549 MetaRowByteC,
2550 mode_lib->vba.meta_row_height[k],
2551 mode_lib->vba.meta_row_height_chroma[k],
2552 PixelPTEBytesPerRowY,
2553 PixelPTEBytesPerRowC,
2554 mode_lib->vba.dpte_row_height[k],
2555 mode_lib->vba.dpte_row_height_chroma[k],
2556 &mode_lib->vba.meta_row_bw[k],
2557 &mode_lib->vba.dpte_row_bw[k],
2558 &mode_lib->vba.qual_row_bw[k]);
2559 }
2560
2561 mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep;
2562
2563 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2564 if (mode_lib->vba.BlendingAndTiming[k] == k) {
2565 if (mode_lib->vba.WritebackEnable[k] == true) {
2566 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
2567 mode_lib->vba.WritebackLatency
2568 + CalculateWriteBackDelay(
2569 mode_lib->vba.WritebackPixelFormat[k],
2570 mode_lib->vba.WritebackHRatio[k],
2571 mode_lib->vba.WritebackVRatio[k],
2572 mode_lib->vba.WritebackLumaHTaps[k],
2573 mode_lib->vba.WritebackLumaVTaps[k],
2574 mode_lib->vba.WritebackChromaHTaps[k],
2575 mode_lib->vba.WritebackChromaVTaps[k],
2576 mode_lib->vba.WritebackDestinationWidth[k])
2577 / mode_lib->vba.DISPCLK;
2578 } else
2579 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
2580 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
2581 if (mode_lib->vba.BlendingAndTiming[j] == k
2582 && mode_lib->vba.WritebackEnable[j] == true) {
2583 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
2584 dml_max(
2585 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
2586 mode_lib->vba.WritebackLatency
2587 + CalculateWriteBackDelay(
2588 mode_lib->vba.WritebackPixelFormat[j],
2589 mode_lib->vba.WritebackHRatio[j],
2590 mode_lib->vba.WritebackVRatio[j],
2591 mode_lib->vba.WritebackLumaHTaps[j],
2592 mode_lib->vba.WritebackLumaVTaps[j],
2593 mode_lib->vba.WritebackChromaHTaps[j],
2594 mode_lib->vba.WritebackChromaVTaps[j],
2595 mode_lib->vba.WritebackDestinationWidth[j])
2596 / mode_lib->vba.DISPCLK);
2597 }
2598 }
2599 }
2600 }
2601
2602 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
2603 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
2604 if (mode_lib->vba.BlendingAndTiming[k] == j)
2605 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
2606 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
2607
2608 mode_lib->vba.VStartupLines = 13;
2609 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2610 mode_lib->vba.MaxVStartupLines[k] =
2611 mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
2612 - dml_max(
2613 1.0,
2614 dml_ceil(
2615 mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
2616 / (mode_lib->vba.HTotal[k]
2617 / mode_lib->vba.PixelClock[k]),
2618 1));
2619 }
2620
2621 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
2622 mode_lib->vba.MaximumMaxVStartupLines = dml_max(
2623 mode_lib->vba.MaximumMaxVStartupLines,
2624 mode_lib->vba.MaxVStartupLines[k]);
2625
2626 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2627 mode_lib->vba.cursor_bw[k] = 0.0;
2628 for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
2629 mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
2630 * mode_lib->vba.CursorBPP[k][j] / 8.0
2631 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
2632 * mode_lib->vba.VRatio[k];
2633 }
2634
2635 do {
2636 double MaxTotalRDBandwidth = 0;
2637 bool DestinationLineTimesForPrefetchLessThan2 = false;
2638 bool VRatioPrefetchMoreThan4 = false;
2639 bool prefetch_vm_bw_valid = true;
2640 bool prefetch_row_bw_valid = true;
2641 double TWait = CalculateTWait(
2642 mode_lib->vba.PrefetchMode,
2643 mode_lib->vba.DRAMClockChangeLatency,
2644 mode_lib->vba.UrgentLatency,
2645 mode_lib->vba.SREnterPlusExitTime);
2646
2647 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2648 if (mode_lib->vba.XFCEnabled[k] == true) {
2649 mode_lib->vba.XFCRemoteSurfaceFlipDelay =
2650 CalculateRemoteSurfaceFlipDelay(
2651 mode_lib,
2652 mode_lib->vba.VRatio[k],
2653 mode_lib->vba.SwathWidthY[k],
2654 dml_ceil(
2655 mode_lib->vba.BytePerPixelDETY[k],
2656 1),
2657 mode_lib->vba.HTotal[k]
2658 / mode_lib->vba.PixelClock[k],
2659 mode_lib->vba.XFCTSlvVupdateOffset,
2660 mode_lib->vba.XFCTSlvVupdateWidth,
2661 mode_lib->vba.XFCTSlvVreadyOffset,
2662 mode_lib->vba.XFCXBUFLatencyTolerance,
2663 mode_lib->vba.XFCFillBWOverhead,
2664 mode_lib->vba.XFCSlvChunkSize,
2665 mode_lib->vba.XFCBusTransportTime,
2666 mode_lib->vba.TCalc,
2667 TWait,
2668 &mode_lib->vba.SrcActiveDrainRate,
2669 &mode_lib->vba.TInitXFill,
2670 &mode_lib->vba.TslvChk);
2671 } else {
2672 mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
2673 }
2674 mode_lib->vba.ErrorResult[k] =
2675 CalculatePrefetchSchedule(
2676 mode_lib,
2677 mode_lib->vba.DPPCLK[k],
2678 mode_lib->vba.DISPCLK,
2679 mode_lib->vba.PixelClock[k],
2680 mode_lib->vba.DCFClkDeepSleep,
2681 mode_lib->vba.DSCDelay[k],
2682 mode_lib->vba.DPPPerPlane[k],
2683 mode_lib->vba.ScalerEnabled[k],
2684 mode_lib->vba.NumberOfCursors[k],
2685 mode_lib->vba.DPPCLKDelaySubtotal,
2686 mode_lib->vba.DPPCLKDelaySCL,
2687 mode_lib->vba.DPPCLKDelaySCLLBOnly,
2688 mode_lib->vba.DPPCLKDelayCNVCFormater,
2689 mode_lib->vba.DPPCLKDelayCNVCCursor,
2690 mode_lib->vba.DISPCLKDelaySubtotal,
2691 (unsigned int) (mode_lib->vba.SwathWidthY[k]
2692 / mode_lib->vba.HRatio[k]),
2693 mode_lib->vba.OutputFormat[k],
2694 mode_lib->vba.VTotal[k]
2695 - mode_lib->vba.VActive[k],
2696 mode_lib->vba.HTotal[k],
2697 mode_lib->vba.MaxInterDCNTileRepeaters,
2698 dml_min(
2699 mode_lib->vba.VStartupLines,
2700 mode_lib->vba.MaxVStartupLines[k]),
2701 mode_lib->vba.MaxPageTableLevels,
2702 mode_lib->vba.VirtualMemoryEnable,
2703 mode_lib->vba.DynamicMetadataEnable[k],
2704 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
2705 mode_lib->vba.DynamicMetadataTransmittedBytes[k],
2706 mode_lib->vba.DCCEnable[k],
2707 mode_lib->vba.UrgentLatency,
2708 mode_lib->vba.UrgentExtraLatency,
2709 mode_lib->vba.TCalc,
2710 mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
2711 mode_lib->vba.MetaRowByte[k],
2712 mode_lib->vba.PixelPTEBytesPerRow[k],
2713 mode_lib->vba.PrefetchSourceLinesY[k],
2714 mode_lib->vba.SwathWidthY[k],
2715 mode_lib->vba.BytePerPixelDETY[k],
2716 mode_lib->vba.VInitPreFillY[k],
2717 mode_lib->vba.MaxNumSwathY[k],
2718 mode_lib->vba.PrefetchSourceLinesC[k],
2719 mode_lib->vba.BytePerPixelDETC[k],
2720 mode_lib->vba.VInitPreFillC[k],
2721 mode_lib->vba.MaxNumSwathC[k],
2722 mode_lib->vba.SwathHeightY[k],
2723 mode_lib->vba.SwathHeightC[k],
2724 TWait,
2725 mode_lib->vba.XFCEnabled[k],
2726 mode_lib->vba.XFCRemoteSurfaceFlipDelay,
2727 mode_lib->vba.Interlace[k],
2728 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
2729 &mode_lib->vba.DSTXAfterScaler[k],
2730 &mode_lib->vba.DSTYAfterScaler[k],
2731 &mode_lib->vba.DestinationLinesForPrefetch[k],
2732 &mode_lib->vba.PrefetchBandwidth[k],
2733 &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
2734 &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
2735 &mode_lib->vba.VRatioPrefetchY[k],
2736 &mode_lib->vba.VRatioPrefetchC[k],
2737 &mode_lib->vba.RequiredPrefetchPixDataBW[k],
2738 &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
2739 &mode_lib->vba.Tno_bw[k],
2740 &mode_lib->vba.VUpdateOffsetPix[k],
2741 &mode_lib->vba.VUpdateWidthPix[k],
2742 &mode_lib->vba.VReadyOffsetPix[k]);
2743 if (mode_lib->vba.BlendingAndTiming[k] == k) {
2744 mode_lib->vba.VStartup[k] = dml_min(
2745 mode_lib->vba.VStartupLines,
2746 mode_lib->vba.MaxVStartupLines[k]);
2747 if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
2748 != 0) {
2749 mode_lib->vba.VStartup[k] =
2750 mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
2751 }
2752 } else {
2753 mode_lib->vba.VStartup[k] =
2754 dml_min(
2755 mode_lib->vba.VStartupLines,
2756 mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
2757 }
2758 }
2759
2760 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2761
2762 if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
2763 mode_lib->vba.prefetch_vm_bw[k] = 0;
2764 else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
2765 mode_lib->vba.prefetch_vm_bw[k] =
2766 (double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
2767 / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
2768 * mode_lib->vba.HTotal[k]
2769 / mode_lib->vba.PixelClock[k]);
2770 } else {
2771 mode_lib->vba.prefetch_vm_bw[k] = 0;
2772 prefetch_vm_bw_valid = false;
2773 }
2774 if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
2775 == 0)
2776 mode_lib->vba.prefetch_row_bw[k] = 0;
2777 else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
2778 mode_lib->vba.prefetch_row_bw[k] =
2779 (double) (mode_lib->vba.MetaRowByte[k]
2780 + mode_lib->vba.PixelPTEBytesPerRow[k])
2781 / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
2782 * mode_lib->vba.HTotal[k]
2783 / mode_lib->vba.PixelClock[k]);
2784 } else {
2785 mode_lib->vba.prefetch_row_bw[k] = 0;
2786 prefetch_row_bw_valid = false;
2787 }
2788
2789 MaxTotalRDBandwidth =
2790 MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
2791 + dml_max(
2792 mode_lib->vba.prefetch_vm_bw[k],
2793 dml_max(
2794 mode_lib->vba.prefetch_row_bw[k],
2795 dml_max(
2796 mode_lib->vba.ReadBandwidthPlaneLuma[k]
2797 + mode_lib->vba.ReadBandwidthPlaneChroma[k],
2798 mode_lib->vba.RequiredPrefetchPixDataBW[k])
2799 + mode_lib->vba.meta_row_bw[k]
2800 + mode_lib->vba.dpte_row_bw[k]));
2801
2802 if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
2803 DestinationLineTimesForPrefetchLessThan2 = true;
2804 if (mode_lib->vba.VRatioPrefetchY[k] > 4
2805 || mode_lib->vba.VRatioPrefetchC[k] > 4)
2806 VRatioPrefetchMoreThan4 = true;
2807 }
2808
2809 if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
2810 && prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
2811 && !DestinationLineTimesForPrefetchLessThan2)
2812 mode_lib->vba.PrefetchModeSupported = true;
2813 else {
2814 mode_lib->vba.PrefetchModeSupported = false;
2815 dml_print(
2816 "DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
2817 }
2818
2819 if (mode_lib->vba.PrefetchModeSupported == true) {
2820 double final_flip_bw[DC__NUM_DPP__MAX];
2821 unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
2822 double total_dcn_read_bw_with_flip = 0;
2823
2824 mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
2825 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2826 mode_lib->vba.BandwidthAvailableForImmediateFlip =
2827 mode_lib->vba.BandwidthAvailableForImmediateFlip
2828 - mode_lib->vba.cursor_bw[k]
2829 - dml_max(
2830 mode_lib->vba.ReadBandwidthPlaneLuma[k]
2831 + mode_lib->vba.ReadBandwidthPlaneChroma[k]
2832 + mode_lib->vba.qual_row_bw[k],
2833 mode_lib->vba.PrefetchBandwidth[k]);
2834 }
2835
2836 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2837 ImmediateFlipBytes[k] = 0;
2838 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
2839 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
2840 ImmediateFlipBytes[k] =
2841 mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
2842 + mode_lib->vba.MetaRowByte[k]
2843 + mode_lib->vba.PixelPTEBytesPerRow[k];
2844 }
2845 }
2846 mode_lib->vba.TotImmediateFlipBytes = 0;
2847 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2848 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
2849 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
2850 mode_lib->vba.TotImmediateFlipBytes =
2851 mode_lib->vba.TotImmediateFlipBytes
2852 + ImmediateFlipBytes[k];
2853 }
2854 }
2855 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2856 CalculateFlipSchedule(
2857 mode_lib,
2858 mode_lib->vba.UrgentExtraLatency,
2859 mode_lib->vba.UrgentLatency,
2860 mode_lib->vba.MaxPageTableLevels,
2861 mode_lib->vba.VirtualMemoryEnable,
2862 mode_lib->vba.BandwidthAvailableForImmediateFlip,
2863 mode_lib->vba.TotImmediateFlipBytes,
2864 mode_lib->vba.SourcePixelFormat[k],
2865 ImmediateFlipBytes[k],
2866 mode_lib->vba.HTotal[k]
2867 / mode_lib->vba.PixelClock[k],
2868 mode_lib->vba.VRatio[k],
2869 mode_lib->vba.Tno_bw[k],
2870 mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
2871 mode_lib->vba.MetaRowByte[k],
2872 mode_lib->vba.PixelPTEBytesPerRow[k],
2873 mode_lib->vba.DCCEnable[k],
2874 mode_lib->vba.dpte_row_height[k],
2875 mode_lib->vba.meta_row_height[k],
2876 mode_lib->vba.qual_row_bw[k],
2877 &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
2878 &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
2879 &final_flip_bw[k],
2880 &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
2881 }
2882 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2883 total_dcn_read_bw_with_flip =
2884 total_dcn_read_bw_with_flip
2885 + mode_lib->vba.cursor_bw[k]
2886 + dml_max(
2887 mode_lib->vba.prefetch_vm_bw[k],
2888 dml_max(
2889 mode_lib->vba.prefetch_row_bw[k],
2890 final_flip_bw[k]
2891 + dml_max(
2892 mode_lib->vba.ReadBandwidthPlaneLuma[k]
2893 + mode_lib->vba.ReadBandwidthPlaneChroma[k],
2894 mode_lib->vba.RequiredPrefetchPixDataBW[k])));
2895 }
2896 mode_lib->vba.ImmediateFlipSupported = true;
2897 if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
2898 mode_lib->vba.ImmediateFlipSupported = false;
2899 }
2900 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2901 if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
2902 mode_lib->vba.ImmediateFlipSupported = false;
2903 }
2904 }
2905 } else {
2906 mode_lib->vba.ImmediateFlipSupported = false;
2907 }
2908
2909 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2910 if (mode_lib->vba.ErrorResult[k]) {
2911 mode_lib->vba.PrefetchModeSupported = false;
2912 dml_print(
2913 "DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
2914 }
2915 }
2916
2917 mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
2918 } while (!((mode_lib->vba.PrefetchModeSupported
2919 && (!mode_lib->vba.ImmediateFlipSupport
2920 || mode_lib->vba.ImmediateFlipSupported))
2921 || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
2922
2923 //Display Pipeline Delivery Time in Prefetch
2924 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2925 if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
2926 mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
2927 mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
2928 / mode_lib->vba.HRatio[k]
2929 / mode_lib->vba.PixelClock[k];
2930 } else {
2931 mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
2932 mode_lib->vba.SwathWidthY[k]
2933 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2934 / mode_lib->vba.DPPCLK[k];
2935 }
2936 if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
2937 mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
2938 } else {
2939 if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
2940 mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
2941 mode_lib->vba.SwathWidthY[k]
2942 * mode_lib->vba.DPPPerPlane[k]
2943 / mode_lib->vba.HRatio[k]
2944 / mode_lib->vba.PixelClock[k];
2945 } else {
2946 mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
2947 mode_lib->vba.SwathWidthY[k]
2948 / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
2949 / mode_lib->vba.DPPCLK[k];
2950 }
2951 }
2952 }
2953
2954 // Min TTUVBlank
2955 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2956 if (mode_lib->vba.PrefetchMode == 0) {
2957 mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
2958 mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
2959 mode_lib->vba.MinTTUVBlank[k] = dml_max(
2960 mode_lib->vba.DRAMClockChangeWatermark,
2961 dml_max(
2962 mode_lib->vba.StutterEnterPlusExitWatermark,
2963 mode_lib->vba.UrgentWatermark));
2964 } else if (mode_lib->vba.PrefetchMode == 1) {
2965 mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
2966 mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
2967 mode_lib->vba.MinTTUVBlank[k] = dml_max(
2968 mode_lib->vba.StutterEnterPlusExitWatermark,
2969 mode_lib->vba.UrgentWatermark);
2970 } else {
2971 mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
2972 mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
2973 mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
2974 }
2975 if (!mode_lib->vba.DynamicMetadataEnable[k])
2976 mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
2977 + mode_lib->vba.MinTTUVBlank[k];
2978 }
2979
2980 // DCC Configuration
2981 mode_lib->vba.ActiveDPPs = 0;
2982 // NB P-State/DRAM Clock Change Support
2983 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2984 mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
2985 }
2986
2987 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
2988 double EffectiveLBLatencyHidingY;
2989 double EffectiveLBLatencyHidingC;
2990 double DPPOutputBufferLinesY;
2991 double DPPOutputBufferLinesC;
2992 double DPPOPPBufferingY;
2993 double MaxDETBufferingTimeY;
2994 double ActiveDRAMClockChangeLatencyMarginY;
2995
2996 mode_lib->vba.LBLatencyHidingSourceLinesY =
2997 dml_min(
2998 mode_lib->vba.MaxLineBufferLines,
2999 (unsigned int) dml_floor(
3000 (double) mode_lib->vba.LineBufferSize
3001 / mode_lib->vba.LBBitPerPixel[k]
3002 / (mode_lib->vba.SwathWidthY[k]
3003 / dml_max(
3004 mode_lib->vba.HRatio[k],
3005 1.0)),
3006 1)) - (mode_lib->vba.vtaps[k] - 1);
3007
3008 mode_lib->vba.LBLatencyHidingSourceLinesC =
3009 dml_min(
3010 mode_lib->vba.MaxLineBufferLines,
3011 (unsigned int) dml_floor(
3012 (double) mode_lib->vba.LineBufferSize
3013 / mode_lib->vba.LBBitPerPixel[k]
3014 / (mode_lib->vba.SwathWidthY[k]
3015 / 2.0
3016 / dml_max(
3017 mode_lib->vba.HRatio[k]
3018 / 2,
3019 1.0)),
3020 1))
3021 - (mode_lib->vba.VTAPsChroma[k] - 1);
3022
3023 EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
3024 / mode_lib->vba.VRatio[k]
3025 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
3026
3027 EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
3028 / (mode_lib->vba.VRatio[k] / 2)
3029 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
3030
3031 if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
3032 DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
3033 / mode_lib->vba.SwathWidthY[k];
3034 } else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
3035 DPPOutputBufferLinesY = 0.5;
3036 } else {
3037 DPPOutputBufferLinesY = 1;
3038 }
3039
3040 if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
3041 DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
3042 / (mode_lib->vba.SwathWidthY[k] / 2);
3043 } else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
3044 DPPOutputBufferLinesC = 0.5;
3045 } else {
3046 DPPOutputBufferLinesC = 1;
3047 }
3048
3049 DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
3050 * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
3051 MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
3052 + (mode_lib->vba.LinesInDETY[k]
3053 - mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
3054 / mode_lib->vba.SwathHeightY[k]
3055 * (mode_lib->vba.HTotal[k]
3056 / mode_lib->vba.PixelClock[k]);
3057
3058 ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
3059 + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
3060
3061 if (mode_lib->vba.ActiveDPPs > 1) {
3062 ActiveDRAMClockChangeLatencyMarginY =
3063 ActiveDRAMClockChangeLatencyMarginY
3064 - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
3065 * mode_lib->vba.SwathHeightY[k]
3066 * (mode_lib->vba.HTotal[k]
3067 / mode_lib->vba.PixelClock[k]);
3068 }
3069
3070 if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
3071 double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
3072 / mode_lib->vba.PixelClock[k])
3073 * (DPPOutputBufferLinesC
3074 + mode_lib->vba.OPPOutputBufferLines);
3075 double MaxDETBufferingTimeC =
3076 mode_lib->vba.FullDETBufferingTimeC[k]
3077 + (mode_lib->vba.LinesInDETC[k]
3078 - mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
3079 / mode_lib->vba.SwathHeightC[k]
3080 * (mode_lib->vba.HTotal[k]
3081 / mode_lib->vba.PixelClock[k]);
3082 double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
3083 + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
3084 - mode_lib->vba.DRAMClockChangeWatermark;
3085
3086 if (mode_lib->vba.ActiveDPPs > 1) {
3087 ActiveDRAMClockChangeLatencyMarginC =
3088 ActiveDRAMClockChangeLatencyMarginC
3089 - (1
3090 - 1
3091 / (mode_lib->vba.ActiveDPPs
3092 - 1))
3093 * mode_lib->vba.SwathHeightC[k]
3094 * (mode_lib->vba.HTotal[k]
3095 / mode_lib->vba.PixelClock[k]);
3096 }
3097 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
3098 ActiveDRAMClockChangeLatencyMarginY,
3099 ActiveDRAMClockChangeLatencyMarginC);
3100 } else {
3101 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
3102 ActiveDRAMClockChangeLatencyMarginY;
3103 }
3104
3105 if (mode_lib->vba.WritebackEnable[k]) {
3106 double WritebackDRAMClockChangeLatencyMargin;
3107
3108 if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
3109 WritebackDRAMClockChangeLatencyMargin =
3110 (double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
3111 + mode_lib->vba.WritebackInterfaceChromaBufferSize)
3112 / (mode_lib->vba.WritebackDestinationWidth[k]
3113 * mode_lib->vba.WritebackDestinationHeight[k]
3114 / (mode_lib->vba.WritebackSourceHeight[k]
3115 * mode_lib->vba.HTotal[k]
3116 / mode_lib->vba.PixelClock[k])
3117 * 4)
3118 - mode_lib->vba.WritebackDRAMClockChangeWatermark;
3119 } else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
3120 WritebackDRAMClockChangeLatencyMargin =
3121 dml_min(
3122 (double) mode_lib->vba.WritebackInterfaceLumaBufferSize
3123 * 8.0 / 10,
3124 2.0
3125 * mode_lib->vba.WritebackInterfaceChromaBufferSize
3126 * 8 / 10)
3127 / (mode_lib->vba.WritebackDestinationWidth[k]
3128 * mode_lib->vba.WritebackDestinationHeight[k]
3129 / (mode_lib->vba.WritebackSourceHeight[k]
3130 * mode_lib->vba.HTotal[k]
3131 / mode_lib->vba.PixelClock[k]))
3132 - mode_lib->vba.WritebackDRAMClockChangeWatermark;
3133 } else {
3134 WritebackDRAMClockChangeLatencyMargin =
3135 dml_min(
3136 (double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
3137 2.0
3138 * mode_lib->vba.WritebackInterfaceChromaBufferSize)
3139 / (mode_lib->vba.WritebackDestinationWidth[k]
3140 * mode_lib->vba.WritebackDestinationHeight[k]
3141 / (mode_lib->vba.WritebackSourceHeight[k]
3142 * mode_lib->vba.HTotal[k]
3143 / mode_lib->vba.PixelClock[k]))
3144 - mode_lib->vba.WritebackDRAMClockChangeWatermark;
3145 }
3146 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
3147 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
3148 WritebackDRAMClockChangeLatencyMargin);
3149 }
3150 }
3151
3152 mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
3153 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3154 if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
3155 < mode_lib->vba.MinActiveDRAMClockChangeMargin) {
3156 mode_lib->vba.MinActiveDRAMClockChangeMargin =
3157 mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
3158 }
3159 }
3160
3161 mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
3162 mode_lib->vba.MinActiveDRAMClockChangeMargin
3163 + mode_lib->vba.DRAMClockChangeLatency;
3164
3165 if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
3166 mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive;
3167 } else {
3168 if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
3169 mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank;
3170 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3171 if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
3172 mode_lib->vba.DRAMClockChangeSupport =
3173 dm_dram_clock_change_unsupported;
3174 }
3175 }
3176 } else {
3177 mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
3178 }
3179 }
3180
3181 //XFC Parameters:
3182 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3183 if (mode_lib->vba.XFCEnabled[k] == true) {
3184 double TWait;
3185
3186 mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
3187 mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
3188 mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
3189 TWait = CalculateTWait(
3190 mode_lib->vba.PrefetchMode,
3191 mode_lib->vba.DRAMClockChangeLatency,
3192 mode_lib->vba.UrgentLatency,
3193 mode_lib->vba.SREnterPlusExitTime);
3194 mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
3195 mode_lib,
3196 mode_lib->vba.VRatio[k],
3197 mode_lib->vba.SwathWidthY[k],
3198 dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
3199 mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
3200 mode_lib->vba.XFCTSlvVupdateOffset,
3201 mode_lib->vba.XFCTSlvVupdateWidth,
3202 mode_lib->vba.XFCTSlvVreadyOffset,
3203 mode_lib->vba.XFCXBUFLatencyTolerance,
3204 mode_lib->vba.XFCFillBWOverhead,
3205 mode_lib->vba.XFCSlvChunkSize,
3206 mode_lib->vba.XFCBusTransportTime,
3207 mode_lib->vba.TCalc,
3208 TWait,
3209 &mode_lib->vba.SrcActiveDrainRate,
3210 &mode_lib->vba.TInitXFill,
3211 &mode_lib->vba.TslvChk);
3212 mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
3213 dml_floor(
3214 mode_lib->vba.XFCRemoteSurfaceFlipDelay
3215 / (mode_lib->vba.HTotal[k]
3216 / mode_lib->vba.PixelClock[k]),
3217 1);
3218 mode_lib->vba.XFCTransferDelay[k] =
3219 dml_ceil(
3220 mode_lib->vba.XFCBusTransportTime
3221 / (mode_lib->vba.HTotal[k]
3222 / mode_lib->vba.PixelClock[k]),
3223 1);
3224 mode_lib->vba.XFCPrechargeDelay[k] =
3225 dml_ceil(
3226 (mode_lib->vba.XFCBusTransportTime
3227 + mode_lib->vba.TInitXFill
3228 + mode_lib->vba.TslvChk)
3229 / (mode_lib->vba.HTotal[k]
3230 / mode_lib->vba.PixelClock[k]),
3231 1);
3232 mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
3233 * mode_lib->vba.SrcActiveDrainRate;
3234 mode_lib->vba.FinalFillMargin =
3235 (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
3236 + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
3237 * mode_lib->vba.HTotal[k]
3238 / mode_lib->vba.PixelClock[k]
3239 * mode_lib->vba.SrcActiveDrainRate
3240 + mode_lib->vba.XFCFillConstant;
3241 mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
3242 * mode_lib->vba.SrcActiveDrainRate
3243 + mode_lib->vba.FinalFillMargin;
3244 mode_lib->vba.RemainingFillLevel = dml_max(
3245 0.0,
3246 mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
3247 mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
3248 / (mode_lib->vba.SrcActiveDrainRate
3249 * mode_lib->vba.XFCFillBWOverhead / 100);
3250 mode_lib->vba.XFCPrefetchMargin[k] =
3251 mode_lib->vba.XFCRemoteSurfaceFlipDelay
3252 + mode_lib->vba.TFinalxFill
3253 + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
3254 + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
3255 * mode_lib->vba.HTotal[k]
3256 / mode_lib->vba.PixelClock[k];
3257 } else {
3258 mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
3259 mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
3260 mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
3261 mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
3262 mode_lib->vba.XFCPrechargeDelay[k] = 0;
3263 mode_lib->vba.XFCTransferDelay[k] = 0;
3264 mode_lib->vba.XFCPrefetchMargin[k] = 0;
3265 }
3266 }
3267}
3268
3269static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
3270{
3271 double BytePerPixDETY;
3272 double BytePerPixDETC;
3273 double Read256BytesBlockHeightY;
3274 double Read256BytesBlockHeightC;
3275 double Read256BytesBlockWidthY;
3276 double Read256BytesBlockWidthC;
3277 double MaximumSwathHeightY;
3278 double MaximumSwathHeightC;
3279 double MinimumSwathHeightY;
3280 double MinimumSwathHeightC;
3281 double SwathWidth;
3282 double SwathWidthGranularityY;
3283 double SwathWidthGranularityC;
3284 double RoundedUpMaxSwathSizeBytesY;
3285 double RoundedUpMaxSwathSizeBytesC;
3286 unsigned int j, k;
3287
3288 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3289 bool MainPlaneDoesODMCombine = false;
3290
3291 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
3292 BytePerPixDETY = 8;
3293 BytePerPixDETC = 0;
3294 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
3295 BytePerPixDETY = 4;
3296 BytePerPixDETC = 0;
3297 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
3298 BytePerPixDETY = 2;
3299 BytePerPixDETC = 0;
3300 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
3301 BytePerPixDETY = 1;
3302 BytePerPixDETC = 0;
3303 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
3304 BytePerPixDETY = 1;
3305 BytePerPixDETC = 2;
3306 } else {
3307 BytePerPixDETY = 4.0 / 3.0;
3308 BytePerPixDETC = 8.0 / 3.0;
3309 }
3310
3311 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3312 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3313 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
3314 || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
3315 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3316 Read256BytesBlockHeightY = 1;
3317 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
3318 Read256BytesBlockHeightY = 4;
3319 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3320 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
3321 Read256BytesBlockHeightY = 8;
3322 } else {
3323 Read256BytesBlockHeightY = 16;
3324 }
3325 Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
3326 / Read256BytesBlockHeightY;
3327 Read256BytesBlockHeightC = 0;
3328 Read256BytesBlockWidthC = 0;
3329 } else {
3330 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3331 Read256BytesBlockHeightY = 1;
3332 Read256BytesBlockHeightC = 1;
3333 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
3334 Read256BytesBlockHeightY = 16;
3335 Read256BytesBlockHeightC = 8;
3336 } else {
3337 Read256BytesBlockHeightY = 8;
3338 Read256BytesBlockHeightC = 8;
3339 }
3340 Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
3341 / Read256BytesBlockHeightY;
3342 Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
3343 / Read256BytesBlockHeightC;
3344 }
3345
3346 if (mode_lib->vba.SourceScan[k] == dm_horz) {
3347 MaximumSwathHeightY = Read256BytesBlockHeightY;
3348 MaximumSwathHeightC = Read256BytesBlockHeightC;
3349 } else {
3350 MaximumSwathHeightY = Read256BytesBlockWidthY;
3351 MaximumSwathHeightC = Read256BytesBlockWidthC;
3352 }
3353
3354 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3355 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
3356 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
3357 || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
3358 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
3359 || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
3360 && (mode_lib->vba.SurfaceTiling[k]
3361 == dm_sw_4kb_s
3362 || mode_lib->vba.SurfaceTiling[k]
3363 == dm_sw_4kb_s_x
3364 || mode_lib->vba.SurfaceTiling[k]
3365 == dm_sw_64kb_s
3366 || mode_lib->vba.SurfaceTiling[k]
3367 == dm_sw_64kb_s_t
3368 || mode_lib->vba.SurfaceTiling[k]
3369 == dm_sw_64kb_s_x
3370 || mode_lib->vba.SurfaceTiling[k]
3371 == dm_sw_var_s
3372 || mode_lib->vba.SurfaceTiling[k]
3373 == dm_sw_var_s_x)
3374 && mode_lib->vba.SourceScan[k] == dm_horz)) {
3375 MinimumSwathHeightY = MaximumSwathHeightY;
3376 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
3377 && mode_lib->vba.SourceScan[k] != dm_horz) {
3378 MinimumSwathHeightY = MaximumSwathHeightY;
3379 } else {
3380 MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
3381 }
3382 MinimumSwathHeightC = MaximumSwathHeightC;
3383 } else {
3384 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
3385 MinimumSwathHeightY = MaximumSwathHeightY;
3386 MinimumSwathHeightC = MaximumSwathHeightC;
3387 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
3388 && mode_lib->vba.SourceScan[k] == dm_horz) {
3389 MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
3390 MinimumSwathHeightC = MaximumSwathHeightC;
3391 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
3392 && mode_lib->vba.SourceScan[k] == dm_horz) {
3393 MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
3394 MinimumSwathHeightY = MaximumSwathHeightY;
3395 } else {
3396 MinimumSwathHeightY = MaximumSwathHeightY;
3397 MinimumSwathHeightC = MaximumSwathHeightC;
3398 }
3399 }
3400
3401 if (mode_lib->vba.SourceScan[k] == dm_horz) {
3402 SwathWidth = mode_lib->vba.ViewportWidth[k];
3403 } else {
3404 SwathWidth = mode_lib->vba.ViewportHeight[k];
3405 }
3406
3407 if (mode_lib->vba.ODMCombineEnabled[k] == true) {
3408 MainPlaneDoesODMCombine = true;
3409 }
3410 for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
3411 if (mode_lib->vba.BlendingAndTiming[k] == j
3412 && mode_lib->vba.ODMCombineEnabled[j] == true) {
3413 MainPlaneDoesODMCombine = true;
3414 }
3415 }
3416
3417 if (MainPlaneDoesODMCombine == true) {
3418 SwathWidth = dml_min(
3419 SwathWidth,
3420 mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
3421 } else {
3422 SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
3423 }
3424
3425 SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
3426 RoundedUpMaxSwathSizeBytesY = (dml_ceil(
3427 (double) (SwathWidth - 1),
3428 SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
3429 * MaximumSwathHeightY;
3430 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
3431 RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
3432 + 256;
3433 }
3434 if (MaximumSwathHeightC > 0) {
3435 SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
3436 / MaximumSwathHeightC;
3437 RoundedUpMaxSwathSizeBytesC = (dml_ceil(
3438 (double) (SwathWidth / 2.0 - 1),
3439 SwathWidthGranularityC) + SwathWidthGranularityC)
3440 * BytePerPixDETC * MaximumSwathHeightC;
3441 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
3442 RoundedUpMaxSwathSizeBytesC = dml_ceil(
3443 RoundedUpMaxSwathSizeBytesC,
3444 256) + 256;
3445 }
3446 } else
3447 RoundedUpMaxSwathSizeBytesC = 0.0;
3448
3449 if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
3450 <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
3451 mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
3452 mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
3453 } else {
3454 mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
3455 mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
3456 }
3457
3458 if (mode_lib->vba.SwathHeightC[k] == 0) {
3459 mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
3460 mode_lib->vba.DETBufferSizeC[k] = 0;
3461 } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
3462 mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
3463 * 1024.0 / 2;
3464 mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
3465 * 1024.0 / 2;
3466 } else {
3467 mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
3468 * 1024.0 * 2 / 3;
3469 mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
3470 * 1024.0 / 3;
3471 }
3472 }
3473}
3474
3475bool Calculate256BBlockSizes(
3476 enum source_format_class SourcePixelFormat,
3477 enum dm_swizzle_mode SurfaceTiling,
3478 unsigned int BytePerPixelY,
3479 unsigned int BytePerPixelC,
3480 unsigned int *BlockHeight256BytesY,
3481 unsigned int *BlockHeight256BytesC,
3482 unsigned int *BlockWidth256BytesY,
3483 unsigned int *BlockWidth256BytesC)
3484{
3485 if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
3486 || SourcePixelFormat == dm_444_16
3487 || SourcePixelFormat == dm_444_8)) {
3488 if (SurfaceTiling == dm_sw_linear) {
3489 *BlockHeight256BytesY = 1;
3490 } else if (SourcePixelFormat == dm_444_64) {
3491 *BlockHeight256BytesY = 4;
3492 } else if (SourcePixelFormat == dm_444_8) {
3493 *BlockHeight256BytesY = 16;
3494 } else {
3495 *BlockHeight256BytesY = 8;
3496 }
3497 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
3498 *BlockHeight256BytesC = 0;
3499 *BlockWidth256BytesC = 0;
3500 } else {
3501 if (SurfaceTiling == dm_sw_linear) {
3502 *BlockHeight256BytesY = 1;
3503 *BlockHeight256BytesC = 1;
3504 } else if (SourcePixelFormat == dm_420_8) {
3505 *BlockHeight256BytesY = 16;
3506 *BlockHeight256BytesC = 8;
3507 } else {
3508 *BlockHeight256BytesY = 8;
3509 *BlockHeight256BytesC = 8;
3510 }
3511 *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
3512 *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
3513 }
3514 return true;
3515}
3516
3517static double CalculateTWait(
3518 unsigned int PrefetchMode,
3519 double DRAMClockChangeLatency,
3520 double UrgentLatency,
3521 double SREnterPlusExitTime)
3522{
3523 if (PrefetchMode == 0) {
3524 return dml_max(
3525 DRAMClockChangeLatency + UrgentLatency,
3526 dml_max(SREnterPlusExitTime, UrgentLatency));
3527 } else if (PrefetchMode == 1) {
3528 return dml_max(SREnterPlusExitTime, UrgentLatency);
3529 } else {
3530 return UrgentLatency;
3531 }
3532}
3533
3534static double CalculateRemoteSurfaceFlipDelay(
3535 struct display_mode_lib *mode_lib,
3536 double VRatio,
3537 double SwathWidth,
3538 double Bpp,
3539 double LineTime,
3540 double XFCTSlvVupdateOffset,
3541 double XFCTSlvVupdateWidth,
3542 double XFCTSlvVreadyOffset,
3543 double XFCXBUFLatencyTolerance,
3544 double XFCFillBWOverhead,
3545 double XFCSlvChunkSize,
3546 double XFCBusTransportTime,
3547 double TCalc,
3548 double TWait,
3549 double *SrcActiveDrainRate,
3550 double *TInitXFill,
3551 double *TslvChk)
3552{
3553 double TSlvSetup, AvgfillRate, result;
3554
3555 *SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
3556 TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
3557 *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
3558 AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
3559 *TslvChk = XFCSlvChunkSize / AvgfillRate;
3560 dml_print(
3561 "DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
3562 *SrcActiveDrainRate);
3563 dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
3564 dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
3565 dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
3566 dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
3567 result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
3568 dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
3569 return result;
3570}
3571
3572static double CalculateWriteBackDISPCLK(
3573 enum source_format_class WritebackPixelFormat,
3574 double PixelClock,
3575 double WritebackHRatio,
3576 double WritebackVRatio,
3577 unsigned int WritebackLumaHTaps,
3578 unsigned int WritebackLumaVTaps,
3579 unsigned int WritebackChromaHTaps,
3580 unsigned int WritebackChromaVTaps,
3581 double WritebackDestinationWidth,
3582 unsigned int HTotal,
3583 unsigned int WritebackChromaLineBufferWidth)
3584{
3585 double CalculateWriteBackDISPCLK =
3586 1.01 * PixelClock
3587 * dml_max(
3588 dml_ceil(WritebackLumaHTaps / 4.0, 1)
3589 / WritebackHRatio,
3590 dml_max(
3591 (WritebackLumaVTaps
3592 * dml_ceil(
3593 1.0
3594 / WritebackVRatio,
3595 1)
3596 * dml_ceil(
3597 WritebackDestinationWidth
3598 / 4.0,
3599 1)
3600 + dml_ceil(
3601 WritebackDestinationWidth
3602 / 4.0,
3603 1))
3604 / (double) HTotal
3605 + dml_ceil(
3606 1.0
3607 / WritebackVRatio,
3608 1)
3609 * (dml_ceil(
3610 WritebackLumaVTaps
3611 / 4.0,
3612 1)
3613 + 4.0)
3614 / (double) HTotal,
3615 dml_ceil(
3616 1.0
3617 / WritebackVRatio,
3618 1)
3619 * WritebackDestinationWidth
3620 / (double) HTotal));
3621 if (WritebackPixelFormat != dm_444_32) {
3622 CalculateWriteBackDISPCLK =
3623 dml_max(
3624 CalculateWriteBackDISPCLK,
3625 1.01 * PixelClock
3626 * dml_max(
3627 dml_ceil(
3628 WritebackChromaHTaps
3629 / 2.0,
3630 1)
3631 / (2
3632 * WritebackHRatio),
3633 dml_max(
3634 (WritebackChromaVTaps
3635 * dml_ceil(
3636 1
3637 / (2
3638 * WritebackVRatio),
3639 1)
3640 * dml_ceil(
3641 WritebackDestinationWidth
3642 / 2.0
3643 / 2.0,
3644 1)
3645 + dml_ceil(
3646 WritebackDestinationWidth
3647 / 2.0
3648 / WritebackChromaLineBufferWidth,
3649 1))
3650 / HTotal
3651 + dml_ceil(
3652 1
3653 / (2
3654 * WritebackVRatio),
3655 1)
3656 * (dml_ceil(
3657 WritebackChromaVTaps
3658 / 4.0,
3659 1)
3660 + 4)
3661 / HTotal,
3662 dml_ceil(
3663 1.0
3664 / (2
3665 * WritebackVRatio),
3666 1)
3667 * WritebackDestinationWidth
3668 / 2.0
3669 / HTotal)));
3670 }
3671 return CalculateWriteBackDISPCLK;
3672}
3673
3674static double CalculateWriteBackDelay(
3675 enum source_format_class WritebackPixelFormat,
3676 double WritebackHRatio,
3677 double WritebackVRatio,
3678 unsigned int WritebackLumaHTaps,
3679 unsigned int WritebackLumaVTaps,
3680 unsigned int WritebackChromaHTaps,
3681 unsigned int WritebackChromaVTaps,
3682 unsigned int WritebackDestinationWidth)
3683{
3684 double CalculateWriteBackDelay =
3685 dml_max(
3686 dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
3687 WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
3688 * dml_ceil(
3689 WritebackDestinationWidth
3690 / 4.0,
3691 1)
3692 + dml_ceil(1.0 / WritebackVRatio, 1)
3693 * (dml_ceil(
3694 WritebackLumaVTaps
3695 / 4.0,
3696 1) + 4));
3697
3698 if (WritebackPixelFormat != dm_444_32) {
3699 CalculateWriteBackDelay =
3700 dml_max(
3701 CalculateWriteBackDelay,
3702 dml_max(
3703 dml_ceil(
3704 WritebackChromaHTaps
3705 / 2.0,
3706 1)
3707 / (2
3708 * WritebackHRatio),
3709 WritebackChromaVTaps
3710 * dml_ceil(
3711 1
3712 / (2
3713 * WritebackVRatio),
3714 1)
3715 * dml_ceil(
3716 WritebackDestinationWidth
3717 / 2.0
3718 / 2.0,
3719 1)
3720 + dml_ceil(
3721 1
3722 / (2
3723 * WritebackVRatio),
3724 1)
3725 * (dml_ceil(
3726 WritebackChromaVTaps
3727 / 4.0,
3728 1)
3729 + 4)));
3730 }
3731 return CalculateWriteBackDelay;
3732}
3733
3734static void CalculateActiveRowBandwidth(
3735 bool VirtualMemoryEnable,
3736 enum source_format_class SourcePixelFormat,
3737 double VRatio,
3738 bool DCCEnable,
3739 double LineTime,
3740 unsigned int MetaRowByteLuma,
3741 unsigned int MetaRowByteChroma,
3742 unsigned int meta_row_height_luma,
3743 unsigned int meta_row_height_chroma,
3744 unsigned int PixelPTEBytesPerRowLuma,
3745 unsigned int PixelPTEBytesPerRowChroma,
3746 unsigned int dpte_row_height_luma,
3747 unsigned int dpte_row_height_chroma,
3748 double *meta_row_bw,
3749 double *dpte_row_bw,
3750 double *qual_row_bw)
3751{
3752 if (DCCEnable != true) {
3753 *meta_row_bw = 0;
3754 } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3755 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
3756 + VRatio / 2 * MetaRowByteChroma
3757 / (meta_row_height_chroma * LineTime);
3758 } else {
3759 *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
3760 }
3761
3762 if (VirtualMemoryEnable != true) {
3763 *dpte_row_bw = 0;
3764 } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3765 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
3766 + VRatio / 2 * PixelPTEBytesPerRowChroma
3767 / (dpte_row_height_chroma * LineTime);
3768 } else {
3769 *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
3770 }
3771
3772 if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
3773 *qual_row_bw = *meta_row_bw + *dpte_row_bw;
3774 } else {
3775 *qual_row_bw = 0;
3776 }
3777}
3778
3779static void CalculateFlipSchedule(
3780 struct display_mode_lib *mode_lib,
3781 double UrgentExtraLatency,
3782 double UrgentLatency,
3783 unsigned int MaxPageTableLevels,
3784 bool VirtualMemoryEnable,
3785 double BandwidthAvailableForImmediateFlip,
3786 unsigned int TotImmediateFlipBytes,
3787 enum source_format_class SourcePixelFormat,
3788 unsigned int ImmediateFlipBytes,
3789 double LineTime,
3790 double Tno_bw,
3791 double VRatio,
3792 double PDEAndMetaPTEBytesFrame,
3793 unsigned int MetaRowByte,
3794 unsigned int PixelPTEBytesPerRow,
3795 bool DCCEnable,
3796 unsigned int dpte_row_height,
3797 unsigned int meta_row_height,
3798 double qual_row_bw,
3799 double *DestinationLinesToRequestVMInImmediateFlip,
3800 double *DestinationLinesToRequestRowInImmediateFlip,
3801 double *final_flip_bw,
3802 bool *ImmediateFlipSupportedForPipe)
3803{
3804 double min_row_time = 0.0;
3805
3806 if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
3807 *DestinationLinesToRequestVMInImmediateFlip = 0.0;
3808 *DestinationLinesToRequestRowInImmediateFlip = 0.0;
3809 *final_flip_bw = qual_row_bw;
3810 *ImmediateFlipSupportedForPipe = true;
3811 } else {
3812 double TimeForFetchingMetaPTEImmediateFlip;
3813 double TimeForFetchingRowInVBlankImmediateFlip;
3814
3815 if (VirtualMemoryEnable == true) {
3816 mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
3817 * ImmediateFlipBytes / TotImmediateFlipBytes;
3818 TimeForFetchingMetaPTEImmediateFlip =
3819 dml_max(
3820 Tno_bw
3821 + PDEAndMetaPTEBytesFrame
3822 / mode_lib->vba.ImmediateFlipBW,
3823 dml_max(
3824 UrgentExtraLatency
3825 + UrgentLatency
3826 * (MaxPageTableLevels
3827 - 1),
3828 LineTime / 4.0));
3829 } else {
3830 TimeForFetchingMetaPTEImmediateFlip = 0;
3831 }
3832
3833 *DestinationLinesToRequestVMInImmediateFlip = dml_floor(
3834 4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
3835 1) / 4.0;
3836
3837 if ((VirtualMemoryEnable == true || DCCEnable == true)) {
3838 mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
3839 * ImmediateFlipBytes / TotImmediateFlipBytes;
3840 TimeForFetchingRowInVBlankImmediateFlip = dml_max(
3841 (MetaRowByte + PixelPTEBytesPerRow)
3842 / mode_lib->vba.ImmediateFlipBW,
3843 dml_max(UrgentLatency, LineTime / 4.0));
3844 } else {
3845 TimeForFetchingRowInVBlankImmediateFlip = 0;
3846 }
3847
3848 *DestinationLinesToRequestRowInImmediateFlip = dml_floor(
3849 4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
3850 1) / 4.0;
3851
3852 if (VirtualMemoryEnable == true) {
3853 *final_flip_bw =
3854 dml_max(
3855 PDEAndMetaPTEBytesFrame
3856 / (*DestinationLinesToRequestVMInImmediateFlip
3857 * LineTime),
3858 (MetaRowByte + PixelPTEBytesPerRow)
3859 / (TimeForFetchingRowInVBlankImmediateFlip
3860 * LineTime));
3861 } else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
3862 *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
3863 / (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
3864 } else {
3865 *final_flip_bw = 0;
3866 }
3867
3868 if (VirtualMemoryEnable && !DCCEnable)
3869 min_row_time = dpte_row_height * LineTime / VRatio;
3870 else if (!VirtualMemoryEnable && DCCEnable)
3871 min_row_time = meta_row_height * LineTime / VRatio;
3872 else
3873 min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
3874 / VRatio;
3875
3876 if (*DestinationLinesToRequestVMInImmediateFlip >= 8
3877 || *DestinationLinesToRequestRowInImmediateFlip >= 16
3878 || TimeForFetchingMetaPTEImmediateFlip
3879 + 2 * TimeForFetchingRowInVBlankImmediateFlip
3880 > min_row_time)
3881 *ImmediateFlipSupportedForPipe = false;
3882 else
3883 *ImmediateFlipSupportedForPipe = true;
3884 }
3885}
3886
3887static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
3888{
3889 unsigned int k;
3890
3891 //Progressive To dml_ml->vba.Interlace Unit Effect
3892 for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
3893 mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
3894 if (mode_lib->vba.Interlace[k] == 1
3895 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
3896 mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
3897 }
3898 }
3899}
3900
3901static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
3902{
3903 switch (ebpp) {
3904 case dm_cur_2bit:
3905 return 2;
3906 case dm_cur_32bit:
3907 return 32;
3908 case dm_cur_64bit:
3909 return 64;
3910 default:
3911 return 0;
3912 }
3913}
3914
3915static unsigned int TruncToValidBPP(
3916 double DecimalBPP,
3917 bool DSCEnabled,
3918 enum output_encoder_class Output,
3919 enum output_format_class Format,
3920 unsigned int DSCInputBitPerComponent)
3921{
3922 if (Output == dm_hdmi) {
3923 if (Format == dm_420) {
3924 if (DecimalBPP >= 18)
3925 return 18;
3926 else if (DecimalBPP >= 15)
3927 return 15;
3928 else if (DecimalBPP >= 12)
3929 return 12;
3930 else
3931 return 0;
3932 } else if (Format == dm_444) {
3933 if (DecimalBPP >= 36)
3934 return 36;
3935 else if (DecimalBPP >= 30)
3936 return 30;
3937 else if (DecimalBPP >= 24)
3938 return 24;
3939 else
3940 return 0;
3941 } else {
3942 if (DecimalBPP / 1.5 >= 24)
3943 return 24;
3944 else if (DecimalBPP / 1.5 >= 20)
3945 return 20;
3946 else if (DecimalBPP / 1.5 >= 16)
3947 return 16;
3948 else
3949 return 0;
3950 }
3951 } else {
3952 if (DSCEnabled) {
3953 if (Format == dm_420) {
3954 if (DecimalBPP < 6)
3955 return 0;
3956 else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
3957 return 1.5 * DSCInputBitPerComponent - 1 / 16;
3958 else
3959 return dml_floor(16 * DecimalBPP, 1) / 16;
3960 } else if (Format == dm_n422) {
3961 if (DecimalBPP < 7)
3962 return 0;
3963 else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
3964 return 2 * DSCInputBitPerComponent - 1 / 16;
3965 else
3966 return dml_floor(16 * DecimalBPP, 1) / 16;
3967 } else {
3968 if (DecimalBPP < 8)
3969 return 0;
3970 else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
3971 return 3 * DSCInputBitPerComponent - 1 / 16;
3972 else
3973 return dml_floor(16 * DecimalBPP, 1) / 16;
3974 }
3975 } else if (Format == dm_420) {
3976 if (DecimalBPP >= 18)
3977 return 18;
3978 else if (DecimalBPP >= 15)
3979 return 15;
3980 else if (DecimalBPP >= 12)
3981 return 12;
3982 else
3983 return 0;
3984 } else if (Format == dm_s422 || Format == dm_n422) {
3985 if (DecimalBPP >= 24)
3986 return 24;
3987 else if (DecimalBPP >= 20)
3988 return 20;
3989 else if (DecimalBPP >= 16)
3990 return 16;
3991 else
3992 return 0;
3993 } else {
3994 if (DecimalBPP >= 36)
3995 return 36;
3996 else if (DecimalBPP >= 30)
3997 return 30;
3998 else if (DecimalBPP >= 24)
3999 return 24;
4000 else
4001 return 0;
4002 }
4003 }
4004}
4005
4006static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
4007{
4008 int i;
4009 unsigned int j, k;
4010 /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
4011
4012 /*Scale Ratio, taps Support Check*/
4013
4014 mode_lib->vba.ScaleRatioAndTapsSupport = true;
4015 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4016 if (mode_lib->vba.ScalerEnabled[k] == false
4017 && ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
4018 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
4019 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
4020 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
4021 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
4022 || mode_lib->vba.HRatio[k] != 1.0
4023 || mode_lib->vba.htaps[k] != 1.0
4024 || mode_lib->vba.VRatio[k] != 1.0
4025 || mode_lib->vba.vtaps[k] != 1.0)) {
4026 mode_lib->vba.ScaleRatioAndTapsSupport = false;
4027 } else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
4028 || mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
4029 || (mode_lib->vba.htaps[k] > 1.0
4030 && (mode_lib->vba.htaps[k] % 2) == 1)
4031 || mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
4032 || mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
4033 || mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
4034 || mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
4035 || (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
4036 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
4037 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
4038 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
4039 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
4040 && (mode_lib->vba.HRatio[k] / 2.0
4041 > mode_lib->vba.HTAPsChroma[k]
4042 || mode_lib->vba.VRatio[k] / 2.0
4043 > mode_lib->vba.VTAPsChroma[k]))) {
4044 mode_lib->vba.ScaleRatioAndTapsSupport = false;
4045 }
4046 }
4047 /*Source Format, Pixel Format and Scan Support Check*/
4048
4049 mode_lib->vba.SourceFormatPixelAndScanSupport = true;
4050 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4051 if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
4052 && mode_lib->vba.SourceScan[k] != dm_horz)
4053 || ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
4054 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
4055 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
4056 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
4057 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
4058 || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
4059 || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
4060 && mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
4061 || (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
4062 && (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
4063 || mode_lib->vba.SourcePixelFormat[k]
4064 == dm_420_8
4065 || mode_lib->vba.SourcePixelFormat[k]
4066 == dm_420_10))
4067 || (((mode_lib->vba.SurfaceTiling[k]
4068 == dm_sw_gfx7_2d_thin_gl
4069 || mode_lib->vba.SurfaceTiling[k]
4070 == dm_sw_gfx7_2d_thin_lvp)
4071 && !((mode_lib->vba.SourcePixelFormat[k]
4072 == dm_444_64
4073 || mode_lib->vba.SourcePixelFormat[k]
4074 == dm_444_32)
4075 && mode_lib->vba.SourceScan[k]
4076 == dm_horz
4077 && mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
4078 == true
4079 && mode_lib->vba.DCCEnable[k]
4080 == false))
4081 || (mode_lib->vba.DCCEnable[k] == true
4082 && (mode_lib->vba.SurfaceTiling[k]
4083 == dm_sw_linear
4084 || mode_lib->vba.SourcePixelFormat[k]
4085 == dm_420_8
4086 || mode_lib->vba.SourcePixelFormat[k]
4087 == dm_420_10)))) {
4088 mode_lib->vba.SourceFormatPixelAndScanSupport = false;
4089 }
4090 }
4091 /*Bandwidth Support Check*/
4092
4093 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4094 if (mode_lib->vba.SourceScan[k] == dm_horz) {
4095 mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
4096 } else {
4097 mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
4098 }
4099 if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
4100 mode_lib->vba.BytePerPixelInDETY[k] = 8.0;
4101 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4102 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
4103 mode_lib->vba.BytePerPixelInDETY[k] = 4.0;
4104 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4105 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
4106 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
4107 mode_lib->vba.BytePerPixelInDETY[k] = 2.0;
4108 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4109 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
4110 mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
4111 mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
4112 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
4113 mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
4114 mode_lib->vba.BytePerPixelInDETC[k] = 2.0;
4115 } else {
4116 mode_lib->vba.BytePerPixelInDETY[k] = 4.0 / 3;
4117 mode_lib->vba.BytePerPixelInDETC[k] = 8.0 / 3;
4118 }
4119 }
4120 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = 0.0;
4121 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4122 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.SwathWidthYSingleDPP[k]
4123 * (dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
4124 * mode_lib->vba.VRatio[k]
4125 + dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
4126 / 2.0 * mode_lib->vba.VRatio[k] / 2)
4127 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
4128 if (mode_lib->vba.DCCEnable[k] == true) {
4129 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4130 * (1 + 1 / 256);
4131 }
4132 if (mode_lib->vba.VirtualMemoryEnable == true
4133 && mode_lib->vba.SourceScan[k] != dm_horz
4134 && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s
4135 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s_x
4136 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
4137 || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x)) {
4138 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4139 * (1 + 1 / 64);
4140 } else if (mode_lib->vba.VirtualMemoryEnable == true
4141 && mode_lib->vba.SourceScan[k] == dm_horz
4142 && (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
4143 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32)
4144 && (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s
4145 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_t
4146 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_x
4147 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
4148 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
4149 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
4150 || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x)) {
4151 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4152 * (1 + 1 / 256);
4153 } else if (mode_lib->vba.VirtualMemoryEnable == true) {
4154 mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
4155 * (1 + 1 / 512);
4156 }
4157 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond =
4158 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
4159 + mode_lib->vba.ReadBandwidth[k] / 1000.0;
4160 }
4161 mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = 0.0;
4162 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4163 if (mode_lib->vba.WritebackEnable[k] == true
4164 && mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
4165 mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
4166 * mode_lib->vba.WritebackDestinationHeight[k]
4167 / (mode_lib->vba.WritebackSourceHeight[k]
4168 * mode_lib->vba.HTotal[k]
4169 / mode_lib->vba.PixelClock[k]) * 4.0;
4170 } else if (mode_lib->vba.WritebackEnable[k] == true
4171 && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
4172 mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
4173 * mode_lib->vba.WritebackDestinationHeight[k]
4174 / (mode_lib->vba.WritebackSourceHeight[k]
4175 * mode_lib->vba.HTotal[k]
4176 / mode_lib->vba.PixelClock[k]) * 3.0;
4177 } else if (mode_lib->vba.WritebackEnable[k] == true) {
4178 mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
4179 * mode_lib->vba.WritebackDestinationHeight[k]
4180 / (mode_lib->vba.WritebackSourceHeight[k]
4181 * mode_lib->vba.HTotal[k]
4182 / mode_lib->vba.PixelClock[k]) * 1.5;
4183 } else {
4184 mode_lib->vba.WriteBandwidth[k] = 0.0;
4185 }
4186 mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond =
4187 mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond
4188 + mode_lib->vba.WriteBandwidth[k] / 1000.0;
4189 }
4190 mode_lib->vba.TotalBandwidthConsumedGBytePerSecond =
4191 mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
4192 + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond;
4193 mode_lib->vba.DCCEnabledInAnyPlane = false;
4194 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4195 if (mode_lib->vba.DCCEnable[k] == true) {
4196 mode_lib->vba.DCCEnabledInAnyPlane = true;
4197 }
4198 }
4199 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4200 mode_lib->vba.FabricAndDRAMBandwidthPerState[i] = dml_min(
4201 mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
4202 * mode_lib->vba.DRAMChannelWidth,
4203 mode_lib->vba.FabricClockPerState[i]
4204 * mode_lib->vba.FabricDatapathToDCNDataReturn)
4205 / 1000;
4206 mode_lib->vba.ReturnBWToDCNPerState = dml_min(
4207 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
4208 mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0)
4209 * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
4210 / 100;
4211 mode_lib->vba.ReturnBWPerState[i] = mode_lib->vba.ReturnBWToDCNPerState;
4212 if (mode_lib->vba.DCCEnabledInAnyPlane == true
4213 && mode_lib->vba.ReturnBWToDCNPerState
4214 > mode_lib->vba.DCFCLKPerState[i]
4215 * mode_lib->vba.ReturnBusWidth
4216 / 4.0) {
4217 mode_lib->vba.ReturnBWPerState[i] =
4218 dml_min(
4219 mode_lib->vba.ReturnBWPerState[i],
4220 mode_lib->vba.ReturnBWToDCNPerState * 4.0
4221 * (1.0
4222 - mode_lib->vba.UrgentLatency
4223 / ((mode_lib->vba.ROBBufferSizeInKByte
4224 - mode_lib->vba.PixelChunkSizeInKByte)
4225 * 1024.0
4226 / (mode_lib->vba.ReturnBWToDCNPerState
4227 - mode_lib->vba.DCFCLKPerState[i]
4228 * mode_lib->vba.ReturnBusWidth
4229 / 4.0)
4230 + mode_lib->vba.UrgentLatency)));
4231 }
4232 mode_lib->vba.CriticalPoint =
4233 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
4234 * mode_lib->vba.UrgentLatency
4235 / (mode_lib->vba.ReturnBWToDCNPerState
4236 * mode_lib->vba.UrgentLatency
4237 + (mode_lib->vba.ROBBufferSizeInKByte
4238 - mode_lib->vba.PixelChunkSizeInKByte)
4239 * 1024.0);
4240 if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
4241 && mode_lib->vba.CriticalPoint < 4.0) {
4242 mode_lib->vba.ReturnBWPerState[i] =
4243 dml_min(
4244 mode_lib->vba.ReturnBWPerState[i],
4245 dml_pow(
4246 4.0
4247 * mode_lib->vba.ReturnBWToDCNPerState
4248 * (mode_lib->vba.ROBBufferSizeInKByte
4249 - mode_lib->vba.PixelChunkSizeInKByte)
4250 * 1024.0
4251 * mode_lib->vba.ReturnBusWidth
4252 * mode_lib->vba.DCFCLKPerState[i]
4253 * mode_lib->vba.UrgentLatency
4254 / (mode_lib->vba.ReturnBWToDCNPerState
4255 * mode_lib->vba.UrgentLatency
4256 + (mode_lib->vba.ROBBufferSizeInKByte
4257 - mode_lib->vba.PixelChunkSizeInKByte)
4258 * 1024.0),
4259 2));
4260 }
4261 mode_lib->vba.ReturnBWToDCNPerState = dml_min(
4262 mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
4263 mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0);
4264 if (mode_lib->vba.DCCEnabledInAnyPlane == true
4265 && mode_lib->vba.ReturnBWToDCNPerState
4266 > mode_lib->vba.DCFCLKPerState[i]
4267 * mode_lib->vba.ReturnBusWidth
4268 / 4.0) {
4269 mode_lib->vba.ReturnBWPerState[i] =
4270 dml_min(
4271 mode_lib->vba.ReturnBWPerState[i],
4272 mode_lib->vba.ReturnBWToDCNPerState * 4.0
4273 * (1.0
4274 - mode_lib->vba.UrgentLatency
4275 / ((mode_lib->vba.ROBBufferSizeInKByte
4276 - mode_lib->vba.PixelChunkSizeInKByte)
4277 * 1024.0
4278 / (mode_lib->vba.ReturnBWToDCNPerState
4279 - mode_lib->vba.DCFCLKPerState[i]
4280 * mode_lib->vba.ReturnBusWidth
4281 / 4.0)
4282 + mode_lib->vba.UrgentLatency)));
4283 }
4284 mode_lib->vba.CriticalPoint =
4285 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
4286 * mode_lib->vba.UrgentLatency
4287 / (mode_lib->vba.ReturnBWToDCNPerState
4288 * mode_lib->vba.UrgentLatency
4289 + (mode_lib->vba.ROBBufferSizeInKByte
4290 - mode_lib->vba.PixelChunkSizeInKByte)
4291 * 1024.0);
4292 if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
4293 && mode_lib->vba.CriticalPoint < 4.0) {
4294 mode_lib->vba.ReturnBWPerState[i] =
4295 dml_min(
4296 mode_lib->vba.ReturnBWPerState[i],
4297 dml_pow(
4298 4.0
4299 * mode_lib->vba.ReturnBWToDCNPerState
4300 * (mode_lib->vba.ROBBufferSizeInKByte
4301 - mode_lib->vba.PixelChunkSizeInKByte)
4302 * 1024.0
4303 * mode_lib->vba.ReturnBusWidth
4304 * mode_lib->vba.DCFCLKPerState[i]
4305 * mode_lib->vba.UrgentLatency
4306 / (mode_lib->vba.ReturnBWToDCNPerState
4307 * mode_lib->vba.UrgentLatency
4308 + (mode_lib->vba.ROBBufferSizeInKByte
4309 - mode_lib->vba.PixelChunkSizeInKByte)
4310 * 1024.0),
4311 2));
4312 }
4313 }
4314 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4315 if ((mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond * 1000.0
4316 <= mode_lib->vba.ReturnBWPerState[i])
4317 && (mode_lib->vba.TotalBandwidthConsumedGBytePerSecond * 1000.0
4318 <= mode_lib->vba.FabricAndDRAMBandwidthPerState[i]
4319 * 1000.0
4320 * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
4321 / 100.0)) {
4322 mode_lib->vba.BandwidthSupport[i] = true;
4323 } else {
4324 mode_lib->vba.BandwidthSupport[i] = false;
4325 }
4326 }
4327 /*Writeback Latency support check*/
4328
4329 mode_lib->vba.WritebackLatencySupport = true;
4330 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4331 if (mode_lib->vba.WritebackEnable[k] == true) {
4332 if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
4333 if (mode_lib->vba.WriteBandwidth[k]
4334 > (mode_lib->vba.WritebackInterfaceLumaBufferSize
4335 + mode_lib->vba.WritebackInterfaceChromaBufferSize)
4336 / mode_lib->vba.WritebackLatency) {
4337 mode_lib->vba.WritebackLatencySupport = false;
4338 }
4339 } else {
4340 if (mode_lib->vba.WriteBandwidth[k]
4341 > 1.5
4342 * dml_min(
4343 mode_lib->vba.WritebackInterfaceLumaBufferSize,
4344 2.0
4345 * mode_lib->vba.WritebackInterfaceChromaBufferSize)
4346 / mode_lib->vba.WritebackLatency) {
4347 mode_lib->vba.WritebackLatencySupport = false;
4348 }
4349 }
4350 }
4351 }
4352 /*Re-ordering Buffer Support Check*/
4353
4354 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4355 mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
4356 (mode_lib->vba.RoundTripPingLatencyCycles + 32.0)
4357 / mode_lib->vba.DCFCLKPerState[i]
4358 + mode_lib->vba.UrgentOutOfOrderReturnPerChannel
4359 * mode_lib->vba.NumberOfChannels
4360 / mode_lib->vba.ReturnBWPerState[i];
4361 if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte)
4362 * 1024.0 / mode_lib->vba.ReturnBWPerState[i]
4363 > mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
4364 mode_lib->vba.ROBSupport[i] = true;
4365 } else {
4366 mode_lib->vba.ROBSupport[i] = false;
4367 }
4368 }
4369 /*Writeback Mode Support Check*/
4370
4371 mode_lib->vba.TotalNumberOfActiveWriteback = 0;
4372 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4373 if (mode_lib->vba.WritebackEnable[k] == true) {
4374 mode_lib->vba.TotalNumberOfActiveWriteback =
4375 mode_lib->vba.TotalNumberOfActiveWriteback + 1;
4376 }
4377 }
4378 mode_lib->vba.WritebackModeSupport = true;
4379 if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
4380 mode_lib->vba.WritebackModeSupport = false;
4381 }
4382 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4383 if (mode_lib->vba.WritebackEnable[k] == true
4384 && mode_lib->vba.Writeback10bpc420Supported != true
4385 && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
4386 mode_lib->vba.WritebackModeSupport = false;
4387 }
4388 }
4389 /*Writeback Scale Ratio and Taps Support Check*/
4390
4391 mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
4392 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4393 if (mode_lib->vba.WritebackEnable[k] == true) {
4394 if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
4395 && (mode_lib->vba.WritebackHRatio[k] != 1.0
4396 || mode_lib->vba.WritebackVRatio[k] != 1.0)) {
4397 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4398 }
4399 if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
4400 || mode_lib->vba.WritebackVRatio[k]
4401 > mode_lib->vba.WritebackMaxVSCLRatio
4402 || mode_lib->vba.WritebackHRatio[k]
4403 < mode_lib->vba.WritebackMinHSCLRatio
4404 || mode_lib->vba.WritebackVRatio[k]
4405 < mode_lib->vba.WritebackMinVSCLRatio
4406 || mode_lib->vba.WritebackLumaHTaps[k]
4407 > mode_lib->vba.WritebackMaxHSCLTaps
4408 || mode_lib->vba.WritebackLumaVTaps[k]
4409 > mode_lib->vba.WritebackMaxVSCLTaps
4410 || mode_lib->vba.WritebackHRatio[k]
4411 > mode_lib->vba.WritebackLumaHTaps[k]
4412 || mode_lib->vba.WritebackVRatio[k]
4413 > mode_lib->vba.WritebackLumaVTaps[k]
4414 || (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
4415 && ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
4416 == 1))
4417 || (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
4418 && (mode_lib->vba.WritebackChromaHTaps[k]
4419 > mode_lib->vba.WritebackMaxHSCLTaps
4420 || mode_lib->vba.WritebackChromaVTaps[k]
4421 > mode_lib->vba.WritebackMaxVSCLTaps
4422 || 2.0
4423 * mode_lib->vba.WritebackHRatio[k]
4424 > mode_lib->vba.WritebackChromaHTaps[k]
4425 || 2.0
4426 * mode_lib->vba.WritebackVRatio[k]
4427 > mode_lib->vba.WritebackChromaVTaps[k]
4428 || (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
4429 && ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
4430 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4431 }
4432 if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
4433 mode_lib->vba.WritebackLumaVExtra =
4434 dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
4435 } else {
4436 mode_lib->vba.WritebackLumaVExtra = -1;
4437 }
4438 if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
4439 && mode_lib->vba.WritebackLumaVTaps[k]
4440 > (mode_lib->vba.WritebackLineBufferLumaBufferSize
4441 + mode_lib->vba.WritebackLineBufferChromaBufferSize)
4442 / 3.0
4443 / mode_lib->vba.WritebackDestinationWidth[k]
4444 - mode_lib->vba.WritebackLumaVExtra)
4445 || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
4446 && mode_lib->vba.WritebackLumaVTaps[k]
4447 > mode_lib->vba.WritebackLineBufferLumaBufferSize
4448 / mode_lib->vba.WritebackDestinationWidth[k]
4449 - mode_lib->vba.WritebackLumaVExtra)
4450 || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
4451 && mode_lib->vba.WritebackLumaVTaps[k]
4452 > mode_lib->vba.WritebackLineBufferLumaBufferSize
4453 * 8.0 / 10.0
4454 / mode_lib->vba.WritebackDestinationWidth[k]
4455 - mode_lib->vba.WritebackLumaVExtra)) {
4456 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4457 }
4458 if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
4459 mode_lib->vba.WritebackChromaVExtra = 0.0;
4460 } else {
4461 mode_lib->vba.WritebackChromaVExtra = -1;
4462 }
4463 if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
4464 && mode_lib->vba.WritebackChromaVTaps[k]
4465 > mode_lib->vba.WritebackLineBufferChromaBufferSize
4466 / mode_lib->vba.WritebackDestinationWidth[k]
4467 - mode_lib->vba.WritebackChromaVExtra)
4468 || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
4469 && mode_lib->vba.WritebackChromaVTaps[k]
4470 > mode_lib->vba.WritebackLineBufferChromaBufferSize
4471 * 8.0 / 10.0
4472 / mode_lib->vba.WritebackDestinationWidth[k]
4473 - mode_lib->vba.WritebackChromaVExtra)) {
4474 mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
4475 }
4476 }
4477 }
4478 /*Maximum DISPCLK/DPPCLK Support check*/
4479
4480 mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
4481 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4482 if (mode_lib->vba.WritebackEnable[k] == true) {
4483 mode_lib->vba.WritebackRequiredDISPCLK =
4484 dml_max(
4485 mode_lib->vba.WritebackRequiredDISPCLK,
4486 CalculateWriteBackDISPCLK(
4487 mode_lib->vba.WritebackPixelFormat[k],
4488 mode_lib->vba.PixelClock[k],
4489 mode_lib->vba.WritebackHRatio[k],
4490 mode_lib->vba.WritebackVRatio[k],
4491 mode_lib->vba.WritebackLumaHTaps[k],
4492 mode_lib->vba.WritebackLumaVTaps[k],
4493 mode_lib->vba.WritebackChromaHTaps[k],
4494 mode_lib->vba.WritebackChromaVTaps[k],
4495 mode_lib->vba.WritebackDestinationWidth[k],
4496 mode_lib->vba.HTotal[k],
4497 mode_lib->vba.WritebackChromaLineBufferWidth));
4498 }
4499 }
4500 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4501 if (mode_lib->vba.HRatio[k] > 1.0) {
4502 mode_lib->vba.PSCL_FACTOR[k] = dml_min(
4503 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4504 mode_lib->vba.MaxPSCLToLBThroughput
4505 * mode_lib->vba.HRatio[k]
4506 / dml_ceil(
4507 mode_lib->vba.htaps[k]
4508 / 6.0,
4509 1.0));
4510 } else {
4511 mode_lib->vba.PSCL_FACTOR[k] = dml_min(
4512 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4513 mode_lib->vba.MaxPSCLToLBThroughput);
4514 }
4515 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
4516 mode_lib->vba.PSCL_FACTOR_CHROMA[k] = 0.0;
4517 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
4518 mode_lib->vba.PixelClock[k]
4519 * dml_max3(
4520 mode_lib->vba.vtaps[k] / 6.0
4521 * dml_min(
4522 1.0,
4523 mode_lib->vba.HRatio[k]),
4524 mode_lib->vba.HRatio[k]
4525 * mode_lib->vba.VRatio[k]
4526 / mode_lib->vba.PSCL_FACTOR[k],
4527 1.0);
4528 if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
4529 && mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4530 < 2.0 * mode_lib->vba.PixelClock[k]) {
4531 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
4532 * mode_lib->vba.PixelClock[k];
4533 }
4534 } else {
4535 if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
4536 mode_lib->vba.PSCL_FACTOR_CHROMA[k] =
4537 dml_min(
4538 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4539 mode_lib->vba.MaxPSCLToLBThroughput
4540 * mode_lib->vba.HRatio[k]
4541 / 2.0
4542 / dml_ceil(
4543 mode_lib->vba.HTAPsChroma[k]
4544 / 6.0,
4545 1.0));
4546 } else {
4547 mode_lib->vba.PSCL_FACTOR_CHROMA[k] = dml_min(
4548 mode_lib->vba.MaxDCHUBToPSCLThroughput,
4549 mode_lib->vba.MaxPSCLToLBThroughput);
4550 }
4551 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
4552 mode_lib->vba.PixelClock[k]
4553 * dml_max5(
4554 mode_lib->vba.vtaps[k] / 6.0
4555 * dml_min(
4556 1.0,
4557 mode_lib->vba.HRatio[k]),
4558 mode_lib->vba.HRatio[k]
4559 * mode_lib->vba.VRatio[k]
4560 / mode_lib->vba.PSCL_FACTOR[k],
4561 mode_lib->vba.VTAPsChroma[k]
4562 / 6.0
4563 * dml_min(
4564 1.0,
4565 mode_lib->vba.HRatio[k]
4566 / 2.0),
4567 mode_lib->vba.HRatio[k]
4568 * mode_lib->vba.VRatio[k]
4569 / 4.0
4570 / mode_lib->vba.PSCL_FACTOR_CHROMA[k],
4571 1.0);
4572 if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
4573 || mode_lib->vba.HTAPsChroma[k] > 6.0
4574 || mode_lib->vba.VTAPsChroma[k] > 6.0)
4575 && mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4576 < 2.0 * mode_lib->vba.PixelClock[k]) {
4577 mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
4578 * mode_lib->vba.PixelClock[k];
4579 }
4580 }
4581 }
4582 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4583 Calculate256BBlockSizes(
4584 mode_lib->vba.SourcePixelFormat[k],
4585 mode_lib->vba.SurfaceTiling[k],
4586 dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
4587 dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
4588 &mode_lib->vba.Read256BlockHeightY[k],
4589 &mode_lib->vba.Read256BlockHeightC[k],
4590 &mode_lib->vba.Read256BlockWidthY[k],
4591 &mode_lib->vba.Read256BlockWidthC[k]);
4592 if (mode_lib->vba.SourceScan[k] == dm_horz) {
4593 mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockHeightY[k];
4594 mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockHeightC[k];
4595 } else {
4596 mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockWidthY[k];
4597 mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockWidthC[k];
4598 }
4599 if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
4600 || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
4601 || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
4602 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
4603 || mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
4604 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
4605 || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
4606 && (mode_lib->vba.SurfaceTiling[k]
4607 == dm_sw_4kb_s
4608 || mode_lib->vba.SurfaceTiling[k]
4609 == dm_sw_4kb_s_x
4610 || mode_lib->vba.SurfaceTiling[k]
4611 == dm_sw_64kb_s
4612 || mode_lib->vba.SurfaceTiling[k]
4613 == dm_sw_64kb_s_t
4614 || mode_lib->vba.SurfaceTiling[k]
4615 == dm_sw_64kb_s_x
4616 || mode_lib->vba.SurfaceTiling[k]
4617 == dm_sw_var_s
4618 || mode_lib->vba.SurfaceTiling[k]
4619 == dm_sw_var_s_x)
4620 && mode_lib->vba.SourceScan[k] == dm_horz)) {
4621 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4622 } else {
4623 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
4624 / 2.0;
4625 }
4626 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4627 } else {
4628 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
4629 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4630 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4631 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
4632 && mode_lib->vba.SourceScan[k] == dm_horz) {
4633 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
4634 / 2.0;
4635 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4636 } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
4637 && mode_lib->vba.SourceScan[k] == dm_horz) {
4638 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]
4639 / 2.0;
4640 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4641 } else {
4642 mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
4643 mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
4644 }
4645 }
4646 if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
4647 mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
4648 } else {
4649 mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
4650 }
4651 mode_lib->vba.MaximumSwathWidthInDETBuffer =
4652 dml_min(
4653 mode_lib->vba.MaximumSwathWidthSupport,
4654 mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
4655 / (mode_lib->vba.BytePerPixelInDETY[k]
4656 * mode_lib->vba.MinSwathHeightY[k]
4657 + mode_lib->vba.BytePerPixelInDETC[k]
4658 / 2.0
4659 * mode_lib->vba.MinSwathHeightC[k]));
4660 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
4661 mode_lib->vba.MaximumSwathWidthInLineBuffer =
4662 mode_lib->vba.LineBufferSize
4663 * dml_max(mode_lib->vba.HRatio[k], 1.0)
4664 / mode_lib->vba.LBBitPerPixel[k]
4665 / (mode_lib->vba.vtaps[k]
4666 + dml_max(
4667 dml_ceil(
4668 mode_lib->vba.VRatio[k],
4669 1.0)
4670 - 2,
4671 0.0));
4672 } else {
4673 mode_lib->vba.MaximumSwathWidthInLineBuffer =
4674 dml_min(
4675 mode_lib->vba.LineBufferSize
4676 * dml_max(
4677 mode_lib->vba.HRatio[k],
4678 1.0)
4679 / mode_lib->vba.LBBitPerPixel[k]
4680 / (mode_lib->vba.vtaps[k]
4681 + dml_max(
4682 dml_ceil(
4683 mode_lib->vba.VRatio[k],
4684 1.0)
4685 - 2,
4686 0.0)),
4687 2.0 * mode_lib->vba.LineBufferSize
4688 * dml_max(
4689 mode_lib->vba.HRatio[k]
4690 / 2.0,
4691 1.0)
4692 / mode_lib->vba.LBBitPerPixel[k]
4693 / (mode_lib->vba.VTAPsChroma[k]
4694 + dml_max(
4695 dml_ceil(
4696 mode_lib->vba.VRatio[k]
4697 / 2.0,
4698 1.0)
4699 - 2,
4700 0.0)));
4701 }
4702 mode_lib->vba.MaximumSwathWidth[k] = dml_min(
4703 mode_lib->vba.MaximumSwathWidthInDETBuffer,
4704 mode_lib->vba.MaximumSwathWidthInLineBuffer);
4705 }
4706 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4707 mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
4708 mode_lib->vba.MaxDispclk[i],
4709 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
4710 mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
4711 mode_lib->vba.MaxDppclk[i],
4712 mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
4713 mode_lib->vba.RequiredDISPCLK[i] = 0.0;
4714 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
4715 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4716 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
4717 mode_lib->vba.PixelClock[k]
4718 * (1.0
4719 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4720 / 100.0)
4721 * (1.0
4722 + mode_lib->vba.DISPCLKRampingMargin
4723 / 100.0);
4724 if (mode_lib->vba.ODMCapability == true
4725 && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4726 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
4727 mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
4728 mode_lib->vba.PlaneRequiredDISPCLK =
4729 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4730 / 2.0;
4731 } else {
4732 mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
4733 mode_lib->vba.PlaneRequiredDISPCLK =
4734 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
4735 }
4736 if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4737 * (1.0
4738 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4739 / 100.0)
4740 <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
4741 && mode_lib->vba.SwathWidthYSingleDPP[k]
4742 <= mode_lib->vba.MaximumSwathWidth[k]
4743 && mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
4744 mode_lib->vba.NoOfDPP[i][k] = 1;
4745 mode_lib->vba.RequiredDPPCLK[i][k] =
4746 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4747 * (1.0
4748 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4749 / 100.0);
4750 } else {
4751 mode_lib->vba.NoOfDPP[i][k] = 2;
4752 mode_lib->vba.RequiredDPPCLK[i][k] =
4753 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4754 * (1.0
4755 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4756 / 100.0)
4757 / 2.0;
4758 }
4759 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4760 mode_lib->vba.RequiredDISPCLK[i],
4761 mode_lib->vba.PlaneRequiredDISPCLK);
4762 if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] / mode_lib->vba.NoOfDPP[i][k]
4763 * (1.0
4764 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4765 / 100.0)
4766 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
4767 || (mode_lib->vba.PlaneRequiredDISPCLK
4768 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
4769 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4770 }
4771 }
4772 mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
4773 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4774 mode_lib->vba.TotalNumberOfActiveDPP[i] =
4775 mode_lib->vba.TotalNumberOfActiveDPP[i]
4776 + mode_lib->vba.NoOfDPP[i][k];
4777 }
4778 if ((mode_lib->vba.MaxDispclk[i] == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
4779 && mode_lib->vba.MaxDppclk[i]
4780 == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])
4781 && (mode_lib->vba.TotalNumberOfActiveDPP[i]
4782 > mode_lib->vba.MaxNumDPP
4783 || mode_lib->vba.DISPCLK_DPPCLK_Support[i] == false)) {
4784 mode_lib->vba.RequiredDISPCLK[i] = 0.0;
4785 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
4786 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4787 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
4788 mode_lib->vba.PixelClock[k]
4789 * (1.0
4790 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4791 / 100.0);
4792 if (mode_lib->vba.ODMCapability == true
4793 && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4794 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
4795 mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
4796 mode_lib->vba.PlaneRequiredDISPCLK =
4797 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
4798 / 2.0;
4799 } else {
4800 mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
4801 mode_lib->vba.PlaneRequiredDISPCLK =
4802 mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
4803 }
4804 if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4805 * (1.0
4806 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4807 / 100.0)
4808 <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
4809 && mode_lib->vba.SwathWidthYSingleDPP[k]
4810 <= mode_lib->vba.MaximumSwathWidth[k]
4811 && mode_lib->vba.ODMCombineEnablePerState[i][k]
4812 == false) {
4813 mode_lib->vba.NoOfDPP[i][k] = 1;
4814 mode_lib->vba.RequiredDPPCLK[i][k] =
4815 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4816 * (1.0
4817 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4818 / 100.0);
4819 } else {
4820 mode_lib->vba.NoOfDPP[i][k] = 2;
4821 mode_lib->vba.RequiredDPPCLK[i][k] =
4822 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4823 * (1.0
4824 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4825 / 100.0)
4826 / 2.0;
4827 }
4828 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4829 mode_lib->vba.RequiredDISPCLK[i],
4830 mode_lib->vba.PlaneRequiredDISPCLK);
4831 if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4832 / mode_lib->vba.NoOfDPP[i][k]
4833 * (1.0
4834 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4835 / 100.0)
4836 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
4837 || (mode_lib->vba.PlaneRequiredDISPCLK
4838 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
4839 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4840 }
4841 }
4842 mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
4843 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4844 mode_lib->vba.TotalNumberOfActiveDPP[i] =
4845 mode_lib->vba.TotalNumberOfActiveDPP[i]
4846 + mode_lib->vba.NoOfDPP[i][k];
4847 }
4848 }
4849 if (mode_lib->vba.TotalNumberOfActiveDPP[i] > mode_lib->vba.MaxNumDPP) {
4850 mode_lib->vba.RequiredDISPCLK[i] = 0.0;
4851 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
4852 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4853 mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
4854 if (mode_lib->vba.SwathWidthYSingleDPP[k]
4855 <= mode_lib->vba.MaximumSwathWidth[k]) {
4856 mode_lib->vba.NoOfDPP[i][k] = 1;
4857 mode_lib->vba.RequiredDPPCLK[i][k] =
4858 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4859 * (1.0
4860 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4861 / 100.0);
4862 } else {
4863 mode_lib->vba.NoOfDPP[i][k] = 2;
4864 mode_lib->vba.RequiredDPPCLK[i][k] =
4865 mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4866 * (1.0
4867 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4868 / 100.0)
4869 / 2.0;
4870 }
4871 if (!(mode_lib->vba.MaxDispclk[i]
4872 == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
4873 && mode_lib->vba.MaxDppclk[i]
4874 == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])) {
4875 mode_lib->vba.PlaneRequiredDISPCLK =
4876 mode_lib->vba.PixelClock[k]
4877 * (1.0
4878 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4879 / 100.0)
4880 * (1.0
4881 + mode_lib->vba.DISPCLKRampingMargin
4882 / 100.0);
4883 } else {
4884 mode_lib->vba.PlaneRequiredDISPCLK =
4885 mode_lib->vba.PixelClock[k]
4886 * (1.0
4887 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4888 / 100.0);
4889 }
4890 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4891 mode_lib->vba.RequiredDISPCLK[i],
4892 mode_lib->vba.PlaneRequiredDISPCLK);
4893 if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
4894 / mode_lib->vba.NoOfDPP[i][k]
4895 * (1.0
4896 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
4897 / 100.0)
4898 > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
4899 || (mode_lib->vba.PlaneRequiredDISPCLK
4900 > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
4901 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4902 }
4903 }
4904 mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
4905 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4906 mode_lib->vba.TotalNumberOfActiveDPP[i] =
4907 mode_lib->vba.TotalNumberOfActiveDPP[i]
4908 + mode_lib->vba.NoOfDPP[i][k];
4909 }
4910 }
4911 mode_lib->vba.RequiredDISPCLK[i] = dml_max(
4912 mode_lib->vba.RequiredDISPCLK[i],
4913 mode_lib->vba.WritebackRequiredDISPCLK);
4914 if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
4915 < mode_lib->vba.WritebackRequiredDISPCLK) {
4916 mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
4917 }
4918 }
4919 /*Viewport Size Check*/
4920
4921 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4922 mode_lib->vba.ViewportSizeSupport[i] = true;
4923 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4924 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
4925 if (dml_min(
4926 mode_lib->vba.SwathWidthYSingleDPP[k],
4927 dml_round(
4928 mode_lib->vba.HActive[k] / 2.0
4929 * mode_lib->vba.HRatio[k]))
4930 > mode_lib->vba.MaximumSwathWidth[k]) {
4931 mode_lib->vba.ViewportSizeSupport[i] = false;
4932 }
4933 } else {
4934 if (mode_lib->vba.SwathWidthYSingleDPP[k] / 2.0
4935 > mode_lib->vba.MaximumSwathWidth[k]) {
4936 mode_lib->vba.ViewportSizeSupport[i] = false;
4937 }
4938 }
4939 }
4940 }
4941 /*Total Available Pipes Support Check*/
4942
4943 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4944 if (mode_lib->vba.TotalNumberOfActiveDPP[i] <= mode_lib->vba.MaxNumDPP) {
4945 mode_lib->vba.TotalAvailablePipesSupport[i] = true;
4946 } else {
4947 mode_lib->vba.TotalAvailablePipesSupport[i] = false;
4948 }
4949 }
4950 /*Total Available OTG Support Check*/
4951
4952 mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
4953 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4954 if (mode_lib->vba.BlendingAndTiming[k] == k) {
4955 mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
4956 + 1.0;
4957 }
4958 }
4959 if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
4960 mode_lib->vba.NumberOfOTGSupport = true;
4961 } else {
4962 mode_lib->vba.NumberOfOTGSupport = false;
4963 }
4964 /*Display IO and DSC Support Check*/
4965
4966 mode_lib->vba.NonsupportedDSCInputBPC = false;
4967 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4968 if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
4969 || mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
4970 || mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
4971 mode_lib->vba.NonsupportedDSCInputBPC = true;
4972 }
4973 }
4974 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
4975 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
4976 mode_lib->vba.RequiresDSC[i][k] = 0;
4977 mode_lib->vba.RequiresFEC[i][k] = 0;
4978 if (mode_lib->vba.BlendingAndTiming[k] == k) {
4979 if (mode_lib->vba.Output[k] == dm_hdmi) {
4980 mode_lib->vba.RequiresDSC[i][k] = 0;
4981 mode_lib->vba.RequiresFEC[i][k] = 0;
4982 mode_lib->vba.OutputBppPerState[i][k] =
4983 TruncToValidBPP(
4984 dml_min(
4985 600.0,
4986 mode_lib->vba.PHYCLKPerState[i])
4987 / mode_lib->vba.PixelClockBackEnd[k]
4988 * 24,
4989 false,
4990 mode_lib->vba.Output[k],
4991 mode_lib->vba.OutputFormat[k],
4992 mode_lib->vba.DSCInputBitPerComponent[k]);
4993 } else if (mode_lib->vba.Output[k] == dm_dp
4994 || mode_lib->vba.Output[k] == dm_edp) {
4995 if (mode_lib->vba.Output[k] == dm_edp) {
4996 mode_lib->vba.EffectiveFECOverhead = 0.0;
4997 } else {
4998 mode_lib->vba.EffectiveFECOverhead =
4999 mode_lib->vba.FECOverhead;
5000 }
5001 if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
5002 mode_lib->vba.Outbpp =
5003 TruncToValidBPP(
5004 (1.0
5005 - mode_lib->vba.Downspreading
5006 / 100.0)
5007 * 270.0
5008 * mode_lib->vba.OutputLinkDPLanes[k]
5009 / mode_lib->vba.PixelClockBackEnd[k]
5010 * 8.0,
5011 false,
5012 mode_lib->vba.Output[k],
5013 mode_lib->vba.OutputFormat[k],
5014 mode_lib->vba.DSCInputBitPerComponent[k]);
5015 mode_lib->vba.OutbppDSC =
5016 TruncToValidBPP(
5017 (1.0
5018 - mode_lib->vba.Downspreading
5019 / 100.0)
5020 * (1.0
5021 - mode_lib->vba.EffectiveFECOverhead
5022 / 100.0)
5023 * 270.0
5024 * mode_lib->vba.OutputLinkDPLanes[k]
5025 / mode_lib->vba.PixelClockBackEnd[k]
5026 * 8.0,
5027 true,
5028 mode_lib->vba.Output[k],
5029 mode_lib->vba.OutputFormat[k],
5030 mode_lib->vba.DSCInputBitPerComponent[k]);
5031 if (mode_lib->vba.DSCEnabled[k] == true) {
5032 mode_lib->vba.RequiresDSC[i][k] = true;
5033 if (mode_lib->vba.Output[k] == dm_dp) {
5034 mode_lib->vba.RequiresFEC[i][k] =
5035 true;
5036 } else {
5037 mode_lib->vba.RequiresFEC[i][k] =
5038 false;
5039 }
5040 mode_lib->vba.Outbpp =
5041 mode_lib->vba.OutbppDSC;
5042 } else {
5043 mode_lib->vba.RequiresDSC[i][k] = false;
5044 mode_lib->vba.RequiresFEC[i][k] = false;
5045 }
5046 mode_lib->vba.OutputBppPerState[i][k] =
5047 mode_lib->vba.Outbpp;
5048 }
5049 if (mode_lib->vba.Outbpp == 0) {
5050 mode_lib->vba.Outbpp =
5051 TruncToValidBPP(
5052 (1.0
5053 - mode_lib->vba.Downspreading
5054 / 100.0)
5055 * 540.0
5056 * mode_lib->vba.OutputLinkDPLanes[k]
5057 / mode_lib->vba.PixelClockBackEnd[k]
5058 * 8.0,
5059 false,
5060 mode_lib->vba.Output[k],
5061 mode_lib->vba.OutputFormat[k],
5062 mode_lib->vba.DSCInputBitPerComponent[k]);
5063 mode_lib->vba.OutbppDSC =
5064 TruncToValidBPP(
5065 (1.0
5066 - mode_lib->vba.Downspreading
5067 / 100.0)
5068 * (1.0
5069 - mode_lib->vba.EffectiveFECOverhead
5070 / 100.0)
5071 * 540.0
5072 * mode_lib->vba.OutputLinkDPLanes[k]
5073 / mode_lib->vba.PixelClockBackEnd[k]
5074 * 8.0,
5075 true,
5076 mode_lib->vba.Output[k],
5077 mode_lib->vba.OutputFormat[k],
5078 mode_lib->vba.DSCInputBitPerComponent[k]);
5079 if (mode_lib->vba.DSCEnabled[k] == true) {
5080 mode_lib->vba.RequiresDSC[i][k] = true;
5081 if (mode_lib->vba.Output[k] == dm_dp) {
5082 mode_lib->vba.RequiresFEC[i][k] =
5083 true;
5084 } else {
5085 mode_lib->vba.RequiresFEC[i][k] =
5086 false;
5087 }
5088 mode_lib->vba.Outbpp =
5089 mode_lib->vba.OutbppDSC;
5090 } else {
5091 mode_lib->vba.RequiresDSC[i][k] = false;
5092 mode_lib->vba.RequiresFEC[i][k] = false;
5093 }
5094 mode_lib->vba.OutputBppPerState[i][k] =
5095 mode_lib->vba.Outbpp;
5096 }
5097 if (mode_lib->vba.Outbpp == 0
5098 && mode_lib->vba.PHYCLKPerState[i]
5099 >= 810.0) {
5100 mode_lib->vba.Outbpp =
5101 TruncToValidBPP(
5102 (1.0
5103 - mode_lib->vba.Downspreading
5104 / 100.0)
5105 * 810.0
5106 * mode_lib->vba.OutputLinkDPLanes[k]
5107 / mode_lib->vba.PixelClockBackEnd[k]
5108 * 8.0,
5109 false,
5110 mode_lib->vba.Output[k],
5111 mode_lib->vba.OutputFormat[k],
5112 mode_lib->vba.DSCInputBitPerComponent[k]);
5113 mode_lib->vba.OutbppDSC =
5114 TruncToValidBPP(
5115 (1.0
5116 - mode_lib->vba.Downspreading
5117 / 100.0)
5118 * (1.0
5119 - mode_lib->vba.EffectiveFECOverhead
5120 / 100.0)
5121 * 810.0
5122 * mode_lib->vba.OutputLinkDPLanes[k]
5123 / mode_lib->vba.PixelClockBackEnd[k]
5124 * 8.0,
5125 true,
5126 mode_lib->vba.Output[k],
5127 mode_lib->vba.OutputFormat[k],
5128 mode_lib->vba.DSCInputBitPerComponent[k]);
5129 if (mode_lib->vba.DSCEnabled[k] == true
5130 || mode_lib->vba.Outbpp == 0) {
5131 mode_lib->vba.RequiresDSC[i][k] = true;
5132 if (mode_lib->vba.Output[k] == dm_dp) {
5133 mode_lib->vba.RequiresFEC[i][k] =
5134 true;
5135 } else {
5136 mode_lib->vba.RequiresFEC[i][k] =
5137 false;
5138 }
5139 mode_lib->vba.Outbpp =
5140 mode_lib->vba.OutbppDSC;
5141 } else {
5142 mode_lib->vba.RequiresDSC[i][k] = false;
5143 mode_lib->vba.RequiresFEC[i][k] = false;
5144 }
5145 mode_lib->vba.OutputBppPerState[i][k] =
5146 mode_lib->vba.Outbpp;
5147 }
5148 }
5149 } else {
5150 mode_lib->vba.OutputBppPerState[i][k] = 0;
5151 }
5152 }
5153 }
5154 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5155 mode_lib->vba.DIOSupport[i] = true;
5156 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5157 if (mode_lib->vba.OutputBppPerState[i][k] == 0
5158 || (mode_lib->vba.OutputFormat[k] == dm_420
5159 && mode_lib->vba.ProgressiveToInterlaceUnitInOPP
5160 == true)) {
5161 mode_lib->vba.DIOSupport[i] = false;
5162 }
5163 }
5164 }
5165 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5166 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5167 mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = false;
5168 if (mode_lib->vba.BlendingAndTiming[k] == k) {
5169 if ((mode_lib->vba.Output[k] == dm_dp
5170 || mode_lib->vba.Output[k] == dm_edp)) {
5171 if (mode_lib->vba.OutputFormat[k] == dm_420
5172 || mode_lib->vba.OutputFormat[k]
5173 == dm_n422) {
5174 mode_lib->vba.DSCFormatFactor = 2;
5175 } else {
5176 mode_lib->vba.DSCFormatFactor = 1;
5177 }
5178 if (mode_lib->vba.RequiresDSC[i][k] == true) {
5179 if (mode_lib->vba.ODMCombineEnablePerState[i][k]
5180 == true) {
5181 if (mode_lib->vba.PixelClockBackEnd[k] / 6.0
5182 / mode_lib->vba.DSCFormatFactor
5183 > (1.0
5184 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
5185 / 100.0)
5186 * mode_lib->vba.MaxDSCCLK[i]) {
5187 mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
5188 true;
5189 }
5190 } else {
5191 if (mode_lib->vba.PixelClockBackEnd[k] / 3.0
5192 / mode_lib->vba.DSCFormatFactor
5193 > (1.0
5194 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
5195 / 100.0)
5196 * mode_lib->vba.MaxDSCCLK[i]) {
5197 mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
5198 true;
5199 }
5200 }
5201 }
5202 }
5203 }
5204 }
5205 }
5206 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5207 mode_lib->vba.NotEnoughDSCUnits[i] = false;
5208 mode_lib->vba.TotalDSCUnitsRequired = 0.0;
5209 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5210 if (mode_lib->vba.RequiresDSC[i][k] == true) {
5211 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
5212 mode_lib->vba.TotalDSCUnitsRequired =
5213 mode_lib->vba.TotalDSCUnitsRequired + 2.0;
5214 } else {
5215 mode_lib->vba.TotalDSCUnitsRequired =
5216 mode_lib->vba.TotalDSCUnitsRequired + 1.0;
5217 }
5218 }
5219 }
5220 if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
5221 mode_lib->vba.NotEnoughDSCUnits[i] = true;
5222 }
5223 }
5224 /*DSC Delay per state*/
5225
5226 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5227 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5228 if (mode_lib->vba.BlendingAndTiming[k] != k) {
5229 mode_lib->vba.slices = 0;
5230 } else if (mode_lib->vba.RequiresDSC[i][k] == 0
5231 || mode_lib->vba.RequiresDSC[i][k] == false) {
5232 mode_lib->vba.slices = 0;
5233 } else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
5234 mode_lib->vba.slices = dml_ceil(
5235 mode_lib->vba.PixelClockBackEnd[k] / 400.0,
5236 4.0);
5237 } else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
5238 mode_lib->vba.slices = 8.0;
5239 } else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
5240 mode_lib->vba.slices = 4.0;
5241 } else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
5242 mode_lib->vba.slices = 2.0;
5243 } else {
5244 mode_lib->vba.slices = 1.0;
5245 }
5246 if (mode_lib->vba.OutputBppPerState[i][k] == 0
5247 || mode_lib->vba.OutputBppPerState[i][k] == 0) {
5248 mode_lib->vba.bpp = 0.0;
5249 } else {
5250 mode_lib->vba.bpp = mode_lib->vba.OutputBppPerState[i][k];
5251 }
5252 if (mode_lib->vba.RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
5253 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
5254 mode_lib->vba.DSCDelayPerState[i][k] =
5255 dscceComputeDelay(
5256 mode_lib->vba.DSCInputBitPerComponent[k],
5257 mode_lib->vba.bpp,
5258 dml_ceil(
5259 mode_lib->vba.HActive[k]
5260 / mode_lib->vba.slices,
5261 1.0),
5262 mode_lib->vba.slices,
5263 mode_lib->vba.OutputFormat[k])
5264 + dscComputeDelay(
5265 mode_lib->vba.OutputFormat[k]);
5266 } else {
5267 mode_lib->vba.DSCDelayPerState[i][k] =
5268 2.0
5269 * (dscceComputeDelay(
5270 mode_lib->vba.DSCInputBitPerComponent[k],
5271 mode_lib->vba.bpp,
5272 dml_ceil(
5273 mode_lib->vba.HActive[k]
5274 / mode_lib->vba.slices,
5275 1.0),
5276 mode_lib->vba.slices
5277 / 2,
5278 mode_lib->vba.OutputFormat[k])
5279 + dscComputeDelay(
5280 mode_lib->vba.OutputFormat[k]));
5281 }
5282 mode_lib->vba.DSCDelayPerState[i][k] =
5283 mode_lib->vba.DSCDelayPerState[i][k]
5284 * mode_lib->vba.PixelClock[k]
5285 / mode_lib->vba.PixelClockBackEnd[k];
5286 } else {
5287 mode_lib->vba.DSCDelayPerState[i][k] = 0.0;
5288 }
5289 }
5290 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5291 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
5292 if (mode_lib->vba.BlendingAndTiming[k] == j
5293 && mode_lib->vba.RequiresDSC[i][j] == true) {
5294 mode_lib->vba.DSCDelayPerState[i][k] =
5295 mode_lib->vba.DSCDelayPerState[i][j];
5296 }
5297 }
5298 }
5299 }
5300 /*Urgent Latency Support Check*/
5301
5302 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5303 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5304 if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
5305 mode_lib->vba.SwathWidthYPerState[i][k] =
5306 dml_min(
5307 mode_lib->vba.SwathWidthYSingleDPP[k],
5308 dml_round(
5309 mode_lib->vba.HActive[k]
5310 / 2.0
5311 * mode_lib->vba.HRatio[k]));
5312 } else {
5313 mode_lib->vba.SwathWidthYPerState[i][k] =
5314 mode_lib->vba.SwathWidthYSingleDPP[k]
5315 / mode_lib->vba.NoOfDPP[i][k];
5316 }
5317 mode_lib->vba.SwathWidthGranularityY = 256.0
5318 / dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
5319 / mode_lib->vba.MaxSwathHeightY[k];
5320 mode_lib->vba.RoundedUpMaxSwathSizeBytesY = (dml_ceil(
5321 mode_lib->vba.SwathWidthYPerState[i][k] - 1.0,
5322 mode_lib->vba.SwathWidthGranularityY)
5323 + mode_lib->vba.SwathWidthGranularityY)
5324 * mode_lib->vba.BytePerPixelInDETY[k]
5325 * mode_lib->vba.MaxSwathHeightY[k];
5326 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
5327 mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil(
5328 mode_lib->vba.RoundedUpMaxSwathSizeBytesY,
5329 256.0) + 256;
5330 }
5331 if (mode_lib->vba.MaxSwathHeightC[k] > 0.0) {
5332 mode_lib->vba.SwathWidthGranularityC = 256.0
5333 / dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
5334 / mode_lib->vba.MaxSwathHeightC[k];
5335 mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil(
5336 mode_lib->vba.SwathWidthYPerState[i][k] / 2.0 - 1.0,
5337 mode_lib->vba.SwathWidthGranularityC)
5338 + mode_lib->vba.SwathWidthGranularityC)
5339 * mode_lib->vba.BytePerPixelInDETC[k]
5340 * mode_lib->vba.MaxSwathHeightC[k];
5341 if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
5342 mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil(
5343 mode_lib->vba.RoundedUpMaxSwathSizeBytesC,
5344 256.0) + 256;
5345 }
5346 } else {
5347 mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0;
5348 }
5349 if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY
5350 + mode_lib->vba.RoundedUpMaxSwathSizeBytesC
5351 <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
5352 mode_lib->vba.SwathHeightYPerState[i][k] =
5353 mode_lib->vba.MaxSwathHeightY[k];
5354 mode_lib->vba.SwathHeightCPerState[i][k] =
5355 mode_lib->vba.MaxSwathHeightC[k];
5356 } else {
5357 mode_lib->vba.SwathHeightYPerState[i][k] =
5358 mode_lib->vba.MinSwathHeightY[k];
5359 mode_lib->vba.SwathHeightCPerState[i][k] =
5360 mode_lib->vba.MinSwathHeightC[k];
5361 }
5362 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
5363 mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
5364 * 1024.0 / mode_lib->vba.BytePerPixelInDETY[k]
5365 / mode_lib->vba.SwathWidthYPerState[i][k];
5366 mode_lib->vba.LinesInDETChroma = 0.0;
5367 } else if (mode_lib->vba.SwathHeightYPerState[i][k]
5368 <= mode_lib->vba.SwathHeightCPerState[i][k]) {
5369 mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
5370 * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETY[k]
5371 / mode_lib->vba.SwathWidthYPerState[i][k];
5372 mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
5373 * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETC[k]
5374 / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
5375 } else {
5376 mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
5377 * 1024.0 * 2.0 / 3.0
5378 / mode_lib->vba.BytePerPixelInDETY[k]
5379 / mode_lib->vba.SwathWidthYPerState[i][k];
5380 mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
5381 * 1024.0 / 3.0 / mode_lib->vba.BytePerPixelInDETY[k]
5382 / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
5383 }
5384 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma =
5385 dml_min(
5386 mode_lib->vba.MaxLineBufferLines,
5387 dml_floor(
5388 mode_lib->vba.LineBufferSize
5389 / mode_lib->vba.LBBitPerPixel[k]
5390 / (mode_lib->vba.SwathWidthYPerState[i][k]
5391 / dml_max(
5392 mode_lib->vba.HRatio[k],
5393 1.0)),
5394 1.0))
5395 - (mode_lib->vba.vtaps[k] - 1.0);
5396 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma =
5397 dml_min(
5398 mode_lib->vba.MaxLineBufferLines,
5399 dml_floor(
5400 mode_lib->vba.LineBufferSize
5401 / mode_lib->vba.LBBitPerPixel[k]
5402 / (mode_lib->vba.SwathWidthYPerState[i][k]
5403 / 2.0
5404 / dml_max(
5405 mode_lib->vba.HRatio[k]
5406 / 2.0,
5407 1.0)),
5408 1.0))
5409 - (mode_lib->vba.VTAPsChroma[k] - 1.0);
5410 mode_lib->vba.EffectiveDETLBLinesLuma =
5411 dml_floor(
5412 mode_lib->vba.LinesInDETLuma
5413 + dml_min(
5414 mode_lib->vba.LinesInDETLuma
5415 * mode_lib->vba.RequiredDISPCLK[i]
5416 * mode_lib->vba.BytePerPixelInDETY[k]
5417 * mode_lib->vba.PSCL_FACTOR[k]
5418 / mode_lib->vba.ReturnBWPerState[i],
5419 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
5420 mode_lib->vba.SwathHeightYPerState[i][k]);
5421 mode_lib->vba.EffectiveDETLBLinesChroma =
5422 dml_floor(
5423 mode_lib->vba.LinesInDETChroma
5424 + dml_min(
5425 mode_lib->vba.LinesInDETChroma
5426 * mode_lib->vba.RequiredDISPCLK[i]
5427 * mode_lib->vba.BytePerPixelInDETC[k]
5428 * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
5429 / mode_lib->vba.ReturnBWPerState[i],
5430 mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
5431 mode_lib->vba.SwathHeightCPerState[i][k]);
5432 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
5433 mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
5434 mode_lib->vba.EffectiveDETLBLinesLuma
5435 * (mode_lib->vba.HTotal[k]
5436 / mode_lib->vba.PixelClock[k])
5437 / mode_lib->vba.VRatio[k]
5438 - mode_lib->vba.EffectiveDETLBLinesLuma
5439 * mode_lib->vba.SwathWidthYPerState[i][k]
5440 * dml_ceil(
5441 mode_lib->vba.BytePerPixelInDETY[k],
5442 1.0)
5443 / (mode_lib->vba.ReturnBWPerState[i]
5444 / mode_lib->vba.NoOfDPP[i][k]);
5445 } else {
5446 mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
5447 dml_min(
5448 mode_lib->vba.EffectiveDETLBLinesLuma
5449 * (mode_lib->vba.HTotal[k]
5450 / mode_lib->vba.PixelClock[k])
5451 / mode_lib->vba.VRatio[k]
5452 - mode_lib->vba.EffectiveDETLBLinesLuma
5453 * mode_lib->vba.SwathWidthYPerState[i][k]
5454 * dml_ceil(
5455 mode_lib->vba.BytePerPixelInDETY[k],
5456 1.0)
5457 / (mode_lib->vba.ReturnBWPerState[i]
5458 / mode_lib->vba.NoOfDPP[i][k]),
5459 mode_lib->vba.EffectiveDETLBLinesChroma
5460 * (mode_lib->vba.HTotal[k]
5461 / mode_lib->vba.PixelClock[k])
5462 / (mode_lib->vba.VRatio[k]
5463 / 2.0)
5464 - mode_lib->vba.EffectiveDETLBLinesChroma
5465 * mode_lib->vba.SwathWidthYPerState[i][k]
5466 / 2.0
5467 * dml_ceil(
5468 mode_lib->vba.BytePerPixelInDETC[k],
5469 2.0)
5470 / (mode_lib->vba.ReturnBWPerState[i]
5471 / mode_lib->vba.NoOfDPP[i][k]));
5472 }
5473 }
5474 }
5475 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5476 mode_lib->vba.UrgentLatencySupport[i] = true;
5477 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5478 if (mode_lib->vba.UrgentLatencySupportUsPerState[i][k]
5479 < mode_lib->vba.UrgentLatency / 1.0) {
5480 mode_lib->vba.UrgentLatencySupport[i] = false;
5481 }
5482 }
5483 }
5484 /*Prefetch Check*/
5485
5486 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5487 mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = 0.0;
5488 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5489 if (mode_lib->vba.DCCEnable[k] == true) {
5490 mode_lib->vba.TotalNumberOfDCCActiveDPP[i] =
5491 mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
5492 + mode_lib->vba.NoOfDPP[i][k];
5493 }
5494 }
5495 }
5496 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5497 mode_lib->vba.ProjectedDCFCLKDeepSleep = 8.0;
5498 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5499 mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
5500 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5501 mode_lib->vba.PixelClock[k] / 16.0);
5502 if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
5503 if (mode_lib->vba.VRatio[k] <= 1.0) {
5504 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5505 dml_max(
5506 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5507 1.1
5508 * dml_ceil(
5509 mode_lib->vba.BytePerPixelInDETY[k],
5510 1.0)
5511 / 64.0
5512 * mode_lib->vba.HRatio[k]
5513 * mode_lib->vba.PixelClock[k]
5514 / mode_lib->vba.NoOfDPP[i][k]);
5515 } else {
5516 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5517 dml_max(
5518 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5519 1.1
5520 * dml_ceil(
5521 mode_lib->vba.BytePerPixelInDETY[k],
5522 1.0)
5523 / 64.0
5524 * mode_lib->vba.PSCL_FACTOR[k]
5525 * mode_lib->vba.RequiredDPPCLK[i][k]);
5526 }
5527 } else {
5528 if (mode_lib->vba.VRatio[k] <= 1.0) {
5529 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5530 dml_max(
5531 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5532 1.1
5533 * dml_ceil(
5534 mode_lib->vba.BytePerPixelInDETY[k],
5535 1.0)
5536 / 32.0
5537 * mode_lib->vba.HRatio[k]
5538 * mode_lib->vba.PixelClock[k]
5539 / mode_lib->vba.NoOfDPP[i][k]);
5540 } else {
5541 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5542 dml_max(
5543 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5544 1.1
5545 * dml_ceil(
5546 mode_lib->vba.BytePerPixelInDETY[k],
5547 1.0)
5548 / 32.0
5549 * mode_lib->vba.PSCL_FACTOR[k]
5550 * mode_lib->vba.RequiredDPPCLK[i][k]);
5551 }
5552 if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
5553 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5554 dml_max(
5555 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5556 1.1
5557 * dml_ceil(
5558 mode_lib->vba.BytePerPixelInDETC[k],
5559 2.0)
5560 / 32.0
5561 * mode_lib->vba.HRatio[k]
5562 / 2.0
5563 * mode_lib->vba.PixelClock[k]
5564 / mode_lib->vba.NoOfDPP[i][k]);
5565 } else {
5566 mode_lib->vba.ProjectedDCFCLKDeepSleep =
5567 dml_max(
5568 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5569 1.1
5570 * dml_ceil(
5571 mode_lib->vba.BytePerPixelInDETC[k],
5572 2.0)
5573 / 32.0
5574 * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
5575 * mode_lib->vba.RequiredDPPCLK[i][k]);
5576 }
5577 }
5578 }
5579 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5580 mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
5581 mode_lib,
5582 mode_lib->vba.DCCEnable[k],
5583 mode_lib->vba.Read256BlockHeightY[k],
5584 mode_lib->vba.Read256BlockWidthY[k],
5585 mode_lib->vba.SourcePixelFormat[k],
5586 mode_lib->vba.SurfaceTiling[k],
5587 dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
5588 mode_lib->vba.SourceScan[k],
5589 mode_lib->vba.ViewportWidth[k],
5590 mode_lib->vba.ViewportHeight[k],
5591 mode_lib->vba.SwathWidthYPerState[i][k],
5592 mode_lib->vba.VirtualMemoryEnable,
5593 mode_lib->vba.VMMPageSize,
5594 mode_lib->vba.PTEBufferSizeInRequests,
5595 mode_lib->vba.PDEProcessingBufIn64KBReqs,
5596 mode_lib->vba.PitchY[k],
5597 mode_lib->vba.DCCMetaPitchY[k],
5598 &mode_lib->vba.MacroTileWidthY[k],
5599 &mode_lib->vba.MetaRowBytesY,
5600 &mode_lib->vba.DPTEBytesPerRowY,
5601 &mode_lib->vba.PTEBufferSizeNotExceededY[i][k],
5602 &mode_lib->vba.dpte_row_height[k],
5603 &mode_lib->vba.meta_row_height[k]);
5604 mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
5605 mode_lib,
5606 mode_lib->vba.VRatio[k],
5607 mode_lib->vba.vtaps[k],
5608 mode_lib->vba.Interlace[k],
5609 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
5610 mode_lib->vba.SwathHeightYPerState[i][k],
5611 mode_lib->vba.ViewportYStartY[k],
5612 &mode_lib->vba.PrefillY[k],
5613 &mode_lib->vba.MaxNumSwY[k]);
5614 if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
5615 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
5616 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
5617 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
5618 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
5619 mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
5620 mode_lib,
5621 mode_lib->vba.DCCEnable[k],
5622 mode_lib->vba.Read256BlockHeightY[k],
5623 mode_lib->vba.Read256BlockWidthY[k],
5624 mode_lib->vba.SourcePixelFormat[k],
5625 mode_lib->vba.SurfaceTiling[k],
5626 dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
5627 mode_lib->vba.SourceScan[k],
5628 mode_lib->vba.ViewportWidth[k] / 2.0,
5629 mode_lib->vba.ViewportHeight[k] / 2.0,
5630 mode_lib->vba.SwathWidthYPerState[i][k] / 2.0,
5631 mode_lib->vba.VirtualMemoryEnable,
5632 mode_lib->vba.VMMPageSize,
5633 mode_lib->vba.PTEBufferSizeInRequests,
5634 mode_lib->vba.PDEProcessingBufIn64KBReqs,
5635 mode_lib->vba.PitchC[k],
5636 0.0,
5637 &mode_lib->vba.MacroTileWidthC[k],
5638 &mode_lib->vba.MetaRowBytesC,
5639 &mode_lib->vba.DPTEBytesPerRowC,
5640 &mode_lib->vba.PTEBufferSizeNotExceededC[i][k],
5641 &mode_lib->vba.dpte_row_height_chroma[k],
5642 &mode_lib->vba.meta_row_height_chroma[k]);
5643 mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
5644 mode_lib,
5645 mode_lib->vba.VRatio[k] / 2.0,
5646 mode_lib->vba.VTAPsChroma[k],
5647 mode_lib->vba.Interlace[k],
5648 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
5649 mode_lib->vba.SwathHeightCPerState[i][k],
5650 mode_lib->vba.ViewportYStartC[k],
5651 &mode_lib->vba.PrefillC[k],
5652 &mode_lib->vba.MaxNumSwC[k]);
5653 } else {
5654 mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
5655 mode_lib->vba.MetaRowBytesC = 0.0;
5656 mode_lib->vba.DPTEBytesPerRowC = 0.0;
5657 mode_lib->vba.PrefetchLinesC[k] = 0.0;
5658 mode_lib->vba.PTEBufferSizeNotExceededC[i][k] = true;
5659 }
5660 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] =
5661 mode_lib->vba.PDEAndMetaPTEBytesPerFrameY
5662 + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
5663 mode_lib->vba.MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY
5664 + mode_lib->vba.MetaRowBytesC;
5665 mode_lib->vba.DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY
5666 + mode_lib->vba.DPTEBytesPerRowC;
5667 }
5668 mode_lib->vba.ExtraLatency =
5669 mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
5670 + (mode_lib->vba.TotalNumberOfActiveDPP[i]
5671 * mode_lib->vba.PixelChunkSizeInKByte
5672 + mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
5673 * mode_lib->vba.MetaChunkSize)
5674 * 1024.0
5675 / mode_lib->vba.ReturnBWPerState[i];
5676 if (mode_lib->vba.VirtualMemoryEnable == true) {
5677 mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
5678 + mode_lib->vba.TotalNumberOfActiveDPP[i]
5679 * mode_lib->vba.PTEChunkSize * 1024.0
5680 / mode_lib->vba.ReturnBWPerState[i];
5681 }
5682 mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
5683 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5684 if (mode_lib->vba.BlendingAndTiming[k] == k) {
5685 if (mode_lib->vba.WritebackEnable[k] == true) {
5686 mode_lib->vba.WritebackDelay[i][k] =
5687 mode_lib->vba.WritebackLatency
5688 + CalculateWriteBackDelay(
5689 mode_lib->vba.WritebackPixelFormat[k],
5690 mode_lib->vba.WritebackHRatio[k],
5691 mode_lib->vba.WritebackVRatio[k],
5692 mode_lib->vba.WritebackLumaHTaps[k],
5693 mode_lib->vba.WritebackLumaVTaps[k],
5694 mode_lib->vba.WritebackChromaHTaps[k],
5695 mode_lib->vba.WritebackChromaVTaps[k],
5696 mode_lib->vba.WritebackDestinationWidth[k])
5697 / mode_lib->vba.RequiredDISPCLK[i];
5698 } else {
5699 mode_lib->vba.WritebackDelay[i][k] = 0.0;
5700 }
5701 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
5702 if (mode_lib->vba.BlendingAndTiming[j] == k
5703 && mode_lib->vba.WritebackEnable[j]
5704 == true) {
5705 mode_lib->vba.WritebackDelay[i][k] =
5706 dml_max(
5707 mode_lib->vba.WritebackDelay[i][k],
5708 mode_lib->vba.WritebackLatency
5709 + CalculateWriteBackDelay(
5710 mode_lib->vba.WritebackPixelFormat[j],
5711 mode_lib->vba.WritebackHRatio[j],
5712 mode_lib->vba.WritebackVRatio[j],
5713 mode_lib->vba.WritebackLumaHTaps[j],
5714 mode_lib->vba.WritebackLumaVTaps[j],
5715 mode_lib->vba.WritebackChromaHTaps[j],
5716 mode_lib->vba.WritebackChromaVTaps[j],
5717 mode_lib->vba.WritebackDestinationWidth[j])
5718 / mode_lib->vba.RequiredDISPCLK[i]);
5719 }
5720 }
5721 }
5722 }
5723 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5724 for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
5725 if (mode_lib->vba.BlendingAndTiming[k] == j) {
5726 mode_lib->vba.WritebackDelay[i][k] =
5727 mode_lib->vba.WritebackDelay[i][j];
5728 }
5729 }
5730 }
5731 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5732 mode_lib->vba.MaximumVStartup[k] =
5733 mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
5734 - dml_max(
5735 1.0,
5736 dml_ceil(
5737 mode_lib->vba.WritebackDelay[i][k]
5738 / (mode_lib->vba.HTotal[k]
5739 / mode_lib->vba.PixelClock[k]),
5740 1.0));
5741 }
5742 mode_lib->vba.TWait = CalculateTWait(
5743 mode_lib->vba.PrefetchMode,
5744 mode_lib->vba.DRAMClockChangeLatency,
5745 mode_lib->vba.UrgentLatency,
5746 mode_lib->vba.SREnterPlusExitTime);
5747 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5748 if (mode_lib->vba.XFCEnabled[k] == true) {
5749 mode_lib->vba.XFCRemoteSurfaceFlipDelay =
5750 CalculateRemoteSurfaceFlipDelay(
5751 mode_lib,
5752 mode_lib->vba.VRatio[k],
5753 mode_lib->vba.SwathWidthYPerState[i][k],
5754 dml_ceil(
5755 mode_lib->vba.BytePerPixelInDETY[k],
5756 1.0),
5757 mode_lib->vba.HTotal[k]
5758 / mode_lib->vba.PixelClock[k],
5759 mode_lib->vba.XFCTSlvVupdateOffset,
5760 mode_lib->vba.XFCTSlvVupdateWidth,
5761 mode_lib->vba.XFCTSlvVreadyOffset,
5762 mode_lib->vba.XFCXBUFLatencyTolerance,
5763 mode_lib->vba.XFCFillBWOverhead,
5764 mode_lib->vba.XFCSlvChunkSize,
5765 mode_lib->vba.XFCBusTransportTime,
5766 mode_lib->vba.TimeCalc,
5767 mode_lib->vba.TWait,
5768 &mode_lib->vba.SrcActiveDrainRate,
5769 &mode_lib->vba.TInitXFill,
5770 &mode_lib->vba.TslvChk);
5771 } else {
5772 mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
5773 }
5774 mode_lib->vba.IsErrorResult[i][k] =
5775 CalculatePrefetchSchedule(
5776 mode_lib,
5777 mode_lib->vba.RequiredDPPCLK[i][k],
5778 mode_lib->vba.RequiredDISPCLK[i],
5779 mode_lib->vba.PixelClock[k],
5780 mode_lib->vba.ProjectedDCFCLKDeepSleep,
5781 mode_lib->vba.DSCDelayPerState[i][k],
5782 mode_lib->vba.NoOfDPP[i][k],
5783 mode_lib->vba.ScalerEnabled[k],
5784 mode_lib->vba.NumberOfCursors[k],
5785 mode_lib->vba.DPPCLKDelaySubtotal,
5786 mode_lib->vba.DPPCLKDelaySCL,
5787 mode_lib->vba.DPPCLKDelaySCLLBOnly,
5788 mode_lib->vba.DPPCLKDelayCNVCFormater,
5789 mode_lib->vba.DPPCLKDelayCNVCCursor,
5790 mode_lib->vba.DISPCLKDelaySubtotal,
5791 mode_lib->vba.SwathWidthYPerState[i][k]
5792 / mode_lib->vba.HRatio[k],
5793 mode_lib->vba.OutputFormat[k],
5794 mode_lib->vba.VTotal[k]
5795 - mode_lib->vba.VActive[k],
5796 mode_lib->vba.HTotal[k],
5797 mode_lib->vba.MaxInterDCNTileRepeaters,
5798 mode_lib->vba.MaximumVStartup[k],
5799 mode_lib->vba.MaxPageTableLevels,
5800 mode_lib->vba.VirtualMemoryEnable,
5801 mode_lib->vba.DynamicMetadataEnable[k],
5802 mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
5803 mode_lib->vba.DynamicMetadataTransmittedBytes[k],
5804 mode_lib->vba.DCCEnable[k],
5805 mode_lib->vba.UrgentLatency,
5806 mode_lib->vba.ExtraLatency,
5807 mode_lib->vba.TimeCalc,
5808 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
5809 mode_lib->vba.MetaRowBytes[k],
5810 mode_lib->vba.DPTEBytesPerRow[k],
5811 mode_lib->vba.PrefetchLinesY[k],
5812 mode_lib->vba.SwathWidthYPerState[i][k],
5813 mode_lib->vba.BytePerPixelInDETY[k],
5814 mode_lib->vba.PrefillY[k],
5815 mode_lib->vba.MaxNumSwY[k],
5816 mode_lib->vba.PrefetchLinesC[k],
5817 mode_lib->vba.BytePerPixelInDETC[k],
5818 mode_lib->vba.PrefillC[k],
5819 mode_lib->vba.MaxNumSwC[k],
5820 mode_lib->vba.SwathHeightYPerState[i][k],
5821 mode_lib->vba.SwathHeightCPerState[i][k],
5822 mode_lib->vba.TWait,
5823 mode_lib->vba.XFCEnabled[k],
5824 mode_lib->vba.XFCRemoteSurfaceFlipDelay,
5825 mode_lib->vba.Interlace[k],
5826 mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
5827 mode_lib->vba.DSTXAfterScaler,
5828 mode_lib->vba.DSTYAfterScaler,
5829 &mode_lib->vba.LineTimesForPrefetch[k],
5830 &mode_lib->vba.PrefetchBW[k],
5831 &mode_lib->vba.LinesForMetaPTE[k],
5832 &mode_lib->vba.LinesForMetaAndDPTERow[k],
5833 &mode_lib->vba.VRatioPreY[i][k],
5834 &mode_lib->vba.VRatioPreC[i][k],
5835 &mode_lib->vba.RequiredPrefetchPixelDataBW[i][k],
5836 &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
5837 &mode_lib->vba.Tno_bw[k],
5838 &mode_lib->vba.VUpdateOffsetPix[k],
5839 &mode_lib->vba.VUpdateWidthPix[k],
5840 &mode_lib->vba.VReadyOffsetPix[k]);
5841 }
5842 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5843 mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k]
5844 * mode_lib->vba.CursorWidth[k][0]
5845 * mode_lib->vba.CursorBPP[k][0] / 8.0
5846 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
5847 * mode_lib->vba.VRatio[k];
5848 }
5849 mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
5850 mode_lib->vba.prefetch_vm_bw_valid = true;
5851 mode_lib->vba.prefetch_row_bw_valid = true;
5852 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5853 if (mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] == 0.0) {
5854 mode_lib->vba.prefetch_vm_bw[k] = 0.0;
5855 } else if (mode_lib->vba.LinesForMetaPTE[k] > 0.0) {
5856 mode_lib->vba.prefetch_vm_bw[k] =
5857 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
5858 / (mode_lib->vba.LinesForMetaPTE[k]
5859 * mode_lib->vba.HTotal[k]
5860 / mode_lib->vba.PixelClock[k]);
5861 } else {
5862 mode_lib->vba.prefetch_vm_bw[k] = 0.0;
5863 mode_lib->vba.prefetch_vm_bw_valid = false;
5864 }
5865 if (mode_lib->vba.MetaRowBytes[k] + mode_lib->vba.DPTEBytesPerRow[k]
5866 == 0.0) {
5867 mode_lib->vba.prefetch_row_bw[k] = 0.0;
5868 } else if (mode_lib->vba.LinesForMetaAndDPTERow[k] > 0.0) {
5869 mode_lib->vba.prefetch_row_bw[k] = (mode_lib->vba.MetaRowBytes[k]
5870 + mode_lib->vba.DPTEBytesPerRow[k])
5871 / (mode_lib->vba.LinesForMetaAndDPTERow[k]
5872 * mode_lib->vba.HTotal[k]
5873 / mode_lib->vba.PixelClock[k]);
5874 } else {
5875 mode_lib->vba.prefetch_row_bw[k] = 0.0;
5876 mode_lib->vba.prefetch_row_bw_valid = false;
5877 }
5878 mode_lib->vba.MaximumReadBandwidthWithPrefetch =
5879 mode_lib->vba.MaximumReadBandwidthWithPrefetch
5880 + mode_lib->vba.cursor_bw[k]
5881 + dml_max4(
5882 mode_lib->vba.prefetch_vm_bw[k],
5883 mode_lib->vba.prefetch_row_bw[k],
5884 mode_lib->vba.ReadBandwidth[k],
5885 mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]);
5886 }
5887 mode_lib->vba.PrefetchSupported[i] = true;
5888 if (mode_lib->vba.MaximumReadBandwidthWithPrefetch
5889 > mode_lib->vba.ReturnBWPerState[i]
5890 || mode_lib->vba.prefetch_vm_bw_valid == false
5891 || mode_lib->vba.prefetch_row_bw_valid == false) {
5892 mode_lib->vba.PrefetchSupported[i] = false;
5893 }
5894 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5895 if (mode_lib->vba.LineTimesForPrefetch[k] < 2.0
5896 || mode_lib->vba.LinesForMetaPTE[k] >= 8.0
5897 || mode_lib->vba.LinesForMetaAndDPTERow[k] >= 16.0
5898 || mode_lib->vba.IsErrorResult[i][k] == true) {
5899 mode_lib->vba.PrefetchSupported[i] = false;
5900 }
5901 }
5902 mode_lib->vba.VRatioInPrefetchSupported[i] = true;
5903 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5904 if (mode_lib->vba.VRatioPreY[i][k] > 4.0
5905 || mode_lib->vba.VRatioPreC[i][k] > 4.0
5906 || mode_lib->vba.IsErrorResult[i][k] == true) {
5907 mode_lib->vba.VRatioInPrefetchSupported[i] = false;
5908 }
5909 }
5910 if (mode_lib->vba.PrefetchSupported[i] == true
5911 && mode_lib->vba.VRatioInPrefetchSupported[i] == true) {
5912 mode_lib->vba.BandwidthAvailableForImmediateFlip =
5913 mode_lib->vba.ReturnBWPerState[i];
5914 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5915 mode_lib->vba.BandwidthAvailableForImmediateFlip =
5916 mode_lib->vba.BandwidthAvailableForImmediateFlip
5917 - mode_lib->vba.cursor_bw[k]
5918 - dml_max(
5919 mode_lib->vba.ReadBandwidth[k],
5920 mode_lib->vba.PrefetchBW[k]);
5921 }
5922 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5923 mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
5924 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
5925 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
5926 mode_lib->vba.ImmediateFlipBytes[k] =
5927 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
5928 + mode_lib->vba.MetaRowBytes[k]
5929 + mode_lib->vba.DPTEBytesPerRow[k];
5930 }
5931 }
5932 mode_lib->vba.TotImmediateFlipBytes = 0.0;
5933 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5934 if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
5935 && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
5936 mode_lib->vba.TotImmediateFlipBytes =
5937 mode_lib->vba.TotImmediateFlipBytes
5938 + mode_lib->vba.ImmediateFlipBytes[k];
5939 }
5940 }
5941 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5942 CalculateFlipSchedule(
5943 mode_lib,
5944 mode_lib->vba.ExtraLatency,
5945 mode_lib->vba.UrgentLatency,
5946 mode_lib->vba.MaxPageTableLevels,
5947 mode_lib->vba.VirtualMemoryEnable,
5948 mode_lib->vba.BandwidthAvailableForImmediateFlip,
5949 mode_lib->vba.TotImmediateFlipBytes,
5950 mode_lib->vba.SourcePixelFormat[k],
5951 mode_lib->vba.ImmediateFlipBytes[k],
5952 mode_lib->vba.HTotal[k]
5953 / mode_lib->vba.PixelClock[k],
5954 mode_lib->vba.VRatio[k],
5955 mode_lib->vba.Tno_bw[k],
5956 mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
5957 mode_lib->vba.MetaRowBytes[k],
5958 mode_lib->vba.DPTEBytesPerRow[k],
5959 mode_lib->vba.DCCEnable[k],
5960 mode_lib->vba.dpte_row_height[k],
5961 mode_lib->vba.meta_row_height[k],
5962 mode_lib->vba.qual_row_bw[k],
5963 &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
5964 &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
5965 &mode_lib->vba.final_flip_bw[k],
5966 &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
5967 }
5968 mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
5969 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5970 mode_lib->vba.total_dcn_read_bw_with_flip =
5971 mode_lib->vba.total_dcn_read_bw_with_flip
5972 + mode_lib->vba.cursor_bw[k]
5973 + dml_max3(
5974 mode_lib->vba.prefetch_vm_bw[k],
5975 mode_lib->vba.prefetch_row_bw[k],
5976 mode_lib->vba.final_flip_bw[k]
5977 + dml_max(
5978 mode_lib->vba.ReadBandwidth[k],
5979 mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]));
5980 }
5981 mode_lib->vba.ImmediateFlipSupportedForState[i] = true;
5982 if (mode_lib->vba.total_dcn_read_bw_with_flip
5983 > mode_lib->vba.ReturnBWPerState[i]) {
5984 mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
5985 }
5986 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
5987 if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
5988 mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
5989 }
5990 }
5991 } else {
5992 mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
5993 }
5994 }
5995 /*PTE Buffer Size Check*/
5996
5997 for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
5998 mode_lib->vba.PTEBufferSizeNotExceeded[i] = true;
5999 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6000 if (mode_lib->vba.PTEBufferSizeNotExceededY[i][k] == false
6001 || mode_lib->vba.PTEBufferSizeNotExceededC[i][k] == false) {
6002 mode_lib->vba.PTEBufferSizeNotExceeded[i] = false;
6003 }
6004 }
6005 }
6006 /*Cursor Support Check*/
6007
6008 mode_lib->vba.CursorSupport = true;
6009 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6010 if (mode_lib->vba.CursorWidth[k][0] > 0.0) {
6011 if (dml_floor(
6012 dml_floor(
6013 mode_lib->vba.CursorBufferSize
6014 - mode_lib->vba.CursorChunkSize,
6015 mode_lib->vba.CursorChunkSize) * 1024.0
6016 / (mode_lib->vba.CursorWidth[k][0]
6017 * mode_lib->vba.CursorBPP[k][0]
6018 / 8.0),
6019 1.0)
6020 * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
6021 / mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatency
6022 || (mode_lib->vba.CursorBPP[k][0] == 64.0
6023 && mode_lib->vba.Cursor64BppSupport == false)) {
6024 mode_lib->vba.CursorSupport = false;
6025 }
6026 }
6027 }
6028 /*Valid Pitch Check*/
6029
6030 mode_lib->vba.PitchSupport = true;
6031 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6032 mode_lib->vba.AlignedYPitch[k] = dml_ceil(
6033 dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
6034 mode_lib->vba.MacroTileWidthY[k]);
6035 if (mode_lib->vba.AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
6036 mode_lib->vba.PitchSupport = false;
6037 }
6038 if (mode_lib->vba.DCCEnable[k] == true) {
6039 mode_lib->vba.AlignedDCCMetaPitch[k] = dml_ceil(
6040 dml_max(
6041 mode_lib->vba.DCCMetaPitchY[k],
6042 mode_lib->vba.ViewportWidth[k]),
6043 64.0 * mode_lib->vba.Read256BlockWidthY[k]);
6044 } else {
6045 mode_lib->vba.AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
6046 }
6047 if (mode_lib->vba.AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
6048 mode_lib->vba.PitchSupport = false;
6049 }
6050 if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
6051 && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
6052 && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
6053 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
6054 && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
6055 mode_lib->vba.AlignedCPitch[k] = dml_ceil(
6056 dml_max(
6057 mode_lib->vba.PitchC[k],
6058 mode_lib->vba.ViewportWidth[k] / 2.0),
6059 mode_lib->vba.MacroTileWidthC[k]);
6060 } else {
6061 mode_lib->vba.AlignedCPitch[k] = mode_lib->vba.PitchC[k];
6062 }
6063 if (mode_lib->vba.AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
6064 mode_lib->vba.PitchSupport = false;
6065 }
6066 }
6067 /*Mode Support, Voltage State and SOC Configuration*/
6068
6069 for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
6070 if (mode_lib->vba.ScaleRatioAndTapsSupport == true
6071 && mode_lib->vba.SourceFormatPixelAndScanSupport == true
6072 && mode_lib->vba.ViewportSizeSupport[i] == true
6073 && mode_lib->vba.BandwidthSupport[i] == true
6074 && mode_lib->vba.DIOSupport[i] == true
6075 && mode_lib->vba.NotEnoughDSCUnits[i] == false
6076 && mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] == false
6077 && mode_lib->vba.UrgentLatencySupport[i] == true
6078 && mode_lib->vba.ROBSupport[i] == true
6079 && mode_lib->vba.DISPCLK_DPPCLK_Support[i] == true
6080 && mode_lib->vba.TotalAvailablePipesSupport[i] == true
6081 && mode_lib->vba.NumberOfOTGSupport == true
6082 && mode_lib->vba.WritebackModeSupport == true
6083 && mode_lib->vba.WritebackLatencySupport == true
6084 && mode_lib->vba.WritebackScaleRatioAndTapsSupport == true
6085 && mode_lib->vba.CursorSupport == true
6086 && mode_lib->vba.PitchSupport == true
6087 && mode_lib->vba.PrefetchSupported[i] == true
6088 && mode_lib->vba.VRatioInPrefetchSupported[i] == true
6089 && mode_lib->vba.PTEBufferSizeNotExceeded[i] == true
6090 && mode_lib->vba.NonsupportedDSCInputBPC == false) {
6091 mode_lib->vba.ModeSupport[i] = true;
6092 } else {
6093 mode_lib->vba.ModeSupport[i] = false;
6094 }
6095 }
6096 for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
6097 if (i == DC__VOLTAGE_STATES || mode_lib->vba.ModeSupport[i] == true) {
6098 mode_lib->vba.VoltageLevel = i;
6099 }
6100 }
6101 mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
6102 mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
6103 mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
6104 mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
6105 mode_lib->vba.FabricAndDRAMBandwidth =
6106 mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
6107 mode_lib->vba.ImmediateFlipSupport =
6108 mode_lib->vba.ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel];
6109 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6110 mode_lib->vba.DPPPerPlane[k] = mode_lib->vba.NoOfDPP[mode_lib->vba.VoltageLevel][k];
6111 }
6112 for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
6113 if (mode_lib->vba.BlendingAndTiming[k] == k) {
6114 mode_lib->vba.ODMCombineEnabled[k] =
6115 mode_lib->vba.ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
6116 } else {
6117 mode_lib->vba.ODMCombineEnabled[k] = 0;
6118 }
6119 mode_lib->vba.DSCEnabled[k] =
6120 mode_lib->vba.RequiresDSC[mode_lib->vba.VoltageLevel][k];
6121 mode_lib->vba.OutputBpp[k] =
6122 mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k];
6123 }
6124}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
new file mode 100644
index 000000000000..4112409cd974
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
@@ -0,0 +1,598 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef __DML2_DISPLAY_MODE_VBA_H__
27#define __DML2_DISPLAY_MODE_VBA_H__
28
29#include "dml_common_defs.h"
30
31struct display_mode_lib;
32
33void set_prefetch_mode(struct display_mode_lib *mode_lib,
34 bool cstate_en,
35 bool pstate_en,
36 bool ignore_viewport_pos,
37 bool immediate_flip_support);
38
39#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)
40
41dml_get_attr_decl(clk_dcf_deepsleep);
42dml_get_attr_decl(wm_urgent);
43dml_get_attr_decl(wm_memory_trip);
44dml_get_attr_decl(wm_writeback_urgent);
45dml_get_attr_decl(wm_stutter_exit);
46dml_get_attr_decl(wm_stutter_enter_exit);
47dml_get_attr_decl(wm_dram_clock_change);
48dml_get_attr_decl(wm_writeback_dram_clock_change);
49dml_get_attr_decl(wm_xfc_underflow);
50dml_get_attr_decl(stutter_efficiency_no_vblank);
51dml_get_attr_decl(stutter_efficiency);
52dml_get_attr_decl(urgent_latency);
53dml_get_attr_decl(urgent_extra_latency);
54dml_get_attr_decl(nonurgent_latency);
55dml_get_attr_decl(dram_clock_change_latency);
56dml_get_attr_decl(dispclk_calculated);
57dml_get_attr_decl(total_data_read_bw);
58dml_get_attr_decl(return_bw);
59dml_get_attr_decl(tcalc);
60
61#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)
62
63dml_get_pipe_attr_decl(dsc_delay);
64dml_get_pipe_attr_decl(dppclk_calculated);
65dml_get_pipe_attr_decl(dscclk_calculated);
66dml_get_pipe_attr_decl(min_ttu_vblank);
67dml_get_pipe_attr_decl(vratio_prefetch_l);
68dml_get_pipe_attr_decl(vratio_prefetch_c);
69dml_get_pipe_attr_decl(dst_x_after_scaler);
70dml_get_pipe_attr_decl(dst_y_after_scaler);
71dml_get_pipe_attr_decl(dst_y_per_vm_vblank);
72dml_get_pipe_attr_decl(dst_y_per_row_vblank);
73dml_get_pipe_attr_decl(dst_y_prefetch);
74dml_get_pipe_attr_decl(dst_y_per_vm_flip);
75dml_get_pipe_attr_decl(dst_y_per_row_flip);
76dml_get_pipe_attr_decl(xfc_transfer_delay);
77dml_get_pipe_attr_decl(xfc_precharge_delay);
78dml_get_pipe_attr_decl(xfc_remote_surface_flip_latency);
79dml_get_pipe_attr_decl(xfc_prefetch_margin);
80
81unsigned int get_vstartup_calculated(
82 struct display_mode_lib *mode_lib,
83 const display_e2e_pipe_params_st *pipes,
84 unsigned int num_pipes,
85 unsigned int which_pipe);
86
87double get_total_immediate_flip_bytes(
88 struct display_mode_lib *mode_lib,
89 const display_e2e_pipe_params_st *pipes,
90 unsigned int num_pipes);
91double get_total_immediate_flip_bw(
92 struct display_mode_lib *mode_lib,
93 const display_e2e_pipe_params_st *pipes,
94 unsigned int num_pipes);
95double get_total_prefetch_bw(
96 struct display_mode_lib *mode_lib,
97 const display_e2e_pipe_params_st *pipes,
98 unsigned int num_pipes);
99
100unsigned int dml_get_voltage_level(
101 struct display_mode_lib *mode_lib,
102 const display_e2e_pipe_params_st *pipes,
103 unsigned int num_pipes);
104
105bool Calculate256BBlockSizes(
106 enum source_format_class SourcePixelFormat,
107 enum dm_swizzle_mode SurfaceTiling,
108 unsigned int BytePerPixelY,
109 unsigned int BytePerPixelC,
110 unsigned int *BlockHeight256BytesY,
111 unsigned int *BlockHeight256BytesC,
112 unsigned int *BlockWidth256BytesY,
113 unsigned int *BlockWidth256BytesC);
114
115
116struct vba_vars_st {
117 ip_params_st ip;
118 soc_bounding_box_st soc;
119
120 unsigned int MaximumMaxVStartupLines;
121 double cursor_bw[DC__NUM_DPP__MAX];
122 double meta_row_bw[DC__NUM_DPP__MAX];
123 double dpte_row_bw[DC__NUM_DPP__MAX];
124 double qual_row_bw[DC__NUM_DPP__MAX];
125 double WritebackDISPCLK;
126 double PSCL_THROUGHPUT_LUMA[DC__NUM_DPP__MAX];
127 double PSCL_THROUGHPUT_CHROMA[DC__NUM_DPP__MAX];
128 double DPPCLKUsingSingleDPPLuma;
129 double DPPCLKUsingSingleDPPChroma;
130 double DPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
131 double DISPCLKWithRamping;
132 double DISPCLKWithoutRamping;
133 double GlobalDPPCLK;
134 double DISPCLKWithRampingRoundedToDFSGranularity;
135 double DISPCLKWithoutRampingRoundedToDFSGranularity;
136 double MaxDispclkRoundedToDFSGranularity;
137 bool DCCEnabledAnyPlane;
138 double ReturnBandwidthToDCN;
139 unsigned int SwathWidthY[DC__NUM_DPP__MAX];
140 unsigned int SwathWidthSingleDPPY[DC__NUM_DPP__MAX];
141 double BytePerPixelDETY[DC__NUM_DPP__MAX];
142 double BytePerPixelDETC[DC__NUM_DPP__MAX];
143 double ReadBandwidthPlaneLuma[DC__NUM_DPP__MAX];
144 double ReadBandwidthPlaneChroma[DC__NUM_DPP__MAX];
145 unsigned int TotalActiveDPP;
146 unsigned int TotalDCCActiveDPP;
147 double UrgentRoundTripAndOutOfOrderLatency;
148 double DisplayPipeLineDeliveryTimeLuma[DC__NUM_DPP__MAX]; // WM
149 double DisplayPipeLineDeliveryTimeChroma[DC__NUM_DPP__MAX]; // WM
150 double LinesInDETY[DC__NUM_DPP__MAX]; // WM
151 double LinesInDETC[DC__NUM_DPP__MAX]; // WM
152 unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM
153 unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM
154 double FullDETBufferingTimeY[DC__NUM_DPP__MAX]; // WM
155 double FullDETBufferingTimeC[DC__NUM_DPP__MAX]; // WM
156 double MinFullDETBufferingTime;
157 double FrameTimeForMinFullDETBufferingTime;
158 double AverageReadBandwidthGBytePerSecond;
159 double PartOfBurstThatFitsInROB;
160 double StutterBurstTime;
161 //unsigned int NextPrefetchMode;
162 double VBlankTime;
163 double SmallestVBlank;
164 double DCFCLKDeepSleepPerPlane;
165 double EffectiveDETPlusLBLinesLuma;
166 double EffectiveDETPlusLBLinesChroma;
167 double UrgentLatencySupportUsLuma;
168 double UrgentLatencySupportUsChroma;
169 double UrgentLatencySupportUs[DC__NUM_DPP__MAX];
170 unsigned int DSCFormatFactor;
171 unsigned int BlockHeight256BytesY[DC__NUM_DPP__MAX];
172 unsigned int BlockHeight256BytesC[DC__NUM_DPP__MAX];
173 unsigned int BlockWidth256BytesY[DC__NUM_DPP__MAX];
174 unsigned int BlockWidth256BytesC[DC__NUM_DPP__MAX];
175 double VInitPreFillY[DC__NUM_DPP__MAX];
176 double VInitPreFillC[DC__NUM_DPP__MAX];
177 unsigned int MaxNumSwathY[DC__NUM_DPP__MAX];
178 unsigned int MaxNumSwathC[DC__NUM_DPP__MAX];
179 double PrefetchSourceLinesY[DC__NUM_DPP__MAX];
180 double PrefetchSourceLinesC[DC__NUM_DPP__MAX];
181 double PixelPTEBytesPerRow[DC__NUM_DPP__MAX];
182 double MetaRowByte[DC__NUM_DPP__MAX];
183 unsigned int dpte_row_height[DC__NUM_DPP__MAX];
184 unsigned int dpte_row_height_chroma[DC__NUM_DPP__MAX];
185 unsigned int meta_row_height[DC__NUM_DPP__MAX];
186 unsigned int meta_row_height_chroma[DC__NUM_DPP__MAX];
187
188 unsigned int MacroTileWidthY[DC__NUM_DPP__MAX];
189 unsigned int MacroTileWidthC[DC__NUM_DPP__MAX];
190 unsigned int MaxVStartupLines[DC__NUM_DPP__MAX];
191 double WritebackDelay[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
192 bool PrefetchModeSupported;
193 bool AllowDRAMClockChangeDuringVBlank[DC__NUM_DPP__MAX];
194 bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_DPP__MAX];
195 double RequiredPrefetchPixDataBW[DC__NUM_DPP__MAX];
196 double XFCRemoteSurfaceFlipDelay;
197 double TInitXFill;
198 double TslvChk;
199 double SrcActiveDrainRate;
200 double Tno_bw[DC__NUM_DPP__MAX];
201 bool ImmediateFlipSupported;
202
203 double prefetch_vm_bw[DC__NUM_DPP__MAX];
204 double prefetch_row_bw[DC__NUM_DPP__MAX];
205 bool ImmediateFlipSupportedForPipe[DC__NUM_DPP__MAX];
206 unsigned int VStartupLines;
207 double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_DPP__MAX];
208 double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_DPP__MAX];
209 unsigned int ActiveDPPs;
210 unsigned int LBLatencyHidingSourceLinesY;
211 unsigned int LBLatencyHidingSourceLinesC;
212 double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX];
213 double MinActiveDRAMClockChangeMargin;
214 double XFCSlaveVUpdateOffset[DC__NUM_DPP__MAX];
215 double XFCSlaveVupdateWidth[DC__NUM_DPP__MAX];
216 double XFCSlaveVReadyOffset[DC__NUM_DPP__MAX];
217 double InitFillLevel;
218 double FinalFillMargin;
219 double FinalFillLevel;
220 double RemainingFillLevel;
221 double TFinalxFill;
222
223
224 //
225 // SOC Bounding Box Parameters
226 //
227 double SRExitTime;
228 double SREnterPlusExitTime;
229 double UrgentLatency;
230 double WritebackLatency;
231 double PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency;
232 double NumberOfChannels;
233 double DRAMChannelWidth;
234 double FabricDatapathToDCNDataReturn;
235 double ReturnBusWidth;
236 double Downspreading;
237 double DISPCLKDPPCLKDSCCLKDownSpreading;
238 double DISPCLKDPPCLKVCOSpeed;
239 double RoundTripPingLatencyCycles;
240 double UrgentOutOfOrderReturnPerChannel;
241 unsigned int VMMPageSize;
242 double DRAMClockChangeLatency;
243 double XFCBusTransportTime;
244 double XFCXBUFLatencyTolerance;
245
246 //
247 // IP Parameters
248 //
249 unsigned int ROBBufferSizeInKByte;
250 double DETBufferSizeInKByte;
251 unsigned int DPPOutputBufferPixels;
252 unsigned int OPPOutputBufferLines;
253 unsigned int PixelChunkSizeInKByte;
254 double ReturnBW;
255 bool VirtualMemoryEnable;
256 unsigned int MaxPageTableLevels;
257 unsigned int OverridePageTableLevels;
258 unsigned int PTEChunkSize;
259 unsigned int MetaChunkSize;
260 unsigned int WritebackChunkSize;
261 bool ODMCapability;
262 unsigned int NumberOfDSC;
263 unsigned int LineBufferSize;
264 unsigned int MaxLineBufferLines;
265 unsigned int WritebackInterfaceLumaBufferSize;
266 unsigned int WritebackInterfaceChromaBufferSize;
267 unsigned int WritebackChromaLineBufferWidth;
268 double MaxDCHUBToPSCLThroughput;
269 double MaxPSCLToLBThroughput;
270 unsigned int PTEBufferSizeInRequests;
271 double DISPCLKRampingMargin;
272 unsigned int MaxInterDCNTileRepeaters;
273 bool XFCSupported;
274 double XFCSlvChunkSize;
275 double XFCFillBWOverhead;
276 double XFCFillConstant;
277 double XFCTSlvVupdateOffset;
278 double XFCTSlvVupdateWidth;
279 double XFCTSlvVreadyOffset;
280 double DPPCLKDelaySubtotal;
281 double DPPCLKDelaySCL;
282 double DPPCLKDelaySCLLBOnly;
283 double DPPCLKDelayCNVCFormater;
284 double DPPCLKDelayCNVCCursor;
285 double DISPCLKDelaySubtotal;
286 bool ProgressiveToInterlaceUnitInOPP;
287 unsigned int PDEProcessingBufIn64KBReqs;
288
289 // Pipe/Plane Parameters
290 int VoltageLevel;
291 double FabricAndDRAMBandwidth;
292 double FabricClock;
293 double DRAMSpeed;
294 double DISPCLK;
295 double SOCCLK;
296 double DCFCLK;
297
298 unsigned int NumberOfActivePlanes;
299 unsigned int ViewportWidth[DC__NUM_DPP__MAX];
300 unsigned int ViewportHeight[DC__NUM_DPP__MAX];
301 unsigned int ViewportYStartY[DC__NUM_DPP__MAX];
302 unsigned int ViewportYStartC[DC__NUM_DPP__MAX];
303 unsigned int PitchY[DC__NUM_DPP__MAX];
304 unsigned int PitchC[DC__NUM_DPP__MAX];
305 double HRatio[DC__NUM_DPP__MAX];
306 double VRatio[DC__NUM_DPP__MAX];
307 unsigned int htaps[DC__NUM_DPP__MAX];
308 unsigned int vtaps[DC__NUM_DPP__MAX];
309 unsigned int HTAPsChroma[DC__NUM_DPP__MAX];
310 unsigned int VTAPsChroma[DC__NUM_DPP__MAX];
311 unsigned int HTotal[DC__NUM_DPP__MAX];
312 unsigned int VTotal[DC__NUM_DPP__MAX];
313 unsigned int DPPPerPlane[DC__NUM_DPP__MAX];
314 double PixelClock[DC__NUM_DPP__MAX];
315 double PixelClockBackEnd[DC__NUM_DPP__MAX];
316 double DPPCLK[DC__NUM_DPP__MAX];
317 bool DCCEnable[DC__NUM_DPP__MAX];
318 unsigned int DCCMetaPitchY[DC__NUM_DPP__MAX];
319 enum scan_direction_class SourceScan[DC__NUM_DPP__MAX];
320 enum source_format_class SourcePixelFormat[DC__NUM_DPP__MAX];
321 bool WritebackEnable[DC__NUM_DPP__MAX];
322 double WritebackDestinationWidth[DC__NUM_DPP__MAX];
323 double WritebackDestinationHeight[DC__NUM_DPP__MAX];
324 double WritebackSourceHeight[DC__NUM_DPP__MAX];
325 enum source_format_class WritebackPixelFormat[DC__NUM_DPP__MAX];
326 unsigned int WritebackLumaHTaps[DC__NUM_DPP__MAX];
327 unsigned int WritebackLumaVTaps[DC__NUM_DPP__MAX];
328 unsigned int WritebackChromaHTaps[DC__NUM_DPP__MAX];
329 unsigned int WritebackChromaVTaps[DC__NUM_DPP__MAX];
330 double WritebackHRatio[DC__NUM_DPP__MAX];
331 double WritebackVRatio[DC__NUM_DPP__MAX];
332 unsigned int HActive[DC__NUM_DPP__MAX];
333 unsigned int VActive[DC__NUM_DPP__MAX];
334 bool Interlace[DC__NUM_DPP__MAX];
335 enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP__MAX];
336 unsigned int ScalerRecoutWidth[DC__NUM_DPP__MAX];
337 bool DynamicMetadataEnable[DC__NUM_DPP__MAX];
338 unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP__MAX];
339 unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP__MAX];
340 double DCCRate[DC__NUM_DPP__MAX];
341 bool ODMCombineEnabled[DC__NUM_DPP__MAX];
342 double OutputBpp[DC__NUM_DPP__MAX];
343 unsigned int NumberOfDSCSlices[DC__NUM_DPP__MAX];
344 bool DSCEnabled[DC__NUM_DPP__MAX];
345 unsigned int DSCDelay[DC__NUM_DPP__MAX];
346 unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX];
347 enum output_format_class OutputFormat[DC__NUM_DPP__MAX];
348 enum output_encoder_class Output[DC__NUM_DPP__MAX];
349 unsigned int BlendingAndTiming[DC__NUM_DPP__MAX];
350 bool SynchronizedVBlank;
351 unsigned int NumberOfCursors[DC__NUM_DPP__MAX];
352 unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
353 unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
354 bool XFCEnabled[DC__NUM_DPP__MAX];
355 bool ScalerEnabled[DC__NUM_DPP__MAX];
356
357 // Intermediates/Informational
358 bool ImmediateFlipSupport;
359 unsigned int SwathHeightY[DC__NUM_DPP__MAX];
360 unsigned int SwathHeightC[DC__NUM_DPP__MAX];
361 unsigned int DETBufferSizeY[DC__NUM_DPP__MAX];
362 unsigned int DETBufferSizeC[DC__NUM_DPP__MAX];
363 unsigned int LBBitPerPixel[DC__NUM_DPP__MAX];
364 double LastPixelOfLineExtraWatermark;
365 double TotalDataReadBandwidth;
366 unsigned int TotalActiveWriteback;
367 unsigned int EffectiveLBLatencyHidingSourceLinesLuma;
368 unsigned int EffectiveLBLatencyHidingSourceLinesChroma;
369 double BandwidthAvailableForImmediateFlip;
370 unsigned int PrefetchMode;
371 bool IgnoreViewportPositioning;
372 double PrefetchBandwidth[DC__NUM_DPP__MAX];
373 bool ErrorResult[DC__NUM_DPP__MAX];
374 double PDEAndMetaPTEBytesFrame[DC__NUM_DPP__MAX];
375
376 //
377 // Calculated dml_ml->vba.Outputs
378 //
379 double DCFClkDeepSleep;
380 double UrgentWatermark;
381 double UrgentExtraLatency;
382 double MemoryTripWatermark;
383 double WritebackUrgentWatermark;
384 double StutterExitWatermark;
385 double StutterEnterPlusExitWatermark;
386 double DRAMClockChangeWatermark;
387 double WritebackDRAMClockChangeWatermark;
388 double StutterEfficiency;
389 double StutterEfficiencyNotIncludingVBlank;
390 double MinUrgentLatencySupportUs;
391 double NonUrgentLatencyTolerance;
392 double MinActiveDRAMClockChangeLatencySupported;
393 enum clock_change_support DRAMClockChangeSupport;
394
395 // These are the clocks calcuated by the library but they are not actually
396 // used explicitly. They are fetched by tests and then possibly used. The
397 // ultimate values to use are the ones specified by the parameters to DML
398 double DISPCLK_calculated;
399 double DSCCLK_calculated[DC__NUM_DPP__MAX];
400 double DPPCLK_calculated[DC__NUM_DPP__MAX];
401
402 unsigned int VStartup[DC__NUM_DPP__MAX];
403 unsigned int VUpdateOffsetPix[DC__NUM_DPP__MAX];
404 unsigned int VUpdateWidthPix[DC__NUM_DPP__MAX];
405 unsigned int VReadyOffsetPix[DC__NUM_DPP__MAX];
406 unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
407
408 double ImmediateFlipBW;
409 unsigned int TotImmediateFlipBytes;
410 double TCalc;
411 double MinTTUVBlank[DC__NUM_DPP__MAX];
412 double VRatioPrefetchY[DC__NUM_DPP__MAX];
413 double VRatioPrefetchC[DC__NUM_DPP__MAX];
414 double DSTXAfterScaler[DC__NUM_DPP__MAX];
415 double DSTYAfterScaler[DC__NUM_DPP__MAX];
416
417 double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP__MAX];
418 double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP__MAX];
419 double DestinationLinesForPrefetch[DC__NUM_DPP__MAX];
420 double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP__MAX];
421 double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP__MAX];
422
423 double XFCTransferDelay[DC__NUM_DPP__MAX];
424 double XFCPrechargeDelay[DC__NUM_DPP__MAX];
425 double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP__MAX];
426 double XFCPrefetchMargin[DC__NUM_DPP__MAX];
427
428 display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP__MAX];
429 unsigned int cache_num_pipes;
430 unsigned int pipe_plane[DC__NUM_DPP__MAX];
431
432 /* vba mode support */
433 /*inputs*/
434 bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
435 double MaxHSCLRatio;
436 double MaxVSCLRatio;
437 unsigned int MaxNumWriteback;
438 bool WritebackLumaAndChromaScalingSupported;
439 bool Cursor64BppSupport;
440 double DCFCLKPerState[DC__VOLTAGE_STATES + 1];
441 double FabricClockPerState[DC__VOLTAGE_STATES + 1];
442 double SOCCLKPerState[DC__VOLTAGE_STATES + 1];
443 double PHYCLKPerState[DC__VOLTAGE_STATES + 1];
444 double MaxDppclk[DC__VOLTAGE_STATES + 1];
445 double MaxDSCCLK[DC__VOLTAGE_STATES + 1];
446 double DRAMSpeedPerState[DC__VOLTAGE_STATES + 1];
447 double MaxDispclk[DC__VOLTAGE_STATES + 1];
448
449 /*outputs*/
450 bool ScaleRatioAndTapsSupport;
451 bool SourceFormatPixelAndScanSupport;
452 unsigned int SwathWidthYSingleDPP[DC__NUM_DPP__MAX];
453 double BytePerPixelInDETY[DC__NUM_DPP__MAX];
454 double BytePerPixelInDETC[DC__NUM_DPP__MAX];
455 double TotalReadBandwidthConsumedGBytePerSecond;
456 double ReadBandwidth[DC__NUM_DPP__MAX];
457 double TotalWriteBandwidthConsumedGBytePerSecond;
458 double WriteBandwidth[DC__NUM_DPP__MAX];
459 double TotalBandwidthConsumedGBytePerSecond;
460 bool DCCEnabledInAnyPlane;
461 bool WritebackLatencySupport;
462 bool WritebackModeSupport;
463 bool Writeback10bpc420Supported;
464 bool BandwidthSupport[DC__VOLTAGE_STATES + 1];
465 unsigned int TotalNumberOfActiveWriteback;
466 double CriticalPoint;
467 double ReturnBWToDCNPerState;
468 double FabricAndDRAMBandwidthPerState[DC__VOLTAGE_STATES + 1];
469 double ReturnBWPerState[DC__VOLTAGE_STATES + 1];
470 double UrgentRoundTripAndOutOfOrderLatencyPerState[DC__VOLTAGE_STATES + 1];
471 bool ODMCombineEnablePerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
472 bool PTEBufferSizeNotExceededY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
473 bool PTEBufferSizeNotExceededC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
474 bool PrefetchSupported[DC__VOLTAGE_STATES + 1];
475 bool VRatioInPrefetchSupported[DC__VOLTAGE_STATES + 1];
476 bool DISPCLK_DPPCLK_Support[DC__VOLTAGE_STATES + 1];
477 bool TotalAvailablePipesSupport[DC__VOLTAGE_STATES + 1];
478 bool UrgentLatencySupport[DC__VOLTAGE_STATES + 1];
479 bool ModeSupport[DC__VOLTAGE_STATES + 1];
480 bool DIOSupport[DC__VOLTAGE_STATES + 1];
481 bool NotEnoughDSCUnits[DC__VOLTAGE_STATES + 1];
482 bool DSCCLKRequiredMoreThanSupported[DC__VOLTAGE_STATES + 1];
483 bool ROBSupport[DC__VOLTAGE_STATES + 1];
484 bool PTEBufferSizeNotExceeded[DC__VOLTAGE_STATES + 1];
485 bool RequiresDSC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
486 bool IsErrorResult[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
487 bool ViewportSizeSupport[DC__VOLTAGE_STATES + 1];
488 bool prefetch_vm_bw_valid;
489 bool prefetch_row_bw_valid;
490 bool NumberOfOTGSupport;
491 bool NonsupportedDSCInputBPC;
492 bool WritebackScaleRatioAndTapsSupport;
493 bool CursorSupport;
494 bool PitchSupport;
495
496 double WritebackLineBufferLumaBufferSize;
497 double WritebackLineBufferChromaBufferSize;
498 double WritebackMinHSCLRatio;
499 double WritebackMinVSCLRatio;
500 double WritebackMaxHSCLRatio;
501 double WritebackMaxVSCLRatio;
502 double WritebackMaxHSCLTaps;
503 double WritebackMaxVSCLTaps;
504 unsigned int MaxNumDPP;
505 unsigned int MaxNumOTG;
506 double CursorBufferSize;
507 double CursorChunkSize;
508 unsigned int Mode;
509 unsigned int NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
510 double OutputLinkDPLanes[DC__NUM_DPP__MAX];
511 double SwathWidthYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
512 double SwathHeightYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
513 double SwathHeightCPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
514 double UrgentLatencySupportUsPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
515 double VRatioPreY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
516 double VRatioPreC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
517 double RequiredPrefetchPixelDataBW[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
518 double RequiredDPPCLK[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
519 double RequiredDISPCLK[DC__VOLTAGE_STATES + 1];
520 double TotalNumberOfActiveDPP[DC__VOLTAGE_STATES + 1];
521 double TotalNumberOfDCCActiveDPP[DC__VOLTAGE_STATES + 1];
522 double PrefetchBW[DC__NUM_DPP__MAX];
523 double PDEAndMetaPTEBytesPerFrame[DC__NUM_DPP__MAX];
524 double MetaRowBytes[DC__NUM_DPP__MAX];
525 double DPTEBytesPerRow[DC__NUM_DPP__MAX];
526 double PrefetchLinesY[DC__NUM_DPP__MAX];
527 double PrefetchLinesC[DC__NUM_DPP__MAX];
528 unsigned int MaxNumSwY[DC__NUM_DPP__MAX];
529 unsigned int MaxNumSwC[DC__NUM_DPP__MAX];
530 double PrefillY[DC__NUM_DPP__MAX];
531 double PrefillC[DC__NUM_DPP__MAX];
532 double LineTimesForPrefetch[DC__NUM_DPP__MAX];
533 double LinesForMetaPTE[DC__NUM_DPP__MAX];
534 double LinesForMetaAndDPTERow[DC__NUM_DPP__MAX];
535 double MinDPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
536 double RequiresFEC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
537 unsigned int OutputBppPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
538 double DSCDelayPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
539 unsigned int Read256BlockHeightY[DC__NUM_DPP__MAX];
540 unsigned int Read256BlockWidthY[DC__NUM_DPP__MAX];
541 unsigned int Read256BlockHeightC[DC__NUM_DPP__MAX];
542 unsigned int Read256BlockWidthC[DC__NUM_DPP__MAX];
543 unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
544 double MaxSwathHeightY[DC__NUM_DPP__MAX];
545 double MaxSwathHeightC[DC__NUM_DPP__MAX];
546 double MinSwathHeightY[DC__NUM_DPP__MAX];
547 double MinSwathHeightC[DC__NUM_DPP__MAX];
548 double PSCL_FACTOR[DC__NUM_DPP__MAX];
549 double PSCL_FACTOR_CHROMA[DC__NUM_DPP__MAX];
550 double MaximumVStartup[DC__NUM_DPP__MAX];
551 double AlignedDCCMetaPitch[DC__NUM_DPP__MAX];
552 double AlignedYPitch[DC__NUM_DPP__MAX];
553 double AlignedCPitch[DC__NUM_DPP__MAX];
554 double MaximumSwathWidth[DC__NUM_DPP__MAX];
555 double final_flip_bw[DC__NUM_DPP__MAX];
556 double ImmediateFlipSupportedForState[DC__VOLTAGE_STATES + 1];
557
558 double WritebackLumaVExtra;
559 double WritebackChromaVExtra;
560 double WritebackRequiredDISPCLK;
561 double MaximumSwathWidthSupport;
562 double MaximumSwathWidthInDETBuffer;
563 double MaximumSwathWidthInLineBuffer;
564 double MaxDispclkRoundedDownToDFSGranularity;
565 double MaxDppclkRoundedDownToDFSGranularity;
566 double PlaneRequiredDISPCLKWithoutODMCombine;
567 double PlaneRequiredDISPCLK;
568 double TotalNumberOfActiveOTG;
569 double FECOverhead;
570 double EffectiveFECOverhead;
571 unsigned int Outbpp;
572 unsigned int OutbppDSC;
573 double TotalDSCUnitsRequired;
574 double bpp;
575 unsigned int slices;
576 double SwathWidthGranularityY;
577 double RoundedUpMaxSwathSizeBytesY;
578 double SwathWidthGranularityC;
579 double RoundedUpMaxSwathSizeBytesC;
580 double LinesInDETLuma;
581 double LinesInDETChroma;
582 double EffectiveDETLBLinesLuma;
583 double EffectiveDETLBLinesChroma;
584 double ProjectedDCFCLKDeepSleep;
585 double PDEAndMetaPTEBytesPerFrameY;
586 double PDEAndMetaPTEBytesPerFrameC;
587 unsigned int MetaRowBytesY;
588 unsigned int MetaRowBytesC;
589 unsigned int DPTEBytesPerRowC;
590 unsigned int DPTEBytesPerRowY;
591 double ExtraLatency;
592 double TimeCalc;
593 double TWait;
594 double MaximumReadBandwidthWithPrefetch;
595 double total_dcn_read_bw_with_flip;
596};
597
598#endif /* _DML2_DISPLAY_MODE_VBA_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
index 7a5fb1cef303..8ba962df42e6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
@@ -22,8 +22,22 @@
22 * Authors: AMD 22 * Authors: AMD
23 * 23 *
24 */ 24 */
25#include "display_rq_dlg_calc.h" 25
26#include "display_mode_lib.h" 26#include "display_mode_lib.h"
27#include "display_mode_vba.h"
28#include "display_rq_dlg_calc.h"
29
30static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
31 double *refcyc_per_req_delivery_pre_cur,
32 double *refcyc_per_req_delivery_cur,
33 double refclk_freq_in_mhz,
34 double ref_freq_to_pix_freq,
35 double hscale_pixel_rate_l,
36 double hscl_ratio,
37 double vratio_pre_l,
38 double vratio_l,
39 unsigned int cur_width,
40 enum cursor_bpp cur_bpp);
27 41
28#include "dml_inline_defs.h" 42#include "dml_inline_defs.h"
29 43
@@ -50,6 +64,8 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format
50 ret_val = 4; 64 ret_val = 4;
51 else 65 else
52 ret_val = 2; 66 ret_val = 2;
67 } else if (source_format == dm_444_8) {
68 ret_val = 1;
53 } 69 }
54 return ret_val; 70 return ret_val;
55} 71}
@@ -64,123 +80,43 @@ static bool is_dual_plane(enum source_format_class source_format)
64 return ret_val; 80 return ret_val;
65} 81}
66 82
67static void get_blk256_size( 83static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib,
68 unsigned int *blk256_width,
69 unsigned int *blk256_height,
70 unsigned int bytes_per_element)
71{
72 if (bytes_per_element == 1) {
73 *blk256_width = 16;
74 *blk256_height = 16;
75 } else if (bytes_per_element == 2) {
76 *blk256_width = 16;
77 *blk256_height = 8;
78 } else if (bytes_per_element == 4) {
79 *blk256_width = 8;
80 *blk256_height = 8;
81 } else if (bytes_per_element == 8) {
82 *blk256_width = 8;
83 *blk256_height = 4;
84 }
85}
86
87static double get_refcyc_per_delivery(
88 struct display_mode_lib *mode_lib,
89 double refclk_freq_in_mhz, 84 double refclk_freq_in_mhz,
90 double pclk_freq_in_mhz, 85 double pclk_freq_in_mhz,
91 int unsigned recout_width, 86 bool odm_combine,
87 unsigned int recout_width,
88 unsigned int hactive,
92 double vratio, 89 double vratio,
93 double hscale_pixel_rate, 90 double hscale_pixel_rate,
94 int unsigned delivery_width, 91 unsigned int delivery_width,
95 int unsigned req_per_swath_ub) 92 unsigned int req_per_swath_ub)
96{ 93{
97 double refcyc_per_delivery = 0.0; 94 double refcyc_per_delivery = 0.0;
95
98 if (vratio <= 1.0) { 96 if (vratio <= 1.0) {
99 refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width 97 if (odm_combine)
100 / pclk_freq_in_mhz / (double) req_per_swath_ub; 98 refcyc_per_delivery = (double) refclk_freq_in_mhz
99 * dml_min((double) recout_width, (double) hactive / 2.0)
100 / pclk_freq_in_mhz / (double) req_per_swath_ub;
101 else
102 refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
103 / pclk_freq_in_mhz / (double) req_per_swath_ub;
101 } else { 104 } else {
102 refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width 105 refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
103 / (double) hscale_pixel_rate / (double) req_per_swath_ub; 106 / (double) hscale_pixel_rate / (double) req_per_swath_ub;
104 } 107 }
105 108
106 DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); 109 dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
107 DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz); 110 dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz);
108 DTRACE("DLG: %s: recout_width = %d", __func__, recout_width); 111 dml_print("DML_DLG: %s: recout_width = %d\n", __func__, recout_width);
109 DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio); 112 dml_print("DML_DLG: %s: vratio = %3.2f\n", __func__, vratio);
110 DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub); 113 dml_print("DML_DLG: %s: req_per_swath_ub = %d\n", __func__, req_per_swath_ub);
111 DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery); 114 dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery);
112 115
113 return refcyc_per_delivery; 116 return refcyc_per_delivery;
114 117
115} 118}
116 119
117static double get_vratio_pre(
118 struct display_mode_lib *mode_lib,
119 unsigned int max_num_sw,
120 unsigned int max_partial_sw,
121 unsigned int swath_height,
122 double vinit,
123 double l_sw)
124{
125 double prefill = dml_floor(vinit);
126 double vratio_pre = 1.0;
127
128 vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw;
129
130 if (swath_height > 4) {
131 double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0);
132 if (tmp0 > vratio_pre)
133 vratio_pre = tmp0;
134 }
135
136 DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw);
137 DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw);
138 DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
139 DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
140 DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre);
141
142 if (vratio_pre < 1.0) {
143 DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre);
144 vratio_pre = 1.0;
145 }
146
147 if (vratio_pre > 4.0) {
148 DTRACE(
149 "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0",
150 __func__,
151 vratio_pre);
152 vratio_pre = 4.0;
153 }
154
155 return vratio_pre;
156}
157
158static void get_swath_need(
159 struct display_mode_lib *mode_lib,
160 unsigned int *max_num_sw,
161 unsigned int *max_partial_sw,
162 unsigned int swath_height,
163 double vinit)
164{
165 double prefill = dml_floor(vinit);
166 unsigned int max_partial_sw_int;
167
168 DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
169 DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
170
171 ASSERT(prefill > 0.0 && prefill <= 8.0);
172
173 *max_num_sw = (int unsigned) (dml_ceil((prefill - 1.0) / (double) swath_height) + 1.0); /* prefill has to be >= 1 */
174 max_partial_sw_int =
175 (prefill == 1) ?
176 (swath_height - 1) :
177 ((int unsigned) (prefill - 2.0) % swath_height);
178 *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */
179
180 DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw);
181 DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw);
182}
183
184static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size) 120static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
185{ 121{
186 if (tile_size == dm_256k_tile) 122 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
191 return (4 * 1024); 127 return (4 * 1024);
192} 128}
193 129
194static void extract_rq_sizing_regs( 130static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib,
195 struct display_mode_lib *mode_lib, 131 display_data_rq_regs_st *rq_regs,
196 struct _vcs_dpi_display_data_rq_regs_st *rq_regs, 132 const display_data_rq_sizing_params_st rq_sizing)
197 const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
198{ 133{
199 DTRACE("DLG: %s: rq_sizing param", __func__); 134 dml_print("DML_DLG: %s: rq_sizing param\n", __func__);
200 print__data_rq_sizing_params_st(mode_lib, rq_sizing); 135 print__data_rq_sizing_params_st(mode_lib, rq_sizing);
201 136
202 rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; 137 rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
@@ -216,25 +151,30 @@ static void extract_rq_sizing_regs(
216 rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; 151 rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
217} 152}
218 153
219void extract_rq_regs( 154static void extract_rq_regs(struct display_mode_lib *mode_lib,
220 struct display_mode_lib *mode_lib, 155 display_rq_regs_st *rq_regs,
221 struct _vcs_dpi_display_rq_regs_st *rq_regs, 156 const display_rq_params_st rq_param)
222 const struct _vcs_dpi_display_rq_params_st rq_param)
223{ 157{
224 unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; 158 unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
225 unsigned int detile_buf_plane1_addr = 0; 159 unsigned int detile_buf_plane1_addr = 0;
226 160
227 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); 161 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
228 if (rq_param.yuv420) 162
163 rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height),
164 1) - 3;
165
166 if (rq_param.yuv420) {
229 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); 167 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
168 rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height),
169 1) - 3;
170 }
230 171
231 rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); 172 rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
232 rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); 173 rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
233 174
234 /* FIXME: take the max between luma, chroma chunk size? 175 // FIXME: take the max between luma, chroma chunk size?
235 * okay for now, as we are setting chunk_bytes to 8kb anyways 176 // okay for now, as we are setting chunk_bytes to 8kb anyways
236 */ 177 if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb
237 if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */
238 rq_regs->drq_expansion_mode = 0; 178 rq_regs->drq_expansion_mode = 0;
239 } else { 179 } else {
240 rq_regs->drq_expansion_mode = 2; 180 rq_regs->drq_expansion_mode = 2;
@@ -246,21 +186,19 @@ void extract_rq_regs(
246 if (rq_param.yuv420) { 186 if (rq_param.yuv420) {
247 if ((double) rq_param.misc.rq_l.stored_swath_bytes 187 if ((double) rq_param.misc.rq_l.stored_swath_bytes
248 / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { 188 / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
249 detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */ 189 detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma
250 } else { 190 } else {
251 detile_buf_plane1_addr = dml_round_to_multiple( 191 detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
252 (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
253 256, 192 256,
254 0) / 64.0; /* 2/3 to chroma */ 193 0) / 64.0; // 2/3 to chroma
255 } 194 }
256 } 195 }
257 rq_regs->plane1_base_address = detile_buf_plane1_addr; 196 rq_regs->plane1_base_address = detile_buf_plane1_addr;
258} 197}
259 198
260static void handle_det_buf_split( 199static void handle_det_buf_split(struct display_mode_lib *mode_lib,
261 struct display_mode_lib *mode_lib, 200 display_rq_params_st *rq_param,
262 struct _vcs_dpi_display_rq_params_st *rq_param, 201 const display_pipe_source_params_st pipe_src_param)
263 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
264{ 202{
265 unsigned int total_swath_bytes = 0; 203 unsigned int total_swath_bytes = 0;
266 unsigned int swath_bytes_l = 0; 204 unsigned int swath_bytes_l = 0;
@@ -279,12 +217,10 @@ static void handle_det_buf_split(
279 full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes; 217 full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
280 218
281 if (rq_param->yuv420_10bpc) { 219 if (rq_param->yuv420_10bpc) {
282 full_swath_bytes_packed_l = dml_round_to_multiple( 220 full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
283 rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
284 256, 221 256,
285 1) + 256; 222 1) + 256;
286 full_swath_bytes_packed_c = dml_round_to_multiple( 223 full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
287 rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
288 256, 224 256,
289 1) + 256; 225 1) + 256;
290 } 226 }
@@ -292,29 +228,19 @@ static void handle_det_buf_split(
292 if (rq_param->yuv420) { 228 if (rq_param->yuv420) {
293 total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c; 229 total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
294 230
295 if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */ 231 if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request
296 req128_l = 0; 232 req128_l = 0;
297 req128_c = 0; 233 req128_c = 0;
298 swath_bytes_l = full_swath_bytes_packed_l; 234 swath_bytes_l = full_swath_bytes_packed_l;
299 swath_bytes_c = full_swath_bytes_packed_c; 235 swath_bytes_c = full_swath_bytes_packed_c;
300 } else { /*128b request (for luma only for yuv420 8bpc) */ 236 } else { //128b request (for luma only for yuv420 8bpc)
301 req128_l = 1; 237 req128_l = 1;
302 req128_c = 0; 238 req128_c = 0;
303 swath_bytes_l = full_swath_bytes_packed_l / 2; 239 swath_bytes_l = full_swath_bytes_packed_l / 2;
304 swath_bytes_c = full_swath_bytes_packed_c; 240 swath_bytes_c = full_swath_bytes_packed_c;
305 } 241 }
306 242 // Note: assumption, the config that pass in will fit into
307 /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137) 243 // the detiled buffer.
308 * TODO: Remove after rtl fix
309 */
310 if (req128_l == 1) {
311 req128_c = 1;
312 DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__);
313 }
314
315 /* Note: assumption, the config that pass in will fit into
316 * the detiled buffer.
317 */
318 } else { 244 } else {
319 total_swath_bytes = 2 * full_swath_bytes_packed_l; 245 total_swath_bytes = 2 * full_swath_bytes_packed_l;
320 246
@@ -342,207 +268,47 @@ static void handle_det_buf_split(
342 rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; 268 rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
343 rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c; 269 rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
344 270
345 DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l); 271 dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l);
346 DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c); 272 dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c);
347 DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l); 273 dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n",
348 DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c); 274 __func__,
275 full_swath_bytes_packed_l);
276 dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n",
277 __func__,
278 full_swath_bytes_packed_c);
349} 279}
350 280
351/* Need refactor. */ 281static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
352void dml_rq_dlg_get_row_heights( 282 display_data_rq_dlg_params_st *rq_dlg_param,
353 struct display_mode_lib *mode_lib, 283 display_data_rq_misc_params_st *rq_misc_param,
354 unsigned int *o_dpte_row_height, 284 display_data_rq_sizing_params_st *rq_sizing_param,
355 unsigned int *o_meta_row_height,
356 unsigned int vp_width, 285 unsigned int vp_width,
286 unsigned int vp_height,
357 unsigned int data_pitch, 287 unsigned int data_pitch,
358 int source_format, 288 unsigned int meta_pitch,
359 int tiling, 289 unsigned int source_format,
360 int macro_tile_size, 290 unsigned int tiling,
361 int source_scan, 291 unsigned int macro_tile_size,
362 int is_chroma) 292 unsigned int source_scan,
293 unsigned int is_chroma)
363{ 294{
364 bool surf_linear = (tiling == dm_sw_linear); 295 bool surf_linear = (tiling == dm_sw_linear);
365 bool surf_vert = (source_scan == dm_vert); 296 bool surf_vert = (source_scan == dm_vert);
366 297
367 unsigned int bytes_per_element = get_bytes_per_element( 298 unsigned int bytes_per_element;
368 (enum source_format_class) source_format, 299 unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format),
369 is_chroma); 300 false);
370 unsigned int log2_bytes_per_element = dml_log2(bytes_per_element); 301 unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format),
302 true);
303
371 unsigned int blk256_width = 0; 304 unsigned int blk256_width = 0;
372 unsigned int blk256_height = 0; 305 unsigned int blk256_height = 0;
373 306
374 unsigned int log2_blk256_height; 307 unsigned int blk256_width_y = 0;
375 unsigned int blk_bytes; 308 unsigned int blk256_height_y = 0;
376 unsigned int log2_blk_bytes; 309 unsigned int blk256_width_c = 0;
377 unsigned int log2_blk_height; 310 unsigned int blk256_height_c = 0;
378 unsigned int log2_blk_width;
379 unsigned int log2_meta_req_bytes;
380 unsigned int log2_meta_req_height;
381 unsigned int log2_meta_req_width;
382 unsigned int log2_meta_row_height;
383 unsigned int log2_vmpg_bytes;
384 unsigned int dpte_buf_in_pte_reqs;
385 unsigned int log2_vmpg_height;
386 unsigned int log2_vmpg_width;
387 unsigned int log2_dpte_req_height_ptes;
388 unsigned int log2_dpte_req_width_ptes;
389 unsigned int log2_dpte_req_height;
390 unsigned int log2_dpte_req_width;
391 unsigned int log2_dpte_row_height_linear;
392 unsigned int log2_dpte_row_height;
393 unsigned int dpte_req_width;
394
395 if (surf_linear) {
396 blk256_width = 256;
397 blk256_height = 1;
398 } else {
399 get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
400 }
401
402 log2_blk256_height = dml_log2((double) blk256_height);
403 blk_bytes = surf_linear ?
404 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
405 log2_blk_bytes = dml_log2((double) blk_bytes);
406 log2_blk_height = 0;
407 log2_blk_width = 0;
408
409 /* remember log rule
410 * "+" in log is multiply
411 * "-" in log is divide
412 * "/2" is like square root
413 * blk is vertical biased
414 */
415 if (tiling != dm_sw_linear)
416 log2_blk_height = log2_blk256_height
417 + dml_ceil((double) (log2_blk_bytes - 8) / 2.0);
418 else
419 log2_blk_height = 0; /* blk height of 1 */
420
421 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
422
423 /* ------- */
424 /* meta */
425 /* ------- */
426 log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
427
428 /* each 64b meta request for dcn is 8x8 meta elements and
429 * a meta element covers one 256b block of the the data surface.
430 */
431 log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */
432 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
433 - log2_meta_req_height;
434 log2_meta_row_height = 0;
435
436 /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
437 * calculate upper bound of the meta_row_width
438 */
439 if (!surf_vert)
440 log2_meta_row_height = log2_meta_req_height;
441 else
442 log2_meta_row_height = log2_meta_req_width;
443
444 *o_meta_row_height = 1 << log2_meta_row_height;
445
446 /* ------ */
447 /* dpte */
448 /* ------ */
449 log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
450 dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
451
452 log2_vmpg_height = 0;
453 log2_vmpg_width = 0;
454 log2_dpte_req_height_ptes = 0;
455 log2_dpte_req_width_ptes = 0;
456 log2_dpte_req_height = 0;
457 log2_dpte_req_width = 0;
458 log2_dpte_row_height_linear = 0;
459 log2_dpte_row_height = 0;
460 dpte_req_width = 0; /* 64b dpte req width in data element */
461
462 if (surf_linear) {
463 log2_vmpg_height = 0; /* one line high */
464 } else {
465 log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
466 }
467 log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
468
469 /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
470 if (log2_blk_bytes <= log2_vmpg_bytes)
471 log2_dpte_req_height_ptes = 0;
472 else if (log2_blk_height - log2_vmpg_height >= 2)
473 log2_dpte_req_height_ptes = 2;
474 else
475 log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
476 log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
477
478 ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
479 (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
480 (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
481
482 /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height
483 * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent
484 */
485 log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
486 log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
487 dpte_req_width = 1 << log2_dpte_req_width;
488
489 /* calculate pitch dpte row buffer can hold
490 * round the result down to a power of two.
491 */
492 if (surf_linear) {
493 log2_dpte_row_height_linear = dml_floor(
494 dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch));
495
496 ASSERT(log2_dpte_row_height_linear >= 3);
497
498 if (log2_dpte_row_height_linear > 7)
499 log2_dpte_row_height_linear = 7;
500
501 log2_dpte_row_height = log2_dpte_row_height_linear;
502 } else {
503 /* the upper bound of the dpte_row_width without dependency on viewport position follows. */
504 if (!surf_vert) {
505 log2_dpte_row_height = log2_dpte_req_height;
506 } else {
507 log2_dpte_row_height =
508 (log2_blk_width < log2_dpte_req_width) ?
509 log2_blk_width : log2_dpte_req_width;
510 }
511 }
512
513 /* From programming guide:
514 * There is a special case of saving only half of ptes returned due to buffer space limits.
515 * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
516 * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
517 */
518 if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
519 && log2_blk_bytes >= 16) {
520 log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
521 }
522
523 *o_dpte_row_height = 1 << log2_dpte_row_height;
524}
525
526static void get_surf_rq_param(
527 struct display_mode_lib *mode_lib,
528 struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param,
529 struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param,
530 struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param,
531 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param,
532 bool is_chroma)
533{
534 bool mode_422 = 0;
535 unsigned int vp_width = 0;
536 unsigned int vp_height = 0;
537 unsigned int data_pitch = 0;
538 unsigned int meta_pitch = 0;
539 unsigned int ppe = mode_422 ? 2 : 1;
540 bool surf_linear;
541 bool surf_vert;
542 unsigned int bytes_per_element;
543 unsigned int log2_bytes_per_element; 311 unsigned int log2_bytes_per_element;
544 unsigned int blk256_width;
545 unsigned int blk256_height;
546 unsigned int log2_blk256_width; 312 unsigned int log2_blk256_width;
547 unsigned int log2_blk256_height; 313 unsigned int log2_blk256_height;
548 unsigned int blk_bytes; 314 unsigned int blk_bytes;
@@ -558,6 +324,8 @@ static void get_surf_rq_param(
558 unsigned int meta_row_width_ub; 324 unsigned int meta_row_width_ub;
559 unsigned int log2_meta_chunk_bytes; 325 unsigned int log2_meta_chunk_bytes;
560 unsigned int log2_meta_chunk_height; 326 unsigned int log2_meta_chunk_height;
327
328 //full sized meta chunk width in unit of data elements
561 unsigned int log2_meta_chunk_width; 329 unsigned int log2_meta_chunk_width;
562 unsigned int log2_min_meta_chunk_bytes; 330 unsigned int log2_min_meta_chunk_bytes;
563 unsigned int min_meta_chunk_width; 331 unsigned int min_meta_chunk_width;
@@ -572,93 +340,72 @@ static void get_surf_rq_param(
572 unsigned int vmpg_bytes; 340 unsigned int vmpg_bytes;
573 unsigned int meta_pte_req_per_frame_ub; 341 unsigned int meta_pte_req_per_frame_ub;
574 unsigned int meta_pte_bytes_per_frame_ub; 342 unsigned int meta_pte_bytes_per_frame_ub;
575 unsigned int log2_vmpg_bytes; 343 const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
576 unsigned int dpte_buf_in_pte_reqs; 344 const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
577 unsigned int log2_vmpg_height; 345 const unsigned int pde_proc_buffer_size_64k_reqs =
578 unsigned int log2_vmpg_width; 346 mode_lib->ip.pde_proc_buffer_size_64k_reqs;
579 unsigned int log2_dpte_req_height_ptes; 347
580 unsigned int log2_dpte_req_width_ptes; 348 unsigned int log2_vmpg_height = 0;
581 unsigned int log2_dpte_req_height; 349 unsigned int log2_vmpg_width = 0;
582 unsigned int log2_dpte_req_width; 350 unsigned int log2_dpte_req_height_ptes = 0;
583 unsigned int log2_dpte_row_height_linear; 351 unsigned int log2_dpte_req_height = 0;
584 unsigned int log2_dpte_row_height; 352 unsigned int log2_dpte_req_width = 0;
585 unsigned int log2_dpte_group_width; 353 unsigned int log2_dpte_row_height_linear = 0;
586 unsigned int dpte_row_width_ub; 354 unsigned int log2_dpte_row_height = 0;
587 unsigned int dpte_row_height; 355 unsigned int log2_dpte_group_width = 0;
588 unsigned int dpte_req_height; 356 unsigned int dpte_row_width_ub = 0;
589 unsigned int dpte_req_width; 357 unsigned int dpte_req_height = 0;
590 unsigned int dpte_group_width; 358 unsigned int dpte_req_width = 0;
591 unsigned int log2_dpte_group_bytes; 359 unsigned int dpte_group_width = 0;
592 unsigned int log2_dpte_group_length; 360 unsigned int log2_dpte_group_bytes = 0;
593 unsigned int func_meta_row_height, func_dpte_row_height; 361 unsigned int log2_dpte_group_length = 0;
594 362 unsigned int pde_buf_entries;
595 /* FIXME check if ppe apply for both luma and chroma in 422 case */ 363 bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10);
596 if (is_chroma) { 364
597 vp_width = pipe_src_param.viewport_width_c / ppe; 365 Calculate256BBlockSizes((enum source_format_class)(source_format),
598 vp_height = pipe_src_param.viewport_height_c; 366 (enum dm_swizzle_mode)(tiling),
599 data_pitch = pipe_src_param.data_pitch_c; 367 bytes_per_element_y,
600 meta_pitch = pipe_src_param.meta_pitch_c; 368 bytes_per_element_c,
369 &blk256_height_y,
370 &blk256_height_c,
371 &blk256_width_y,
372 &blk256_width_c);
373
374 if (!is_chroma) {
375 blk256_width = blk256_width_y;
376 blk256_height = blk256_height_y;
377 bytes_per_element = bytes_per_element_y;
601 } else { 378 } else {
602 vp_width = pipe_src_param.viewport_width / ppe; 379 blk256_width = blk256_width_c;
603 vp_height = pipe_src_param.viewport_height; 380 blk256_height = blk256_height_c;
604 data_pitch = pipe_src_param.data_pitch; 381 bytes_per_element = bytes_per_element_c;
605 meta_pitch = pipe_src_param.meta_pitch;
606 } 382 }
607 383
608 rq_sizing_param->chunk_bytes = 8192;
609
610 if (rq_sizing_param->chunk_bytes == 64 * 1024)
611 rq_sizing_param->min_chunk_bytes = 0;
612 else
613 rq_sizing_param->min_chunk_bytes = 1024;
614
615 rq_sizing_param->meta_chunk_bytes = 2048;
616 rq_sizing_param->min_meta_chunk_bytes = 256;
617
618 rq_sizing_param->mpte_group_bytes = 2048;
619
620 surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
621 surf_vert = (pipe_src_param.source_scan == dm_vert);
622
623 bytes_per_element = get_bytes_per_element(
624 (enum source_format_class) pipe_src_param.source_format,
625 is_chroma);
626 log2_bytes_per_element = dml_log2(bytes_per_element); 384 log2_bytes_per_element = dml_log2(bytes_per_element);
627 blk256_width = 0;
628 blk256_height = 0;
629 385
630 if (surf_linear) { 386 dml_print("DML_DLG: %s: surf_linear = %d\n", __func__, surf_linear);
631 blk256_width = 256 / bytes_per_element; 387 dml_print("DML_DLG: %s: surf_vert = %d\n", __func__, surf_vert);
632 blk256_height = 1; 388 dml_print("DML_DLG: %s: blk256_width = %d\n", __func__, blk256_width);
633 } else { 389 dml_print("DML_DLG: %s: blk256_height = %d\n", __func__, blk256_height);
634 get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
635 }
636
637 DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear);
638 DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert);
639 DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width);
640 DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height);
641 390
642 log2_blk256_width = dml_log2((double) blk256_width); 391 log2_blk256_width = dml_log2((double) blk256_width);
643 log2_blk256_height = dml_log2((double) blk256_height); 392 log2_blk256_height = dml_log2((double) blk256_height);
644 blk_bytes = 393 blk_bytes = surf_linear ?
645 surf_linear ? 256 : get_blk_size_bytes( 394 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
646 (enum source_macro_tile_size) pipe_src_param.macro_tile_size);
647 log2_blk_bytes = dml_log2((double) blk_bytes); 395 log2_blk_bytes = dml_log2((double) blk_bytes);
648 log2_blk_height = 0; 396 log2_blk_height = 0;
649 log2_blk_width = 0; 397 log2_blk_width = 0;
650 398
651 /* remember log rule 399 // remember log rule
652 * "+" in log is multiply 400 // "+" in log is multiply
653 * "-" in log is divide 401 // "-" in log is divide
654 * "/2" is like square root 402 // "/2" is like square root
655 * blk is vertical biased 403 // blk is vertical biased
656 */ 404 if (tiling != dm_sw_linear)
657 if (pipe_src_param.sw_mode != dm_sw_linear)
658 log2_blk_height = log2_blk256_height 405 log2_blk_height = log2_blk256_height
659 + dml_ceil((double) (log2_blk_bytes - 8) / 2.0); 406 + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
660 else 407 else
661 log2_blk_height = 0; /* blk height of 1 */ 408 log2_blk_height = 0; // blk height of 1
662 409
663 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height; 410 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
664 411
@@ -667,10 +414,8 @@ static void get_surf_rq_param(
667 + blk256_width; 414 + blk256_width;
668 rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width; 415 rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
669 } else { 416 } else {
670 rq_dlg_param->swath_width_ub = dml_round_to_multiple( 417 rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_height - 1, blk256_height, 1)
671 vp_height - 1, 418 + blk256_height;
672 blk256_height,
673 1) + blk256_height;
674 rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height; 419 rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
675 } 420 }
676 421
@@ -684,15 +429,14 @@ static void get_surf_rq_param(
684 rq_misc_param->blk256_height = blk256_height; 429 rq_misc_param->blk256_height = blk256_height;
685 rq_misc_param->blk256_width = blk256_width; 430 rq_misc_param->blk256_width = blk256_width;
686 431
687 /* ------- */ 432 // -------
688 /* meta */ 433 // meta
689 /* ------- */ 434 // -------
690 log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */ 435 log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
691 436
692 /* each 64b meta request for dcn is 8x8 meta elements and 437 // each 64b meta request for dcn is 8x8 meta elements and
693 * a meta element covers one 256b block of the the data surface. 438 // a meta element covers one 256b block of the the data surface.
694 */ 439 log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
695 log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
696 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element 440 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
697 - log2_meta_req_height; 441 - log2_meta_req_height;
698 meta_req_width = 1 << log2_meta_req_width; 442 meta_req_width = 1 << log2_meta_req_width;
@@ -700,9 +444,8 @@ static void get_surf_rq_param(
700 log2_meta_row_height = 0; 444 log2_meta_row_height = 0;
701 meta_row_width_ub = 0; 445 meta_row_width_ub = 0;
702 446
703 /* the dimensions of a meta row are meta_row_width x meta_row_height in elements. 447 // the dimensions of a meta row are meta_row_width x meta_row_height in elements.
704 * calculate upper bound of the meta_row_width 448 // calculate upper bound of the meta_row_width
705 */
706 if (!surf_vert) { 449 if (!surf_vert) {
707 log2_meta_row_height = log2_meta_req_height; 450 log2_meta_row_height = log2_meta_req_height;
708 meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1) 451 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(
716 } 459 }
717 rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64; 460 rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
718 461
462 rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
463
719 log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes); 464 log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
720 log2_meta_chunk_height = log2_meta_row_height; 465 log2_meta_chunk_height = log2_meta_row_height;
721 466
722 /*full sized meta chunk width in unit of data elements */ 467 //full sized meta chunk width in unit of data elements
723 log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element 468 log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element
724 - log2_meta_chunk_height; 469 - log2_meta_chunk_height;
725 log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes); 470 log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
@@ -734,21 +479,24 @@ static void get_surf_rq_param(
734 meta_blk_height = blk256_height * 64; 479 meta_blk_height = blk256_height * 64;
735 meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height; 480 meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height;
736 meta_surface_bytes = meta_pitch 481 meta_surface_bytes = meta_pitch
737 * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) 482 * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height)
738 + meta_blk_height) * bytes_per_element / 256; 483 * bytes_per_element / 256;
739 vmpg_bytes = mode_lib->soc.vmm_page_size_bytes; 484 vmpg_bytes = mode_lib->soc.vmm_page_size_bytes;
740 meta_pte_req_per_frame_ub = (dml_round_to_multiple( 485 meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes,
741 meta_surface_bytes - vmpg_bytes,
742 8 * vmpg_bytes, 486 8 * vmpg_bytes,
743 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes); 487 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
744 meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */ 488 meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request
745 rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub; 489 rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
746 490
747 DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height); 491 dml_print("DML_DLG: %s: meta_blk_height = %d\n", __func__, meta_blk_height);
748 DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width); 492 dml_print("DML_DLG: %s: meta_blk_width = %d\n", __func__, meta_blk_width);
749 DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes); 493 dml_print("DML_DLG: %s: meta_surface_bytes = %d\n", __func__, meta_surface_bytes);
750 DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub); 494 dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub = %d\n",
751 DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub); 495 __func__,
496 meta_pte_req_per_frame_ub);
497 dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n",
498 __func__,
499 meta_pte_bytes_per_frame_ub);
752 500
753 if (!surf_vert) 501 if (!surf_vert)
754 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width; 502 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
@@ -760,67 +508,58 @@ static void get_surf_rq_param(
760 else 508 else
761 rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2; 509 rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
762 510
763 rq_dlg_param->meta_row_height = 1 << log2_meta_row_height; 511 // ------
764 512 // dpte
765 /* ------ */ 513 // ------
766 /* dpte */
767 /* ------ */
768 log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
769 dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
770
771 log2_vmpg_height = 0;
772 log2_vmpg_width = 0;
773 log2_dpte_req_height_ptes = 0;
774 log2_dpte_req_width_ptes = 0;
775 log2_dpte_req_height = 0;
776 log2_dpte_req_width = 0;
777 log2_dpte_row_height_linear = 0;
778 log2_dpte_row_height = 0;
779 log2_dpte_group_width = 0;
780 dpte_row_width_ub = 0;
781 dpte_row_height = 0;
782 dpte_req_height = 0; /* 64b dpte req height in data element */
783 dpte_req_width = 0; /* 64b dpte req width in data element */
784 dpte_group_width = 0;
785 log2_dpte_group_bytes = 0;
786 log2_dpte_group_length = 0;
787
788 if (surf_linear) { 514 if (surf_linear) {
789 log2_vmpg_height = 0; /* one line high */ 515 log2_vmpg_height = 0; // one line high
790 } else { 516 } else {
791 log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height; 517 log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
792 } 518 }
793 log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height; 519 log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
794 520
795 /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */ 521 // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4.
796 if (log2_blk_bytes <= log2_vmpg_bytes) 522 if (surf_linear) { //one 64B PTE request returns 8 PTEs
797 log2_dpte_req_height_ptes = 0; 523 log2_dpte_req_height_ptes = 0;
798 else if (log2_blk_height - log2_vmpg_height >= 2) 524 log2_dpte_req_width = log2_vmpg_width + 3;
799 log2_dpte_req_height_ptes = 2; 525 log2_dpte_req_height = 0;
800 else 526 } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size
801 log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height; 527 //one 64B req gives 8x1 PTEs for 4KB tile
802 log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes; 528 log2_dpte_req_height_ptes = 0;
803 529 log2_dpte_req_width = log2_blk_width + 3;
804 /* Ensure we only have the 3 shapes */ 530 log2_dpte_req_height = log2_blk_height + 0;
805 ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */ 531 } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB
806 (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */ 532 //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB
807 (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */ 533 log2_dpte_req_height_ptes = 4;
808 534 log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width
809 /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height 535 log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height
810 * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent 536 } else { //64KB page size and must 64KB tile block
811 * That depends on the pte shape (i.e. 8x1, 4x2, 2x4) 537 //one 64B req gives 8x1 PTEs for 64KB tile
812 */ 538 log2_dpte_req_height_ptes = 0;
813 log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes; 539 log2_dpte_req_width = log2_blk_width + 3;
814 log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes; 540 log2_dpte_req_height = log2_blk_height + 0;
541 }
542
543 // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
544 // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
545 // That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
546 //log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
547 //log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
815 dpte_req_height = 1 << log2_dpte_req_height; 548 dpte_req_height = 1 << log2_dpte_req_height;
816 dpte_req_width = 1 << log2_dpte_req_width; 549 dpte_req_width = 1 << log2_dpte_req_width;
817 550
818 /* calculate pitch dpte row buffer can hold 551 // calculate pitch dpte row buffer can hold
819 * round the result down to a power of two. 552 // round the result down to a power of two.
820 */ 553 pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs;
821 if (surf_linear) { 554 if (surf_linear) {
822 log2_dpte_row_height_linear = dml_floor( 555 unsigned int dpte_row_height;
823 dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch)); 556
557 log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries
558 / bytes_per_element,
559 dpte_buf_in_pte_reqs
560 * dpte_req_width)
561 / data_pitch),
562 1);
824 563
825 ASSERT(log2_dpte_row_height_linear >= 3); 564 ASSERT(log2_dpte_row_height_linear >= 3);
826 565
@@ -828,18 +567,16 @@ static void get_surf_rq_param(
828 log2_dpte_row_height_linear = 7; 567 log2_dpte_row_height_linear = 7;
829 568
830 log2_dpte_row_height = log2_dpte_row_height_linear; 569 log2_dpte_row_height = log2_dpte_row_height_linear;
831 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height; 570 // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
832 571 // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
833 /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary. 572 dpte_row_height = 1 << log2_dpte_row_height;
834 * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering. 573 dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1,
835 */
836 dpte_row_width_ub = dml_round_to_multiple(
837 data_pitch * dpte_row_height - 1,
838 dpte_req_width, 574 dpte_req_width,
839 1) + dpte_req_width; 575 1) + dpte_req_width;
840 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width; 576 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
841 } else { 577 } else {
842 /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */ 578 // the upper bound of the dpte_row_width without dependency on viewport position follows.
579 // for tiled mode, row height is the same as req height and row store up to vp size upper bound
843 if (!surf_vert) { 580 if (!surf_vert) {
844 log2_dpte_row_height = log2_dpte_req_height; 581 log2_dpte_row_height = log2_dpte_req_height;
845 dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1) 582 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(
853 + dpte_req_height; 590 + dpte_req_height;
854 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height; 591 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
855 } 592 }
856 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
857 }
858 rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64;
859
860 /* From programming guide:
861 * There is a special case of saving only half of ptes returned due to buffer space limits.
862 * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
863 * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
864 */
865 if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
866 && log2_blk_bytes >= 16) {
867 log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
868 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
869 } 593 }
594 if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB
595 rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request
596 else
597 rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request
598
599 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
870 600
871 /* the dpte_group_bytes is reduced for the specific case of vertical 601 // the dpte_group_bytes is reduced for the specific case of vertical
872 * access of a tile surface that has dpte request of 8x1 ptes. 602 // access of a tile surface that has dpte request of 8x1 ptes.
873 */ 603 if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group
874 if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */
875 rq_sizing_param->dpte_group_bytes = 512; 604 rq_sizing_param->dpte_group_bytes = 512;
876 else 605 else
877 /*full size */ 606 //full size
878 rq_sizing_param->dpte_group_bytes = 2048; 607 rq_sizing_param->dpte_group_bytes = 2048;
879 608
880 /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */ 609 //since pte request size is 64byte, the number of data pte requests per full sized group is as follows.
881 log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes); 610 log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
882 log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */ 611 log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests
883 612
884 /* full sized data pte group width in elements */ 613 // full sized data pte group width in elements
885 if (!surf_vert) 614 if (!surf_vert)
886 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width; 615 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
887 else 616 else
888 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height; 617 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
889 618
619 //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B
620 if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB
621 log2_dpte_group_width = log2_dpte_group_width - 1;
622
890 dpte_group_width = 1 << log2_dpte_group_width; 623 dpte_group_width = 1 << log2_dpte_group_width;
891 624
892 /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width, 625 // since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
893 * the upper bound for the dpte groups per row is as follows. 626 // the upper bound for the dpte groups per row is as follows.
894 */ 627 rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width,
895 rq_dlg_param->dpte_groups_per_row_ub = dml_ceil( 628 1);
896 (double) dpte_row_width_ub / dpte_group_width); 629}
630
631static void get_surf_rq_param(struct display_mode_lib *mode_lib,
632 display_data_rq_sizing_params_st *rq_sizing_param,
633 display_data_rq_dlg_params_st *rq_dlg_param,
634 display_data_rq_misc_params_st *rq_misc_param,
635 const display_pipe_source_params_st pipe_src_param,
636 bool is_chroma)
637{
638 bool mode_422 = 0;
639 unsigned int vp_width = 0;
640 unsigned int vp_height = 0;
641 unsigned int data_pitch = 0;
642 unsigned int meta_pitch = 0;
643 unsigned int ppe = mode_422 ? 2 : 1;
644
645 // FIXME check if ppe apply for both luma and chroma in 422 case
646 if (is_chroma) {
647 vp_width = pipe_src_param.viewport_width_c / ppe;
648 vp_height = pipe_src_param.viewport_height_c;
649 data_pitch = pipe_src_param.data_pitch_c;
650 meta_pitch = pipe_src_param.meta_pitch_c;
651 } else {
652 vp_width = pipe_src_param.viewport_width / ppe;
653 vp_height = pipe_src_param.viewport_height;
654 data_pitch = pipe_src_param.data_pitch;
655 meta_pitch = pipe_src_param.meta_pitch;
656 }
657
658 rq_sizing_param->chunk_bytes = 8192;
659
660 if (rq_sizing_param->chunk_bytes == 64 * 1024)
661 rq_sizing_param->min_chunk_bytes = 0;
662 else
663 rq_sizing_param->min_chunk_bytes = 1024;
664
665 rq_sizing_param->meta_chunk_bytes = 2048;
666 rq_sizing_param->min_meta_chunk_bytes = 256;
897 667
898 dml_rq_dlg_get_row_heights( 668 rq_sizing_param->mpte_group_bytes = 2048;
899 mode_lib, 669
900 &func_dpte_row_height, 670 get_meta_and_pte_attr(mode_lib,
901 &func_meta_row_height, 671 rq_dlg_param,
672 rq_misc_param,
673 rq_sizing_param,
902 vp_width, 674 vp_width,
675 vp_height,
903 data_pitch, 676 data_pitch,
677 meta_pitch,
904 pipe_src_param.source_format, 678 pipe_src_param.source_format,
905 pipe_src_param.sw_mode, 679 pipe_src_param.sw_mode,
906 pipe_src_param.macro_tile_size, 680 pipe_src_param.macro_tile_size,
907 pipe_src_param.source_scan, 681 pipe_src_param.source_scan,
908 is_chroma); 682 is_chroma);
909
910 /* Just a check to make sure this function and the new one give the same
911 * result. The standalone get_row_heights() function is based off of the
912 * code in this function so the same changes need to be made to both.
913 */
914 if (rq_dlg_param->meta_row_height != func_meta_row_height) {
915 DTRACE(
916 "MISMATCH: rq_dlg_param->meta_row_height = %d",
917 rq_dlg_param->meta_row_height);
918 DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height);
919 ASSERT(0);
920 }
921
922 if (rq_dlg_param->dpte_row_height != func_dpte_row_height) {
923 DTRACE(
924 "MISMATCH: rq_dlg_param->dpte_row_height = %d",
925 rq_dlg_param->dpte_row_height);
926 DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height);
927 ASSERT(0);
928 }
929} 683}
930 684
931void dml_rq_dlg_get_rq_params( 685void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
932 struct display_mode_lib *mode_lib, 686 display_rq_params_st *rq_param,
933 struct _vcs_dpi_display_rq_params_st *rq_param, 687 const display_pipe_source_params_st pipe_src_param)
934 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
935{ 688{
936 /* get param for luma surface */ 689 // get param for luma surface
937 rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 690 rq_param->yuv420 = pipe_src_param.source_format == dm_420_8
938 || pipe_src_param.source_format == dm_420_10; 691 || pipe_src_param.source_format == dm_420_10;
939 rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; 692 rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10;
940 693
941 get_surf_rq_param( 694 get_surf_rq_param(mode_lib,
942 mode_lib,
943 &(rq_param->sizing.rq_l), 695 &(rq_param->sizing.rq_l),
944 &(rq_param->dlg.rq_l), 696 &(rq_param->dlg.rq_l),
945 &(rq_param->misc.rq_l), 697 &(rq_param->misc.rq_l),
946 pipe_src_param, 698 pipe_src_param,
947 0); 699 0);
948 700
949 if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) { 701 if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) {
950 /* get param for chroma surface */ 702 // get param for chroma surface
951 get_surf_rq_param( 703 get_surf_rq_param(mode_lib,
952 mode_lib,
953 &(rq_param->sizing.rq_c), 704 &(rq_param->sizing.rq_c),
954 &(rq_param->dlg.rq_c), 705 &(rq_param->dlg.rq_c),
955 &(rq_param->misc.rq_c), 706 &(rq_param->misc.rq_c),
@@ -957,355 +708,126 @@ void dml_rq_dlg_get_rq_params(
957 1); 708 1);
958 } 709 }
959 710
960 /* calculate how to split the det buffer space between luma and chroma */ 711 // calculate how to split the det buffer space between luma and chroma
961 handle_det_buf_split(mode_lib, rq_param, pipe_src_param); 712 handle_det_buf_split(mode_lib, rq_param, pipe_src_param);
962 print__rq_params_st(mode_lib, *rq_param); 713 print__rq_params_st(mode_lib, *rq_param);
963} 714}
964 715
965void dml_rq_dlg_get_rq_reg( 716void dml_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
966 struct display_mode_lib *mode_lib, 717 display_rq_regs_st *rq_regs,
967 struct _vcs_dpi_display_rq_regs_st *rq_regs, 718 const display_pipe_source_params_st pipe_src_param)
968 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
969{ 719{
970 struct _vcs_dpi_display_rq_params_st rq_param = {0}; 720 display_rq_params_st rq_param = {0};
971 721
972 memset(rq_regs, 0, sizeof(*rq_regs)); 722 memset(rq_regs, 0, sizeof(*rq_regs));
973
974 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_src_param); 723 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_src_param);
975 extract_rq_regs(mode_lib, rq_regs, rq_param); 724 extract_rq_regs(mode_lib, rq_regs, rq_param);
976 725
977 print__rq_regs_st(mode_lib, *rq_regs); 726 print__rq_regs_st(mode_lib, *rq_regs);
978} 727}
979 728
980/* TODO: Need refactor, so this is used by dml_rq_dlg_get_dlg_params as well 729// Note: currently taken in as is.
981 * The problem is that there are some intermediate terms that would need by 730// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
982 * some dlg calculation (i.e. rest of prefetch and active prog guide calculation) 731void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
983 */ 732 const display_e2e_pipe_params_st *e2e_pipe_param,
984void dml_rq_dlg_get_dlg_params_prefetch( 733 const unsigned int num_pipes,
985 struct display_mode_lib *mode_lib, 734 const unsigned int pipe_idx,
986 struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param, 735 display_dlg_regs_st *disp_dlg_regs,
987 struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, 736 display_ttu_regs_st *disp_ttu_regs,
988 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, 737 const display_rq_dlg_params_st rq_dlg_param,
989 struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, 738 const display_dlg_sys_params_st dlg_sys_param,
990 const bool cstate_en,
991 const bool pstate_en,
992 const bool vm_en)
993{
994 /* Prefetch */
995 unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
996 bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
997 unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
998 const double prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
999 double min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
1000 double t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
1001
1002 bool dcc_en = e2e_pipe_param.pipe.src.dcc;
1003 bool dual_plane = is_dual_plane(
1004 (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
1005 unsigned int bytes_per_element_l = get_bytes_per_element(
1006 (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
1007 0);
1008 unsigned int bytes_per_element_c = get_bytes_per_element(
1009 (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
1010 1);
1011
1012 double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
1013 double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
1014 double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
1015
1016 double line_time_in_us = (htotal / pclk_freq_in_mhz);
1017 double vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
1018 double vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
1019 double vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
1020 double vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
1021
1022 unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height;
1023 unsigned int swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
1024 unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
1025 unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
1026 unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
1027
1028 unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height;
1029 unsigned int swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
1030 unsigned int dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
1031 unsigned int vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
1032 unsigned int vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
1033 unsigned int vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
1034
1035 const unsigned int dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
1036 const unsigned int dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
1037 unsigned int pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz
1038 / dppclk_freq_in_mhz
1039 + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
1040 unsigned int dst_y_after_scaler = 0;
1041 unsigned int dst_x_after_scaler = 0;
1042
1043 unsigned int vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
1044
1045 double line_wait;
1046 double line_o;
1047 double line_setup;
1048 double line_calc;
1049 double dst_y_prefetch;
1050 double t_pre_us;
1051 int unsigned vm_bytes;
1052 int unsigned meta_row_bytes;
1053 int unsigned max_num_sw_l;
1054 int unsigned max_num_sw_c;
1055 int unsigned max_partial_sw_l;
1056 int unsigned max_partial_sw_c;
1057
1058 double max_vinit_l;
1059 double max_vinit_c;
1060 int unsigned lsw_l;
1061 int unsigned lsw_c;
1062 int unsigned sw_bytes_ub_l;
1063 int unsigned sw_bytes_ub_c;
1064 int unsigned sw_bytes;
1065 int unsigned dpte_row_bytes;
1066
1067 if (interlaced)
1068 vstartup_start = vstartup_start / 2;
1069
1070 if (vstartup_start >= min_vblank) {
1071 min_vblank = vstartup_start + 1;
1072 DTRACE(
1073 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1074 __func__,
1075 vstartup_start,
1076 min_vblank);
1077 }
1078
1079 if (e2e_pipe_param.pipe.src.is_hsplit)
1080 dst_x_after_scaler = pixel_rate_delay_subtotal
1081 + e2e_pipe_param.pipe.dest.recout_width;
1082 else
1083 dst_x_after_scaler = pixel_rate_delay_subtotal;
1084
1085 if (e2e_pipe_param.dout.output_format == dm_420)
1086 dst_y_after_scaler = 1;
1087 else
1088 dst_y_after_scaler = 0;
1089
1090 if (dst_x_after_scaler >= htotal) {
1091 dst_x_after_scaler = dst_x_after_scaler - htotal;
1092 dst_y_after_scaler = dst_y_after_scaler + 1;
1093 }
1094
1095 DTRACE("DLG: %s: htotal = %d", __func__, htotal);
1096 DTRACE(
1097 "DLG: %s: pixel_rate_delay_subtotal = %d",
1098 __func__,
1099 pixel_rate_delay_subtotal);
1100 DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler);
1101 DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler);
1102
1103 line_wait = mode_lib->soc.urgent_latency_us;
1104 if (cstate_en)
1105 line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
1106 if (pstate_en)
1107 line_wait = dml_max(
1108 mode_lib->soc.dram_clock_change_latency_us
1109 + mode_lib->soc.urgent_latency_us,
1110 line_wait);
1111 line_wait = line_wait / line_time_in_us;
1112
1113 line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
1114 line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
1115 line_calc = t_calc_us / line_time_in_us;
1116
1117 DTRACE(
1118 "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f",
1119 __func__,
1120 (double) mode_lib->soc.sr_enter_plus_exit_time_us);
1121 DTRACE(
1122 "DLG: %s: soc.dram_clock_change_latency_us = %3.2f",
1123 __func__,
1124 (double) mode_lib->soc.dram_clock_change_latency_us);
1125
1126 DTRACE("DLG: %s: urgent_latency_us = %3.2f", __func__, mode_lib->soc.urgent_latency_us);
1127 DTRACE(
1128 "DLG: %s: t_srx_delay_us = %3.2f",
1129 __func__,
1130 (double) dlg_sys_param.t_srx_delay_us);
1131 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
1132 DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
1133 DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
1134 DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset);
1135 DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait);
1136 DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o);
1137 DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup);
1138 DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc);
1139
1140 dst_y_prefetch = ((double) min_vblank - 1.0)
1141 - (line_setup + line_calc + line_wait + line_o);
1142 DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
1143 ASSERT(dst_y_prefetch >= 2.0);
1144
1145 dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4;
1146 DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
1147
1148 t_pre_us = dst_y_prefetch * line_time_in_us;
1149 vm_bytes = 0;
1150 meta_row_bytes = 0;
1151
1152 if (dcc_en && vm_en)
1153 vm_bytes = meta_pte_bytes_per_frame_ub_l;
1154 if (dcc_en)
1155 meta_row_bytes = meta_bytes_per_row_ub_l;
1156
1157 max_num_sw_l = 0;
1158 max_num_sw_c = 0;
1159 max_partial_sw_l = 0;
1160 max_partial_sw_c = 0;
1161
1162 max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
1163 max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
1164
1165 get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
1166 if (dual_plane)
1167 get_swath_need(
1168 mode_lib,
1169 &max_num_sw_c,
1170 &max_partial_sw_c,
1171 swath_height_c,
1172 max_vinit_c);
1173
1174 lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
1175 lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
1176 sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
1177 sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
1178 sw_bytes = 0;
1179 dpte_row_bytes = 0;
1180
1181 if (vm_en) {
1182 if (dual_plane)
1183 dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
1184 else
1185 dpte_row_bytes = dpte_bytes_per_row_ub_l;
1186 } else {
1187 dpte_row_bytes = 0;
1188 }
1189
1190 if (dual_plane)
1191 sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
1192 else
1193 sw_bytes = sw_bytes_ub_l;
1194
1195 DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l);
1196 DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c);
1197 DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes);
1198 DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes);
1199 DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes);
1200 DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes);
1201
1202 prefetch_param->prefetch_bw =
1203 (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
1204 prefetch_param->flip_bytes = (vm_bytes + dpte_row_bytes + meta_row_bytes);
1205}
1206
1207/* Note: currently taken in as is.
1208 * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
1209 */
1210void dml_rq_dlg_get_dlg_params(
1211 struct display_mode_lib *mode_lib,
1212 struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs,
1213 struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs,
1214 const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
1215 const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
1216 const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
1217 const bool cstate_en, 739 const bool cstate_en,
1218 const bool pstate_en, 740 const bool pstate_en,
1219 const bool vm_en, 741 const bool vm_en,
1220 const bool iflip_en) 742 const bool ignore_viewport_pos,
743 const bool immediate_flip_support)
1221{ 744{
1222 /* Timing */ 745 const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
1223 unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; 746 const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
1224 unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end; 747 const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout;
1225 unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start; 748 const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
1226 unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end; 749 const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth;
1227 bool interlaced = e2e_pipe_param.pipe.dest.interlaced; 750 const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps;
751
752 // -------------------------
753 // Section 1.15.2.1: OTG dependent Params
754 // -------------------------
755 // Timing
756 unsigned int htotal = dst->htotal;
757// unsigned int hblank_start = dst.hblank_start; // TODO: Remove
758 unsigned int hblank_end = dst->hblank_end;
759 unsigned int vblank_start = dst->vblank_start;
760 unsigned int vblank_end = dst->vblank_end;
1228 unsigned int min_vblank = mode_lib->ip.min_vblank_lines; 761 unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
1229 762
1230 double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; 763 double dppclk_freq_in_mhz = clks->dppclk_mhz;
1231 double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz; 764 double dispclk_freq_in_mhz = clks->dispclk_mhz;
1232 double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; 765 double refclk_freq_in_mhz = clks->refclk_mhz;
1233 double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; 766 double pclk_freq_in_mhz = dst->pixel_rate_mhz;
767 bool interlaced = dst->interlaced;
768
769 double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
1234 770
1235 double ref_freq_to_pix_freq;
1236 double prefetch_xy_calc_in_dcfclk;
1237 double min_dcfclk_mhz; 771 double min_dcfclk_mhz;
1238 double t_calc_us; 772 double t_calc_us;
1239 double min_ttu_vblank; 773 double min_ttu_vblank;
774
1240 double min_dst_y_ttu_vblank; 775 double min_dst_y_ttu_vblank;
1241 int unsigned dlg_vblank_start; 776 unsigned int dlg_vblank_start;
1242 bool dcc_en;
1243 bool dual_plane; 777 bool dual_plane;
1244 bool mode_422; 778 bool mode_422;
1245 unsigned int access_dir; 779 unsigned int access_dir;
1246 unsigned int bytes_per_element_l;
1247 unsigned int bytes_per_element_c;
1248 unsigned int vp_height_l; 780 unsigned int vp_height_l;
1249 unsigned int vp_width_l; 781 unsigned int vp_width_l;
1250 unsigned int vp_height_c; 782 unsigned int vp_height_c;
1251 unsigned int vp_width_c; 783 unsigned int vp_width_c;
784
785 // Scaling
1252 unsigned int htaps_l; 786 unsigned int htaps_l;
1253 unsigned int htaps_c; 787 unsigned int htaps_c;
1254 double hratios_l; 788 double hratio_l;
1255 double hratios_c; 789 double hratio_c;
1256 double vratio_l; 790 double vratio_l;
1257 double vratio_c; 791 double vratio_c;
792 bool scl_enable;
793
1258 double line_time_in_us; 794 double line_time_in_us;
1259 double vinit_l; 795 // double vinit_l;
1260 double vinit_c; 796 // double vinit_c;
1261 double vinit_bot_l; 797 // double vinit_bot_l;
1262 double vinit_bot_c; 798 // double vinit_bot_c;
1263 unsigned int swath_height_l; 799
800 // unsigned int swath_height_l;
1264 unsigned int swath_width_ub_l; 801 unsigned int swath_width_ub_l;
1265 unsigned int dpte_bytes_per_row_ub_l; 802 // unsigned int dpte_bytes_per_row_ub_l;
1266 unsigned int dpte_groups_per_row_ub_l; 803 unsigned int dpte_groups_per_row_ub_l;
1267 unsigned int meta_pte_bytes_per_frame_ub_l; 804 // unsigned int meta_pte_bytes_per_frame_ub_l;
1268 unsigned int meta_bytes_per_row_ub_l; 805 // unsigned int meta_bytes_per_row_ub_l;
1269 unsigned int swath_height_c; 806
807 // unsigned int swath_height_c;
1270 unsigned int swath_width_ub_c; 808 unsigned int swath_width_ub_c;
1271 unsigned int dpte_bytes_per_row_ub_c; 809 // unsigned int dpte_bytes_per_row_ub_c;
1272 unsigned int dpte_groups_per_row_ub_c; 810 unsigned int dpte_groups_per_row_ub_c;
811
1273 unsigned int meta_chunks_per_row_ub_l; 812 unsigned int meta_chunks_per_row_ub_l;
813 unsigned int meta_chunks_per_row_ub_c;
1274 unsigned int vupdate_offset; 814 unsigned int vupdate_offset;
1275 unsigned int vupdate_width; 815 unsigned int vupdate_width;
1276 unsigned int vready_offset; 816 unsigned int vready_offset;
817
1277 unsigned int dppclk_delay_subtotal; 818 unsigned int dppclk_delay_subtotal;
1278 unsigned int dispclk_delay_subtotal; 819 unsigned int dispclk_delay_subtotal;
1279 unsigned int pixel_rate_delay_subtotal; 820 unsigned int pixel_rate_delay_subtotal;
821
1280 unsigned int vstartup_start; 822 unsigned int vstartup_start;
1281 unsigned int dst_x_after_scaler; 823 unsigned int dst_x_after_scaler;
1282 unsigned int dst_y_after_scaler; 824 unsigned int dst_y_after_scaler;
1283 double line_wait; 825 double line_wait;
1284 double line_o;
1285 double line_setup;
1286 double line_calc;
1287 double dst_y_prefetch; 826 double dst_y_prefetch;
1288 double t_pre_us;
1289 int unsigned vm_bytes;
1290 int unsigned meta_row_bytes;
1291 int unsigned max_num_sw_l;
1292 int unsigned max_num_sw_c;
1293 int unsigned max_partial_sw_l;
1294 int unsigned max_partial_sw_c;
1295 double max_vinit_l;
1296 double max_vinit_c;
1297 int unsigned lsw_l;
1298 int unsigned lsw_c;
1299 int unsigned sw_bytes_ub_l;
1300 int unsigned sw_bytes_ub_c;
1301 int unsigned sw_bytes;
1302 int unsigned dpte_row_bytes;
1303 double prefetch_bw;
1304 double flip_bw;
1305 double t_vm_us;
1306 double t_r0_us;
1307 double dst_y_per_vm_vblank; 827 double dst_y_per_vm_vblank;
1308 double dst_y_per_row_vblank; 828 double dst_y_per_row_vblank;
829 double dst_y_per_vm_flip;
830 double dst_y_per_row_flip;
1309 double min_dst_y_per_vm_vblank; 831 double min_dst_y_per_vm_vblank;
1310 double min_dst_y_per_row_vblank; 832 double min_dst_y_per_row_vblank;
1311 double lsw; 833 double lsw;
@@ -1314,6 +836,7 @@ void dml_rq_dlg_get_dlg_params(
1314 unsigned int req_per_swath_ub_l; 836 unsigned int req_per_swath_ub_l;
1315 unsigned int req_per_swath_ub_c; 837 unsigned int req_per_swath_ub_c;
1316 unsigned int meta_row_height_l; 838 unsigned int meta_row_height_l;
839 unsigned int meta_row_height_c;
1317 unsigned int swath_width_pixels_ub_l; 840 unsigned int swath_width_pixels_ub_l;
1318 unsigned int swath_width_pixels_ub_c; 841 unsigned int swath_width_pixels_ub_c;
1319 unsigned int scaler_rec_in_width_l; 842 unsigned int scaler_rec_in_width_l;
@@ -1328,59 +851,52 @@ void dml_rq_dlg_get_dlg_params(
1328 double refcyc_per_line_delivery_pre_c; 851 double refcyc_per_line_delivery_pre_c;
1329 double refcyc_per_line_delivery_l; 852 double refcyc_per_line_delivery_l;
1330 double refcyc_per_line_delivery_c; 853 double refcyc_per_line_delivery_c;
854
1331 double refcyc_per_req_delivery_pre_l; 855 double refcyc_per_req_delivery_pre_l;
1332 double refcyc_per_req_delivery_pre_c; 856 double refcyc_per_req_delivery_pre_c;
1333 double refcyc_per_req_delivery_l; 857 double refcyc_per_req_delivery_l;
1334 double refcyc_per_req_delivery_c; 858 double refcyc_per_req_delivery_c;
859
860 unsigned int full_recout_width;
861 double xfc_transfer_delay;
862 double xfc_precharge_delay;
863 double xfc_remote_surface_flip_latency;
864 double xfc_dst_y_delta_drq_limit;
865 double xfc_prefetch_margin;
1335 double refcyc_per_req_delivery_pre_cur0; 866 double refcyc_per_req_delivery_pre_cur0;
1336 double refcyc_per_req_delivery_cur0; 867 double refcyc_per_req_delivery_cur0;
1337 int unsigned full_recout_width; 868 double refcyc_per_req_delivery_pre_cur1;
1338 double hratios_cur0; 869 double refcyc_per_req_delivery_cur1;
1339 unsigned int cur0_src_width;
1340 enum cursor_bpp cur0_bpp;
1341 unsigned int cur0_req_size;
1342 unsigned int cur0_req_width;
1343 double cur0_width_ub;
1344 double cur0_req_per_width;
1345 double hactive_cur0;
1346 870
1347 memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs)); 871 memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
1348 memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs)); 872 memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
1349 873
1350 DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en); 874 dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en);
1351 DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en); 875 dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en);
1352 DTRACE("DLG: %s: vm_en = %d", __func__, vm_en); 876 dml_print("DML_DLG: %s: vm_en = %d\n", __func__, vm_en);
1353 DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en); 877 dml_print("DML_DLG: %s: ignore_viewport_pos = %d\n", __func__, ignore_viewport_pos);
1354 878 dml_print("DML_DLG: %s: immediate_flip_support = %d\n", __func__, immediate_flip_support);
1355 /* ------------------------- */ 879
1356 /* Section 1.5.2.1: OTG dependent Params */ 880 dml_print("DML_DLG: %s: dppclk_freq_in_mhz = %3.2f\n", __func__, dppclk_freq_in_mhz);
1357 /* ------------------------- */ 881 dml_print("DML_DLG: %s: dispclk_freq_in_mhz = %3.2f\n", __func__, dispclk_freq_in_mhz);
1358 DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz); 882 dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
1359 DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz); 883 dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz);
1360 DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz); 884 dml_print("DML_DLG: %s: interlaced = %d\n", __func__, interlaced);
1361 DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
1362 DTRACE("DLG: %s: interlaced = %d", __func__, interlaced);
1363
1364 ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
1365 ASSERT(ref_freq_to_pix_freq < 4.0); 885 ASSERT(ref_freq_to_pix_freq < 4.0);
886
1366 disp_dlg_regs->ref_freq_to_pix_freq = 887 disp_dlg_regs->ref_freq_to_pix_freq =
1367 (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19)); 888 (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
1368 disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal 889 disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal
1369 * dml_pow(2, 8)); 890 * dml_pow(2, 8));
891 disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits
1370 disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end 892 disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end
1371 * (double) ref_freq_to_pix_freq); 893 * (double) ref_freq_to_pix_freq);
1372 ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); 894 ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13));
1373 disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */
1374 895
1375 prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
1376 min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; 896 min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
1377 t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; 897 set_prefetch_mode(mode_lib, cstate_en, pstate_en, ignore_viewport_pos, immediate_flip_support);
1378 min_ttu_vblank = dlg_sys_param.t_urg_wm_us; 898 t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes);
1379 if (cstate_en) 899 min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1380 min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank);
1381 if (pstate_en)
1382 min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank);
1383 min_ttu_vblank = min_ttu_vblank + t_calc_us;
1384 900
1385 min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal; 901 min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal;
1386 dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start; 902 dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
@@ -1389,383 +905,202 @@ void dml_rq_dlg_get_dlg_params(
1389 + min_dst_y_ttu_vblank) * dml_pow(2, 2)); 905 + min_dst_y_ttu_vblank) * dml_pow(2, 2));
1390 ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18)); 906 ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18));
1391 907
1392 DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz); 908 dml_print("DML_DLG: %s: min_dcfclk_mhz = %3.2f\n",
1393 DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank); 909 __func__,
1394 DTRACE( 910 min_dcfclk_mhz);
1395 "DLG: %s: min_dst_y_ttu_vblank = %3.2f", 911 dml_print("DML_DLG: %s: min_ttu_vblank = %3.2f\n",
912 __func__,
913 min_ttu_vblank);
914 dml_print("DML_DLG: %s: min_dst_y_ttu_vblank = %3.2f\n",
1396 __func__, 915 __func__,
1397 min_dst_y_ttu_vblank); 916 min_dst_y_ttu_vblank);
1398 DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us); 917 dml_print("DML_DLG: %s: t_calc_us = %3.2f\n",
1399 DTRACE( 918 __func__,
1400 "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x", 919 t_calc_us);
920 dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x\n",
1401 __func__, 921 __func__,
1402 disp_dlg_regs->min_dst_y_next_start); 922 disp_dlg_regs->min_dst_y_next_start);
1403 DTRACE( 923 dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n",
1404 "DLG: %s: ref_freq_to_pix_freq = %3.2f",
1405 __func__, 924 __func__,
1406 ref_freq_to_pix_freq); 925 ref_freq_to_pix_freq);
1407 926
1408 /* ------------------------- */ 927 // -------------------------
1409 /* Section 1.5.2.2: Prefetch, Active and TTU */ 928 // Section 1.15.2.2: Prefetch, Active and TTU
1410 /* ------------------------- */ 929 // -------------------------
1411 /* Prefetch Calc */ 930 // Prefetch Calc
1412 /* Source */ 931 // Source
1413 dcc_en = e2e_pipe_param.pipe.src.dcc; 932// dcc_en = src.dcc;
1414 dual_plane = is_dual_plane( 933 dual_plane = is_dual_plane((enum source_format_class)(src->source_format));
1415 (enum source_format_class) e2e_pipe_param.pipe.src.source_format); 934 mode_422 = 0; // FIXME
1416 mode_422 = 0; /* FIXME */ 935 access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
1417 access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ 936// bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0);
1418 bytes_per_element_l = get_bytes_per_element( 937// bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1);
1419 (enum source_format_class) e2e_pipe_param.pipe.src.source_format, 938 vp_height_l = src->viewport_height;
1420 0); 939 vp_width_l = src->viewport_width;
1421 bytes_per_element_c = get_bytes_per_element( 940 vp_height_c = src->viewport_height_c;
1422 (enum source_format_class) e2e_pipe_param.pipe.src.source_format, 941 vp_width_c = src->viewport_width_c;
1423 1); 942
1424 vp_height_l = e2e_pipe_param.pipe.src.viewport_height; 943 // Scaling
1425 vp_width_l = e2e_pipe_param.pipe.src.viewport_width; 944 htaps_l = taps->htaps;
1426 vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c; 945 htaps_c = taps->htaps_c;
1427 vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c; 946 hratio_l = scl->hscl_ratio;
1428 947 hratio_c = scl->hscl_ratio_c;
1429 /* Scaling */ 948 vratio_l = scl->vscl_ratio;
1430 htaps_l = e2e_pipe_param.pipe.scale_taps.htaps; 949 vratio_c = scl->vscl_ratio_c;
1431 htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c; 950 scl_enable = scl->scl_enable;
1432 hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
1433 hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c;
1434 vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio;
1435 vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c;
1436 951
1437 line_time_in_us = (htotal / pclk_freq_in_mhz); 952 line_time_in_us = (htotal / pclk_freq_in_mhz);
1438 vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; 953// vinit_l = scl.vinit;
1439 vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; 954// vinit_c = scl.vinit_c;
1440 vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; 955// vinit_bot_l = scl.vinit_bot;
1441 vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; 956// vinit_bot_c = scl.vinit_bot_c;
1442 957
1443 swath_height_l = rq_dlg_param.rq_l.swath_height; 958// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height;
1444 swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; 959 swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
1445 dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; 960// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
1446 dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; 961 dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
1447 meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; 962// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
1448 meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; 963// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
1449 964
1450 swath_height_c = rq_dlg_param.rq_c.swath_height; 965// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height;
1451 swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; 966 swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
1452 dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; 967 // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
1453 dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; 968 dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
1454 969
1455 meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; 970 meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
1456 vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; 971 meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub;
1457 vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; 972 vupdate_offset = dst->vupdate_offset;
1458 vready_offset = e2e_pipe_param.pipe.dest.vready_offset; 973 vupdate_width = dst->vupdate_width;
974 vready_offset = dst->vready_offset;
1459 975
1460 dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; 976 dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
1461 dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; 977 dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
978
979 if (scl_enable)
980 dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl;
981 else
982 dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only;
983
984 dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter
985 + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor;
986
987 if (dout->dsc_enable) {
988 double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
989
990 dispclk_delay_subtotal += dsc_delay;
991 }
992
1462 pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz 993 pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
1463 + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; 994 + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
1464 995
1465 vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; 996 vstartup_start = dst->vstartup_start;
997 if (interlaced) {
998 if (vstartup_start / 2.0
999 - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
1000 <= vblank_end / 2.0)
1001 disp_dlg_regs->vready_after_vcount0 = 1;
1002 else
1003 disp_dlg_regs->vready_after_vcount0 = 0;
1004 } else {
1005 if (vstartup_start
1006 - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
1007 <= vblank_end)
1008 disp_dlg_regs->vready_after_vcount0 = 1;
1009 else
1010 disp_dlg_regs->vready_after_vcount0 = 0;
1011 }
1466 1012
1013 // TODO: Where is this coming from?
1467 if (interlaced) 1014 if (interlaced)
1468 vstartup_start = vstartup_start / 2; 1015 vstartup_start = vstartup_start / 2;
1469 1016
1017 // TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp?
1470 if (vstartup_start >= min_vblank) { 1018 if (vstartup_start >= min_vblank) {
1471 DTRACE( 1019 dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n",
1472 "WARNING_DLG: %s: vblank_start=%d vblank_end=%d",
1473 __func__, 1020 __func__,
1474 vblank_start, 1021 vblank_start,
1475 vblank_end); 1022 vblank_end);
1476 DTRACE( 1023 dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
1477 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1478 __func__, 1024 __func__,
1479 vstartup_start, 1025 vstartup_start,
1480 min_vblank); 1026 min_vblank);
1481 min_vblank = vstartup_start + 1; 1027 min_vblank = vstartup_start + 1;
1482 DTRACE( 1028 dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
1483 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1484 __func__, 1029 __func__,
1485 vstartup_start, 1030 vstartup_start,
1486 min_vblank); 1031 min_vblank);
1487 } 1032 }
1488 1033
1489 dst_x_after_scaler = 0; 1034 dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1490 dst_y_after_scaler = 0; 1035 dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1491
1492 if (e2e_pipe_param.pipe.src.is_hsplit)
1493 dst_x_after_scaler = pixel_rate_delay_subtotal
1494 + e2e_pipe_param.pipe.dest.recout_width;
1495 else
1496 dst_x_after_scaler = pixel_rate_delay_subtotal;
1497
1498 if (e2e_pipe_param.dout.output_format == dm_420)
1499 dst_y_after_scaler = 1;
1500 else
1501 dst_y_after_scaler = 0;
1502 1036
1503 if (dst_x_after_scaler >= htotal) { 1037 dml_print("DML_DLG: %s: htotal = %d\n", __func__, htotal);
1504 dst_x_after_scaler = dst_x_after_scaler - htotal; 1038 dml_print("DML_DLG: %s: pixel_rate_delay_subtotal = %d\n",
1505 dst_y_after_scaler = dst_y_after_scaler + 1;
1506 }
1507
1508 DTRACE("DLG: %s: htotal = %d", __func__, htotal);
1509 DTRACE(
1510 "DLG: %s: pixel_rate_delay_subtotal = %d",
1511 __func__, 1039 __func__,
1512 pixel_rate_delay_subtotal); 1040 pixel_rate_delay_subtotal);
1513 DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler); 1041 dml_print("DML_DLG: %s: dst_x_after_scaler = %d\n",
1514 DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler); 1042 __func__,
1043 dst_x_after_scaler);
1044 dml_print("DML_DLG: %s: dst_y_after_scaler = %d\n",
1045 __func__,
1046 dst_y_after_scaler);
1515 1047
1048 // Lwait
1516 line_wait = mode_lib->soc.urgent_latency_us; 1049 line_wait = mode_lib->soc.urgent_latency_us;
1517 if (cstate_en) 1050 if (cstate_en)
1518 line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait); 1051 line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
1519 if (pstate_en) 1052 if (pstate_en)
1520 line_wait = dml_max( 1053 line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us
1521 mode_lib->soc.dram_clock_change_latency_us
1522 + mode_lib->soc.urgent_latency_us, 1054 + mode_lib->soc.urgent_latency_us,
1523 line_wait); 1055 line_wait);
1524 line_wait = line_wait / line_time_in_us; 1056 line_wait = line_wait / line_time_in_us;
1525 1057
1526 line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal; 1058 dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1527 line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal; 1059 dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
1528 line_calc = t_calc_us / line_time_in_us;
1529 1060
1530 DTRACE( 1061 dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib,
1531 "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f", 1062 e2e_pipe_param,
1532 __func__, 1063 num_pipes,
1533 (double) mode_lib->soc.sr_enter_plus_exit_time_us); 1064 pipe_idx);
1534 DTRACE( 1065 dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib,
1535 "DLG: %s: soc.dram_clock_change_latency_us = %3.2f", 1066 e2e_pipe_param,
1536 __func__, 1067 num_pipes,
1537 (double) mode_lib->soc.dram_clock_change_latency_us); 1068 pipe_idx);
1538 DTRACE( 1069 dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1539 "DLG: %s: soc.urgent_latency_us = %3.2f", 1070 dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1540 __func__,
1541 mode_lib->soc.urgent_latency_us);
1542
1543 DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l);
1544 if (dual_plane)
1545 DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c);
1546
1547 DTRACE(
1548 "DLG: %s: t_srx_delay_us = %3.2f",
1549 __func__,
1550 (double) dlg_sys_param.t_srx_delay_us);
1551 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
1552 DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
1553 DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
1554 DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset);
1555 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us);
1556 DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait);
1557 DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o);
1558 DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup);
1559 DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc);
1560
1561 dst_y_prefetch = ((double) min_vblank - 1.0)
1562 - (line_setup + line_calc + line_wait + line_o);
1563 DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
1564 ASSERT(dst_y_prefetch >= 2.0);
1565
1566 dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4;
1567 DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
1568
1569 t_pre_us = dst_y_prefetch * line_time_in_us;
1570 vm_bytes = 0;
1571 meta_row_bytes = 0;
1572
1573 if (dcc_en && vm_en)
1574 vm_bytes = meta_pte_bytes_per_frame_ub_l;
1575 if (dcc_en)
1576 meta_row_bytes = meta_bytes_per_row_ub_l;
1577
1578 max_num_sw_l = 0;
1579 max_num_sw_c = 0;
1580 max_partial_sw_l = 0;
1581 max_partial_sw_c = 0;
1582
1583 max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
1584 max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
1585
1586 get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
1587 if (dual_plane)
1588 get_swath_need(
1589 mode_lib,
1590 &max_num_sw_c,
1591 &max_partial_sw_c,
1592 swath_height_c,
1593 max_vinit_c);
1594
1595 lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
1596 lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
1597 sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
1598 sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
1599 sw_bytes = 0;
1600 dpte_row_bytes = 0;
1601
1602 if (vm_en) {
1603 if (dual_plane)
1604 dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
1605 else
1606 dpte_row_bytes = dpte_bytes_per_row_ub_l;
1607 } else {
1608 dpte_row_bytes = 0;
1609 }
1610
1611 if (dual_plane)
1612 sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
1613 else
1614 sw_bytes = sw_bytes_ub_l;
1615
1616 DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l);
1617 DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c);
1618 DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes);
1619 DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes);
1620 DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes);
1621 DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes);
1622
1623 prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
1624 flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw)
1625 / (double) dlg_sys_param.total_flip_bytes;
1626 t_vm_us = line_time_in_us / 4.0;
1627 if (vm_en && dcc_en) {
1628 t_vm_us = dml_max(
1629 dlg_sys_param.t_extra_us,
1630 dml_max((double) vm_bytes / prefetch_bw, t_vm_us));
1631
1632 if (iflip_en && !dual_plane) {
1633 t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us);
1634 if (flip_bw > 0.)
1635 t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us);
1636 }
1637 }
1638
1639 t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us);
1640
1641 if (vm_en || dcc_en) {
1642 t_r0_us = dml_max(
1643 (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw,
1644 dlg_sys_param.t_extra_us);
1645 t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us);
1646
1647 if (iflip_en && !dual_plane) {
1648 t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us);
1649 if (flip_bw > 0.)
1650 t_r0_us = dml_max(
1651 (dpte_row_bytes + meta_row_bytes) / flip_bw,
1652 t_r0_us);
1653 }
1654 }
1655
1656 disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */
1657 disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */
1658 ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
1659 DTRACE(
1660 "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x",
1661 __func__,
1662 disp_dlg_regs->dst_y_after_scaler);
1663 DTRACE(
1664 "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x",
1665 __func__,
1666 disp_dlg_regs->refcyc_x_after_scaler);
1667
1668 disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
1669 DTRACE(
1670 "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d",
1671 __func__,
1672 disp_dlg_regs->dst_y_prefetch);
1673
1674 dst_y_per_vm_vblank = 0.0;
1675 dst_y_per_row_vblank = 0.0;
1676
1677 dst_y_per_vm_vblank = t_vm_us / line_time_in_us;
1678 dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125)) / 4.0;
1679 disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
1680
1681 dst_y_per_row_vblank = t_r0_us / line_time_in_us;
1682 dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125)) / 4.0;
1683 disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
1684
1685 DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l);
1686 DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c);
1687 DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l);
1688 DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c);
1689
1690 DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw);
1691 DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw);
1692 DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us);
1693 DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us);
1694 DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us);
1695 DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank);
1696 DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank);
1697 DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch);
1698 1071
1699 min_dst_y_per_vm_vblank = 8.0; 1072 min_dst_y_per_vm_vblank = 8.0;
1700 min_dst_y_per_row_vblank = 16.0; 1073 min_dst_y_per_row_vblank = 16.0;
1074
1075 // magic!
1701 if (htotal <= 75) { 1076 if (htotal <= 75) {
1702 min_vblank = 300; 1077 min_vblank = 300;
1703 min_dst_y_per_vm_vblank = 100.0; 1078 min_dst_y_per_vm_vblank = 100.0;
1704 min_dst_y_per_row_vblank = 100.0; 1079 min_dst_y_per_row_vblank = 100.0;
1705 } 1080 }
1706 1081
1082 dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank);
1083 dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank);
1084
1707 ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank); 1085 ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
1708 ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank); 1086 ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
1709 1087
1710 ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank)); 1088 ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
1711 lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank); 1089 lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
1712 1090
1713 DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw); 1091 dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw);
1714
1715 vratio_pre_l = get_vratio_pre(
1716 mode_lib,
1717 max_num_sw_l,
1718 max_partial_sw_l,
1719 swath_height_l,
1720 max_vinit_l,
1721 lsw);
1722 vratio_pre_c = 1.0;
1723 if (dual_plane)
1724 vratio_pre_c = get_vratio_pre(
1725 mode_lib,
1726 max_num_sw_c,
1727 max_partial_sw_c,
1728 swath_height_c,
1729 max_vinit_c,
1730 lsw);
1731
1732 DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l);
1733 DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c);
1734
1735 ASSERT(vratio_pre_l <= 4.0);
1736 if (vratio_pre_l >= 4.0)
1737 disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1;
1738 else
1739 disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
1740 1092
1741 ASSERT(vratio_pre_c <= 4.0); 1093 vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1742 if (vratio_pre_c >= 4.0) 1094 vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
1743 disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1;
1744 else
1745 disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
1746 1095
1747 disp_dlg_regs->refcyc_per_pte_group_vblank_l = 1096 dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l);
1748 (unsigned int) (dst_y_per_row_vblank * (double) htotal 1097 dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c);
1749 * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
1750 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
1751
1752 disp_dlg_regs->refcyc_per_pte_group_vblank_c =
1753 (unsigned int) (dst_y_per_row_vblank * (double) htotal
1754 * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c);
1755 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13));
1756
1757 disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
1758 (unsigned int) (dst_y_per_row_vblank * (double) htotal
1759 * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
1760 ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
1761 1098
1762 disp_dlg_regs->refcyc_per_meta_chunk_vblank_c = 1099 // Active
1763 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 */
1764
1765 /* Active */
1766 req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; 1100 req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
1767 req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; 1101 req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
1768 meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; 1102 meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
1103 meta_row_height_c = rq_dlg_param.rq_c.meta_row_height;
1769 swath_width_pixels_ub_l = 0; 1104 swath_width_pixels_ub_l = 0;
1770 swath_width_pixels_ub_c = 0; 1105 swath_width_pixels_ub_c = 0;
1771 scaler_rec_in_width_l = 0; 1106 scaler_rec_in_width_l = 0;
@@ -1773,40 +1108,8 @@ void dml_rq_dlg_get_dlg_params(
1773 dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; 1108 dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
1774 dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; 1109 dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
1775 1110
1776 disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
1777 / (double) vratio_l * dml_pow(2, 2));
1778 ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
1779
1780 disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
1781 / (double) vratio_c * dml_pow(2, 2));
1782 ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17));
1783
1784 disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
1785 / (double) vratio_l * dml_pow(2, 2));
1786 ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
1787
1788 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 */
1789
1790 disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
1791 / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1792 / (double) dpte_groups_per_row_ub_l);
1793 if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
1794 disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
1795
1796 disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c
1797 / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq
1798 / (double) dpte_groups_per_row_ub_c);
1799 if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
1800 disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
1801
1802 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
1803 / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1804 / (double) meta_chunks_per_row_ub_l);
1805 if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
1806 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
1807
1808 if (mode_422) { 1111 if (mode_422) {
1809 swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */ 1112 swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element
1810 swath_width_pixels_ub_c = swath_width_ub_c * 2; 1113 swath_width_pixels_ub_c = swath_width_ub_c * 2;
1811 } else { 1114 } else {
1812 swath_width_pixels_ub_l = swath_width_ub_l * 1; 1115 swath_width_pixels_ub_l = swath_width_ub_l * 1;
@@ -1821,15 +1124,15 @@ void dml_rq_dlg_get_dlg_params(
1821 if (htaps_l <= 1) 1124 if (htaps_l <= 1)
1822 min_hratio_fact_l = 2.0; 1125 min_hratio_fact_l = 2.0;
1823 else if (htaps_l <= 6) { 1126 else if (htaps_l <= 6) {
1824 if ((hratios_l * 2.0) > 4.0) 1127 if ((hratio_l * 2.0) > 4.0)
1825 min_hratio_fact_l = 4.0; 1128 min_hratio_fact_l = 4.0;
1826 else 1129 else
1827 min_hratio_fact_l = hratios_l * 2.0; 1130 min_hratio_fact_l = hratio_l * 2.0;
1828 } else { 1131 } else {
1829 if (hratios_l > 4.0) 1132 if (hratio_l > 4.0)
1830 min_hratio_fact_l = 4.0; 1133 min_hratio_fact_l = 4.0;
1831 else 1134 else
1832 min_hratio_fact_l = hratios_l; 1135 min_hratio_fact_l = hratio_l;
1833 } 1136 }
1834 1137
1835 hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz; 1138 hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
@@ -1837,15 +1140,15 @@ void dml_rq_dlg_get_dlg_params(
1837 if (htaps_c <= 1) 1140 if (htaps_c <= 1)
1838 min_hratio_fact_c = 2.0; 1141 min_hratio_fact_c = 2.0;
1839 else if (htaps_c <= 6) { 1142 else if (htaps_c <= 6) {
1840 if ((hratios_c * 2.0) > 4.0) 1143 if ((hratio_c * 2.0) > 4.0)
1841 min_hratio_fact_c = 4.0; 1144 min_hratio_fact_c = 4.0;
1842 else 1145 else
1843 min_hratio_fact_c = hratios_c * 2.0; 1146 min_hratio_fact_c = hratio_c * 2.0;
1844 } else { 1147 } else {
1845 if (hratios_c > 4.0) 1148 if (hratio_c > 4.0)
1846 min_hratio_fact_c = 4.0; 1149 min_hratio_fact_c = 4.0;
1847 else 1150 else
1848 min_hratio_fact_c = hratios_c; 1151 min_hratio_fact_c = hratio_c;
1849 } 1152 }
1850 1153
1851 hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz; 1154 hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
@@ -1859,97 +1162,90 @@ void dml_rq_dlg_get_dlg_params(
1859 refcyc_per_req_delivery_pre_c = 0.; 1162 refcyc_per_req_delivery_pre_c = 0.;
1860 refcyc_per_req_delivery_l = 0.; 1163 refcyc_per_req_delivery_l = 0.;
1861 refcyc_per_req_delivery_c = 0.; 1164 refcyc_per_req_delivery_c = 0.;
1862 refcyc_per_req_delivery_pre_cur0 = 0.;
1863 refcyc_per_req_delivery_cur0 = 0.;
1864 1165
1865 full_recout_width = 0; 1166 full_recout_width = 0;
1866 if (e2e_pipe_param.pipe.src.is_hsplit) { 1167 // In ODM
1867 if (e2e_pipe_param.pipe.dest.full_recout_width == 0) { 1168 if (src->is_hsplit) {
1868 DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__); 1169 // This "hack" is only allowed (and valid) for MPC combine. In ODM
1869 full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */ 1170 // combine, you MUST specify the full_recout_width...according to Oswin
1171 if (dst->full_recout_width == 0 && !dst->odm_combine) {
1172 dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n",
1173 __func__);
1174 full_recout_width = dst->recout_width * 2; // assume half split for dcn1
1870 } else 1175 } else
1871 full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width; 1176 full_recout_width = dst->full_recout_width;
1872 } else 1177 } else
1873 full_recout_width = e2e_pipe_param.pipe.dest.recout_width; 1178 full_recout_width = dst->recout_width;
1874 1179
1875 refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery( 1180 // mpc_combine and odm_combine are mutually exclusive
1876 mode_lib, 1181 refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
1877 refclk_freq_in_mhz, 1182 refclk_freq_in_mhz,
1878 pclk_freq_in_mhz, 1183 pclk_freq_in_mhz,
1184 dst->odm_combine,
1879 full_recout_width, 1185 full_recout_width,
1186 dst->hactive,
1880 vratio_pre_l, 1187 vratio_pre_l,
1881 hscale_pixel_rate_l, 1188 hscale_pixel_rate_l,
1882 swath_width_pixels_ub_l, 1189 swath_width_pixels_ub_l,
1883 1); /* per line */ 1190 1); // per line
1884 1191
1885 refcyc_per_line_delivery_l = get_refcyc_per_delivery( 1192 refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib,
1886 mode_lib,
1887 refclk_freq_in_mhz, 1193 refclk_freq_in_mhz,
1888 pclk_freq_in_mhz, 1194 pclk_freq_in_mhz,
1195 dst->odm_combine,
1889 full_recout_width, 1196 full_recout_width,
1197 dst->hactive,
1890 vratio_l, 1198 vratio_l,
1891 hscale_pixel_rate_l, 1199 hscale_pixel_rate_l,
1892 swath_width_pixels_ub_l, 1200 swath_width_pixels_ub_l,
1893 1); /* per line */ 1201 1); // per line
1894 1202
1895 DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width); 1203 dml_print("DML_DLG: %s: full_recout_width = %d\n",
1896 DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l);
1897 DTRACE(
1898 "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f",
1899 __func__, 1204 __func__,
1900 refcyc_per_line_delivery_pre_l); 1205 full_recout_width);
1901 DTRACE( 1206 dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n",
1902 "DLG: %s: refcyc_per_line_delivery_l = %3.2f", 1207 __func__,
1208 hscale_pixel_rate_l);
1209 dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n",
1903 __func__, 1210 __func__,
1904 refcyc_per_line_delivery_l);
1905
1906 disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(
1907 refcyc_per_line_delivery_pre_l); 1211 refcyc_per_line_delivery_pre_l);
1908 disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor( 1212 dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n",
1213 __func__,
1909 refcyc_per_line_delivery_l); 1214 refcyc_per_line_delivery_l);
1910 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
1911 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
1912 1215
1913 if (dual_plane) { 1216 if (dual_plane) {
1914 refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery( 1217 refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
1915 mode_lib,
1916 refclk_freq_in_mhz, 1218 refclk_freq_in_mhz,
1917 pclk_freq_in_mhz, 1219 pclk_freq_in_mhz,
1220 dst->odm_combine,
1918 full_recout_width, 1221 full_recout_width,
1222 dst->hactive,
1919 vratio_pre_c, 1223 vratio_pre_c,
1920 hscale_pixel_rate_c, 1224 hscale_pixel_rate_c,
1921 swath_width_pixels_ub_c, 1225 swath_width_pixels_ub_c,
1922 1); /* per line */ 1226 1); // per line
1923 1227
1924 refcyc_per_line_delivery_c = get_refcyc_per_delivery( 1228 refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib,
1925 mode_lib,
1926 refclk_freq_in_mhz, 1229 refclk_freq_in_mhz,
1927 pclk_freq_in_mhz, 1230 pclk_freq_in_mhz,
1231 dst->odm_combine,
1928 full_recout_width, 1232 full_recout_width,
1233 dst->hactive,
1929 vratio_c, 1234 vratio_c,
1930 hscale_pixel_rate_c, 1235 hscale_pixel_rate_c,
1931 swath_width_pixels_ub_c, 1236 swath_width_pixels_ub_c,
1932 1); /* per line */ 1237 1); // per line
1933 1238
1934 DTRACE( 1239 dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n",
1935 "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
1936 __func__, 1240 __func__,
1937 refcyc_per_line_delivery_pre_c); 1241 refcyc_per_line_delivery_pre_c);
1938 DTRACE( 1242 dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n",
1939 "DLG: %s: refcyc_per_line_delivery_c = %3.2f",
1940 __func__, 1243 __func__,
1941 refcyc_per_line_delivery_c); 1244 refcyc_per_line_delivery_c);
1942
1943 disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(
1944 refcyc_per_line_delivery_pre_c);
1945 disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(
1946 refcyc_per_line_delivery_c);
1947 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));
1948 } 1245 }
1949 disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
1950 1246
1951 /* TTU - Luma / Chroma */ 1247 // TTU - Luma / Chroma
1952 if (access_dir) { /* vertical access */ 1248 if (access_dir) { // vertical access
1953 scaler_rec_in_width_l = vp_height_l; 1249 scaler_rec_in_width_l = vp_height_l;
1954 scaler_rec_in_width_c = vp_height_c; 1250 scaler_rec_in_width_c = vp_height_c;
1955 } else { 1251 } else {
@@ -1957,167 +1253,264 @@ void dml_rq_dlg_get_dlg_params(
1957 scaler_rec_in_width_c = vp_width_c; 1253 scaler_rec_in_width_c = vp_width_c;
1958 } 1254 }
1959 1255
1960 refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery( 1256 refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
1961 mode_lib,
1962 refclk_freq_in_mhz, 1257 refclk_freq_in_mhz,
1963 pclk_freq_in_mhz, 1258 pclk_freq_in_mhz,
1259 dst->odm_combine,
1964 full_recout_width, 1260 full_recout_width,
1261 dst->hactive,
1965 vratio_pre_l, 1262 vratio_pre_l,
1966 hscale_pixel_rate_l, 1263 hscale_pixel_rate_l,
1967 scaler_rec_in_width_l, 1264 scaler_rec_in_width_l,
1968 req_per_swath_ub_l); /* per req */ 1265 req_per_swath_ub_l); // per req
1969 refcyc_per_req_delivery_l = get_refcyc_per_delivery( 1266 refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib,
1970 mode_lib,
1971 refclk_freq_in_mhz, 1267 refclk_freq_in_mhz,
1972 pclk_freq_in_mhz, 1268 pclk_freq_in_mhz,
1269 dst->odm_combine,
1973 full_recout_width, 1270 full_recout_width,
1271 dst->hactive,
1974 vratio_l, 1272 vratio_l,
1975 hscale_pixel_rate_l, 1273 hscale_pixel_rate_l,
1976 scaler_rec_in_width_l, 1274 scaler_rec_in_width_l,
1977 req_per_swath_ub_l); /* per req */ 1275 req_per_swath_ub_l); // per req
1978 1276
1979 DTRACE( 1277 dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n",
1980 "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
1981 __func__, 1278 __func__,
1982 refcyc_per_req_delivery_pre_l); 1279 refcyc_per_req_delivery_pre_l);
1983 DTRACE( 1280 dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n",
1984 "DLG: %s: refcyc_per_req_delivery_l = %3.2f",
1985 __func__, 1281 __func__,
1986 refcyc_per_req_delivery_l); 1282 refcyc_per_req_delivery_l);
1987 1283
1988 disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
1989 * dml_pow(2, 10));
1990 disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
1991 * dml_pow(2, 10));
1992
1993 ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13)); 1284 ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
1994 ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13)); 1285 ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
1995 1286
1996 if (dual_plane) { 1287 if (dual_plane) {
1997 refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery( 1288 refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
1998 mode_lib,
1999 refclk_freq_in_mhz, 1289 refclk_freq_in_mhz,
2000 pclk_freq_in_mhz, 1290 pclk_freq_in_mhz,
1291 dst->odm_combine,
2001 full_recout_width, 1292 full_recout_width,
1293 dst->hactive,
2002 vratio_pre_c, 1294 vratio_pre_c,
2003 hscale_pixel_rate_c, 1295 hscale_pixel_rate_c,
2004 scaler_rec_in_width_c, 1296 scaler_rec_in_width_c,
2005 req_per_swath_ub_c); /* per req */ 1297 req_per_swath_ub_c); // per req
2006 refcyc_per_req_delivery_c = get_refcyc_per_delivery( 1298 refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib,
2007 mode_lib,
2008 refclk_freq_in_mhz, 1299 refclk_freq_in_mhz,
2009 pclk_freq_in_mhz, 1300 pclk_freq_in_mhz,
1301 dst->odm_combine,
2010 full_recout_width, 1302 full_recout_width,
1303 dst->hactive,
2011 vratio_c, 1304 vratio_c,
2012 hscale_pixel_rate_c, 1305 hscale_pixel_rate_c,
2013 scaler_rec_in_width_c, 1306 scaler_rec_in_width_c,
2014 req_per_swath_ub_c); /* per req */ 1307 req_per_swath_ub_c); // per req
2015 1308
2016 DTRACE( 1309 dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n",
2017 "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
2018 __func__, 1310 __func__,
2019 refcyc_per_req_delivery_pre_c); 1311 refcyc_per_req_delivery_pre_c);
2020 DTRACE( 1312 dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n",
2021 "DLG: %s: refcyc_per_req_delivery_c = %3.2f",
2022 __func__, 1313 __func__,
2023 refcyc_per_req_delivery_c); 1314 refcyc_per_req_delivery_c);
2024 1315
2025 disp_ttu_regs->refcyc_per_req_delivery_pre_c =
2026 (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10));
2027 disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
2028 * dml_pow(2, 10));
2029
2030 ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13)); 1316 ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
2031 ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13)); 1317 ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
2032 } 1318 }
2033 1319
2034 /* TTU - Cursor */ 1320 // XFC
2035 hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; 1321 xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
2036 cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */ 1322 xfc_precharge_delay = get_xfc_precharge_delay(mode_lib,
2037 cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp; 1323 e2e_pipe_param,
2038 cur0_req_size = 0; 1324 num_pipes,
2039 cur0_req_width = 0; 1325 pipe_idx);
2040 cur0_width_ub = 0.0; 1326 xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib,
2041 cur0_req_per_width = 0.0; 1327 e2e_pipe_param,
2042 hactive_cur0 = 0.0; 1328 num_pipes,
2043 1329 pipe_idx);
2044 ASSERT(cur0_src_width <= 256); 1330 xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency;
2045 1331 xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib,
2046 if (cur0_src_width > 0) { 1332 e2e_pipe_param,
2047 unsigned int cur0_bit_per_pixel = 0; 1333 num_pipes,
2048 1334 pipe_idx);
2049 if (cur0_bpp == dm_cur_2bit) { 1335
2050 cur0_req_size = 64; /* byte */ 1336 // TTU - Cursor
2051 cur0_bit_per_pixel = 2; 1337 refcyc_per_req_delivery_pre_cur0 = 0.0;
2052 } else { /* 32bit */ 1338 refcyc_per_req_delivery_cur0 = 0.0;
2053 cur0_bit_per_pixel = 32; 1339 if (src->num_cursors > 0) {
2054 if (cur0_src_width >= 1 && cur0_src_width <= 16) 1340 calculate_ttu_cursor(mode_lib,
2055 cur0_req_size = 64; 1341 &refcyc_per_req_delivery_pre_cur0,
2056 else if (cur0_src_width >= 17 && cur0_src_width <= 31) 1342 &refcyc_per_req_delivery_cur0,
2057 cur0_req_size = 128; 1343 refclk_freq_in_mhz,
2058 else 1344 ref_freq_to_pix_freq,
2059 cur0_req_size = 256; 1345 hscale_pixel_rate_l,
2060 } 1346 scl->hscl_ratio,
1347 vratio_pre_l,
1348 vratio_l,
1349 src->cur0_src_width,
1350 (enum cursor_bpp)(src->cur0_bpp));
1351 }
2061 1352
2062 cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0); 1353 refcyc_per_req_delivery_pre_cur1 = 0.0;
2063 cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width) 1354 refcyc_per_req_delivery_cur1 = 0.0;
2064 * (double) cur0_req_width; 1355 if (src->num_cursors > 1) {
2065 cur0_req_per_width = cur0_width_ub / (double) cur0_req_width; 1356 calculate_ttu_cursor(mode_lib,
2066 hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */ 1357 &refcyc_per_req_delivery_pre_cur1,
1358 &refcyc_per_req_delivery_cur1,
1359 refclk_freq_in_mhz,
1360 ref_freq_to_pix_freq,
1361 hscale_pixel_rate_l,
1362 scl->hscl_ratio,
1363 vratio_pre_l,
1364 vratio_l,
1365 src->cur1_src_width,
1366 (enum cursor_bpp)(src->cur1_bpp));
1367 }
2067 1368
2068 if (vratio_pre_l <= 1.0) { 1369 // TTU - Misc
2069 refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq 1370 // all hard-coded
2070 / (double) cur0_req_per_width;
2071 } else {
2072 refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz
2073 * (double) cur0_src_width / hscale_pixel_rate_l
2074 / (double) cur0_req_per_width;
2075 }
2076 1371
2077 disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 1372 // Assignment to register structures
2078 (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10)); 1373 disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
2079 ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13)); 1374 disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk
1375 ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
1376 disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
1377 disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
1378 disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
1379 disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
1380 disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
2080 1381
2081 if (vratio_l <= 1.0) { 1382 disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
2082 refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq 1383 disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
2083 / (double) cur0_req_per_width; 1384
2084 } else { 1385 disp_dlg_regs->refcyc_per_pte_group_vblank_l =
2085 refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz 1386 (unsigned int) (dst_y_per_row_vblank * (double) htotal
2086 * (double) cur0_src_width / hscale_pixel_rate_l 1387 * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
2087 / (double) cur0_req_per_width; 1388 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
1389
1390 if (dual_plane) {
1391 disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank
1392 * (double) htotal * ref_freq_to_pix_freq
1393 / (double) dpte_groups_per_row_ub_c);
1394 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c
1395 < (unsigned int) dml_pow(2, 13));
1396 }
1397
1398 disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
1399 (unsigned int) (dst_y_per_row_vblank * (double) htotal
1400 * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
1401 ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
1402
1403 disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
1404 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
1405
1406 disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
1407 * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l;
1408 disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
1409 * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l;
1410
1411 if (dual_plane) {
1412 disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip
1413 * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c;
1414 disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip
1415 * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c;
1416 }
1417
1418 disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
1419 / (double) vratio_l * dml_pow(2, 2));
1420 ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
1421
1422 if (dual_plane) {
1423 disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
1424 / (double) vratio_c * dml_pow(2, 2));
1425 if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
1426 dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n",
1427 __func__,
1428 disp_dlg_regs->dst_y_per_pte_row_nom_c,
1429 (unsigned int) dml_pow(2, 17) - 1);
2088 } 1430 }
1431 }
2089 1432
2090 DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width); 1433 disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
2091 DTRACE( 1434 / (double) vratio_l * dml_pow(2, 2));
2092 "DLG: %s: cur0_width_ub = %3.2f", 1435 ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
2093 __func__,
2094 cur0_width_ub);
2095 DTRACE(
2096 "DLG: %s: cur0_req_per_width = %3.2f",
2097 __func__,
2098 cur0_req_per_width);
2099 DTRACE(
2100 "DLG: %s: hactive_cur0 = %3.2f",
2101 __func__,
2102 hactive_cur0);
2103 DTRACE(
2104 "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f",
2105 __func__,
2106 refcyc_per_req_delivery_pre_cur0);
2107 DTRACE(
2108 "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f",
2109 __func__,
2110 refcyc_per_req_delivery_cur0);
2111 1436
2112 disp_ttu_regs->refcyc_per_req_delivery_cur0 = 1437 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
2113 (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10)); 1438
2114 ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13)); 1439 disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
2115 } else { 1440 / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
2116 disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0; 1441 / (double) dpte_groups_per_row_ub_l);
2117 disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0; 1442 if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
1443 disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
1444 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
1445 / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1446 / (double) meta_chunks_per_row_ub_l);
1447 if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
1448 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
1449
1450 if (dual_plane) {
1451 disp_dlg_regs->refcyc_per_pte_group_nom_c =
1452 (unsigned int) ((double) dpte_row_height_c / (double) vratio_c
1453 * (double) htotal * ref_freq_to_pix_freq
1454 / (double) dpte_groups_per_row_ub_c);
1455 if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
1456 disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
1457
1458 // TODO: Is this the right calculation? Does htotal need to be halved?
1459 disp_dlg_regs->refcyc_per_meta_chunk_nom_c =
1460 (unsigned int) ((double) meta_row_height_c / (double) vratio_c
1461 * (double) htotal * ref_freq_to_pix_freq
1462 / (double) meta_chunks_per_row_ub_c);
1463 if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
1464 disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1;
2118 } 1465 }
2119 1466
2120 /* TTU - Misc */ 1467 disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l,
1468 1);
1469 disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l,
1470 1);
1471 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
1472 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
1473
1474 disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c,
1475 1);
1476 disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c,
1477 1);
1478 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
1479 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
1480
1481 disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
1482 disp_dlg_regs->dst_y_offset_cur0 = 0;
1483 disp_dlg_regs->chunk_hdl_adjust_cur1 = 3;
1484 disp_dlg_regs->dst_y_offset_cur1 = 0;
1485
1486 disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay;
1487 disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay;
1488 disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency;
1489 disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz,
1490 1);
1491
1492 // slave has to have this value also set to off
1493 if (src->xfc_enable && !src->xfc_slave)
1494 disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1);
1495 else
1496 disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
1497
1498 disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
1499 * dml_pow(2, 10));
1500 disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
1501 * dml_pow(2, 10));
1502 disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c
1503 * dml_pow(2, 10));
1504 disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
1505 * dml_pow(2, 10));
1506 disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
1507 (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
1508 disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0
1509 * dml_pow(2, 10));
1510 disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 =
1511 (unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10));
1512 disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1
1513 * dml_pow(2, 10));
2121 disp_ttu_regs->qos_level_low_wm = 0; 1514 disp_ttu_regs->qos_level_low_wm = 0;
2122 ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14)); 1515 ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
2123 disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal 1516 disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
@@ -2139,118 +1532,232 @@ void dml_rq_dlg_get_dlg_params(
2139 print__dlg_regs_st(mode_lib, *disp_dlg_regs); 1532 print__dlg_regs_st(mode_lib, *disp_dlg_regs);
2140} 1533}
2141 1534
2142void dml_rq_dlg_get_dlg_reg( 1535void dml_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
2143 struct display_mode_lib *mode_lib, 1536 display_dlg_regs_st *dlg_regs,
2144 struct _vcs_dpi_display_dlg_regs_st *dlg_regs, 1537 display_ttu_regs_st *ttu_regs,
2145 struct _vcs_dpi_display_ttu_regs_st *ttu_regs, 1538 display_e2e_pipe_params_st *e2e_pipe_param,
2146 struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, 1539 const unsigned int num_pipes,
2147 const int unsigned num_pipes, 1540 const unsigned int pipe_idx,
2148 const int unsigned pipe_idx,
2149 const bool cstate_en, 1541 const bool cstate_en,
2150 const bool pstate_en, 1542 const bool pstate_en,
2151 const bool vm_en, 1543 const bool vm_en,
2152 const bool iflip_en) 1544 const bool ignore_viewport_pos,
1545 const bool immediate_flip_support)
2153{ 1546{
2154 struct _vcs_dpi_display_rq_params_st rq_param = {0}; 1547 display_rq_params_st rq_param = {0};
2155 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0}; 1548 display_dlg_sys_params_st dlg_sys_param = {0};
2156 struct _vcs_dpi_wm_calc_pipe_params_st *wm_param = mode_lib->wm_param; 1549
2157 struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm; 1550 // Get watermark and Tex.
2158 struct _vcs_dpi_display_dlg_prefetch_param_st prefetch_param; 1551 dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes);
2159 double total_ret_bw; 1552 dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib,
2160 double total_active_bw;
2161 double total_prefetch_bw;
2162 int unsigned total_flip_bytes;
2163 int unsigned num_planes;
2164 int i;
2165
2166 memset(wm_param, 0, sizeof(mode_lib->wm_param));
2167
2168 /* Get watermark and Tex. */
2169 DTRACE("DLG: Start calculating system setting related parameters. num_pipes=%d", num_pipes);
2170 num_planes = dml_wm_e2e_to_wm(mode_lib, e2e_pipe_param, num_pipes, wm_param);
2171
2172 cstate_pstate_wm = dml_wm_cstate_pstate_e2e(mode_lib, e2e_pipe_param, num_pipes);
2173 dlg_sys_param.t_mclk_wm_us = cstate_pstate_wm.pstate_change_us;
2174 dlg_sys_param.t_sr_wm_us = cstate_pstate_wm.cstate_enter_plus_exit_us;
2175 dlg_sys_param.t_urg_wm_us = dml_wm_urgent_e2e(mode_lib, e2e_pipe_param, num_pipes);
2176 dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
2177 / dml_wm_dcfclk_deepsleep_mhz_e2e(mode_lib, e2e_pipe_param, num_pipes);
2178 dlg_sys_param.t_extra_us = dml_wm_urgent_extra(mode_lib, wm_param, num_planes);
2179 dlg_sys_param.deepsleep_dcfclk_mhz = dml_wm_dcfclk_deepsleep_mhz_e2e(
2180 mode_lib,
2181 e2e_pipe_param, 1553 e2e_pipe_param,
2182 num_pipes); 1554 num_pipes);
1555 dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes);
1556 dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes);
1557 dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes);
1558 dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes);
1559 dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib,
1560 e2e_pipe_param,
1561 num_pipes);
1562 dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
1563 e2e_pipe_param,
1564 num_pipes);
1565 dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
1566 / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
2183 1567
2184 print__dlg_sys_params_st(mode_lib, dlg_sys_param); 1568 print__dlg_sys_params_st(mode_lib, dlg_sys_param);
2185 1569
2186 DTRACE("DLG: Start calculating total prefetch bw. num_planes=%d", num_planes); 1570 // system parameter calculation done
2187 total_ret_bw = dml_wm_calc_return_bw(mode_lib, wm_param, num_planes);
2188 total_active_bw = dml_wm_calc_total_data_read_bw(mode_lib, wm_param, num_planes);
2189 total_prefetch_bw = 0.0;
2190 total_flip_bytes = 0;
2191
2192 for (i = 0; i < num_pipes; i++) {
2193 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[i].pipe.src);
2194 dml_rq_dlg_get_dlg_params_prefetch(
2195 mode_lib,
2196 &prefetch_param,
2197 rq_param.dlg,
2198 dlg_sys_param,
2199 e2e_pipe_param[i],
2200 cstate_en,
2201 pstate_en,
2202 vm_en);
2203 total_prefetch_bw += prefetch_param.prefetch_bw;
2204 total_flip_bytes += prefetch_param.flip_bytes;
2205 DTRACE(
2206 "DLG: pipe=%d, total_prefetch_bw=%3.2f total_flip_bytes=%d",
2207 i,
2208 total_prefetch_bw,
2209 total_flip_bytes);
2210 }
2211
2212 dlg_sys_param.total_flip_bw = total_ret_bw - dml_max(total_active_bw, total_prefetch_bw);
2213
2214 DTRACE("DLG: Done calculating total prefetch bw");
2215 DTRACE("DLG: num_pipes = %d", num_pipes);
2216 DTRACE("DLG: total_ret_bw = %3.2f", total_ret_bw);
2217 DTRACE("DLG: total_active_bw = %3.2f", total_active_bw);
2218 DTRACE("DLG: total_prefetch_bw = %3.2f", total_prefetch_bw);
2219 DTRACE("DLG: total_flip_bw = %3.2f", dlg_sys_param.total_flip_bw);
2220
2221 if (dlg_sys_param.total_flip_bw < 0.0 && iflip_en) {
2222 DTRACE("WARNING_DLG Insufficient bw for immediate flip!");
2223 dlg_sys_param.total_flip_bw = 0;
2224 }
2225 1571
2226 dlg_sys_param.total_flip_bytes = total_flip_bytes; 1572 dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
2227 DTRACE("DLG: total_flip_bytes = %d", dlg_sys_param.total_flip_bytes);
2228 DTRACE("DLG: Done calculating system setting related parameters.");
2229
2230 /* system parameter calculation done */
2231
2232 DTRACE("DLG: Calculation for pipe[%d] start", pipe_idx);
2233 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src); 1573 dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src);
2234 dml_rq_dlg_get_dlg_params( 1574 dml_rq_dlg_get_dlg_params(mode_lib,
2235 mode_lib, 1575 e2e_pipe_param,
1576 num_pipes,
1577 pipe_idx,
2236 dlg_regs, 1578 dlg_regs,
2237 ttu_regs, 1579 ttu_regs,
2238 rq_param.dlg, 1580 rq_param.dlg,
2239 dlg_sys_param, 1581 dlg_sys_param,
2240 e2e_pipe_param[pipe_idx],
2241 cstate_en, 1582 cstate_en,
2242 pstate_en, 1583 pstate_en,
2243 vm_en, 1584 vm_en,
2244 iflip_en); 1585 ignore_viewport_pos,
2245 DTRACE("DLG: Calculation for pipe[%d] end", pipe_idx); 1586 immediate_flip_support);
1587 dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx);
2246} 1588}
2247 1589
2248void dml_rq_dlg_get_arb_params( 1590void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param)
2249 struct display_mode_lib *mode_lib,
2250 struct _vcs_dpi_display_arb_params_st *arb_param)
2251{ 1591{
2252 memset(arb_param, 0, sizeof(*arb_param)); 1592 memset(arb_param, 0, sizeof(*arb_param));
2253 arb_param->max_req_outstanding = 256; 1593 arb_param->max_req_outstanding = 256;
2254 arb_param->min_req_outstanding = 68; 1594 arb_param->min_req_outstanding = 68;
2255 arb_param->sat_level_us = 60; 1595 arb_param->sat_level_us = 60;
2256} 1596}
1597
1598void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
1599 double *refcyc_per_req_delivery_pre_cur,
1600 double *refcyc_per_req_delivery_cur,
1601 double refclk_freq_in_mhz,
1602 double ref_freq_to_pix_freq,
1603 double hscale_pixel_rate_l,
1604 double hscl_ratio,
1605 double vratio_pre_l,
1606 double vratio_l,
1607 unsigned int cur_width,
1608 enum cursor_bpp cur_bpp)
1609{
1610 unsigned int cur_src_width = cur_width;
1611 unsigned int cur_req_size = 0;
1612 unsigned int cur_req_width = 0;
1613 double cur_width_ub = 0.0;
1614 double cur_req_per_width = 0.0;
1615 double hactive_cur = 0.0;
1616
1617 ASSERT(cur_src_width <= 256);
1618
1619 *refcyc_per_req_delivery_pre_cur = 0.0;
1620 *refcyc_per_req_delivery_cur = 0.0;
1621 if (cur_src_width > 0) {
1622 unsigned int cur_bit_per_pixel = 0;
1623
1624 if (cur_bpp == dm_cur_2bit) {
1625 cur_req_size = 64; // byte
1626 cur_bit_per_pixel = 2;
1627 } else { // 32bit
1628 cur_bit_per_pixel = 32;
1629 if (cur_src_width >= 1 && cur_src_width <= 16)
1630 cur_req_size = 64;
1631 else if (cur_src_width >= 17 && cur_src_width <= 31)
1632 cur_req_size = 128;
1633 else
1634 cur_req_size = 256;
1635 }
1636
1637 cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0);
1638 cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1)
1639 * (double) cur_req_width;
1640 cur_req_per_width = cur_width_ub / (double) cur_req_width;
1641 hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor
1642
1643 if (vratio_pre_l <= 1.0) {
1644 *refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq
1645 / (double) cur_req_per_width;
1646 } else {
1647 *refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz
1648 * (double) cur_src_width / hscale_pixel_rate_l
1649 / (double) cur_req_per_width;
1650 }
1651
1652 ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13));
1653
1654 if (vratio_l <= 1.0) {
1655 *refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq
1656 / (double) cur_req_per_width;
1657 } else {
1658 *refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz
1659 * (double) cur_src_width / hscale_pixel_rate_l
1660 / (double) cur_req_per_width;
1661 }
1662
1663 dml_print("DML_DLG: %s: cur_req_width = %d\n",
1664 __func__,
1665 cur_req_width);
1666 dml_print("DML_DLG: %s: cur_width_ub = %3.2f\n",
1667 __func__,
1668 cur_width_ub);
1669 dml_print("DML_DLG: %s: cur_req_per_width = %3.2f\n",
1670 __func__,
1671 cur_req_per_width);
1672 dml_print("DML_DLG: %s: hactive_cur = %3.2f\n",
1673 __func__,
1674 hactive_cur);
1675 dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur = %3.2f\n",
1676 __func__,
1677 *refcyc_per_req_delivery_pre_cur);
1678 dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur = %3.2f\n",
1679 __func__,
1680 *refcyc_per_req_delivery_cur);
1681
1682 ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
1683 }
1684}
1685
1686unsigned int dml_rq_dlg_get_calculated_vstartup(struct display_mode_lib *mode_lib,
1687 display_e2e_pipe_params_st *e2e_pipe_param,
1688 const unsigned int num_pipes,
1689 const unsigned int pipe_idx)
1690{
1691 unsigned int vstartup_pipe[DC__NUM_PIPES__MAX];
1692 bool visited[DC__NUM_PIPES__MAX];
1693 unsigned int pipe_inst = 0;
1694 unsigned int i, j, k;
1695
1696 for (k = 0; k < num_pipes; ++k)
1697 visited[k] = false;
1698
1699 for (i = 0; i < num_pipes; i++) {
1700 if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) {
1701 unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp;
1702
1703 for (j = i; j < num_pipes; j++) {
1704 if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp
1705 && e2e_pipe_param[j].pipe.src.is_hsplit
1706 && !visited[j]) {
1707 vstartup_pipe[j] = get_vstartup_calculated(mode_lib,
1708 e2e_pipe_param,
1709 num_pipes,
1710 pipe_inst);
1711 visited[j] = true;
1712 }
1713 }
1714
1715 pipe_inst++;
1716 }
1717
1718 if (!visited[i]) {
1719 vstartup_pipe[i] = get_vstartup_calculated(mode_lib,
1720 e2e_pipe_param,
1721 num_pipes,
1722 pipe_inst);
1723 visited[i] = true;
1724 pipe_inst++;
1725 }
1726 }
1727
1728 return vstartup_pipe[pipe_idx];
1729
1730}
1731
1732void dml_rq_dlg_get_row_heights(struct display_mode_lib *mode_lib,
1733 unsigned int *o_dpte_row_height,
1734 unsigned int *o_meta_row_height,
1735 unsigned int vp_width,
1736 unsigned int data_pitch,
1737 int source_format,
1738 int tiling,
1739 int macro_tile_size,
1740 int source_scan,
1741 int is_chroma)
1742{
1743 display_data_rq_dlg_params_st rq_dlg_param;
1744 display_data_rq_misc_params_st rq_misc_param;
1745 display_data_rq_sizing_params_st rq_sizing_param;
1746
1747 get_meta_and_pte_attr(mode_lib,
1748 &rq_dlg_param,
1749 &rq_misc_param,
1750 &rq_sizing_param,
1751 vp_width,
1752 0, // dummy
1753 data_pitch,
1754 0, // dummy
1755 source_format,
1756 tiling,
1757 macro_tile_size,
1758 source_scan,
1759 is_chroma);
1760
1761 *o_dpte_row_height = rq_dlg_param.dpte_row_height;
1762 *o_meta_row_height = rq_dlg_param.meta_row_height;
1763}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h
index e63b13fb2887..efdd4c73d8f3 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h
@@ -22,103 +22,114 @@
22 * Authors: AMD 22 * Authors: AMD
23 * 23 *
24 */ 24 */
25#ifndef __DISPLAY_RQ_DLG_CALC_H__ 25
26#define __DISPLAY_RQ_DLG_CALC_H__ 26#ifndef __DML2_DISPLAY_RQ_DLG_CALC_H__
27#define __DML2_DISPLAY_RQ_DLG_CALC_H__
27 28
28#include "dml_common_defs.h" 29#include "dml_common_defs.h"
29#include "display_rq_dlg_helpers.h" 30#include "display_rq_dlg_helpers.h"
30 31
31struct display_mode_lib; 32struct display_mode_lib;
32 33
33void extract_rq_regs( 34// Function: dml_rq_dlg_get_rq_params
34 struct display_mode_lib *mode_lib, 35// Calculate requestor related parameters that register definition agnostic
35 struct _vcs_dpi_display_rq_regs_st *rq_regs, 36// (i.e. this layer does try to separate real values from register definition)
36 const struct _vcs_dpi_display_rq_params_st rq_param); 37// Input:
37/* Function: dml_rq_dlg_get_rq_params 38// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
38 * Calculate requestor related parameters that register definition agnostic 39// Output:
39 * (i.e. this layer does try to separate real values from register defintion) 40// rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
40 * Input: 41//
41 * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
42 * Output:
43 * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
44 */
45void dml_rq_dlg_get_rq_params( 42void dml_rq_dlg_get_rq_params(
46 struct display_mode_lib *mode_lib, 43 struct display_mode_lib *mode_lib,
47 struct _vcs_dpi_display_rq_params_st *rq_param, 44 display_rq_params_st *rq_param,
48 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); 45 const display_pipe_source_params_st pipe_src_param);
49 46
50/* Function: dml_rq_dlg_get_rq_reg 47// Function: dml_rq_dlg_get_rq_reg
51 * Main entry point for test to get the register values out of this DML class. 48// Main entry point for test to get the register values out of this DML class.
52 * This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate 49// This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
53 * and then populate the rq_regs struct 50// and then populate the rq_regs struct
54 * Input: 51// Input:
55 * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.) 52// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
56 * Output: 53// Output:
57 * rq_regs - struct that holds all the RQ registers field value. 54// rq_regs - struct that holds all the RQ registers field value.
58 * See also: <display_rq_regs_st> 55// See also: <display_rq_regs_st>
59 */
60void dml_rq_dlg_get_rq_reg( 56void dml_rq_dlg_get_rq_reg(
61 struct display_mode_lib *mode_lib, 57 struct display_mode_lib *mode_lib,
62 struct _vcs_dpi_display_rq_regs_st *rq_regs, 58 display_rq_regs_st *rq_regs,
63 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); 59 const display_pipe_source_params_st pipe_src_param);
64 60
65/* Function: dml_rq_dlg_get_dlg_params 61// Function: dml_rq_dlg_get_dlg_params
66 * Calculate deadline related parameters 62// Calculate deadline related parameters
67 */ 63//
68void dml_rq_dlg_get_dlg_params( 64void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
69 struct display_mode_lib *mode_lib, 65 const display_e2e_pipe_params_st *e2e_pipe_param,
70 struct _vcs_dpi_display_dlg_regs_st *dlg_regs, 66 const unsigned int num_pipes,
71 struct _vcs_dpi_display_ttu_regs_st *ttu_regs, 67 const unsigned int pipe_idx,
72 const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, 68 display_dlg_regs_st *disp_dlg_regs,
73 const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, 69 display_ttu_regs_st *disp_ttu_regs,
74 const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, 70 const display_rq_dlg_params_st rq_dlg_param,
71 const display_dlg_sys_params_st dlg_sys_param,
75 const bool cstate_en, 72 const bool cstate_en,
76 const bool pstate_en, 73 const bool pstate_en,
77 const bool vm_en, 74 const bool vm_en,
78 const bool iflip_en); 75 const bool ignore_viewport_pos,
76 const bool immediate_flip_support);
79 77
80/* Function: dml_rq_dlg_get_dlg_param_prefetch 78// Function: dml_rq_dlg_get_dlg_param_prefetch
81 * For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw 79// For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw
82 * for ALL pipes and use this info to calculate the prefetch programming. 80// for ALL pipes and use this info to calculate the prefetch programming.
83 * Output: prefetch_param.prefetch_bw and flip_bytes 81// Output: prefetch_param.prefetch_bw and flip_bytes
84 */
85void dml_rq_dlg_get_dlg_params_prefetch( 82void dml_rq_dlg_get_dlg_params_prefetch(
86 struct display_mode_lib *mode_lib, 83 struct display_mode_lib *mode_lib,
87 struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param, 84 display_dlg_prefetch_param_st *prefetch_param,
88 struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, 85 display_rq_dlg_params_st rq_dlg_param,
89 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, 86 display_dlg_sys_params_st dlg_sys_param,
90 struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, 87 display_e2e_pipe_params_st e2e_pipe_param,
91 const bool cstate_en, 88 const bool cstate_en,
92 const bool pstate_en, 89 const bool pstate_en,
93 const bool vm_en); 90 const bool vm_en);
94 91
95/* Function: dml_rq_dlg_get_dlg_reg 92// Function: dml_rq_dlg_get_dlg_reg
96 * Calculate and return DLG and TTU register struct given the system setting 93// Calculate and return DLG and TTU register struct given the system setting
97 * Output: 94// Output:
98 * dlg_regs - output DLG register struct 95// dlg_regs - output DLG register struct
99 * ttu_regs - output DLG TTU register struct 96// ttu_regs - output DLG TTU register struct
100 * Input: 97// Input:
101 * e2e_pipe_param - "compacted" array of e2e pipe param struct 98// e2e_pipe_param - "compacted" array of e2e pipe param struct
102 * num_pipes - num of active "pipe" or "route" 99// num_pipes - num of active "pipe" or "route"
103 * pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg 100// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
104 * cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered. 101// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
105 * Added for legacy or unrealistic timing tests. 102// Added for legacy or unrealistic timing tests.
106 */
107void dml_rq_dlg_get_dlg_reg( 103void dml_rq_dlg_get_dlg_reg(
108 struct display_mode_lib *mode_lib, 104 struct display_mode_lib *mode_lib,
109 struct _vcs_dpi_display_dlg_regs_st *dlg_regs, 105 display_dlg_regs_st *dlg_regs,
110 struct _vcs_dpi_display_ttu_regs_st *ttu_regs, 106 display_ttu_regs_st *ttu_regs,
111 struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, 107 display_e2e_pipe_params_st *e2e_pipe_param,
112 const unsigned int num_pipes, 108 const unsigned int num_pipes,
113 const unsigned int pipe_idx, 109 const unsigned int pipe_idx,
114 const bool cstate_en, 110 const bool cstate_en,
115 const bool pstate_en, 111 const bool pstate_en,
116 const bool vm_en, 112 const bool vm_en,
117 const bool iflip_en); 113 const bool ignore_viewport_pos,
114 const bool immediate_flip_support);
118 115
119/* Function: dml_rq_dlg_get_row_heights 116// Function: dml_rq_dlg_get_calculated_vstartup
120 * Calculate dpte and meta row heights 117// Calculate and return vstartup
121 */ 118// Output:
119// unsigned int vstartup
120// Input:
121// e2e_pipe_param - "compacted" array of e2e pipe param struct
122// num_pipes - num of active "pipe" or "route"
123// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
124// NOTE: this MUST be called after setting the prefetch mode!
125unsigned int dml_rq_dlg_get_calculated_vstartup(
126 struct display_mode_lib *mode_lib,
127 display_e2e_pipe_params_st *e2e_pipe_param,
128 const unsigned int num_pipes,
129 const unsigned int pipe_idx);
130
131// Function: dml_rq_dlg_get_row_heights
132// Calculate dpte and meta row heights
122void dml_rq_dlg_get_row_heights( 133void dml_rq_dlg_get_row_heights(
123 struct display_mode_lib *mode_lib, 134 struct display_mode_lib *mode_lib,
124 unsigned int *o_dpte_row_height, 135 unsigned int *o_dpte_row_height,
@@ -131,9 +142,7 @@ void dml_rq_dlg_get_row_heights(
131 int source_scan, 142 int source_scan,
132 int is_chroma); 143 int is_chroma);
133 144
134/* Function: dml_rq_dlg_get_arb_params */ 145// Function: dml_rq_dlg_get_arb_params
135void dml_rq_dlg_get_arb_params( 146void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param);
136 struct display_mode_lib *mode_lib,
137 struct _vcs_dpi_display_arb_params_st *arb_param);
138 147
139#endif 148#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
index 3dc11366cd36..189052e911fc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c
@@ -25,296 +25,368 @@
25 25
26#include "display_rq_dlg_helpers.h" 26#include "display_rq_dlg_helpers.h"
27 27
28void print__rq_params_st( 28void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param)
29 struct display_mode_lib *mode_lib,
30 struct _vcs_dpi_display_rq_params_st rq_param)
31{ 29{
32 DTRACE("RQ_DLG_CALC: *************************** "); 30 dml_print("DML_RQ_DLG_CALC: ***************************\n");
33 DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST"); 31 dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n");
34 DTRACE("RQ_DLG_CALC: <LUMA>"); 32 dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
35 print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l); 33 print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l);
36 DTRACE("RQ_DLG_CALC: <CHROMA> === "); 34 dml_print("DML_RQ_DLG_CALC: <CHROMA> ===\n");
37 print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c); 35 print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c);
38 36
39 DTRACE("RQ_DLG_CALC: <LUMA>"); 37 dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
40 print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l); 38 print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l);
41 DTRACE("RQ_DLG_CALC: <CHROMA>"); 39 dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
42 print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c); 40 print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c);
43 41
44 DTRACE("RQ_DLG_CALC: <LUMA>"); 42 dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
45 print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l); 43 print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l);
46 DTRACE("RQ_DLG_CALC: <CHROMA>"); 44 dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
47 print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c); 45 print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c);
48 DTRACE("RQ_DLG_CALC: *************************** "); 46 dml_print("DML_RQ_DLG_CALC: ***************************\n");
49} 47}
50 48
51void print__data_rq_sizing_params_st( 49void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing)
52 struct display_mode_lib *mode_lib,
53 struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
54{ 50{
55 DTRACE("RQ_DLG_CALC: ===================================== "); 51 dml_print("DML_RQ_DLG_CALC: =====================================\n");
56 DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST"); 52 dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n");
57 DTRACE("RQ_DLG_CALC: chunk_bytes = %0d", rq_sizing.chunk_bytes); 53 dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing.chunk_bytes);
58 DTRACE("RQ_DLG_CALC: min_chunk_bytes = %0d", rq_sizing.min_chunk_bytes); 54 dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing.min_chunk_bytes);
59 DTRACE("RQ_DLG_CALC: meta_chunk_bytes = %0d", rq_sizing.meta_chunk_bytes); 55 dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing.meta_chunk_bytes);
60 DTRACE("RQ_DLG_CALC: min_meta_chunk_bytes = %0d", rq_sizing.min_meta_chunk_bytes); 56 dml_print(
61 DTRACE("RQ_DLG_CALC: mpte_group_bytes = %0d", rq_sizing.mpte_group_bytes); 57 "DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n",
62 DTRACE("RQ_DLG_CALC: dpte_group_bytes = %0d", rq_sizing.dpte_group_bytes); 58 rq_sizing.min_meta_chunk_bytes);
63 DTRACE("RQ_DLG_CALC: ===================================== "); 59 dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing.mpte_group_bytes);
60 dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing.dpte_group_bytes);
61 dml_print("DML_RQ_DLG_CALC: =====================================\n");
64} 62}
65 63
66void print__data_rq_dlg_params_st( 64void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param)
67 struct display_mode_lib *mode_lib,
68 struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param)
69{ 65{
70 DTRACE("RQ_DLG_CALC: ===================================== "); 66 dml_print("DML_RQ_DLG_CALC: =====================================\n");
71 DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST"); 67 dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n");
72 DTRACE("RQ_DLG_CALC: swath_width_ub = %0d", rq_dlg_param.swath_width_ub); 68 dml_print(
73 DTRACE("RQ_DLG_CALC: swath_height = %0d", rq_dlg_param.swath_height); 69 "DML_RQ_DLG_CALC: swath_width_ub = %0d\n",
74 DTRACE("RQ_DLG_CALC: req_per_swath_ub = %0d", rq_dlg_param.req_per_swath_ub); 70 rq_dlg_param.swath_width_ub);
75 DTRACE( 71 dml_print(
76 "RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d", 72 "DML_RQ_DLG_CALC: swath_height = %0d\n",
73 rq_dlg_param.swath_height);
74 dml_print(
75 "DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n",
76 rq_dlg_param.req_per_swath_ub);
77 dml_print(
78 "DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n",
77 rq_dlg_param.meta_pte_bytes_per_frame_ub); 79 rq_dlg_param.meta_pte_bytes_per_frame_ub);
78 DTRACE( 80 dml_print(
79 "RQ_DLG_CALC: dpte_req_per_row_ub = %0d", 81 "DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n",
80 rq_dlg_param.dpte_req_per_row_ub); 82 rq_dlg_param.dpte_req_per_row_ub);
81 DTRACE( 83 dml_print(
82 "RQ_DLG_CALC: dpte_groups_per_row_ub = %0d", 84 "DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n",
83 rq_dlg_param.dpte_groups_per_row_ub); 85 rq_dlg_param.dpte_groups_per_row_ub);
84 DTRACE("RQ_DLG_CALC: dpte_row_height = %0d", rq_dlg_param.dpte_row_height); 86 dml_print(
85 DTRACE( 87 "DML_RQ_DLG_CALC: dpte_row_height = %0d\n",
86 "RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d", 88 rq_dlg_param.dpte_row_height);
89 dml_print(
90 "DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n",
87 rq_dlg_param.dpte_bytes_per_row_ub); 91 rq_dlg_param.dpte_bytes_per_row_ub);
88 DTRACE( 92 dml_print(
89 "RQ_DLG_CALC: meta_chunks_per_row_ub = %0d", 93 "DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n",
90 rq_dlg_param.meta_chunks_per_row_ub); 94 rq_dlg_param.meta_chunks_per_row_ub);
91 DTRACE( 95 dml_print(
92 "RQ_DLG_CALC: meta_req_per_row_ub = %0d", 96 "DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n",
93 rq_dlg_param.meta_req_per_row_ub); 97 rq_dlg_param.meta_req_per_row_ub);
94 DTRACE("RQ_DLG_CALC: meta_row_height = %0d", rq_dlg_param.meta_row_height); 98 dml_print(
95 DTRACE( 99 "DML_RQ_DLG_CALC: meta_row_height = %0d\n",
96 "RQ_DLG_CALC: meta_bytes_per_row_ub = %0d", 100 rq_dlg_param.meta_row_height);
101 dml_print(
102 "DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n",
97 rq_dlg_param.meta_bytes_per_row_ub); 103 rq_dlg_param.meta_bytes_per_row_ub);
98 DTRACE("RQ_DLG_CALC: ===================================== "); 104 dml_print("DML_RQ_DLG_CALC: =====================================\n");
99} 105}
100 106
101void print__data_rq_misc_params_st( 107void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param)
102 struct display_mode_lib *mode_lib,
103 struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param)
104{ 108{
105 DTRACE("RQ_DLG_CALC: ===================================== "); 109 dml_print("DML_RQ_DLG_CALC: =====================================\n");
106 DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST"); 110 dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n");
107 DTRACE("RQ_DLG_CALC: full_swath_bytes = %0d", rq_misc_param.full_swath_bytes); 111 dml_print(
108 DTRACE("RQ_DLG_CALC: stored_swath_bytes = %0d", rq_misc_param.stored_swath_bytes); 112 "DML_RQ_DLG_CALC: full_swath_bytes = %0d\n",
109 DTRACE("RQ_DLG_CALC: blk256_width = %0d", rq_misc_param.blk256_width); 113 rq_misc_param.full_swath_bytes);
110 DTRACE("RQ_DLG_CALC: blk256_height = %0d", rq_misc_param.blk256_height); 114 dml_print(
111 DTRACE("RQ_DLG_CALC: req_width = %0d", rq_misc_param.req_width); 115 "DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n",
112 DTRACE("RQ_DLG_CALC: req_height = %0d", rq_misc_param.req_height); 116 rq_misc_param.stored_swath_bytes);
113 DTRACE("RQ_DLG_CALC: ===================================== "); 117 dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param.blk256_width);
118 dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param.blk256_height);
119 dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param.req_width);
120 dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param.req_height);
121 dml_print("DML_RQ_DLG_CALC: =====================================\n");
114} 122}
115 123
116void print__rq_dlg_params_st( 124void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param)
117 struct display_mode_lib *mode_lib,
118 struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param)
119{ 125{
120 DTRACE("RQ_DLG_CALC: ===================================== "); 126 dml_print("DML_RQ_DLG_CALC: =====================================\n");
121 DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST"); 127 dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
122 DTRACE("RQ_DLG_CALC: <LUMA> "); 128 dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
123 print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l); 129 print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l);
124 DTRACE("RQ_DLG_CALC: <CHROMA> "); 130 dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
125 print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c); 131 print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c);
126 DTRACE("RQ_DLG_CALC: ===================================== "); 132 dml_print("DML_RQ_DLG_CALC: =====================================\n");
127} 133}
128 134
129void print__dlg_sys_params_st( 135void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param)
130 struct display_mode_lib *mode_lib,
131 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param)
132{ 136{
133 DTRACE("RQ_DLG_CALC: ===================================== "); 137 dml_print("DML_RQ_DLG_CALC: =====================================\n");
134 DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST"); 138 dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
135 DTRACE("RQ_DLG_CALC: t_mclk_wm_us = %3.2f", dlg_sys_param.t_mclk_wm_us); 139 dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param.t_mclk_wm_us);
136 DTRACE("RQ_DLG_CALC: t_urg_wm_us = %3.2f", dlg_sys_param.t_urg_wm_us); 140 dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param.t_urg_wm_us);
137 DTRACE("RQ_DLG_CALC: t_sr_wm_us = %3.2f", dlg_sys_param.t_sr_wm_us); 141 dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param.t_sr_wm_us);
138 DTRACE("RQ_DLG_CALC: t_extra_us = %3.2f", dlg_sys_param.t_extra_us); 142 dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param.t_extra_us);
139 DTRACE("RQ_DLG_CALC: t_srx_delay_us = %3.2f", dlg_sys_param.t_srx_delay_us); 143 dml_print(
140 DTRACE("RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f", dlg_sys_param.deepsleep_dcfclk_mhz); 144 "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n",
141 DTRACE("RQ_DLG_CALC: ===================================== "); 145 dlg_sys_param.t_srx_delay_us);
146 dml_print(
147 "DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n",
148 dlg_sys_param.deepsleep_dcfclk_mhz);
149 dml_print(
150 "DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n",
151 dlg_sys_param.total_flip_bw);
152 dml_print(
153 "DML_RQ_DLG_CALC: total_flip_bytes = %i\n",
154 dlg_sys_param.total_flip_bytes);
155 dml_print("DML_RQ_DLG_CALC: =====================================\n");
142} 156}
143 157
144void print__data_rq_regs_st( 158void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st rq_regs)
145 struct display_mode_lib *mode_lib,
146 struct _vcs_dpi_display_data_rq_regs_st rq_regs)
147{ 159{
148 DTRACE("RQ_DLG_CALC: ===================================== "); 160 dml_print("DML_RQ_DLG_CALC: =====================================\n");
149 DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST"); 161 dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n");
150 DTRACE("RQ_DLG_CALC: chunk_size = 0x%0x", rq_regs.chunk_size); 162 dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs.chunk_size);
151 DTRACE("RQ_DLG_CALC: min_chunk_size = 0x%0x", rq_regs.min_chunk_size); 163 dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs.min_chunk_size);
152 DTRACE("RQ_DLG_CALC: meta_chunk_size = 0x%0x", rq_regs.meta_chunk_size); 164 dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs.meta_chunk_size);
153 DTRACE("RQ_DLG_CALC: min_meta_chunk_size = 0x%0x", rq_regs.min_meta_chunk_size); 165 dml_print(
154 DTRACE("RQ_DLG_CALC: dpte_group_size = 0x%0x", rq_regs.dpte_group_size); 166 "DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n",
155 DTRACE("RQ_DLG_CALC: mpte_group_size = 0x%0x", rq_regs.mpte_group_size); 167 rq_regs.min_meta_chunk_size);
156 DTRACE("RQ_DLG_CALC: swath_height = 0x%0x", rq_regs.swath_height); 168 dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs.dpte_group_size);
157 DTRACE("RQ_DLG_CALC: pte_row_height_linear = 0x%0x", rq_regs.pte_row_height_linear); 169 dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs.mpte_group_size);
158 DTRACE("RQ_DLG_CALC: ===================================== "); 170 dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs.swath_height);
171 dml_print(
172 "DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n",
173 rq_regs.pte_row_height_linear);
174 dml_print("DML_RQ_DLG_CALC: =====================================\n");
159} 175}
160 176
161void print__rq_regs_st( 177void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs)
162 struct display_mode_lib *mode_lib,
163 struct _vcs_dpi_display_rq_regs_st rq_regs)
164{ 178{
165 DTRACE("RQ_DLG_CALC: ===================================== "); 179 dml_print("DML_RQ_DLG_CALC: =====================================\n");
166 DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST"); 180 dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n");
167 DTRACE("RQ_DLG_CALC: <LUMA> "); 181 dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
168 print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l); 182 print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l);
169 DTRACE("RQ_DLG_CALC: <CHROMA> "); 183 dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
170 print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c); 184 print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c);
171 DTRACE("RQ_DLG_CALC: drq_expansion_mode = 0x%0x", rq_regs.drq_expansion_mode); 185 dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs.drq_expansion_mode);
172 DTRACE("RQ_DLG_CALC: prq_expansion_mode = 0x%0x", rq_regs.prq_expansion_mode); 186 dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs.prq_expansion_mode);
173 DTRACE("RQ_DLG_CALC: mrq_expansion_mode = 0x%0x", rq_regs.mrq_expansion_mode); 187 dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs.mrq_expansion_mode);
174 DTRACE("RQ_DLG_CALC: crq_expansion_mode = 0x%0x", rq_regs.crq_expansion_mode); 188 dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs.crq_expansion_mode);
175 DTRACE("RQ_DLG_CALC: plane1_base_address = 0x%0x", rq_regs.plane1_base_address); 189 dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address);
176 DTRACE("RQ_DLG_CALC: ===================================== "); 190 dml_print("DML_RQ_DLG_CALC: =====================================\n");
177} 191}
178 192
179void print__dlg_regs_st( 193void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs)
180 struct display_mode_lib *mode_lib,
181 struct _vcs_dpi_display_dlg_regs_st dlg_regs)
182{ 194{
183 DTRACE("RQ_DLG_CALC: ===================================== "); 195 dml_print("DML_RQ_DLG_CALC: =====================================\n");
184 DTRACE("RQ_DLG_CALC: DISPLAY_DLG_REGS_ST "); 196 dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n");
185 DTRACE( 197 dml_print(
186 "RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x", 198 "DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n",
187 dlg_regs.refcyc_h_blank_end); 199 dlg_regs.refcyc_h_blank_end);
188 DTRACE("RQ_DLG_CALC: dlg_vblank_end = 0x%0x", dlg_regs.dlg_vblank_end); 200 dml_print(
189 DTRACE( 201 "DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n",
190 "RQ_DLG_CALC: min_dst_y_next_start = 0x%0x", 202 dlg_regs.dlg_vblank_end);
203 dml_print(
204 "DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n",
191 dlg_regs.min_dst_y_next_start); 205 dlg_regs.min_dst_y_next_start);
192 DTRACE( 206 dml_print(
193 "RQ_DLG_CALC: refcyc_per_htotal = 0x%0x", 207 "DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n",
194 dlg_regs.refcyc_per_htotal); 208 dlg_regs.refcyc_per_htotal);
195 DTRACE( 209 dml_print(
196 "RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x", 210 "DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n",
197 dlg_regs.refcyc_x_after_scaler); 211 dlg_regs.refcyc_x_after_scaler);
198 DTRACE( 212 dml_print(
199 "RQ_DLG_CALC: dst_y_after_scaler = 0x%0x", 213 "DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n",
200 dlg_regs.dst_y_after_scaler); 214 dlg_regs.dst_y_after_scaler);
201 DTRACE("RQ_DLG_CALC: dst_y_prefetch = 0x%0x", dlg_regs.dst_y_prefetch); 215 dml_print(
202 DTRACE( 216 "DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n",
203 "RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x", 217 dlg_regs.dst_y_prefetch);
218 dml_print(
219 "DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n",
204 dlg_regs.dst_y_per_vm_vblank); 220 dlg_regs.dst_y_per_vm_vblank);
205 DTRACE( 221 dml_print(
206 "RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x", 222 "DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n",
207 dlg_regs.dst_y_per_row_vblank); 223 dlg_regs.dst_y_per_row_vblank);
208 DTRACE( 224 dml_print(
209 "RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x", 225 "DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n",
226 dlg_regs.dst_y_per_vm_flip);
227 dml_print(
228 "DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n",
229 dlg_regs.dst_y_per_row_flip);
230 dml_print(
231 "DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n",
210 dlg_regs.ref_freq_to_pix_freq); 232 dlg_regs.ref_freq_to_pix_freq);
211 DTRACE("RQ_DLG_CALC: vratio_prefetch = 0x%0x", dlg_regs.vratio_prefetch); 233 dml_print(
212 DTRACE( 234 "DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n",
213 "RQ_DLG_CALC: vratio_prefetch_c = 0x%0x", 235 dlg_regs.vratio_prefetch);
236 dml_print(
237 "DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n",
214 dlg_regs.vratio_prefetch_c); 238 dlg_regs.vratio_prefetch_c);
215 DTRACE( 239 dml_print(
216 "RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x", 240 "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n",
217 dlg_regs.refcyc_per_pte_group_vblank_l); 241 dlg_regs.refcyc_per_pte_group_vblank_l);
218 DTRACE( 242 dml_print(
219 "RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x", 243 "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n",
220 dlg_regs.refcyc_per_pte_group_vblank_c); 244 dlg_regs.refcyc_per_pte_group_vblank_c);
221 DTRACE( 245 dml_print(
222 "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x", 246 "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n",
223 dlg_regs.refcyc_per_meta_chunk_vblank_l); 247 dlg_regs.refcyc_per_meta_chunk_vblank_l);
224 DTRACE( 248 dml_print(
225 "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x", 249 "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n",
226 dlg_regs.refcyc_per_meta_chunk_vblank_c); 250 dlg_regs.refcyc_per_meta_chunk_vblank_c);
227 DTRACE( 251 dml_print(
228 "RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x", 252 "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n",
253 dlg_regs.refcyc_per_pte_group_flip_l);
254 dml_print(
255 "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n",
256 dlg_regs.refcyc_per_pte_group_flip_c);
257 dml_print(
258 "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n",
259 dlg_regs.refcyc_per_meta_chunk_flip_l);
260 dml_print(
261 "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n",
262 dlg_regs.refcyc_per_meta_chunk_flip_c);
263 dml_print(
264 "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n",
229 dlg_regs.dst_y_per_pte_row_nom_l); 265 dlg_regs.dst_y_per_pte_row_nom_l);
230 DTRACE( 266 dml_print(
231 "RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x", 267 "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n",
232 dlg_regs.dst_y_per_pte_row_nom_c); 268 dlg_regs.dst_y_per_pte_row_nom_c);
233 DTRACE( 269 dml_print(
234 "RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x", 270 "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n",
235 dlg_regs.refcyc_per_pte_group_nom_l); 271 dlg_regs.refcyc_per_pte_group_nom_l);
236 DTRACE( 272 dml_print(
237 "RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x", 273 "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n",
238 dlg_regs.refcyc_per_pte_group_nom_c); 274 dlg_regs.refcyc_per_pte_group_nom_c);
239 DTRACE( 275 dml_print(
240 "RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x", 276 "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n",
241 dlg_regs.dst_y_per_meta_row_nom_l); 277 dlg_regs.dst_y_per_meta_row_nom_l);
242 DTRACE( 278 dml_print(
243 "RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x", 279 "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n",
244 dlg_regs.dst_y_per_meta_row_nom_c); 280 dlg_regs.dst_y_per_meta_row_nom_c);
245 DTRACE( 281 dml_print(
246 "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x", 282 "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n",
247 dlg_regs.refcyc_per_meta_chunk_nom_l); 283 dlg_regs.refcyc_per_meta_chunk_nom_l);
248 DTRACE( 284 dml_print(
249 "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x", 285 "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n",
250 dlg_regs.refcyc_per_meta_chunk_nom_c); 286 dlg_regs.refcyc_per_meta_chunk_nom_c);
251 DTRACE( 287 dml_print(
252 "RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x", 288 "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n",
253 dlg_regs.refcyc_per_line_delivery_pre_l); 289 dlg_regs.refcyc_per_line_delivery_pre_l);
254 DTRACE( 290 dml_print(
255 "RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x", 291 "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n",
256 dlg_regs.refcyc_per_line_delivery_pre_c); 292 dlg_regs.refcyc_per_line_delivery_pre_c);
257 DTRACE( 293 dml_print(
258 "RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x", 294 "DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n",
259 dlg_regs.refcyc_per_line_delivery_l); 295 dlg_regs.refcyc_per_line_delivery_l);
260 DTRACE( 296 dml_print(
261 "RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x", 297 "DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n",
262 dlg_regs.refcyc_per_line_delivery_c); 298 dlg_regs.refcyc_per_line_delivery_c);
263 DTRACE( 299 dml_print(
264 "RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x", 300 "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n",
265 dlg_regs.chunk_hdl_adjust_cur0); 301 dlg_regs.chunk_hdl_adjust_cur0);
266 DTRACE("RQ_DLG_CALC: ===================================== "); 302 dml_print(
303 "DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n",
304 dlg_regs.dst_y_offset_cur1);
305 dml_print(
306 "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n",
307 dlg_regs.chunk_hdl_adjust_cur1);
308 dml_print(
309 "DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n",
310 dlg_regs.vready_after_vcount0);
311 dml_print(
312 "DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n",
313 dlg_regs.dst_y_delta_drq_limit);
314 dml_print(
315 "DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n",
316 dlg_regs.xfc_reg_transfer_delay);
317 dml_print(
318 "DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n",
319 dlg_regs.xfc_reg_precharge_delay);
320 dml_print(
321 "DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n",
322 dlg_regs.xfc_reg_remote_surface_flip_latency);
323
324 dml_print("DML_RQ_DLG_CALC: =====================================\n");
267} 325}
268 326
269void print__ttu_regs_st( 327void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs)
270 struct display_mode_lib *mode_lib,
271 struct _vcs_dpi_display_ttu_regs_st ttu_regs)
272{ 328{
273 DTRACE("RQ_DLG_CALC: ===================================== "); 329 dml_print("DML_RQ_DLG_CALC: =====================================\n");
274 DTRACE("RQ_DLG_CALC: DISPLAY_TTU_REGS_ST "); 330 dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n");
275 DTRACE( 331 dml_print(
276 "RQ_DLG_CALC: qos_level_low_wm = 0x%0x", 332 "DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n",
277 ttu_regs.qos_level_low_wm); 333 ttu_regs.qos_level_low_wm);
278 DTRACE( 334 dml_print(
279 "RQ_DLG_CALC: qos_level_high_wm = 0x%0x", 335 "DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n",
280 ttu_regs.qos_level_high_wm); 336 ttu_regs.qos_level_high_wm);
281 DTRACE("RQ_DLG_CALC: min_ttu_vblank = 0x%0x", ttu_regs.min_ttu_vblank); 337 dml_print(
282 DTRACE("RQ_DLG_CALC: qos_level_flip = 0x%0x", ttu_regs.qos_level_flip); 338 "DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n",
283 DTRACE( 339 ttu_regs.min_ttu_vblank);
284 "RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x", 340 dml_print(
341 "DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n",
342 ttu_regs.qos_level_flip);
343 dml_print(
344 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n",
285 ttu_regs.refcyc_per_req_delivery_pre_l); 345 ttu_regs.refcyc_per_req_delivery_pre_l);
286 DTRACE( 346 dml_print(
287 "RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x", 347 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n",
288 ttu_regs.refcyc_per_req_delivery_l); 348 ttu_regs.refcyc_per_req_delivery_l);
289 DTRACE( 349 dml_print(
290 "RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x", 350 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n",
291 ttu_regs.refcyc_per_req_delivery_pre_c); 351 ttu_regs.refcyc_per_req_delivery_pre_c);
292 DTRACE( 352 dml_print(
293 "RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x", 353 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n",
294 ttu_regs.refcyc_per_req_delivery_c); 354 ttu_regs.refcyc_per_req_delivery_c);
295 DTRACE( 355 dml_print(
296 "RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x", 356 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n",
297 ttu_regs.refcyc_per_req_delivery_cur0); 357 ttu_regs.refcyc_per_req_delivery_cur0);
298 DTRACE( 358 dml_print(
299 "RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x", 359 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n",
300 ttu_regs.refcyc_per_req_delivery_pre_cur0); 360 ttu_regs.refcyc_per_req_delivery_pre_cur0);
301 DTRACE( 361 dml_print(
302 "RQ_DLG_CALC: qos_level_fixed_l = 0x%0x", 362 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n",
363 ttu_regs.refcyc_per_req_delivery_cur1);
364 dml_print(
365 "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n",
366 ttu_regs.refcyc_per_req_delivery_pre_cur1);
367 dml_print(
368 "DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n",
303 ttu_regs.qos_level_fixed_l); 369 ttu_regs.qos_level_fixed_l);
304 DTRACE( 370 dml_print(
305 "RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x", 371 "DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n",
306 ttu_regs.qos_ramp_disable_l); 372 ttu_regs.qos_ramp_disable_l);
307 DTRACE( 373 dml_print(
308 "RQ_DLG_CALC: qos_level_fixed_c = 0x%0x", 374 "DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n",
309 ttu_regs.qos_level_fixed_c); 375 ttu_regs.qos_level_fixed_c);
310 DTRACE( 376 dml_print(
311 "RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x", 377 "DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n",
312 ttu_regs.qos_ramp_disable_c); 378 ttu_regs.qos_ramp_disable_c);
313 DTRACE( 379 dml_print(
314 "RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x", 380 "DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n",
315 ttu_regs.qos_level_fixed_cur0); 381 ttu_regs.qos_level_fixed_cur0);
316 DTRACE( 382 dml_print(
317 "RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x", 383 "DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n",
318 ttu_regs.qos_ramp_disable_cur0); 384 ttu_regs.qos_ramp_disable_cur0);
319 DTRACE("RQ_DLG_CALC: ===================================== "); 385 dml_print(
386 "DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n",
387 ttu_regs.qos_level_fixed_cur1);
388 dml_print(
389 "DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n",
390 ttu_regs.qos_ramp_disable_cur1);
391 dml_print("DML_RQ_DLG_CALC: =====================================\n");
320} 392}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h
index 7403ccaf637b..1f24db830737 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h
@@ -22,6 +22,7 @@
22 * Authors: AMD 22 * Authors: AMD
23 * 23 *
24 */ 24 */
25
25#ifndef __DISPLAY_RQ_DLG_HELPERS_H__ 26#ifndef __DISPLAY_RQ_DLG_HELPERS_H__
26#define __DISPLAY_RQ_DLG_HELPERS_H__ 27#define __DISPLAY_RQ_DLG_HELPERS_H__
27 28
@@ -31,36 +32,16 @@
31/* Function: Printer functions 32/* Function: Printer functions
32 * Print various struct 33 * Print various struct
33 */ 34 */
34void print__rq_params_st( 35void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param);
35 struct display_mode_lib *mode_lib, 36void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing);
36 struct _vcs_dpi_display_rq_params_st rq_param); 37void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param);
37void print__data_rq_sizing_params_st( 38void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param);
38 struct display_mode_lib *mode_lib, 39void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param);
39 struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing); 40void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param);
40void print__data_rq_dlg_params_st(
41 struct display_mode_lib *mode_lib,
42 struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param);
43void print__data_rq_misc_params_st(
44 struct display_mode_lib *mode_lib,
45 struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param);
46void print__rq_dlg_params_st(
47 struct display_mode_lib *mode_lib,
48 struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param);
49void print__dlg_sys_params_st(
50 struct display_mode_lib *mode_lib,
51 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param);
52 41
53void print__data_rq_regs_st( 42void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs);
54 struct display_mode_lib *mode_lib, 43void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs);
55 struct _vcs_dpi_display_data_rq_regs_st data_rq_regs); 44void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs);
56void print__rq_regs_st( 45void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs);
57 struct display_mode_lib *mode_lib,
58 struct _vcs_dpi_display_rq_regs_st rq_regs);
59void print__dlg_regs_st(
60 struct display_mode_lib *mode_lib,
61 struct _vcs_dpi_display_dlg_regs_st dlg_regs);
62void print__ttu_regs_st(
63 struct display_mode_lib *mode_lib,
64 struct _vcs_dpi_display_ttu_regs_st ttu_regs);
65 46
66#endif 47#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c
deleted file mode 100644
index 142a3284ac44..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.c
+++ /dev/null
@@ -1,1282 +0,0 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25#include "display_watermark.h"
26#include "display_mode_lib.h"
27#include "dml_inline_defs.h"
28
29static void get_bytes_per_pixel(
30 enum source_format_class format,
31 struct _vcs_dpi_wm_calc_pipe_params_st *plane)
32{
33 switch (format) {
34 case dm_444_64:
35 plane->bytes_per_pixel_y = 8.0;
36 plane->bytes_per_pixel_c = 0.0;
37 break;
38 case dm_444_32:
39 plane->bytes_per_pixel_y = 4.0;
40 plane->bytes_per_pixel_c = 0.0;
41 break;
42 case dm_444_16:
43 plane->bytes_per_pixel_y = 2.0;
44 plane->bytes_per_pixel_c = 0.0;
45 break;
46 case dm_422_10:
47 plane->bytes_per_pixel_y = 4.0;
48 plane->bytes_per_pixel_c = 0.0;
49 break;
50 case dm_422_8:
51 plane->bytes_per_pixel_y = 2.0;
52 plane->bytes_per_pixel_c = 0.0;
53 break;
54 case dm_420_8:
55 plane->bytes_per_pixel_y = 1.0;
56 plane->bytes_per_pixel_c = 2.0;
57 break;
58 case dm_420_10:
59 plane->bytes_per_pixel_y = 4.0 / 3;
60 plane->bytes_per_pixel_c = 8.0 / 3;
61 break;
62 default:
63 BREAK_TO_DEBUGGER(); /* invalid format in get_bytes_per_pixel */
64 }
65}
66
67static unsigned int get_swath_width_y(
68 struct _vcs_dpi_display_pipe_source_params_st *src_param,
69 unsigned int num_dpp)
70{
71 unsigned int val;
72
73 /* note that we don't divide by num_dpp here because we have an interface which has already split
74 * any viewports
75 */
76 if (src_param->source_scan == dm_horz) {
77 val = src_param->viewport_width;
78 } else {
79 val = src_param->viewport_height;
80 }
81
82 return val;
83}
84
85static void get_swath_height(
86 struct display_mode_lib *mode_lib,
87 struct _vcs_dpi_display_pipe_source_params_st *src_param,
88 struct _vcs_dpi_wm_calc_pipe_params_st *plane,
89 unsigned int swath_width_y)
90{
91 double buffer_width;
92
93 if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32
94 || src_param->source_format == dm_444_16) {
95 if (src_param->sw_mode == dm_sw_linear) {
96 plane->swath_height_y = 1;
97 } else if (src_param->source_format == dm_444_64) {
98 plane->swath_height_y = 4;
99 } else {
100 plane->swath_height_y = 8;
101 }
102
103 if (src_param->source_scan != dm_horz) {
104 plane->swath_height_y = 256 / (unsigned int) plane->bytes_per_pixel_y
105 / plane->swath_height_y;
106 }
107
108 plane->swath_height_c = 0;
109
110 } else {
111 if (src_param->sw_mode == dm_sw_linear) {
112 plane->swath_height_y = 1;
113 plane->swath_height_c = 1;
114 } else if (src_param->source_format == dm_420_8) {
115 plane->swath_height_y = 16;
116 plane->swath_height_c = 8;
117 } else {
118 plane->swath_height_y = 8;
119 plane->swath_height_c = 8;
120 }
121
122 if (src_param->source_scan != dm_horz) {
123 double bytes_per_pixel_c_ceil;
124
125 plane->swath_height_y = 256 / dml_ceil(plane->bytes_per_pixel_y)
126 / plane->swath_height_y;
127
128 bytes_per_pixel_c_ceil = dml_ceil_2(plane->bytes_per_pixel_c);
129
130 plane->swath_height_c = 256 / bytes_per_pixel_c_ceil
131 / plane->swath_height_c;
132 }
133 }
134
135 /* use swath height min if buffer isn't big enough */
136
137 buffer_width = ((double) mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0)
138 / (plane->bytes_per_pixel_y * (double) plane->swath_height_y
139 + (plane->bytes_per_pixel_c / 2.0
140 * (double) plane->swath_height_c));
141
142 if ((double) swath_width_y <= buffer_width) {
143 /* do nothing, just keep code structure from Gabes vba */
144 } else {
145 /* substitute swath height with swath height min */
146 if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32
147 || src_param->source_format == dm_444_16) {
148 if ((src_param->sw_mode == dm_sw_linear)
149 || (src_param->source_format == dm_444_64
150 && (src_param->sw_mode == dm_sw_4kb_s
151 || src_param->sw_mode
152 == dm_sw_4kb_s_x
153 || src_param->sw_mode
154 == dm_sw_64kb_s
155 || src_param->sw_mode
156 == dm_sw_64kb_s_t
157 || src_param->sw_mode
158 == dm_sw_64kb_s_x
159 || src_param->sw_mode
160 == dm_sw_var_s
161 || src_param->sw_mode
162 == dm_sw_var_s_x)
163 && src_param->source_scan == dm_horz)) {
164 /* do nothing, just keep code structure from Gabes vba */
165 } else {
166 plane->swath_height_y = plane->swath_height_y / 2;
167 }
168 } else {
169 if (src_param->sw_mode == dm_sw_linear) {
170 /* do nothing, just keep code structure from Gabes vba */
171 } else if (src_param->source_format == dm_420_8
172 && src_param->source_scan == dm_horz) {
173 plane->swath_height_y = plane->swath_height_y / 2;
174 } else if (src_param->source_format == dm_420_10
175 && src_param->source_scan == dm_horz) {
176 plane->swath_height_c = plane->swath_height_c / 2;
177 }
178 }
179 }
180
181 if (plane->swath_height_c == 0) {
182 plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0;
183 } else if (plane->swath_height_c <= plane->swath_height_y) {
184 plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0;
185 } else {
186 plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 * 2.0 / 3.0;
187 }
188}
189
190static void calc_display_pipe_line_delivery_time(
191 struct display_mode_lib *mode_lib,
192 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
193 unsigned int num_planes)
194{
195 unsigned int i;
196
197 for (i = 0; i < num_planes; i++) {
198 if (planes[i].v_ratio <= 1.0) {
199 planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y
200 * planes[i].num_dpp / planes[i].h_ratio
201 / planes[i].pixclk_mhz;
202 } else {
203 double dchub_pscl_bw_per_clk;
204
205 if (planes[i].h_ratio > 1) {
206 double num_hscl_kernels;
207
208 num_hscl_kernels = dml_ceil((double) planes[i].h_taps / 6);
209 dchub_pscl_bw_per_clk =
210 dml_min(
211 (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
212 mode_lib->ip.max_pscl_lb_bw_pix_per_clk
213 * planes[i].h_ratio
214 / num_hscl_kernels);
215 } else {
216 dchub_pscl_bw_per_clk =
217 dml_min(
218 (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
219 (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk);
220 }
221
222 planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y
223 / dchub_pscl_bw_per_clk / planes[i].dppclk_mhz;
224 }
225 }
226}
227
228static double calc_total_data_read_bw(
229 struct display_mode_lib *mode_lib,
230 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
231 unsigned int num_planes)
232{
233 double val = 0.0;
234 unsigned int i;
235
236 for (i = 0; i < num_planes; i++) {
237 double swath_width_y_plane = planes[i].swath_width_y * planes[i].num_dpp;
238
239 planes[i].read_bw = swath_width_y_plane
240 * (dml_ceil(planes[i].bytes_per_pixel_y)
241 + dml_ceil_2(planes[i].bytes_per_pixel_c) / 2)
242 / (planes[i].h_total / planes[i].pixclk_mhz) * planes[i].v_ratio;
243
244 val += planes[i].read_bw;
245
246 DTRACE("plane[%d] start", i);
247 DTRACE("read_bw = %f", planes[i].read_bw);
248 DTRACE("plane[%d] end", i);
249 }
250
251 return val;
252}
253
254double dml_wm_calc_total_data_read_bw(
255 struct display_mode_lib *mode_lib,
256 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
257 unsigned int num_planes)
258{
259 return calc_total_data_read_bw(mode_lib, planes, num_planes);
260}
261
262static double calc_dcfclk_mhz(
263 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
264 unsigned int num_planes)
265{
266 double dcfclk_mhz = -1.0;
267 unsigned int i;
268
269 for (i = 0; i < num_planes; i++) {
270 /* voltage and dcfclk must be the same for all pipes */
271 ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == planes[i].dcfclk_mhz);
272 dcfclk_mhz = planes[i].dcfclk_mhz;
273 }
274
275 return dcfclk_mhz;
276}
277
278static enum voltage_state find_voltage(
279 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
280 unsigned int num_planes)
281{
282 int voltage = -1;
283 unsigned int i;
284
285 for (i = 0; i < num_planes; i++) {
286 ASSERT(voltage == -1 || voltage == planes[i].voltage);
287 voltage = planes[i].voltage;
288 }
289
290 return (enum voltage_state) voltage;
291}
292
293static bool find_dcc_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes)
294{
295 unsigned int i;
296
297 for (i = 0; i < num_planes; i++) {
298 if (planes[i].dcc_enable) {
299 return true;
300 }
301 }
302
303 return false;
304}
305
306static double calc_return_bw(
307 struct display_mode_lib *mode_lib,
308 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
309 unsigned int num_planes)
310{
311 struct _vcs_dpi_soc_bounding_box_st *soc;
312 double return_bw_mbps;
313 double dcfclk_mhz;
314 double return_bus_bw;
315 enum voltage_state voltage;
316 double return_bw_to_dcn;
317 bool dcc_enable;
318 double rob_chunk_diff;
319 double urgent_latency_traffic;
320 double critical_compression;
321 struct _vcs_dpi_voltage_scaling_st state;
322
323 soc = &mode_lib->soc;
324
325 dcfclk_mhz = calc_dcfclk_mhz(planes, num_planes);
326 return_bus_bw = dcfclk_mhz * soc->return_bus_width_bytes;
327
328 DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz);
329 DTRACE("INTERMEDIATE return_bus_bw = %f", return_bus_bw);
330
331 voltage = find_voltage(planes, num_planes);
332 return_bw_to_dcn = dml_socbb_return_bw_mhz(soc, voltage);
333
334 dcc_enable = find_dcc_enable(planes, num_planes);
335
336 return_bw_mbps = return_bw_to_dcn;
337 DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps);
338
339 rob_chunk_diff =
340 (mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes)
341 * 1024.0;
342 DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff);
343
344 if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) {
345 double dcc_return_bw =
346 return_bw_to_dcn * 4.0
347 * (1.0
348 - soc->urgent_latency_us
349 / (rob_chunk_diff
350 / (return_bw_to_dcn
351 - return_bus_bw
352 / 4.0)
353 + soc->urgent_latency_us));
354 return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw);
355 DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw);
356 }
357
358 urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us;
359 DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic);
360 critical_compression = 2.0 * urgent_latency_traffic
361 / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff);
362 DTRACE("INTERMEDIATE critical_compression = %f", critical_compression);
363
364 if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) {
365 double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff
366 * urgent_latency_traffic);
367 crit_return_bw = crit_return_bw
368 / dml_pow(
369 return_bw_to_dcn * soc->urgent_latency_us
370 + rob_chunk_diff,
371 2);
372 DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw);
373 return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw);
374 }
375
376 /* Gabe does this again for some reason using the value of return_bw_mpbs from the previous calculation
377 * and a lightly different return_bw_to_dcn
378 */
379
380 state = dml_socbb_voltage_scaling(soc, voltage);
381 return_bw_to_dcn = dml_min(
382 soc->return_bus_width_bytes * dcfclk_mhz,
383 state.dram_bw_per_chan_gbps * 1000.0 * (double) soc->num_chans);
384
385 DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff);
386
387 if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) {
388 double dcc_return_bw =
389 return_bw_to_dcn * 4.0
390 * (1.0
391 - soc->urgent_latency_us
392 / (rob_chunk_diff
393 / (return_bw_to_dcn
394 - return_bus_bw
395 / 4.0)
396 + soc->urgent_latency_us));
397 return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw);
398 DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw);
399 }
400
401 urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us;
402 DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic);
403 critical_compression = 2.0 * urgent_latency_traffic
404 / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff);
405 DTRACE("INTERMEDIATE critical_compression = %f", critical_compression);
406
407 /* problem here? */
408 if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) {
409 double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff
410 * urgent_latency_traffic);
411 crit_return_bw = crit_return_bw
412 / dml_pow(
413 return_bw_to_dcn * soc->urgent_latency_us
414 + rob_chunk_diff,
415 2);
416 DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw);
417 DTRACE("INTERMEDIATE return_bw_to_dcn = %f", return_bw_to_dcn);
418 DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff);
419 DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic);
420
421 return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw);
422 }
423
424 DTRACE("INTERMEDIATE final return_bw_mbps = %f", return_bw_mbps);
425 return return_bw_mbps;
426}
427
428double dml_wm_calc_return_bw(
429 struct display_mode_lib *mode_lib,
430 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
431 unsigned int num_planes)
432{
433 return calc_return_bw(mode_lib, planes, num_planes);
434}
435
436static double calc_last_pixel_of_line_extra_wm_us(
437 struct display_mode_lib *mode_lib,
438 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
439 unsigned int num_planes)
440{
441 double val = 0.0;
442 double total_data_read_bw = calc_total_data_read_bw(mode_lib, planes, num_planes);
443 int voltage = -1;
444 unsigned int i;
445 double return_bw_mbps;
446
447 for (i = 0; i < num_planes; i++) {
448 /* voltage mode must be the same for all pipes */
449 ASSERT(voltage == -1 || voltage == planes[i].voltage);
450 voltage = planes[i].voltage;
451 }
452 return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
453
454 for (i = 0; i < num_planes; i++) {
455 double bytes_pp_y = dml_ceil(planes[i].bytes_per_pixel_y);
456 double bytes_pp_c = dml_ceil_2(planes[i].bytes_per_pixel_c);
457 double swath_bytes_y = (double) planes[i].swath_width_y
458 * (double) planes[i].swath_height_y * (double) bytes_pp_y;
459 double swath_bytes_c = ((double) planes[i].swath_width_y / 2.0)
460 * (double) planes[i].swath_height_c * (double) bytes_pp_c;
461 double data_fabric_line_delivery_time = (swath_bytes_y + swath_bytes_c)
462 / (return_bw_mbps * planes[i].read_bw / (double) planes[i].num_dpp
463 / total_data_read_bw);
464
465 DTRACE(
466 "bytes_pp_y = %f, swath_width_y = %f, swath_height_y = %f, swath_bytes_y = %f",
467 bytes_pp_y,
468 (double) planes[i].swath_width_y,
469 (double) planes[i].swath_height_y,
470 swath_bytes_y);
471 DTRACE(
472 "bytes_pp_c = %f, swath_width_c = %f, swath_height_c = %f, swath_bytes_c = %f",
473 bytes_pp_c,
474 ((double) planes[i].swath_width_y / 2.0),
475 (double) planes[i].swath_height_c,
476 swath_bytes_c);
477 DTRACE(
478 "return_bw_mbps = %f, read_bw = %f, num_dpp = %d, total_data_read_bw = %f",
479 return_bw_mbps,
480 planes[i].read_bw,
481 planes[i].num_dpp,
482 total_data_read_bw);
483 DTRACE("data_fabric_line_delivery_time = %f", data_fabric_line_delivery_time);
484 DTRACE(
485 "display_pipe_line_delivery_time = %f",
486 planes[i].display_pipe_line_delivery_time);
487
488 val = dml_max(
489 val,
490 data_fabric_line_delivery_time
491 - planes[i].display_pipe_line_delivery_time);
492 }
493
494 DTRACE("last_pixel_of_line_extra_wm is %f us", val);
495 return val;
496}
497
498static bool calc_pte_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes)
499{
500 unsigned int i;
501
502 for (i = 0; i < num_planes; i++) {
503 if (planes[i].pte_enable) {
504 return true;
505 }
506 }
507
508 return false;
509}
510
511static void calc_lines_in_det_y(struct _vcs_dpi_wm_calc_pipe_params_st *plane)
512{
513 plane->lines_in_det_y = plane->det_buffer_size_y / plane->bytes_per_pixel_y
514 / plane->swath_width_y;
515 plane->lines_in_det_y_rounded_down_to_swath = dml_floor(
516 (double) plane->lines_in_det_y / plane->swath_height_y)
517 * plane->swath_height_y;
518 plane->full_det_buffering_time = plane->lines_in_det_y_rounded_down_to_swath
519 * (plane->h_total / plane->pixclk_mhz);
520}
521
522/* CHECKME: not obviously 1:1 with calculation described in architectural
523 * document or spreadsheet */
524static void calc_dcfclk_deepsleep_mhz_per_plane(
525 struct display_mode_lib *mode_lib,
526 struct _vcs_dpi_wm_calc_pipe_params_st *plane)
527{
528 double bus_width_per_pixel;
529
530 if (plane->swath_height_c == 0) {
531 bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 64;
532 } else {
533 double bus_width_per_pixel_c;
534
535 bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 32;
536 bus_width_per_pixel_c = dml_ceil(plane->bytes_per_pixel_c) / 32;
537 if (bus_width_per_pixel < bus_width_per_pixel_c)
538 bus_width_per_pixel = bus_width_per_pixel_c;
539 }
540
541 if (plane->v_ratio <= 1) {
542 plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->pixclk_mhz / plane->num_dpp
543 * plane->h_ratio * bus_width_per_pixel;
544 } else if (plane->h_ratio > 1) {
545 double num_hscl_kernels = dml_ceil((double) plane->h_taps / 6);
546 double dchub_pscl_bw_per_clk = dml_min(
547 (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
548 mode_lib->ip.max_pscl_lb_bw_pix_per_clk * plane->h_ratio
549 / num_hscl_kernels);
550
551 plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz
552 * dchub_pscl_bw_per_clk * bus_width_per_pixel;
553 } else {
554 double dchub_pscl_bw_per_clk = dml_min(
555 (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
556 (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk);
557
558 plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz
559 * dchub_pscl_bw_per_clk * bus_width_per_pixel;
560 }
561
562 plane->dcfclk_deepsleep_mhz_per_plane = dml_max(
563 plane->dcfclk_deepsleep_mhz_per_plane,
564 plane->pixclk_mhz / 16);
565}
566
567/* Implementation of expected stutter efficiency from DCN1_Display_Mode.docx */
568double dml_wm_expected_stutter_eff_e2e(
569 struct display_mode_lib *mode_lib,
570 struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
571 unsigned int num_pipes)
572{
573 double min_full_det_buffering_time_us;
574 double frame_time_for_min_full_det_buffering_time_us = 0.0;
575 struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
576 unsigned int num_planes;
577 unsigned int i;
578 double total_data_read_bw_mbps;
579 double average_read_bw_gbps;
580 double min_full_det_buffer_size_bytes;
581 double rob_fill_size_bytes;
582 double part_of_burst_that_fits_in_rob;
583 int voltage;
584 double dcfclk_mhz;
585 unsigned int total_writeback;
586 double return_bw_mbps;
587 double stutter_burst_time_us;
588 double stutter_eff_not_including_vblank;
589 double smallest_vblank_us;
590 double stutter_eff;
591
592 memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
593 DTRACE("calculating expected stutter efficiency");
594
595 num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes);
596
597 for (i = 0; i < num_planes; i++) {
598 calc_lines_in_det_y(&planes[i]);
599
600 DTRACE("swath width y plane %d = %d", i, planes[i].swath_width_y);
601 DTRACE("swath height y plane %d = %d", i, planes[i].swath_height_y);
602 DTRACE(
603 "bytes per pixel det y plane %d = %f",
604 i,
605 planes[i].bytes_per_pixel_y);
606 DTRACE(
607 "bytes per pixel det c plane %d = %f",
608 i,
609 planes[i].bytes_per_pixel_c);
610 DTRACE(
611 "det buffer size plane %d = %d",
612 i,
613 planes[i].det_buffer_size_y);
614 DTRACE("lines in det plane %d = %d", i, planes[i].lines_in_det_y);
615 DTRACE(
616 "lines in det rounded to swaths plane %d = %d",
617 i,
618 planes[i].lines_in_det_y_rounded_down_to_swath);
619 }
620
621 min_full_det_buffering_time_us = 9999.0;
622 for (i = 0; i < num_planes; i++) {
623 if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) {
624 min_full_det_buffering_time_us = planes[i].full_det_buffering_time;
625 frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total
626 * planes[i].h_total / planes[i].pixclk_mhz;
627 }
628 }
629
630 DTRACE("INTERMEDIATE: min_full_det_buffering_time_us = %f", min_full_det_buffering_time_us);
631
632 total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes);
633
634 average_read_bw_gbps = 0.0;
635
636 for (i = 0; i < num_planes; i++) {
637 if (planes[i].dcc_enable) {
638 average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000;
639 } else {
640 average_read_bw_gbps += planes[i].read_bw / 1000;
641 }
642
643 if (planes[i].dcc_enable) {
644 average_read_bw_gbps += planes[i].read_bw / 1000 / 256;
645 }
646
647 if (planes[i].pte_enable) {
648 average_read_bw_gbps += planes[i].read_bw / 1000 / 512;
649 }
650 }
651
652 min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps;
653 rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps
654 / (average_read_bw_gbps * 1000);
655 part_of_burst_that_fits_in_rob = dml_min(
656 min_full_det_buffer_size_bytes,
657 rob_fill_size_bytes);
658
659 voltage = -1;
660 dcfclk_mhz = -1.0;
661 total_writeback = 0;
662
663 for (i = 0; i < num_pipes; i++) {
664 /* voltage and dcfclk must be the same for all pipes */
665 ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage);
666 voltage = e2e[i].clks_cfg.voltage;
667 ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz);
668 dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
669
670 if (e2e[i].dout.output_type == dm_wb)
671 total_writeback++;
672 }
673
674 return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
675
676 DTRACE("INTERMEDIATE: part_of_burst_that_fits_in_rob = %f", part_of_burst_that_fits_in_rob);
677 DTRACE("INTERMEDIATE: average_read_bw_gbps = %f", average_read_bw_gbps);
678 DTRACE("INTERMEDIATE: total_data_read_bw_mbps = %f", total_data_read_bw_mbps);
679 DTRACE("INTERMEDIATE: return_bw_mbps = %f", return_bw_mbps);
680
681 stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000)
682 / total_data_read_bw_mbps / return_bw_mbps
683 + (min_full_det_buffering_time_us * total_data_read_bw_mbps
684 - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64);
685 DTRACE("INTERMEDIATE: stutter_burst_time_us = %f", stutter_burst_time_us);
686
687 if (total_writeback == 0) {
688 stutter_eff_not_including_vblank = (1.0
689 - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us)
690 / min_full_det_buffering_time_us)) * 100.0;
691 } else {
692 stutter_eff_not_including_vblank = 0.0;
693 }
694
695 DTRACE("stutter_efficiency_not_including_vblank = %f", stutter_eff_not_including_vblank);
696
697 smallest_vblank_us = 9999.0;
698
699 for (i = 0; i < num_pipes; i++) {
700 double vblank_us;
701 if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) {
702 vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1
703 - e2e[i].pipe.dest.vblank_start
704 + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal)
705 / e2e[i].pipe.dest.pixel_rate_mhz;
706 } else {
707 vblank_us = 0.0;
708 }
709
710 smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us);
711 }
712
713 DTRACE("smallest vblank = %f us", smallest_vblank_us);
714
715 stutter_eff = 100.0
716 * (((stutter_eff_not_including_vblank / 100.0)
717 * (frame_time_for_min_full_det_buffering_time_us
718 - smallest_vblank_us) + smallest_vblank_us)
719 / frame_time_for_min_full_det_buffering_time_us);
720
721 DTRACE("stutter_efficiency = %f", stutter_eff);
722
723 return stutter_eff_not_including_vblank;
724}
725
726double dml_wm_expected_stutter_eff_e2e_with_vblank(
727 struct display_mode_lib *mode_lib,
728 struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
729 unsigned int num_pipes)
730{
731 double min_full_det_buffering_time_us;
732 double frame_time_for_min_full_det_buffering_time_us = 0.0;
733 struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
734 unsigned int num_planes;
735 unsigned int i;
736 double total_data_read_bw_mbps;
737 double average_read_bw_gbps;
738 double min_full_det_buffer_size_bytes;
739 double rob_fill_size_bytes;
740 double part_of_burst_that_fits_in_rob;
741 int voltage;
742 double dcfclk_mhz;
743 unsigned int total_writeback;
744 double return_bw_mbps;
745 double stutter_burst_time_us;
746 double stutter_eff_not_including_vblank;
747 double smallest_vblank_us;
748 double stutter_eff;
749
750 memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
751 num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes);
752
753 for (i = 0; i < num_planes; i++) {
754 calc_lines_in_det_y(&planes[i]);
755 }
756
757 min_full_det_buffering_time_us = 9999.0;
758 for (i = 0; i < num_planes; i++) {
759 if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) {
760 min_full_det_buffering_time_us = planes[i].full_det_buffering_time;
761 frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total
762 * planes[i].h_total / planes[i].pixclk_mhz;
763 }
764 }
765
766 total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes);
767 average_read_bw_gbps = 0.0;
768
769 for (i = 0; i < num_planes; i++) {
770 if (planes[i].dcc_enable) {
771 average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000;
772 } else {
773 average_read_bw_gbps += planes[i].read_bw / 1000;
774 }
775
776 if (planes[i].dcc_enable) {
777 average_read_bw_gbps += planes[i].read_bw / 1000 / 256;
778 }
779
780 if (planes[i].pte_enable) {
781 average_read_bw_gbps += planes[i].read_bw / 1000 / 512;
782 }
783 }
784
785 min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps;
786 rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps
787 / (average_read_bw_gbps * 1000);
788 part_of_burst_that_fits_in_rob = dml_min(
789 min_full_det_buffer_size_bytes,
790 rob_fill_size_bytes);
791
792 voltage = -1;
793 dcfclk_mhz = -1.0;
794 total_writeback = 0;
795
796 for (i = 0; i < num_pipes; i++) {
797 /* voltage and dcfclk must be the same for all pipes */
798 ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage);
799 voltage = e2e[i].clks_cfg.voltage;
800 ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz);
801 dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
802
803 if (e2e[i].dout.output_type == dm_wb)
804 total_writeback++;
805 }
806
807 return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
808
809 stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000)
810 / total_data_read_bw_mbps / return_bw_mbps
811 + (min_full_det_buffering_time_us * total_data_read_bw_mbps
812 - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64);
813
814 if (total_writeback == 0) {
815 stutter_eff_not_including_vblank = (1.0
816 - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us)
817 / min_full_det_buffering_time_us)) * 100.0;
818 } else {
819 stutter_eff_not_including_vblank = 0.0;
820 }
821
822 smallest_vblank_us = 9999.0;
823
824 for (i = 0; i < num_pipes; i++) {
825 double vblank_us;
826 if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) {
827 vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1
828 - e2e[i].pipe.dest.vblank_start
829 + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal)
830 / e2e[i].pipe.dest.pixel_rate_mhz;
831 } else {
832 vblank_us = 0.0;
833 }
834
835 smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us);
836 }
837
838 stutter_eff = 100.0
839 * (((stutter_eff_not_including_vblank / 100.0)
840 * (frame_time_for_min_full_det_buffering_time_us
841 - smallest_vblank_us) + smallest_vblank_us)
842 / frame_time_for_min_full_det_buffering_time_us);
843
844
845 return stutter_eff;
846}
847
848double urgent_extra_calc(
849 struct display_mode_lib *mode_lib,
850 double dcfclk_mhz,
851 double return_bw_mbps,
852 unsigned int total_active_dpp,
853 unsigned int total_dcc_active_dpp)
854{
855 double urgent_extra_latency_us = 0.0;
856 double urgent_round_trip_ooo_latency_us;
857
858 urgent_round_trip_ooo_latency_us =
859 (((double) mode_lib->soc.round_trip_ping_latency_dcfclk_cycles + 32)
860 / dcfclk_mhz)
861 + (((double) (mode_lib->soc.urgent_out_of_order_return_per_channel_bytes
862 * mode_lib->soc.num_chans)) / return_bw_mbps);
863
864 DTRACE(
865 "INTERMEDIATE round_trip_ping_latency_dcfclk_cycles = %d",
866 mode_lib->soc.round_trip_ping_latency_dcfclk_cycles);
867 DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz);
868 DTRACE(
869 "INTERMEDIATE urgent_out_of_order_return_per_channel_bytes = %d",
870 mode_lib->soc.urgent_out_of_order_return_per_channel_bytes);
871
872 urgent_extra_latency_us = urgent_round_trip_ooo_latency_us
873 + ((double) total_active_dpp * mode_lib->ip.pixel_chunk_size_kbytes
874 + (double) total_dcc_active_dpp
875 * mode_lib->ip.meta_chunk_size_kbytes)
876 * 1024.0 / return_bw_mbps; /* to us */
877
878 DTRACE(
879 "INTERMEDIATE urgent_round_trip_ooo_latency_us = %f",
880 urgent_round_trip_ooo_latency_us);
881 DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp);
882 DTRACE(
883 "INTERMEDIATE pixel_chunk_size_kbytes = %d",
884 mode_lib->ip.pixel_chunk_size_kbytes);
885 DTRACE("INTERMEDIATE total_dcc_active_dpp = %d", total_dcc_active_dpp);
886 DTRACE(
887 "INTERMEDIATE meta_chunk_size_kbyte = %d",
888 mode_lib->ip.meta_chunk_size_kbytes);
889 DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps);
890
891 return urgent_extra_latency_us;
892}
893
894double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib)
895{
896 unsigned int total_active_dpp = DC__NUM_DPP;
897 unsigned int total_dcc_active_dpp = total_active_dpp;
898 double urgent_extra_latency_us = 0.0;
899 double dcfclk_mhz = 0.0;
900 double return_bw_mbps = 0.0;
901 int voltage = dm_vmin;
902
903 /* use minimum voltage */
904 return_bw_mbps = dml_socbb_return_bw_mhz(&mode_lib->soc, (enum voltage_state) voltage);
905 /* use minimum dcfclk */
906 dcfclk_mhz = mode_lib->soc.vmin.dcfclk_mhz;
907 /* use max dpps and dpps with dcc */
908
909 urgent_extra_latency_us = urgent_extra_calc(
910 mode_lib,
911 dcfclk_mhz,
912 return_bw_mbps,
913 total_active_dpp,
914 total_dcc_active_dpp);
915
916 DTRACE("urgent extra max = %f", urgent_extra_latency_us);
917 return urgent_extra_latency_us;
918}
919
920double dml_wm_urgent_extra(
921 struct display_mode_lib *mode_lib,
922 struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
923 unsigned int num_pipes)
924{
925 unsigned int total_active_dpp = 0;
926 unsigned int total_dcc_active_dpp = 0;
927 double urgent_extra_latency_us = 0.0;
928 double dcfclk_mhz = 0.0;
929 double return_bw_mbps = 0.0;
930 int voltage = -1;
931 bool pte_enable = false;
932 unsigned int i;
933
934 for (i = 0; i < num_pipes; i++) {
935 /* num_dpp must be greater than 0 */
936 ASSERT(pipes[i].num_dpp > 0);
937
938 /* voltage mode must be the same for all pipes */
939 ASSERT(voltage == -1 || voltage == pipes[i].voltage);
940 voltage = pipes[i].voltage;
941
942 /* dcfclk for all pipes must be the same */
943 ASSERT(dcfclk_mhz == 0.0 || dcfclk_mhz == pipes[i].dcfclk_mhz);
944 dcfclk_mhz = pipes[i].dcfclk_mhz;
945
946 total_active_dpp += pipes[i].num_dpp;
947
948 if (pipes[i].dcc_enable) {
949 total_dcc_active_dpp += pipes[i].num_dpp;
950 }
951 }
952
953 DTRACE("total active dpps %d", total_active_dpp);
954 DTRACE("total active dpps with dcc %d", total_dcc_active_dpp);
955 DTRACE("voltage state is %d", voltage);
956
957 return_bw_mbps = calc_return_bw(mode_lib, pipes, num_pipes);
958
959 DTRACE("return_bandwidth is %f MBps", return_bw_mbps);
960
961 pte_enable = calc_pte_enable(pipes, num_pipes);
962
963 /* calculate the maximum extra latency just for comparison purposes */
964 /* dml_wm_urgent_extra_max(); */
965 urgent_extra_latency_us = urgent_extra_calc(
966 mode_lib,
967 dcfclk_mhz,
968 return_bw_mbps,
969 total_active_dpp,
970 total_dcc_active_dpp);
971
972 DTRACE("INTERMEDIATE urgent_extra_latency_us_before_pte = %f", urgent_extra_latency_us);
973
974 if (pte_enable) {
975 urgent_extra_latency_us += total_active_dpp * mode_lib->ip.pte_chunk_size_kbytes
976 * 1024.0 / return_bw_mbps;
977
978 DTRACE("INTERMEDIATE pte_enable = true");
979 DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp);
980 DTRACE(
981 "INTERMEDIATE pte_chunk_size_kbytes = %d",
982 mode_lib->ip.pte_chunk_size_kbytes);
983 DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps);
984 }
985
986 return urgent_extra_latency_us;
987}
988
989double dml_wm_urgent_e2e(
990 struct display_mode_lib *mode_lib,
991 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
992 unsigned int num_pipes)
993{
994 struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
995 unsigned int combined_pipes;
996 double urgent_wm;
997
998 memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
999 combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
1000
1001 urgent_wm = dml_wm_urgent(mode_lib, wm, combined_pipes);
1002
1003 return urgent_wm;
1004}
1005
1006double dml_wm_urgent(
1007 struct display_mode_lib *mode_lib,
1008 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
1009 unsigned int num_planes)
1010{
1011 double urgent_watermark;
1012 double urgent_extra_latency_us;
1013 double last_pixel_of_line_extra_wm_us = 0.0;
1014
1015 DTRACE("calculating urgent watermark");
1016 calc_display_pipe_line_delivery_time(mode_lib, planes, num_planes);
1017 urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, planes, num_planes);
1018
1019 last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us(
1020 mode_lib,
1021 planes,
1022 num_planes);
1023
1024 urgent_watermark = mode_lib->soc.urgent_latency_us + last_pixel_of_line_extra_wm_us
1025 + urgent_extra_latency_us;
1026
1027 DTRACE("INTERMEDIATE urgent_latency_us = %f", mode_lib->soc.urgent_latency_us);
1028 DTRACE("INTERMEDIATE last_pixel_of_line_extra_wm_us = %f", last_pixel_of_line_extra_wm_us);
1029 DTRACE("INTERMEDIATE urgent_extra_latency_us = %f", urgent_extra_latency_us);
1030
1031 DTRACE("urgent_watermark_us = %f", urgent_watermark);
1032 return urgent_watermark;
1033}
1034
1035double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us)
1036{
1037 double val;
1038
1039 val = urgent_wm_us + 2.0 * mode_lib->soc.urgent_latency_us;
1040 DTRACE("pte_meta_urgent_watermark_us = %f", val);
1041
1042 return val;
1043}
1044
1045double dml_wm_dcfclk_deepsleep_mhz_e2e(
1046 struct display_mode_lib *mode_lib,
1047 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
1048 unsigned int num_pipes)
1049{
1050 struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
1051 unsigned int num_planes;
1052 double val;
1053
1054 memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
1055 num_planes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, planes);
1056
1057 val = dml_wm_dcfclk_deepsleep_mhz(mode_lib, planes, num_planes);
1058
1059 return val;
1060}
1061
1062double dml_wm_dcfclk_deepsleep_mhz(
1063 struct display_mode_lib *mode_lib,
1064 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
1065 unsigned int num_planes)
1066{
1067 double val = 8.0;
1068 unsigned int i;
1069
1070 for (i = 0; i < num_planes; i++) {
1071 calc_dcfclk_deepsleep_mhz_per_plane(mode_lib, &planes[i]);
1072
1073 if (val < planes[i].dcfclk_deepsleep_mhz_per_plane) {
1074 val = planes[i].dcfclk_deepsleep_mhz_per_plane;
1075 }
1076
1077 DTRACE("plane[%d] start", i);
1078 DTRACE("dcfclk_deepsleep_per_plane = %f", planes[i].dcfclk_deepsleep_mhz_per_plane);
1079 DTRACE("plane[%d] end", i);
1080 }
1081
1082 DTRACE("dcfclk_deepsleep_mhz = %f", val);
1083
1084 return val;
1085}
1086
1087struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
1088 struct display_mode_lib *mode_lib,
1089 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
1090 unsigned int num_pipes)
1091{
1092 struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
1093 unsigned int combined_pipes;
1094 struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm;
1095
1096 memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
1097 combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
1098 cstate_pstate_wm = dml_wm_cstate_pstate(mode_lib, wm, combined_pipes);
1099
1100
1101 return cstate_pstate_wm;
1102}
1103
1104struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
1105 struct display_mode_lib *mode_lib,
1106 struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
1107 unsigned int num_pipes)
1108{
1109 struct _vcs_dpi_cstate_pstate_watermarks_st wm;
1110 double urgent_extra_latency_us;
1111 double urgent_watermark_us;
1112 double last_pixel_of_line_extra_wm_us;
1113 double dcfclk_deepsleep_freq;
1114
1115 DTRACE("calculating cstate and pstate watermarks");
1116 urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, pipes, num_pipes);
1117 urgent_watermark_us = dml_wm_urgent(mode_lib, pipes, num_pipes);
1118
1119 last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us(
1120 mode_lib,
1121 pipes,
1122 num_pipes);
1123 dcfclk_deepsleep_freq = dml_wm_dcfclk_deepsleep_mhz(mode_lib, pipes, num_pipes);
1124
1125 wm.cstate_exit_us = mode_lib->soc.sr_exit_time_us + last_pixel_of_line_extra_wm_us
1126 + urgent_extra_latency_us
1127 + mode_lib->ip.dcfclk_cstate_latency / dcfclk_deepsleep_freq;
1128 wm.cstate_enter_plus_exit_us = mode_lib->soc.sr_enter_plus_exit_time_us
1129 + last_pixel_of_line_extra_wm_us + urgent_extra_latency_us;
1130 wm.pstate_change_us = mode_lib->soc.dram_clock_change_latency_us + urgent_watermark_us;
1131
1132 DTRACE("stutter_exit_watermark_us = %f", wm.cstate_exit_us);
1133 DTRACE("stutter_enter_plus_exit_watermark_us = %f", wm.cstate_enter_plus_exit_us);
1134 DTRACE("dram_clock_change_watermark_us = %f", wm.pstate_change_us);
1135
1136 return wm;
1137}
1138
1139double dml_wm_writeback_pstate_e2e(
1140 struct display_mode_lib *mode_lib,
1141 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
1142 unsigned int num_pipes)
1143{
1144 struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
1145 unsigned int combined_pipes;
1146
1147 memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
1148 combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
1149
1150
1151 return dml_wm_writeback_pstate(mode_lib, wm, combined_pipes);
1152}
1153
1154double dml_wm_writeback_pstate(
1155 struct display_mode_lib *mode_lib,
1156 struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
1157 unsigned int num_pipes)
1158{
1159 unsigned int total_active_wb = 0;
1160 double wm = 0.0;
1161 double socclk_mhz = 0.0;
1162 unsigned int i;
1163
1164 DTRACE("calculating wb pstate watermark");
1165 for (i = 0; i < num_pipes; i++) {
1166 if (pipes[i].output_type == dm_wb)
1167 total_active_wb++;
1168 ASSERT(socclk_mhz == 0.0 || socclk_mhz == pipes[i].socclk_mhz);
1169 socclk_mhz = pipes[i].socclk_mhz;
1170 }
1171
1172 DTRACE("total wb outputs %d", total_active_wb);
1173 DTRACE("socclk frequency %f Mhz", socclk_mhz);
1174
1175 if (total_active_wb <= 1) {
1176 wm = mode_lib->soc.writeback_dram_clock_change_latency_us;
1177 } else {
1178 wm = mode_lib->soc.writeback_dram_clock_change_latency_us
1179 + (mode_lib->ip.writeback_chunk_size_kbytes * 1024.0) / 32.0
1180 / socclk_mhz;
1181 }
1182
1183 DTRACE("wb pstate watermark %f us", wm);
1184 return wm;
1185}
1186
1187unsigned int dml_wm_e2e_to_wm(
1188 struct display_mode_lib *mode_lib,
1189 struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
1190 unsigned int num_pipes,
1191 struct _vcs_dpi_wm_calc_pipe_params_st *wm)
1192{
1193 unsigned int num_planes = 0;
1194 bool visited[DC__NUM_PIPES];
1195 unsigned int i, j;
1196
1197 for (i = 0; i < num_pipes; i++) {
1198 visited[i] = false;
1199 }
1200
1201 for (i = 0; i < num_pipes; i++) {
1202 unsigned int num_dpp = 1;
1203
1204 if (visited[i]) {
1205 continue;
1206 }
1207
1208 visited[i] = true;
1209
1210 if (e2e[i].pipe.src.is_hsplit) {
1211 for (j = i + 1; j < num_pipes; j++) {
1212 if (e2e[j].pipe.src.is_hsplit && !visited[j]
1213 && (e2e[i].pipe.src.hsplit_grp
1214 == e2e[j].pipe.src.hsplit_grp)) {
1215 num_dpp++;
1216 visited[j] = true;
1217 }
1218 }
1219 }
1220
1221 wm[num_planes].num_dpp = num_dpp;
1222 wm[num_planes].voltage = e2e[i].clks_cfg.voltage;
1223 wm[num_planes].output_type = e2e[i].dout.output_type;
1224 wm[num_planes].dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
1225 wm[num_planes].socclk_mhz = e2e[i].clks_cfg.socclk_mhz;
1226 wm[num_planes].dppclk_mhz = e2e[i].clks_cfg.dppclk_mhz;
1227 wm[num_planes].pixclk_mhz = e2e[i].pipe.dest.pixel_rate_mhz;
1228
1229 wm[num_planes].pte_enable = e2e[i].pipe.src.vm;
1230 wm[num_planes].dcc_enable = e2e[i].pipe.src.dcc;
1231 wm[num_planes].dcc_rate = e2e[i].pipe.src.dcc_rate;
1232
1233 get_bytes_per_pixel(
1234 (enum source_format_class) e2e[i].pipe.src.source_format,
1235 &wm[num_planes]);
1236 wm[num_planes].swath_width_y = get_swath_width_y(&e2e[i].pipe.src, num_dpp);
1237 get_swath_height(
1238 mode_lib,
1239 &e2e[i].pipe.src,
1240 &wm[num_planes],
1241 wm[num_planes].swath_width_y);
1242
1243 wm[num_planes].interlace_en = e2e[i].pipe.dest.interlaced;
1244 wm[num_planes].h_ratio = e2e[i].pipe.scale_ratio_depth.hscl_ratio;
1245 wm[num_planes].v_ratio = e2e[i].pipe.scale_ratio_depth.vscl_ratio;
1246 if (wm[num_planes].interlace_en) {
1247 wm[num_planes].v_ratio = 2 * wm[num_planes].v_ratio;
1248 }
1249 wm[num_planes].h_taps = e2e[i].pipe.scale_taps.htaps;
1250 wm[num_planes].h_total = e2e[i].pipe.dest.htotal;
1251 wm[num_planes].v_total = e2e[i].pipe.dest.vtotal;
1252 wm[num_planes].v_active = e2e[i].pipe.dest.vactive;
1253 wm[num_planes].e2e_index = i;
1254 num_planes++;
1255 }
1256
1257 for (i = 0; i < num_planes; i++) {
1258 DTRACE("plane[%d] start", i);
1259 DTRACE("voltage = %d", wm[i].voltage);
1260 DTRACE("v_active = %d", wm[i].v_active);
1261 DTRACE("h_total = %d", wm[i].h_total);
1262 DTRACE("v_total = %d", wm[i].v_total);
1263 DTRACE("pixclk_mhz = %f", wm[i].pixclk_mhz);
1264 DTRACE("dcfclk_mhz = %f", wm[i].dcfclk_mhz);
1265 DTRACE("dppclk_mhz = %f", wm[i].dppclk_mhz);
1266 DTRACE("h_ratio = %f", wm[i].h_ratio);
1267 DTRACE("v_ratio = %f", wm[i].v_ratio);
1268 DTRACE("interlaced = %d", wm[i].interlace_en);
1269 DTRACE("h_taps = %d", wm[i].h_taps);
1270 DTRACE("num_dpp = %d", wm[i].num_dpp);
1271 DTRACE("swath_width_y = %d", wm[i].swath_width_y);
1272 DTRACE("swath_height_y = %d", wm[i].swath_height_y);
1273 DTRACE("swath_height_c = %d", wm[i].swath_height_c);
1274 DTRACE("det_buffer_size_y = %d", wm[i].det_buffer_size_y);
1275 DTRACE("dcc_rate = %f", wm[i].dcc_rate);
1276 DTRACE("dcc_enable = %s", wm[i].dcc_enable ? "true" : "false");
1277 DTRACE("pte_enable = %s", wm[i].pte_enable ? "true" : "false");
1278 DTRACE("plane[%d] end", i);
1279 }
1280
1281 return num_planes;
1282}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h b/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h
deleted file mode 100644
index 94cde8b55e08..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_watermark.h
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25#ifndef __DISPLAY_WATERMARK_H__
26#define __DISPLAY_WATERMARK_H__
27
28#include "dml_common_defs.h"
29
30struct display_mode_lib;
31
32double dml_wm_urgent_extra(
33 struct display_mode_lib *mode_lib,
34 struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
35 unsigned int num_pipes);
36double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib);
37
38double dml_wm_urgent_e2e(
39 struct display_mode_lib *mode_lib,
40 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
41 unsigned int num_pipes);
42double dml_wm_urgent(
43 struct display_mode_lib *mode_lib,
44 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
45 unsigned int num_planes);
46double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us);
47double dml_wm_dcfclk_deepsleep_mhz_e2e(
48 struct display_mode_lib *mode_lib,
49 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
50 unsigned int num_pipes);
51double dml_wm_dcfclk_deepsleep_mhz(
52 struct display_mode_lib *mode_lib,
53 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
54 unsigned int num_planes);
55
56struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
57 struct display_mode_lib *mode_lib,
58 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
59 unsigned int num_pipes);
60struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
61 struct display_mode_lib *mode_lib,
62 struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
63 unsigned int num_pipes);
64
65double dml_wm_writeback_pstate_e2e(
66 struct display_mode_lib *mode_lib,
67 struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
68 unsigned int num_pipes);
69double dml_wm_writeback_pstate(
70 struct display_mode_lib *mode_lib,
71 struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
72 unsigned int num_pipes);
73
74double dml_wm_expected_stutter_eff_e2e(
75 struct display_mode_lib *mode_lib,
76 struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
77 unsigned int num_pipes);
78double dml_wm_expected_stutter_eff_e2e_with_vblank(
79 struct display_mode_lib *mode_lib,
80 struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
81 unsigned int num_pipes);
82
83unsigned int dml_wm_e2e_to_wm(
84 struct display_mode_lib *mode_lib,
85 struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
86 unsigned int num_pipes,
87 struct _vcs_dpi_wm_calc_pipe_params_st *wm);
88
89double dml_wm_calc_total_data_read_bw(
90 struct display_mode_lib *mode_lib,
91 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
92 unsigned int num_planes);
93double dml_wm_calc_return_bw(
94 struct display_mode_lib *mode_lib,
95 struct _vcs_dpi_wm_calc_pipe_params_st *planes,
96 unsigned int num_planes);
97
98#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
new file mode 100644
index 000000000000..1e4b1e383401
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
@@ -0,0 +1,1905 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "dml1_display_rq_dlg_calc.h"
27#include "display_mode_lib.h"
28
29#include "dml_inline_defs.h"
30
31static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
32{
33 unsigned int ret_val = 0;
34
35 if (source_format == dm_444_16) {
36 if (!is_chroma)
37 ret_val = 2;
38 } else if (source_format == dm_444_32) {
39 if (!is_chroma)
40 ret_val = 4;
41 } else if (source_format == dm_444_64) {
42 if (!is_chroma)
43 ret_val = 8;
44 } else if (source_format == dm_420_8) {
45 if (is_chroma)
46 ret_val = 2;
47 else
48 ret_val = 1;
49 } else if (source_format == dm_420_10) {
50 if (is_chroma)
51 ret_val = 4;
52 else
53 ret_val = 2;
54 }
55 return ret_val;
56}
57
58static bool is_dual_plane(enum source_format_class source_format)
59{
60 bool ret_val = 0;
61
62 if ((source_format == dm_420_8) || (source_format == dm_420_10))
63 ret_val = 1;
64
65 return ret_val;
66}
67
68static void get_blk256_size(
69 unsigned int *blk256_width,
70 unsigned int *blk256_height,
71 unsigned int bytes_per_element)
72{
73 if (bytes_per_element == 1) {
74 *blk256_width = 16;
75 *blk256_height = 16;
76 } else if (bytes_per_element == 2) {
77 *blk256_width = 16;
78 *blk256_height = 8;
79 } else if (bytes_per_element == 4) {
80 *blk256_width = 8;
81 *blk256_height = 8;
82 } else if (bytes_per_element == 8) {
83 *blk256_width = 8;
84 *blk256_height = 4;
85 }
86}
87
88static double get_refcyc_per_delivery(
89 struct display_mode_lib *mode_lib,
90 double refclk_freq_in_mhz,
91 double pclk_freq_in_mhz,
92 unsigned int recout_width,
93 double vratio,
94 double hscale_pixel_rate,
95 unsigned int delivery_width,
96 unsigned int req_per_swath_ub)
97{
98 double refcyc_per_delivery = 0.0;
99
100 if (vratio <= 1.0) {
101 refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
102 / pclk_freq_in_mhz / (double) req_per_swath_ub;
103 } else {
104 refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
105 / (double) hscale_pixel_rate / (double) req_per_swath_ub;
106 }
107
108 DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
109 DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
110 DTRACE("DLG: %s: recout_width = %d", __func__, recout_width);
111 DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio);
112 DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub);
113 DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery);
114
115 return refcyc_per_delivery;
116
117}
118
119static double get_vratio_pre(
120 struct display_mode_lib *mode_lib,
121 unsigned int max_num_sw,
122 unsigned int max_partial_sw,
123 unsigned int swath_height,
124 double vinit,
125 double l_sw)
126{
127 double prefill = dml_floor(vinit, 1);
128 double vratio_pre = 1.0;
129
130 vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw;
131
132 if (swath_height > 4) {
133 double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0);
134
135 if (tmp0 > vratio_pre)
136 vratio_pre = tmp0;
137 }
138
139 DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw);
140 DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw);
141 DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
142 DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
143 DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre);
144
145 if (vratio_pre < 1.0) {
146 DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre);
147 vratio_pre = 1.0;
148 }
149
150 if (vratio_pre > 4.0) {
151 DTRACE(
152 "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0",
153 __func__,
154 vratio_pre);
155 vratio_pre = 4.0;
156 }
157
158 return vratio_pre;
159}
160
161static void get_swath_need(
162 struct display_mode_lib *mode_lib,
163 unsigned int *max_num_sw,
164 unsigned int *max_partial_sw,
165 unsigned int swath_height,
166 double vinit)
167{
168 double prefill = dml_floor(vinit, 1);
169 unsigned int max_partial_sw_int;
170
171 DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
172 DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
173
174 ASSERT(prefill > 0.0 && prefill <= 8.0);
175
176 *max_num_sw = (unsigned int) (dml_ceil((prefill - 1.0) / (double) swath_height, 1) + 1.0); /* prefill has to be >= 1 */
177 max_partial_sw_int =
178 (prefill == 1) ?
179 (swath_height - 1) :
180 ((unsigned int) (prefill - 2.0) % swath_height);
181 *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */
182
183 DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw);
184 DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw);
185}
186
187static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
188{
189 if (tile_size == dm_256k_tile)
190 return (256 * 1024);
191 else if (tile_size == dm_64k_tile)
192 return (64 * 1024);
193 else
194 return (4 * 1024);
195}
196
197static void extract_rq_sizing_regs(
198 struct display_mode_lib *mode_lib,
199 struct _vcs_dpi_display_data_rq_regs_st *rq_regs,
200 const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
201{
202 DTRACE("DLG: %s: rq_sizing param", __func__);
203 print__data_rq_sizing_params_st(mode_lib, rq_sizing);
204
205 rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
206
207 if (rq_sizing.min_chunk_bytes == 0)
208 rq_regs->min_chunk_size = 0;
209 else
210 rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1;
211
212 rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10;
213 if (rq_sizing.min_meta_chunk_bytes == 0)
214 rq_regs->min_meta_chunk_size = 0;
215 else
216 rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1;
217
218 rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6;
219 rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
220}
221
222void dml1_extract_rq_regs(
223 struct display_mode_lib *mode_lib,
224 struct _vcs_dpi_display_rq_regs_st *rq_regs,
225 const struct _vcs_dpi_display_rq_params_st rq_param)
226{
227 unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
228 unsigned int detile_buf_plane1_addr = 0;
229
230 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
231 if (rq_param.yuv420)
232 extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
233
234 rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
235 rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
236
237 /* FIXME: take the max between luma, chroma chunk size?
238 * okay for now, as we are setting chunk_bytes to 8kb anyways
239 */
240 if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */
241 rq_regs->drq_expansion_mode = 0;
242 } else {
243 rq_regs->drq_expansion_mode = 2;
244 }
245 rq_regs->prq_expansion_mode = 1;
246 rq_regs->mrq_expansion_mode = 1;
247 rq_regs->crq_expansion_mode = 1;
248
249 if (rq_param.yuv420) {
250 if ((double) rq_param.misc.rq_l.stored_swath_bytes
251 / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
252 detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */
253 } else {
254 detile_buf_plane1_addr = dml_round_to_multiple(
255 (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
256 256,
257 0) / 64.0; /* 2/3 to chroma */
258 }
259 }
260 rq_regs->plane1_base_address = detile_buf_plane1_addr;
261}
262
263static void handle_det_buf_split(
264 struct display_mode_lib *mode_lib,
265 struct _vcs_dpi_display_rq_params_st *rq_param,
266 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
267{
268 unsigned int total_swath_bytes = 0;
269 unsigned int swath_bytes_l = 0;
270 unsigned int swath_bytes_c = 0;
271 unsigned int full_swath_bytes_packed_l = 0;
272 unsigned int full_swath_bytes_packed_c = 0;
273 bool req128_l = 0;
274 bool req128_c = 0;
275 bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
276 bool surf_vert = (pipe_src_param.source_scan == dm_vert);
277 unsigned int log2_swath_height_l = 0;
278 unsigned int log2_swath_height_c = 0;
279 unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
280
281 full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes;
282 full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
283
284 if (rq_param->yuv420_10bpc) {
285 full_swath_bytes_packed_l = dml_round_to_multiple(
286 rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
287 256,
288 1) + 256;
289 full_swath_bytes_packed_c = dml_round_to_multiple(
290 rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
291 256,
292 1) + 256;
293 }
294
295 if (rq_param->yuv420) {
296 total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
297
298 if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */
299 req128_l = 0;
300 req128_c = 0;
301 swath_bytes_l = full_swath_bytes_packed_l;
302 swath_bytes_c = full_swath_bytes_packed_c;
303 } else { /*128b request (for luma only for yuv420 8bpc) */
304 req128_l = 1;
305 req128_c = 0;
306 swath_bytes_l = full_swath_bytes_packed_l / 2;
307 swath_bytes_c = full_swath_bytes_packed_c;
308 }
309
310 /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137)
311 * TODO: Remove after rtl fix
312 */
313 if (req128_l == 1) {
314 req128_c = 1;
315 DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__);
316 }
317
318 /* Note: assumption, the config that pass in will fit into
319 * the detiled buffer.
320 */
321 } else {
322 total_swath_bytes = 2 * full_swath_bytes_packed_l;
323
324 if (total_swath_bytes <= detile_buf_size_in_bytes)
325 req128_l = 0;
326 else
327 req128_l = 1;
328
329 swath_bytes_l = total_swath_bytes;
330 swath_bytes_c = 0;
331 }
332 rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l;
333 rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c;
334
335 if (surf_linear) {
336 log2_swath_height_l = 0;
337 log2_swath_height_c = 0;
338 } else if (!surf_vert) {
339 log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
340 log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
341 } else {
342 log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
343 log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
344 }
345 rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
346 rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
347
348 DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l);
349 DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c);
350 DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l);
351 DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c);
352}
353
354/* Need refactor. */
355static void dml1_rq_dlg_get_row_heights(
356 struct display_mode_lib *mode_lib,
357 unsigned int *o_dpte_row_height,
358 unsigned int *o_meta_row_height,
359 unsigned int vp_width,
360 unsigned int data_pitch,
361 int source_format,
362 int tiling,
363 int macro_tile_size,
364 int source_scan,
365 int is_chroma)
366{
367 bool surf_linear = (tiling == dm_sw_linear);
368 bool surf_vert = (source_scan == dm_vert);
369
370 unsigned int bytes_per_element = get_bytes_per_element(
371 (enum source_format_class) source_format,
372 is_chroma);
373 unsigned int log2_bytes_per_element = dml_log2(bytes_per_element);
374 unsigned int blk256_width = 0;
375 unsigned int blk256_height = 0;
376
377 unsigned int log2_blk256_height;
378 unsigned int blk_bytes;
379 unsigned int log2_blk_bytes;
380 unsigned int log2_blk_height;
381 unsigned int log2_blk_width;
382 unsigned int log2_meta_req_bytes;
383 unsigned int log2_meta_req_height;
384 unsigned int log2_meta_req_width;
385 unsigned int log2_meta_row_height;
386 unsigned int log2_vmpg_bytes;
387 unsigned int dpte_buf_in_pte_reqs;
388 unsigned int log2_vmpg_height;
389 unsigned int log2_vmpg_width;
390 unsigned int log2_dpte_req_height_ptes;
391 unsigned int log2_dpte_req_width_ptes;
392 unsigned int log2_dpte_req_height;
393 unsigned int log2_dpte_req_width;
394 unsigned int log2_dpte_row_height_linear;
395 unsigned int log2_dpte_row_height;
396 unsigned int dpte_req_width;
397
398 if (surf_linear) {
399 blk256_width = 256;
400 blk256_height = 1;
401 } else {
402 get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
403 }
404
405 log2_blk256_height = dml_log2((double) blk256_height);
406 blk_bytes = surf_linear ?
407 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
408 log2_blk_bytes = dml_log2((double) blk_bytes);
409 log2_blk_height = 0;
410 log2_blk_width = 0;
411
412 /* remember log rule
413 * "+" in log is multiply
414 * "-" in log is divide
415 * "/2" is like square root
416 * blk is vertical biased
417 */
418 if (tiling != dm_sw_linear)
419 log2_blk_height = log2_blk256_height
420 + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
421 else
422 log2_blk_height = 0; /* blk height of 1 */
423
424 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
425
426 /* ------- */
427 /* meta */
428 /* ------- */
429 log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
430
431 /* each 64b meta request for dcn is 8x8 meta elements and
432 * a meta element covers one 256b block of the the data surface.
433 */
434 log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */
435 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
436 - log2_meta_req_height;
437 log2_meta_row_height = 0;
438
439 /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
440 * calculate upper bound of the meta_row_width
441 */
442 if (!surf_vert)
443 log2_meta_row_height = log2_meta_req_height;
444 else
445 log2_meta_row_height = log2_meta_req_width;
446
447 *o_meta_row_height = 1 << log2_meta_row_height;
448
449 /* ------ */
450 /* dpte */
451 /* ------ */
452 log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
453 dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
454
455 log2_vmpg_height = 0;
456 log2_vmpg_width = 0;
457 log2_dpte_req_height_ptes = 0;
458 log2_dpte_req_width_ptes = 0;
459 log2_dpte_req_height = 0;
460 log2_dpte_req_width = 0;
461 log2_dpte_row_height_linear = 0;
462 log2_dpte_row_height = 0;
463 dpte_req_width = 0; /* 64b dpte req width in data element */
464
465 if (surf_linear)
466 log2_vmpg_height = 0; /* one line high */
467 else
468 log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
469 log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
470
471 /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
472 if (log2_blk_bytes <= log2_vmpg_bytes)
473 log2_dpte_req_height_ptes = 0;
474 else if (log2_blk_height - log2_vmpg_height >= 2)
475 log2_dpte_req_height_ptes = 2;
476 else
477 log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
478 log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
479
480 ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
481 (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
482 (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
483
484 /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height
485 * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent
486 */
487 log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
488 log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
489 dpte_req_width = 1 << log2_dpte_req_width;
490
491 /* calculate pitch dpte row buffer can hold
492 * round the result down to a power of two.
493 */
494 if (surf_linear) {
495 log2_dpte_row_height_linear = dml_floor(
496 dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch),
497 1);
498
499 ASSERT(log2_dpte_row_height_linear >= 3);
500
501 if (log2_dpte_row_height_linear > 7)
502 log2_dpte_row_height_linear = 7;
503
504 log2_dpte_row_height = log2_dpte_row_height_linear;
505 } else {
506 /* the upper bound of the dpte_row_width without dependency on viewport position follows. */
507 if (!surf_vert)
508 log2_dpte_row_height = log2_dpte_req_height;
509 else
510 log2_dpte_row_height =
511 (log2_blk_width < log2_dpte_req_width) ?
512 log2_blk_width : log2_dpte_req_width;
513 }
514
515 /* From programming guide:
516 * There is a special case of saving only half of ptes returned due to buffer space limits.
517 * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
518 * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
519 */
520 if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
521 && log2_blk_bytes >= 16)
522 log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
523
524 *o_dpte_row_height = 1 << log2_dpte_row_height;
525}
526
527static void get_surf_rq_param(
528 struct display_mode_lib *mode_lib,
529 struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param,
530 struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param,
531 struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param,
532 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param,
533 bool is_chroma)
534{
535 bool mode_422 = 0;
536 unsigned int vp_width = 0;
537 unsigned int vp_height = 0;
538 unsigned int data_pitch = 0;
539 unsigned int meta_pitch = 0;
540 unsigned int ppe = mode_422 ? 2 : 1;
541 bool surf_linear;
542 bool surf_vert;
543 unsigned int bytes_per_element;
544 unsigned int log2_bytes_per_element;
545 unsigned int blk256_width;
546 unsigned int blk256_height;
547 unsigned int log2_blk256_width;
548 unsigned int log2_blk256_height;
549 unsigned int blk_bytes;
550 unsigned int log2_blk_bytes;
551 unsigned int log2_blk_height;
552 unsigned int log2_blk_width;
553 unsigned int log2_meta_req_bytes;
554 unsigned int log2_meta_req_height;
555 unsigned int log2_meta_req_width;
556 unsigned int meta_req_width;
557 unsigned int meta_req_height;
558 unsigned int log2_meta_row_height;
559 unsigned int meta_row_width_ub;
560 unsigned int log2_meta_chunk_bytes;
561 unsigned int log2_meta_chunk_height;
562 unsigned int log2_meta_chunk_width;
563 unsigned int log2_min_meta_chunk_bytes;
564 unsigned int min_meta_chunk_width;
565 unsigned int meta_chunk_width;
566 unsigned int meta_chunk_per_row_int;
567 unsigned int meta_row_remainder;
568 unsigned int meta_chunk_threshold;
569 unsigned int meta_blk_bytes;
570 unsigned int meta_blk_height;
571 unsigned int meta_blk_width;
572 unsigned int meta_surface_bytes;
573 unsigned int vmpg_bytes;
574 unsigned int meta_pte_req_per_frame_ub;
575 unsigned int meta_pte_bytes_per_frame_ub;
576 unsigned int log2_vmpg_bytes;
577 unsigned int dpte_buf_in_pte_reqs;
578 unsigned int log2_vmpg_height;
579 unsigned int log2_vmpg_width;
580 unsigned int log2_dpte_req_height_ptes;
581 unsigned int log2_dpte_req_width_ptes;
582 unsigned int log2_dpte_req_height;
583 unsigned int log2_dpte_req_width;
584 unsigned int log2_dpte_row_height_linear;
585 unsigned int log2_dpte_row_height;
586 unsigned int log2_dpte_group_width;
587 unsigned int dpte_row_width_ub;
588 unsigned int dpte_row_height;
589 unsigned int dpte_req_height;
590 unsigned int dpte_req_width;
591 unsigned int dpte_group_width;
592 unsigned int log2_dpte_group_bytes;
593 unsigned int log2_dpte_group_length;
594 unsigned int func_meta_row_height, func_dpte_row_height;
595
596 /* FIXME check if ppe apply for both luma and chroma in 422 case */
597 if (is_chroma) {
598 vp_width = pipe_src_param.viewport_width_c / ppe;
599 vp_height = pipe_src_param.viewport_height_c;
600 data_pitch = pipe_src_param.data_pitch_c;
601 meta_pitch = pipe_src_param.meta_pitch_c;
602 } else {
603 vp_width = pipe_src_param.viewport_width / ppe;
604 vp_height = pipe_src_param.viewport_height;
605 data_pitch = pipe_src_param.data_pitch;
606 meta_pitch = pipe_src_param.meta_pitch;
607 }
608
609 rq_sizing_param->chunk_bytes = 8192;
610
611 if (rq_sizing_param->chunk_bytes == 64 * 1024)
612 rq_sizing_param->min_chunk_bytes = 0;
613 else
614 rq_sizing_param->min_chunk_bytes = 1024;
615
616 rq_sizing_param->meta_chunk_bytes = 2048;
617 rq_sizing_param->min_meta_chunk_bytes = 256;
618
619 rq_sizing_param->mpte_group_bytes = 2048;
620
621 surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
622 surf_vert = (pipe_src_param.source_scan == dm_vert);
623
624 bytes_per_element = get_bytes_per_element(
625 (enum source_format_class) pipe_src_param.source_format,
626 is_chroma);
627 log2_bytes_per_element = dml_log2(bytes_per_element);
628 blk256_width = 0;
629 blk256_height = 0;
630
631 if (surf_linear) {
632 blk256_width = 256 / bytes_per_element;
633 blk256_height = 1;
634 } else {
635 get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
636 }
637
638 DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear);
639 DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert);
640 DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width);
641 DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height);
642
643 log2_blk256_width = dml_log2((double) blk256_width);
644 log2_blk256_height = dml_log2((double) blk256_height);
645 blk_bytes =
646 surf_linear ? 256 : get_blk_size_bytes(
647 (enum source_macro_tile_size) pipe_src_param.macro_tile_size);
648 log2_blk_bytes = dml_log2((double) blk_bytes);
649 log2_blk_height = 0;
650 log2_blk_width = 0;
651
652 /* remember log rule
653 * "+" in log is multiply
654 * "-" in log is divide
655 * "/2" is like square root
656 * blk is vertical biased
657 */
658 if (pipe_src_param.sw_mode != dm_sw_linear)
659 log2_blk_height = log2_blk256_height
660 + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
661 else
662 log2_blk_height = 0; /* blk height of 1 */
663
664 log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
665
666 if (!surf_vert) {
667 rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1)
668 + blk256_width;
669 rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
670 } else {
671 rq_dlg_param->swath_width_ub = dml_round_to_multiple(
672 vp_height - 1,
673 blk256_height,
674 1) + blk256_height;
675 rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
676 }
677
678 if (!surf_vert)
679 rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height
680 * bytes_per_element;
681 else
682 rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width
683 * bytes_per_element;
684
685 rq_misc_param->blk256_height = blk256_height;
686 rq_misc_param->blk256_width = blk256_width;
687
688 /* ------- */
689 /* meta */
690 /* ------- */
691 log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
692
693 /* each 64b meta request for dcn is 8x8 meta elements and
694 * a meta element covers one 256b block of the the data surface.
695 */
696 log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
697 log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
698 - log2_meta_req_height;
699 meta_req_width = 1 << log2_meta_req_width;
700 meta_req_height = 1 << log2_meta_req_height;
701 log2_meta_row_height = 0;
702 meta_row_width_ub = 0;
703
704 /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
705 * calculate upper bound of the meta_row_width
706 */
707 if (!surf_vert) {
708 log2_meta_row_height = log2_meta_req_height;
709 meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1)
710 + meta_req_width;
711 rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width;
712 } else {
713 log2_meta_row_height = log2_meta_req_width;
714 meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1)
715 + meta_req_height;
716 rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height;
717 }
718 rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
719
720 log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
721 log2_meta_chunk_height = log2_meta_row_height;
722
723 /*full sized meta chunk width in unit of data elements */
724 log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element
725 - log2_meta_chunk_height;
726 log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
727 min_meta_chunk_width = 1
728 << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element
729 - log2_meta_chunk_height);
730 meta_chunk_width = 1 << log2_meta_chunk_width;
731 meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width);
732 meta_row_remainder = meta_row_width_ub % meta_chunk_width;
733 meta_chunk_threshold = 0;
734 meta_blk_bytes = 4096;
735 meta_blk_height = blk256_height * 64;
736 meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height;
737 meta_surface_bytes = meta_pitch
738 * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1)
739 + meta_blk_height) * bytes_per_element / 256;
740 vmpg_bytes = mode_lib->soc.vmm_page_size_bytes;
741 meta_pte_req_per_frame_ub = (dml_round_to_multiple(
742 meta_surface_bytes - vmpg_bytes,
743 8 * vmpg_bytes,
744 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
745 meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */
746 rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
747
748 DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height);
749 DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width);
750 DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes);
751 DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub);
752 DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub);
753
754 if (!surf_vert)
755 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
756 else
757 meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height;
758
759 if (meta_row_remainder <= meta_chunk_threshold)
760 rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
761 else
762 rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
763
764 rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
765
766 /* ------ */
767 /* dpte */
768 /* ------ */
769 log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
770 dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
771
772 log2_vmpg_height = 0;
773 log2_vmpg_width = 0;
774 log2_dpte_req_height_ptes = 0;
775 log2_dpte_req_width_ptes = 0;
776 log2_dpte_req_height = 0;
777 log2_dpte_req_width = 0;
778 log2_dpte_row_height_linear = 0;
779 log2_dpte_row_height = 0;
780 log2_dpte_group_width = 0;
781 dpte_row_width_ub = 0;
782 dpte_row_height = 0;
783 dpte_req_height = 0; /* 64b dpte req height in data element */
784 dpte_req_width = 0; /* 64b dpte req width in data element */
785 dpte_group_width = 0;
786 log2_dpte_group_bytes = 0;
787 log2_dpte_group_length = 0;
788
789 if (surf_linear)
790 log2_vmpg_height = 0; /* one line high */
791 else
792 log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
793 log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
794
795 /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
796 if (log2_blk_bytes <= log2_vmpg_bytes)
797 log2_dpte_req_height_ptes = 0;
798 else if (log2_blk_height - log2_vmpg_height >= 2)
799 log2_dpte_req_height_ptes = 2;
800 else
801 log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
802 log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
803
804 /* Ensure we only have the 3 shapes */
805 ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
806 (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
807 (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
808
809 /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
810 * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
811 * That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
812 */
813 log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
814 log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
815 dpte_req_height = 1 << log2_dpte_req_height;
816 dpte_req_width = 1 << log2_dpte_req_width;
817
818 /* calculate pitch dpte row buffer can hold
819 * round the result down to a power of two.
820 */
821 if (surf_linear) {
822 log2_dpte_row_height_linear = dml_floor(
823 dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch),
824 1);
825
826 ASSERT(log2_dpte_row_height_linear >= 3);
827
828 if (log2_dpte_row_height_linear > 7)
829 log2_dpte_row_height_linear = 7;
830
831 log2_dpte_row_height = log2_dpte_row_height_linear;
832 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
833
834 /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
835 * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
836 */
837 dpte_row_width_ub = dml_round_to_multiple(
838 data_pitch * dpte_row_height - 1,
839 dpte_req_width,
840 1) + dpte_req_width;
841 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
842 } else {
843 /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */
844 if (!surf_vert) {
845 log2_dpte_row_height = log2_dpte_req_height;
846 dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1)
847 + dpte_req_width;
848 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
849 } else {
850 log2_dpte_row_height =
851 (log2_blk_width < log2_dpte_req_width) ?
852 log2_blk_width : log2_dpte_req_width;
853 dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1)
854 + dpte_req_height;
855 rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
856 }
857 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
858 }
859 rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64;
860
861 /* From programming guide:
862 * There is a special case of saving only half of ptes returned due to buffer space limits.
863 * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
864 * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
865 */
866 if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
867 && log2_blk_bytes >= 16) {
868 log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
869 rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
870 }
871
872 /* the dpte_group_bytes is reduced for the specific case of vertical
873 * access of a tile surface that has dpte request of 8x1 ptes.
874 */
875 if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */
876 rq_sizing_param->dpte_group_bytes = 512;
877 else
878 /*full size */
879 rq_sizing_param->dpte_group_bytes = 2048;
880
881 /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */
882 log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
883 log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */
884
885 /* full sized data pte group width in elements */
886 if (!surf_vert)
887 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
888 else
889 log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
890
891 dpte_group_width = 1 << log2_dpte_group_width;
892
893 /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
894 * the upper bound for the dpte groups per row is as follows.
895 */
896 rq_dlg_param->dpte_groups_per_row_ub = dml_ceil(
897 (double) dpte_row_width_ub / dpte_group_width,
898 1);
899
900 dml1_rq_dlg_get_row_heights(
901 mode_lib,
902 &func_dpte_row_height,
903 &func_meta_row_height,
904 vp_width,
905 data_pitch,
906 pipe_src_param.source_format,
907 pipe_src_param.sw_mode,
908 pipe_src_param.macro_tile_size,
909 pipe_src_param.source_scan,
910 is_chroma);
911
912 /* Just a check to make sure this function and the new one give the same
913 * result. The standalone get_row_heights() function is based off of the
914 * code in this function so the same changes need to be made to both.
915 */
916 if (rq_dlg_param->meta_row_height != func_meta_row_height) {
917 DTRACE(
918 "MISMATCH: rq_dlg_param->meta_row_height = %d",
919 rq_dlg_param->meta_row_height);
920 DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height);
921 ASSERT(0);
922 }
923
924 if (rq_dlg_param->dpte_row_height != func_dpte_row_height) {
925 DTRACE(
926 "MISMATCH: rq_dlg_param->dpte_row_height = %d",
927 rq_dlg_param->dpte_row_height);
928 DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height);
929 ASSERT(0);
930 }
931}
932
933void dml1_rq_dlg_get_rq_params(
934 struct display_mode_lib *mode_lib,
935 struct _vcs_dpi_display_rq_params_st *rq_param,
936 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
937{
938 /* get param for luma surface */
939 rq_param->yuv420 = pipe_src_param.source_format == dm_420_8
940 || pipe_src_param.source_format == dm_420_10;
941 rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10;
942
943 get_surf_rq_param(
944 mode_lib,
945 &(rq_param->sizing.rq_l),
946 &(rq_param->dlg.rq_l),
947 &(rq_param->misc.rq_l),
948 pipe_src_param,
949 0);
950
951 if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) {
952 /* get param for chroma surface */
953 get_surf_rq_param(
954 mode_lib,
955 &(rq_param->sizing.rq_c),
956 &(rq_param->dlg.rq_c),
957 &(rq_param->misc.rq_c),
958 pipe_src_param,
959 1);
960 }
961
962 /* calculate how to split the det buffer space between luma and chroma */
963 handle_det_buf_split(mode_lib, rq_param, pipe_src_param);
964 print__rq_params_st(mode_lib, *rq_param);
965}
966
967/* Note: currently taken in as is.
968 * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
969 */
970void dml1_rq_dlg_get_dlg_params(
971 struct display_mode_lib *mode_lib,
972 struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs,
973 struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs,
974 const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
975 const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
976 const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
977 const bool cstate_en,
978 const bool pstate_en,
979 const bool vm_en,
980 const bool iflip_en)
981{
982 /* Timing */
983 unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
984 unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end;
985 unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start;
986 unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end;
987 bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
988 unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
989
990 double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
991 double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz;
992 double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
993 double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
994
995 double ref_freq_to_pix_freq;
996 double prefetch_xy_calc_in_dcfclk;
997 double min_dcfclk_mhz;
998 double t_calc_us;
999 double min_ttu_vblank;
1000 double min_dst_y_ttu_vblank;
1001 unsigned int dlg_vblank_start;
1002 bool dcc_en;
1003 bool dual_plane;
1004 bool mode_422;
1005 unsigned int access_dir;
1006 unsigned int bytes_per_element_l;
1007 unsigned int bytes_per_element_c;
1008 unsigned int vp_height_l;
1009 unsigned int vp_width_l;
1010 unsigned int vp_height_c;
1011 unsigned int vp_width_c;
1012 unsigned int htaps_l;
1013 unsigned int htaps_c;
1014 double hratios_l;
1015 double hratios_c;
1016 double vratio_l;
1017 double vratio_c;
1018 double line_time_in_us;
1019 double vinit_l;
1020 double vinit_c;
1021 double vinit_bot_l;
1022 double vinit_bot_c;
1023 unsigned int swath_height_l;
1024 unsigned int swath_width_ub_l;
1025 unsigned int dpte_bytes_per_row_ub_l;
1026 unsigned int dpte_groups_per_row_ub_l;
1027 unsigned int meta_pte_bytes_per_frame_ub_l;
1028 unsigned int meta_bytes_per_row_ub_l;
1029 unsigned int swath_height_c;
1030 unsigned int swath_width_ub_c;
1031 unsigned int dpte_bytes_per_row_ub_c;
1032 unsigned int dpte_groups_per_row_ub_c;
1033 unsigned int meta_chunks_per_row_ub_l;
1034 unsigned int vupdate_offset;
1035 unsigned int vupdate_width;
1036 unsigned int vready_offset;
1037 unsigned int dppclk_delay_subtotal;
1038 unsigned int dispclk_delay_subtotal;
1039 unsigned int pixel_rate_delay_subtotal;
1040 unsigned int vstartup_start;
1041 unsigned int dst_x_after_scaler;
1042 unsigned int dst_y_after_scaler;
1043 double line_wait;
1044 double line_o;
1045 double line_setup;
1046 double line_calc;
1047 double dst_y_prefetch;
1048 double t_pre_us;
1049 unsigned int vm_bytes;
1050 unsigned int meta_row_bytes;
1051 unsigned int max_num_sw_l;
1052 unsigned int max_num_sw_c;
1053 unsigned int max_partial_sw_l;
1054 unsigned int max_partial_sw_c;
1055 double max_vinit_l;
1056 double max_vinit_c;
1057 unsigned int lsw_l;
1058 unsigned int lsw_c;
1059 unsigned int sw_bytes_ub_l;
1060 unsigned int sw_bytes_ub_c;
1061 unsigned int sw_bytes;
1062 unsigned int dpte_row_bytes;
1063 double prefetch_bw;
1064 double flip_bw;
1065 double t_vm_us;
1066 double t_r0_us;
1067 double dst_y_per_vm_vblank;
1068 double dst_y_per_row_vblank;
1069 double min_dst_y_per_vm_vblank;
1070 double min_dst_y_per_row_vblank;
1071 double lsw;
1072 double vratio_pre_l;
1073 double vratio_pre_c;
1074 unsigned int req_per_swath_ub_l;
1075 unsigned int req_per_swath_ub_c;
1076 unsigned int meta_row_height_l;
1077 unsigned int swath_width_pixels_ub_l;
1078 unsigned int swath_width_pixels_ub_c;
1079 unsigned int scaler_rec_in_width_l;
1080 unsigned int scaler_rec_in_width_c;
1081 unsigned int dpte_row_height_l;
1082 unsigned int dpte_row_height_c;
1083 double hscale_pixel_rate_l;
1084 double hscale_pixel_rate_c;
1085 double min_hratio_fact_l;
1086 double min_hratio_fact_c;
1087 double refcyc_per_line_delivery_pre_l;
1088 double refcyc_per_line_delivery_pre_c;
1089 double refcyc_per_line_delivery_l;
1090 double refcyc_per_line_delivery_c;
1091 double refcyc_per_req_delivery_pre_l;
1092 double refcyc_per_req_delivery_pre_c;
1093 double refcyc_per_req_delivery_l;
1094 double refcyc_per_req_delivery_c;
1095 double refcyc_per_req_delivery_pre_cur0;
1096 double refcyc_per_req_delivery_cur0;
1097 unsigned int full_recout_width;
1098 double hratios_cur0;
1099 unsigned int cur0_src_width;
1100 enum cursor_bpp cur0_bpp;
1101 unsigned int cur0_req_size;
1102 unsigned int cur0_req_width;
1103 double cur0_width_ub;
1104 double cur0_req_per_width;
1105 double hactive_cur0;
1106
1107 memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
1108 memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
1109
1110 DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en);
1111 DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en);
1112 DTRACE("DLG: %s: vm_en = %d", __func__, vm_en);
1113 DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en);
1114
1115 /* ------------------------- */
1116 /* Section 1.5.2.1: OTG dependent Params */
1117 /* ------------------------- */
1118 DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz);
1119 DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz);
1120 DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
1121 DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
1122 DTRACE("DLG: %s: interlaced = %d", __func__, interlaced);
1123
1124 ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
1125 ASSERT(ref_freq_to_pix_freq < 4.0);
1126 disp_dlg_regs->ref_freq_to_pix_freq =
1127 (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
1128 disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal
1129 * dml_pow(2, 8));
1130 disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end
1131 * (double) ref_freq_to_pix_freq);
1132 ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13));
1133 disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */
1134
1135 prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
1136 min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
1137 t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
1138 min_ttu_vblank = dlg_sys_param.t_urg_wm_us;
1139 if (cstate_en)
1140 min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank);
1141 if (pstate_en)
1142 min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank);
1143 min_ttu_vblank = min_ttu_vblank + t_calc_us;
1144
1145 min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal;
1146 dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
1147
1148 disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start
1149 + min_dst_y_ttu_vblank) * dml_pow(2, 2));
1150 ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18));
1151
1152 DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz);
1153 DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank);
1154 DTRACE(
1155 "DLG: %s: min_dst_y_ttu_vblank = %3.2f",
1156 __func__,
1157 min_dst_y_ttu_vblank);
1158 DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us);
1159 DTRACE(
1160 "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x",
1161 __func__,
1162 disp_dlg_regs->min_dst_y_next_start);
1163 DTRACE(
1164 "DLG: %s: ref_freq_to_pix_freq = %3.2f",
1165 __func__,
1166 ref_freq_to_pix_freq);
1167
1168 /* ------------------------- */
1169 /* Section 1.5.2.2: Prefetch, Active and TTU */
1170 /* ------------------------- */
1171 /* Prefetch Calc */
1172 /* Source */
1173 dcc_en = e2e_pipe_param.pipe.src.dcc;
1174 dual_plane = is_dual_plane(
1175 (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
1176 mode_422 = 0; /* FIXME */
1177 access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */
1178 bytes_per_element_l = get_bytes_per_element(
1179 (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
1180 0);
1181 bytes_per_element_c = get_bytes_per_element(
1182 (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
1183 1);
1184 vp_height_l = e2e_pipe_param.pipe.src.viewport_height;
1185 vp_width_l = e2e_pipe_param.pipe.src.viewport_width;
1186 vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c;
1187 vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c;
1188
1189 /* Scaling */
1190 htaps_l = e2e_pipe_param.pipe.scale_taps.htaps;
1191 htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c;
1192 hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
1193 hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c;
1194 vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio;
1195 vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c;
1196
1197 line_time_in_us = (htotal / pclk_freq_in_mhz);
1198 vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
1199 vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
1200 vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
1201 vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
1202
1203 swath_height_l = rq_dlg_param.rq_l.swath_height;
1204 swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
1205 dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
1206 dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
1207 meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
1208 meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
1209
1210 swath_height_c = rq_dlg_param.rq_c.swath_height;
1211 swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
1212 dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
1213 dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
1214
1215 meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
1216 vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
1217 vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
1218 vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
1219
1220 dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
1221 dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
1222 pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
1223 + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
1224
1225 vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
1226
1227 if (interlaced)
1228 vstartup_start = vstartup_start / 2;
1229
1230 if (vstartup_start >= min_vblank) {
1231 DTRACE(
1232 "WARNING_DLG: %s: vblank_start=%d vblank_end=%d",
1233 __func__,
1234 vblank_start,
1235 vblank_end);
1236 DTRACE(
1237 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1238 __func__,
1239 vstartup_start,
1240 min_vblank);
1241 min_vblank = vstartup_start + 1;
1242 DTRACE(
1243 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1244 __func__,
1245 vstartup_start,
1246 min_vblank);
1247 }
1248
1249 dst_x_after_scaler = 0;
1250 dst_y_after_scaler = 0;
1251
1252 if (e2e_pipe_param.pipe.src.is_hsplit)
1253 dst_x_after_scaler = pixel_rate_delay_subtotal
1254 + e2e_pipe_param.pipe.dest.recout_width;
1255 else
1256 dst_x_after_scaler = pixel_rate_delay_subtotal;
1257
1258 if (e2e_pipe_param.dout.output_format == dm_420)
1259 dst_y_after_scaler = 1;
1260 else
1261 dst_y_after_scaler = 0;
1262
1263 if (dst_x_after_scaler >= htotal) {
1264 dst_x_after_scaler = dst_x_after_scaler - htotal;
1265 dst_y_after_scaler = dst_y_after_scaler + 1;
1266 }
1267
1268 DTRACE("DLG: %s: htotal = %d", __func__, htotal);
1269 DTRACE(
1270 "DLG: %s: pixel_rate_delay_subtotal = %d",
1271 __func__,
1272 pixel_rate_delay_subtotal);
1273 DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler);
1274 DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler);
1275
1276 line_wait = mode_lib->soc.urgent_latency_us;
1277 if (cstate_en)
1278 line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
1279 if (pstate_en)
1280 line_wait = dml_max(
1281 mode_lib->soc.dram_clock_change_latency_us
1282 + mode_lib->soc.urgent_latency_us,
1283 line_wait);
1284 line_wait = line_wait / line_time_in_us;
1285
1286 line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
1287 line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
1288 line_calc = t_calc_us / line_time_in_us;
1289
1290 DTRACE(
1291 "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f",
1292 __func__,
1293 (double) mode_lib->soc.sr_enter_plus_exit_time_us);
1294 DTRACE(
1295 "DLG: %s: soc.dram_clock_change_latency_us = %3.2f",
1296 __func__,
1297 (double) mode_lib->soc.dram_clock_change_latency_us);
1298 DTRACE(
1299 "DLG: %s: soc.urgent_latency_us = %3.2f",
1300 __func__,
1301 mode_lib->soc.urgent_latency_us);
1302
1303 DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l);
1304 if (dual_plane)
1305 DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c);
1306
1307 DTRACE(
1308 "DLG: %s: t_srx_delay_us = %3.2f",
1309 __func__,
1310 (double) dlg_sys_param.t_srx_delay_us);
1311 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
1312 DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
1313 DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
1314 DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset);
1315 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us);
1316 DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait);
1317 DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o);
1318 DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup);
1319 DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc);
1320
1321 dst_y_prefetch = ((double) min_vblank - 1.0)
1322 - (line_setup + line_calc + line_wait + line_o);
1323 DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
1324 ASSERT(dst_y_prefetch >= 2.0);
1325
1326 dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125), 1) / 4;
1327 DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
1328
1329 t_pre_us = dst_y_prefetch * line_time_in_us;
1330 vm_bytes = 0;
1331 meta_row_bytes = 0;
1332
1333 if (dcc_en && vm_en)
1334 vm_bytes = meta_pte_bytes_per_frame_ub_l;
1335 if (dcc_en)
1336 meta_row_bytes = meta_bytes_per_row_ub_l;
1337
1338 max_num_sw_l = 0;
1339 max_num_sw_c = 0;
1340 max_partial_sw_l = 0;
1341 max_partial_sw_c = 0;
1342
1343 max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
1344 max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
1345
1346 get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
1347 if (dual_plane)
1348 get_swath_need(
1349 mode_lib,
1350 &max_num_sw_c,
1351 &max_partial_sw_c,
1352 swath_height_c,
1353 max_vinit_c);
1354
1355 lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
1356 lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
1357 sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
1358 sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
1359 sw_bytes = 0;
1360 dpte_row_bytes = 0;
1361
1362 if (vm_en) {
1363 if (dual_plane)
1364 dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
1365 else
1366 dpte_row_bytes = dpte_bytes_per_row_ub_l;
1367 } else {
1368 dpte_row_bytes = 0;
1369 }
1370
1371 if (dual_plane)
1372 sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
1373 else
1374 sw_bytes = sw_bytes_ub_l;
1375
1376 DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l);
1377 DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c);
1378 DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes);
1379 DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes);
1380 DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes);
1381 DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes);
1382
1383 prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
1384 flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw)
1385 / (double) dlg_sys_param.total_flip_bytes;
1386 t_vm_us = line_time_in_us / 4.0;
1387 if (vm_en && dcc_en) {
1388 t_vm_us = dml_max(
1389 dlg_sys_param.t_extra_us,
1390 dml_max((double) vm_bytes / prefetch_bw, t_vm_us));
1391
1392 if (iflip_en && !dual_plane) {
1393 t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us);
1394 if (flip_bw > 0.)
1395 t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us);
1396 }
1397 }
1398
1399 t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us);
1400
1401 if (vm_en || dcc_en) {
1402 t_r0_us = dml_max(
1403 (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw,
1404 dlg_sys_param.t_extra_us);
1405 t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us);
1406
1407 if (iflip_en && !dual_plane) {
1408 t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us);
1409 if (flip_bw > 0.)
1410 t_r0_us = dml_max(
1411 (dpte_row_bytes + meta_row_bytes) / flip_bw,
1412 t_r0_us);
1413 }
1414 }
1415
1416 disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */
1417 disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */
1418 ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
1419 DTRACE(
1420 "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x",
1421 __func__,
1422 disp_dlg_regs->dst_y_after_scaler);
1423 DTRACE(
1424 "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x",
1425 __func__,
1426 disp_dlg_regs->refcyc_x_after_scaler);
1427
1428 disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
1429 DTRACE(
1430 "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d",
1431 __func__,
1432 disp_dlg_regs->dst_y_prefetch);
1433
1434 dst_y_per_vm_vblank = 0.0;
1435 dst_y_per_row_vblank = 0.0;
1436
1437 dst_y_per_vm_vblank = t_vm_us / line_time_in_us;
1438 dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125), 1) / 4.0;
1439 disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
1440
1441 dst_y_per_row_vblank = t_r0_us / line_time_in_us;
1442 dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125), 1) / 4.0;
1443 disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
1444
1445 DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l);
1446 DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c);
1447 DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l);
1448 DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c);
1449
1450 DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw);
1451 DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw);
1452 DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us);
1453 DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us);
1454 DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us);
1455 DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank);
1456 DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank);
1457 DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch);
1458
1459 min_dst_y_per_vm_vblank = 8.0;
1460 min_dst_y_per_row_vblank = 16.0;
1461 if (htotal <= 75) {
1462 min_vblank = 300;
1463 min_dst_y_per_vm_vblank = 100.0;
1464 min_dst_y_per_row_vblank = 100.0;
1465 }
1466
1467 ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
1468 ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
1469
1470 ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
1471 lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
1472
1473 DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw);
1474
1475 vratio_pre_l = get_vratio_pre(
1476 mode_lib,
1477 max_num_sw_l,
1478 max_partial_sw_l,
1479 swath_height_l,
1480 max_vinit_l,
1481 lsw);
1482 vratio_pre_c = 1.0;
1483 if (dual_plane)
1484 vratio_pre_c = get_vratio_pre(
1485 mode_lib,
1486 max_num_sw_c,
1487 max_partial_sw_c,
1488 swath_height_c,
1489 max_vinit_c,
1490 lsw);
1491
1492 DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l);
1493 DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c);
1494
1495 ASSERT(vratio_pre_l <= 4.0);
1496 if (vratio_pre_l >= 4.0)
1497 disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1;
1498 else
1499 disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
1500
1501 ASSERT(vratio_pre_c <= 4.0);
1502 if (vratio_pre_c >= 4.0)
1503 disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1;
1504 else
1505 disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
1506
1507 disp_dlg_regs->refcyc_per_pte_group_vblank_l =
1508 (unsigned int) (dst_y_per_row_vblank * (double) htotal
1509 * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
1510 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
1511
1512 disp_dlg_regs->refcyc_per_pte_group_vblank_c =
1513 (unsigned int) (dst_y_per_row_vblank * (double) htotal
1514 * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c);
1515 ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13));
1516
1517 disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
1518 (unsigned int) (dst_y_per_row_vblank * (double) htotal
1519 * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
1520 ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
1521
1522 disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
1523 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 */
1524
1525 /* Active */
1526 req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
1527 req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
1528 meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
1529 swath_width_pixels_ub_l = 0;
1530 swath_width_pixels_ub_c = 0;
1531 scaler_rec_in_width_l = 0;
1532 scaler_rec_in_width_c = 0;
1533 dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
1534 dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
1535
1536 disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
1537 / (double) vratio_l * dml_pow(2, 2));
1538 ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
1539
1540 disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
1541 / (double) vratio_c * dml_pow(2, 2));
1542 ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17));
1543
1544 disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
1545 / (double) vratio_l * dml_pow(2, 2));
1546 ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
1547
1548 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 */
1549
1550 disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
1551 / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1552 / (double) dpte_groups_per_row_ub_l);
1553 if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
1554 disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
1555
1556 disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c
1557 / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq
1558 / (double) dpte_groups_per_row_ub_c);
1559 if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
1560 disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
1561
1562 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
1563 / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
1564 / (double) meta_chunks_per_row_ub_l);
1565 if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
1566 disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
1567
1568 if (mode_422) {
1569 swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */
1570 swath_width_pixels_ub_c = swath_width_ub_c * 2;
1571 } else {
1572 swath_width_pixels_ub_l = swath_width_ub_l * 1;
1573 swath_width_pixels_ub_c = swath_width_ub_c * 1;
1574 }
1575
1576 hscale_pixel_rate_l = 0.;
1577 hscale_pixel_rate_c = 0.;
1578 min_hratio_fact_l = 1.0;
1579 min_hratio_fact_c = 1.0;
1580
1581 if (htaps_l <= 1)
1582 min_hratio_fact_l = 2.0;
1583 else if (htaps_l <= 6) {
1584 if ((hratios_l * 2.0) > 4.0)
1585 min_hratio_fact_l = 4.0;
1586 else
1587 min_hratio_fact_l = hratios_l * 2.0;
1588 } else {
1589 if (hratios_l > 4.0)
1590 min_hratio_fact_l = 4.0;
1591 else
1592 min_hratio_fact_l = hratios_l;
1593 }
1594
1595 hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
1596
1597 if (htaps_c <= 1)
1598 min_hratio_fact_c = 2.0;
1599 else if (htaps_c <= 6) {
1600 if ((hratios_c * 2.0) > 4.0)
1601 min_hratio_fact_c = 4.0;
1602 else
1603 min_hratio_fact_c = hratios_c * 2.0;
1604 } else {
1605 if (hratios_c > 4.0)
1606 min_hratio_fact_c = 4.0;
1607 else
1608 min_hratio_fact_c = hratios_c;
1609 }
1610
1611 hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
1612
1613 refcyc_per_line_delivery_pre_l = 0.;
1614 refcyc_per_line_delivery_pre_c = 0.;
1615 refcyc_per_line_delivery_l = 0.;
1616 refcyc_per_line_delivery_c = 0.;
1617
1618 refcyc_per_req_delivery_pre_l = 0.;
1619 refcyc_per_req_delivery_pre_c = 0.;
1620 refcyc_per_req_delivery_l = 0.;
1621 refcyc_per_req_delivery_c = 0.;
1622 refcyc_per_req_delivery_pre_cur0 = 0.;
1623 refcyc_per_req_delivery_cur0 = 0.;
1624
1625 full_recout_width = 0;
1626 if (e2e_pipe_param.pipe.src.is_hsplit) {
1627 if (e2e_pipe_param.pipe.dest.full_recout_width == 0) {
1628 DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__);
1629 full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */
1630 } else
1631 full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width;
1632 } else
1633 full_recout_width = e2e_pipe_param.pipe.dest.recout_width;
1634
1635 refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(
1636 mode_lib,
1637 refclk_freq_in_mhz,
1638 pclk_freq_in_mhz,
1639 full_recout_width,
1640 vratio_pre_l,
1641 hscale_pixel_rate_l,
1642 swath_width_pixels_ub_l,
1643 1); /* per line */
1644
1645 refcyc_per_line_delivery_l = get_refcyc_per_delivery(
1646 mode_lib,
1647 refclk_freq_in_mhz,
1648 pclk_freq_in_mhz,
1649 full_recout_width,
1650 vratio_l,
1651 hscale_pixel_rate_l,
1652 swath_width_pixels_ub_l,
1653 1); /* per line */
1654
1655 DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width);
1656 DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l);
1657 DTRACE(
1658 "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f",
1659 __func__,
1660 refcyc_per_line_delivery_pre_l);
1661 DTRACE(
1662 "DLG: %s: refcyc_per_line_delivery_l = %3.2f",
1663 __func__,
1664 refcyc_per_line_delivery_l);
1665
1666 disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(
1667 refcyc_per_line_delivery_pre_l,
1668 1);
1669 disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(
1670 refcyc_per_line_delivery_l,
1671 1);
1672 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
1673 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
1674
1675 if (dual_plane) {
1676 refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(
1677 mode_lib,
1678 refclk_freq_in_mhz,
1679 pclk_freq_in_mhz,
1680 full_recout_width,
1681 vratio_pre_c,
1682 hscale_pixel_rate_c,
1683 swath_width_pixels_ub_c,
1684 1); /* per line */
1685
1686 refcyc_per_line_delivery_c = get_refcyc_per_delivery(
1687 mode_lib,
1688 refclk_freq_in_mhz,
1689 pclk_freq_in_mhz,
1690 full_recout_width,
1691 vratio_c,
1692 hscale_pixel_rate_c,
1693 swath_width_pixels_ub_c,
1694 1); /* per line */
1695
1696 DTRACE(
1697 "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
1698 __func__,
1699 refcyc_per_line_delivery_pre_c);
1700 DTRACE(
1701 "DLG: %s: refcyc_per_line_delivery_c = %3.2f",
1702 __func__,
1703 refcyc_per_line_delivery_c);
1704
1705 disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(
1706 refcyc_per_line_delivery_pre_c,
1707 1);
1708 disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(
1709 refcyc_per_line_delivery_c,
1710 1);
1711 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
1712 ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
1713 }
1714 disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
1715
1716 /* TTU - Luma / Chroma */
1717 if (access_dir) { /* vertical access */
1718 scaler_rec_in_width_l = vp_height_l;
1719 scaler_rec_in_width_c = vp_height_c;
1720 } else {
1721 scaler_rec_in_width_l = vp_width_l;
1722 scaler_rec_in_width_c = vp_width_c;
1723 }
1724
1725 refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(
1726 mode_lib,
1727 refclk_freq_in_mhz,
1728 pclk_freq_in_mhz,
1729 full_recout_width,
1730 vratio_pre_l,
1731 hscale_pixel_rate_l,
1732 scaler_rec_in_width_l,
1733 req_per_swath_ub_l); /* per req */
1734 refcyc_per_req_delivery_l = get_refcyc_per_delivery(
1735 mode_lib,
1736 refclk_freq_in_mhz,
1737 pclk_freq_in_mhz,
1738 full_recout_width,
1739 vratio_l,
1740 hscale_pixel_rate_l,
1741 scaler_rec_in_width_l,
1742 req_per_swath_ub_l); /* per req */
1743
1744 DTRACE(
1745 "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
1746 __func__,
1747 refcyc_per_req_delivery_pre_l);
1748 DTRACE(
1749 "DLG: %s: refcyc_per_req_delivery_l = %3.2f",
1750 __func__,
1751 refcyc_per_req_delivery_l);
1752
1753 disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
1754 * dml_pow(2, 10));
1755 disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
1756 * dml_pow(2, 10));
1757
1758 ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
1759 ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
1760
1761 if (dual_plane) {
1762 refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(
1763 mode_lib,
1764 refclk_freq_in_mhz,
1765 pclk_freq_in_mhz,
1766 full_recout_width,
1767 vratio_pre_c,
1768 hscale_pixel_rate_c,
1769 scaler_rec_in_width_c,
1770 req_per_swath_ub_c); /* per req */
1771 refcyc_per_req_delivery_c = get_refcyc_per_delivery(
1772 mode_lib,
1773 refclk_freq_in_mhz,
1774 pclk_freq_in_mhz,
1775 full_recout_width,
1776 vratio_c,
1777 hscale_pixel_rate_c,
1778 scaler_rec_in_width_c,
1779 req_per_swath_ub_c); /* per req */
1780
1781 DTRACE(
1782 "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
1783 __func__,
1784 refcyc_per_req_delivery_pre_c);
1785 DTRACE(
1786 "DLG: %s: refcyc_per_req_delivery_c = %3.2f",
1787 __func__,
1788 refcyc_per_req_delivery_c);
1789
1790 disp_ttu_regs->refcyc_per_req_delivery_pre_c =
1791 (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10));
1792 disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
1793 * dml_pow(2, 10));
1794
1795 ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
1796 ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
1797 }
1798
1799 /* TTU - Cursor */
1800 hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
1801 cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */
1802 cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp;
1803 cur0_req_size = 0;
1804 cur0_req_width = 0;
1805 cur0_width_ub = 0.0;
1806 cur0_req_per_width = 0.0;
1807 hactive_cur0 = 0.0;
1808
1809 ASSERT(cur0_src_width <= 256);
1810
1811 if (cur0_src_width > 0) {
1812 unsigned int cur0_bit_per_pixel = 0;
1813
1814 if (cur0_bpp == dm_cur_2bit) {
1815 cur0_req_size = 64; /* byte */
1816 cur0_bit_per_pixel = 2;
1817 } else { /* 32bit */
1818 cur0_bit_per_pixel = 32;
1819 if (cur0_src_width >= 1 && cur0_src_width <= 16)
1820 cur0_req_size = 64;
1821 else if (cur0_src_width >= 17 && cur0_src_width <= 31)
1822 cur0_req_size = 128;
1823 else
1824 cur0_req_size = 256;
1825 }
1826
1827 cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0);
1828 cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width, 1)
1829 * (double) cur0_req_width;
1830 cur0_req_per_width = cur0_width_ub / (double) cur0_req_width;
1831 hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */
1832
1833 if (vratio_pre_l <= 1.0) {
1834 refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq
1835 / (double) cur0_req_per_width;
1836 } else {
1837 refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz
1838 * (double) cur0_src_width / hscale_pixel_rate_l
1839 / (double) cur0_req_per_width;
1840 }
1841
1842 disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
1843 (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
1844 ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13));
1845
1846 if (vratio_l <= 1.0) {
1847 refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq
1848 / (double) cur0_req_per_width;
1849 } else {
1850 refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz
1851 * (double) cur0_src_width / hscale_pixel_rate_l
1852 / (double) cur0_req_per_width;
1853 }
1854
1855 DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width);
1856 DTRACE(
1857 "DLG: %s: cur0_width_ub = %3.2f",
1858 __func__,
1859 cur0_width_ub);
1860 DTRACE(
1861 "DLG: %s: cur0_req_per_width = %3.2f",
1862 __func__,
1863 cur0_req_per_width);
1864 DTRACE(
1865 "DLG: %s: hactive_cur0 = %3.2f",
1866 __func__,
1867 hactive_cur0);
1868 DTRACE(
1869 "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f",
1870 __func__,
1871 refcyc_per_req_delivery_pre_cur0);
1872 DTRACE(
1873 "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f",
1874 __func__,
1875 refcyc_per_req_delivery_cur0);
1876
1877 disp_ttu_regs->refcyc_per_req_delivery_cur0 =
1878 (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10));
1879 ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13));
1880 } else {
1881 disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0;
1882 disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0;
1883 }
1884
1885 /* TTU - Misc */
1886 disp_ttu_regs->qos_level_low_wm = 0;
1887 ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
1888 disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
1889 * ref_freq_to_pix_freq);
1890 ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14));
1891
1892 disp_ttu_regs->qos_level_flip = 14;
1893 disp_ttu_regs->qos_level_fixed_l = 8;
1894 disp_ttu_regs->qos_level_fixed_c = 8;
1895 disp_ttu_regs->qos_level_fixed_cur0 = 8;
1896 disp_ttu_regs->qos_ramp_disable_l = 0;
1897 disp_ttu_regs->qos_ramp_disable_c = 0;
1898 disp_ttu_regs->qos_ramp_disable_cur0 = 0;
1899
1900 disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz;
1901 ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24));
1902
1903 print__ttu_regs_st(mode_lib, *disp_ttu_regs);
1904 print__dlg_regs_st(mode_lib, *disp_dlg_regs);
1905}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h
new file mode 100644
index 000000000000..987d7671cd0f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef __DISPLAY_RQ_DLG_CALC_H__
27#define __DISPLAY_RQ_DLG_CALC_H__
28
29#include "dml_common_defs.h"
30#include "display_rq_dlg_helpers.h"
31
32struct display_mode_lib;
33
34void dml1_extract_rq_regs(
35 struct display_mode_lib *mode_lib,
36 struct _vcs_dpi_display_rq_regs_st *rq_regs,
37 const struct _vcs_dpi_display_rq_params_st rq_param);
38/* Function: dml_rq_dlg_get_rq_params
39 * Calculate requestor related parameters that register definition agnostic
40 * (i.e. this layer does try to separate real values from register definition)
41 * Input:
42 * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
43 * Output:
44 * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
45 */
46void dml1_rq_dlg_get_rq_params(
47 struct display_mode_lib *mode_lib,
48 struct _vcs_dpi_display_rq_params_st *rq_param,
49 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
50
51
52/* Function: dml_rq_dlg_get_dlg_params
53 * Calculate deadline related parameters
54 */
55void dml1_rq_dlg_get_dlg_params(
56 struct display_mode_lib *mode_lib,
57 struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
58 struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
59 const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
60 const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
61 const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
62 const bool cstate_en,
63 const bool pstate_en,
64 const bool vm_en,
65 const bool iflip_en);
66
67#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c
index df2d5099b90e..b953b02a1512 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c
@@ -27,11 +27,12 @@
27#include "../calcs/dcn_calc_math.h" 27#include "../calcs/dcn_calc_math.h"
28 28
29#include "dml_inline_defs.h" 29#include "dml_inline_defs.h"
30
30double dml_round(double a) 31double dml_round(double a)
31{ 32{
32 double round_pt = 0.5; 33 double round_pt = 0.5;
33 double ceil = dml_ceil(a); 34 double ceil = dml_ceil(a, 1);
34 double floor = dml_floor(a); 35 double floor = dml_floor(a, 1);
35 36
36 if (a - floor >= round_pt) 37 if (a - floor >= round_pt)
37 return ceil; 38 return ceil;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h
index 81c53d879a16..b2847bc469fe 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.h
@@ -22,6 +22,7 @@
22 * Authors: AMD 22 * Authors: AMD
23 * 23 *
24 */ 24 */
25
25#ifndef __DC_COMMON_DEFS_H__ 26#ifndef __DC_COMMON_DEFS_H__
26#define __DC_COMMON_DEFS_H__ 27#define __DC_COMMON_DEFS_H__
27 28
@@ -30,7 +31,8 @@
30#include "display_mode_structs.h" 31#include "display_mode_structs.h"
31#include "display_mode_enums.h" 32#include "display_mode_enums.h"
32 33
33#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); 34#define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
35#define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
34 36
35double dml_round(double a); 37double dml_round(double a);
36 38
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
index a91b4a6c6154..e68086b8a22f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
@@ -1,5 +1,31 @@
1/*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
1#ifndef __DML_INLINE_DEFS_H__ 26#ifndef __DML_INLINE_DEFS_H__
2#define __DML_INLINE_DEFS_H__ 27#define __DML_INLINE_DEFS_H__
28
3#include "dml_common_defs.h" 29#include "dml_common_defs.h"
4#include "../calcs/dcn_calc_math.h" 30#include "../calcs/dcn_calc_math.h"
5 31
@@ -13,14 +39,29 @@ static inline double dml_max(double a, double b)
13 return (double) dcn_bw_max2(a, b); 39 return (double) dcn_bw_max2(a, b);
14} 40}
15 41
16static inline double dml_ceil(double a) 42static inline double dml_max3(double a, double b, double c)
43{
44 return dml_max(dml_max(a, b), c);
45}
46
47static inline double dml_max4(double a, double b, double c, double d)
48{
49 return dml_max(dml_max(a, b), dml_max(c, d));
50}
51
52static inline double dml_max5(double a, double b, double c, double d, double e)
53{
54 return dml_max(dml_max4(a, b, c, d), e);
55}
56
57static inline double dml_ceil(double a, double granularity)
17{ 58{
18 return (double) dcn_bw_ceil2(a, 1); 59 return (double) dcn_bw_ceil2(a, granularity);
19} 60}
20 61
21static inline double dml_floor(double a) 62static inline double dml_floor(double a, double granularity)
22{ 63{
23 return (double) dcn_bw_floor2(a, 1); 64 return (double) dcn_bw_floor2(a, granularity);
24} 65}
25 66
26static inline int dml_log2(double x) 67static inline int dml_log2(double x)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
index 0745366d80bc..bc7d8c707221 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c
@@ -24,51 +24,46 @@
24 */ 24 */
25#include "soc_bounding_box.h" 25#include "soc_bounding_box.h"
26#include "display_mode_lib.h" 26#include "display_mode_lib.h"
27#include "dc_features.h"
27 28
28#include "dml_inline_defs.h" 29#include "dml_inline_defs.h"
29void dml_socbb_set_latencies( 30void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box)
30 struct display_mode_lib *mode_lib,
31 struct _vcs_dpi_soc_bounding_box_st *from_box)
32{ 31{
33 struct _vcs_dpi_soc_bounding_box_st *to_box = &mode_lib->soc;
34
35 to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us; 32 to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us;
36 to_box->sr_exit_time_us = from_box->sr_exit_time_us; 33 to_box->sr_exit_time_us = from_box->sr_exit_time_us;
37 to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us; 34 to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us;
38 to_box->urgent_latency_us = from_box->urgent_latency_us; 35 to_box->urgent_latency_us = from_box->urgent_latency_us;
39 to_box->writeback_latency_us = from_box->writeback_latency_us; 36 to_box->writeback_latency_us = from_box->writeback_latency_us;
40 DTRACE("box.dram_clock_change_latency_us: %f", from_box->dram_clock_change_latency_us);
41 DTRACE("box.sr_exit_time_us: %f", from_box->sr_exit_time_us);
42 DTRACE("box.sr_enter_plus_exit_time_us: %f", from_box->sr_enter_plus_exit_time_us);
43 DTRACE("box.urgent_latency_us: %f", from_box->urgent_latency_us);
44 DTRACE("box.writeback_latency_us: %f", from_box->writeback_latency_us);
45
46} 37}
47 38
48struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling( 39voltage_scaling_st dml_socbb_voltage_scaling(
49 struct _vcs_dpi_soc_bounding_box_st *box, 40 const soc_bounding_box_st *soc,
50 enum voltage_state voltage) 41 enum voltage_state voltage)
51{ 42{
52 switch (voltage) { 43 const voltage_scaling_st *voltage_state;
53 case dm_vmin: 44 const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES;
54 return box->vmin; 45
55 case dm_vnom: 46 for (voltage_state = soc->clock_limits;
56 return box->vnom; 47 voltage_state < voltage_end && voltage_state->state != voltage;
57 case dm_vmax: 48 voltage_state++) {
58 default:
59 return box->vmax;
60 } 49 }
50
51 if (voltage_state < voltage_end)
52 return *voltage_state;
53 return soc->clock_limits[DC__VOLTAGE_STATES - 1];
61} 54}
62 55
63double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage) 56double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage)
64{ 57{
65 double return_bw; 58 double return_bw;
66 59
67 struct _vcs_dpi_voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage); 60 voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
68 61
69 return_bw = dml_min( 62 return_bw = dml_min((double) box->return_bus_width_bytes * state.dcfclk_mhz,
70 ((double) box->return_bus_width_bytes) * state.dcfclk_mhz,
71 state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans 63 state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans
72 * box->ideal_dram_bw_after_urgent_percent / 100.0); 64 * box->ideal_dram_bw_after_urgent_percent / 100.0);
65
66 return_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw);
67
73 return return_bw; 68 return return_bw;
74} 69}
diff --git a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h
index 7bbae33f163e..7a65206a6d21 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.h
@@ -22,15 +22,14 @@
22 * Authors: AMD 22 * Authors: AMD
23 * 23 *
24 */ 24 */
25
25#ifndef __SOC_BOUNDING_BOX_H__ 26#ifndef __SOC_BOUNDING_BOX_H__
26#define __SOC_BOUNDING_BOX_H__ 27#define __SOC_BOUNDING_BOX_H__
27 28
28#include "dml_common_defs.h" 29#include "dml_common_defs.h"
29 30
30struct display_mode_lib; 31void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box);
31 32voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage);
32void dml_socbb_set_latencies(struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box); 33double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage);
33struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
34double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
35 34
36#endif 35#endif
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
index d4e5ef64e489..80038e0e610f 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
@@ -130,9 +130,8 @@ failure_2:
130 130
131 slot = service->busyness[index_of_id]; 131 slot = service->busyness[index_of_id];
132 132
133 if (slot) 133 kfree(slot);
134 kfree(slot); 134 }
135 };
136 135
137failure_1: 136failure_1:
138 kfree(service); 137 kfree(service);
@@ -171,8 +170,7 @@ void dal_gpio_service_destroy(
171 do { 170 do {
172 uint32_t *slot = (*ptr)->busyness[index_of_id]; 171 uint32_t *slot = (*ptr)->busyness[index_of_id];
173 172
174 if (slot) 173 kfree(slot);
175 kfree(slot);
176 174
177 ++index_of_id; 175 ++index_of_id;
178 } while (index_of_id < GPIO_ID_COUNT); 176 } while (index_of_id < GPIO_ID_COUNT);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
index b5759c0e5a2f..01df85641684 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h
@@ -35,13 +35,14 @@ enum dc_status {
35 DC_FAIL_CONTROLLER_VALIDATE = 5, 35 DC_FAIL_CONTROLLER_VALIDATE = 5,
36 DC_FAIL_ENC_VALIDATE = 6, 36 DC_FAIL_ENC_VALIDATE = 6,
37 DC_FAIL_ATTACH_SURFACES = 7, 37 DC_FAIL_ATTACH_SURFACES = 7,
38 DC_FAIL_SURFACE_VALIDATE = 8, 38 DC_FAIL_DETACH_SURFACES = 8,
39 DC_NO_DP_LINK_BANDWIDTH = 9, 39 DC_FAIL_SURFACE_VALIDATE = 9,
40 DC_EXCEED_DONGLE_MAX_CLK = 10, 40 DC_NO_DP_LINK_BANDWIDTH = 10,
41 DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 11, 41 DC_EXCEED_DONGLE_MAX_CLK = 11,
42 DC_FAIL_BANDWIDTH_VALIDATE = 12, /* BW and Watermark validation */ 42 DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12,
43 DC_FAIL_SCALING = 13, 43 DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */
44 DC_FAIL_DP_LINK_TRAINING = 14, 44 DC_FAIL_SCALING = 14,
45 DC_FAIL_DP_LINK_TRAINING = 15,
45 46
46 DC_ERROR_UNEXPECTED = -1 47 DC_ERROR_UNEXPECTED = -1
47}; 48};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index ff23f268fe02..b69f321e2ab6 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -32,6 +32,7 @@
32#include "ddc_service_types.h" 32#include "ddc_service_types.h"
33#include "dc_bios_types.h" 33#include "dc_bios_types.h"
34#include "mem_input.h" 34#include "mem_input.h"
35#include "hubp.h"
35#if defined(CONFIG_DRM_AMD_DC_DCN1_0) 36#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
36#include "mpc.h" 37#include "mpc.h"
37#endif 38#endif
@@ -58,6 +59,11 @@ struct link_init_data {
58 TODO: remove it when DC is complete. */ 59 TODO: remove it when DC is complete. */
59}; 60};
60 61
62enum {
63 FREE_ACQUIRED_RESOURCE = 0,
64 KEEP_ACQUIRED_RESOURCE = 1,
65};
66
61struct dc_link *link_create(const struct link_init_data *init_params); 67struct dc_link *link_create(const struct link_init_data *init_params);
62void link_destroy(struct dc_link **link); 68void link_destroy(struct dc_link **link);
63 69
@@ -72,12 +78,13 @@ void core_link_enable_stream(
72 struct dc_state *state, 78 struct dc_state *state,
73 struct pipe_ctx *pipe_ctx); 79 struct pipe_ctx *pipe_ctx);
74 80
75void core_link_disable_stream(struct pipe_ctx *pipe_ctx); 81void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option);
76 82
77void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable); 83void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
78/********** DAL Core*********************/ 84/********** DAL Core*********************/
79#include "display_clock.h" 85#include "display_clock.h"
80#include "transform.h" 86#include "transform.h"
87#include "dpp.h"
81 88
82struct resource_pool; 89struct resource_pool;
83struct dc_state; 90struct dc_state;
@@ -106,7 +113,7 @@ struct resource_funcs {
106 const struct resource_pool *pool, 113 const struct resource_pool *pool,
107 struct dc_stream_state *stream); 114 struct dc_stream_state *stream);
108 115
109 enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state); 116 enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps);
110 117
111 enum dc_status (*add_stream_to_ctx)( 118 enum dc_status (*add_stream_to_ctx)(
112 struct dc *dc, 119 struct dc *dc,
@@ -124,8 +131,10 @@ struct audio_support{
124 131
125struct resource_pool { 132struct resource_pool {
126 struct mem_input *mis[MAX_PIPES]; 133 struct mem_input *mis[MAX_PIPES];
134 struct hubp *hubps[MAX_PIPES];
127 struct input_pixel_processor *ipps[MAX_PIPES]; 135 struct input_pixel_processor *ipps[MAX_PIPES];
128 struct transform *transforms[MAX_PIPES]; 136 struct transform *transforms[MAX_PIPES];
137 struct dpp *dpps[MAX_PIPES];
129 struct output_pixel_processor *opps[MAX_PIPES]; 138 struct output_pixel_processor *opps[MAX_PIPES];
130 struct timing_generator *timing_generators[MAX_PIPES]; 139 struct timing_generator *timing_generators[MAX_PIPES];
131 struct stream_encoder *stream_enc[MAX_PIPES * 2]; 140 struct stream_encoder *stream_enc[MAX_PIPES * 2];
@@ -173,10 +182,11 @@ struct stream_resource {
173 182
174struct plane_resource { 183struct plane_resource {
175 struct scaler_data scl_data; 184 struct scaler_data scl_data;
176 185 struct hubp *hubp;
177 struct mem_input *mi; 186 struct mem_input *mi;
178 struct input_pixel_processor *ipp; 187 struct input_pixel_processor *ipp;
179 struct transform *xfm; 188 struct transform *xfm;
189 struct dpp *dpp;
180}; 190};
181 191
182struct pipe_ctx { 192struct pipe_ctx {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
new file mode 100644
index 000000000000..83a68460edcd
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -0,0 +1,134 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26
27#ifndef __DAL_DPP_H__
28#define __DAL_DPP_H__
29
30#include "transform.h"
31
32struct dpp {
33 const struct dpp_funcs *funcs;
34 struct dc_context *ctx;
35 int inst;
36 struct dpp_caps *caps;
37 struct pwl_params regamma_params;
38};
39
40struct dpp_grph_csc_adjustment {
41 struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
42 enum graphics_gamut_adjust_type gamut_adjust_type;
43};
44
45struct dpp_funcs {
46 void (*dpp_reset)(struct dpp *dpp);
47
48 void (*dpp_set_scaler)(struct dpp *dpp,
49 const struct scaler_data *scl_data);
50
51 void (*dpp_set_pixel_storage_depth)(
52 struct dpp *dpp,
53 enum lb_pixel_depth depth,
54 const struct bit_depth_reduction_params *bit_depth_params);
55
56 bool (*dpp_get_optimal_number_of_taps)(
57 struct dpp *dpp,
58 struct scaler_data *scl_data,
59 const struct scaling_taps *in_taps);
60
61 void (*dpp_set_gamut_remap)(
62 struct dpp *dpp,
63 const struct dpp_grph_csc_adjustment *adjust);
64
65 void (*opp_set_csc_default)(
66 struct dpp *dpp,
67 const struct default_adjustment *default_adjust);
68
69 void (*opp_set_csc_adjustment)(
70 struct dpp *dpp,
71 const struct out_csc_color_matrix *tbl_entry);
72
73 void (*opp_power_on_regamma_lut)(
74 struct dpp *dpp,
75 bool power_on);
76
77 void (*opp_program_regamma_lut)(
78 struct dpp *dpp,
79 const struct pwl_result_data *rgb,
80 uint32_t num);
81
82 void (*opp_configure_regamma_lut)(
83 struct dpp *dpp,
84 bool is_ram_a);
85
86 void (*opp_program_regamma_lutb_settings)(
87 struct dpp *dpp,
88 const struct pwl_params *params);
89
90 void (*opp_program_regamma_luta_settings)(
91 struct dpp *dpp,
92 const struct pwl_params *params);
93
94 void (*opp_program_regamma_pwl)(
95 struct dpp *dpp, const struct pwl_params *params);
96
97 void (*opp_set_regamma_mode)(
98 struct dpp *dpp_base,
99 enum opp_regamma mode);
100
101 void (*ipp_set_degamma)(
102 struct dpp *dpp_base,
103 enum ipp_degamma_mode mode);
104
105 void (*ipp_program_input_lut)(
106 struct dpp *dpp_base,
107 const struct dc_gamma *gamma);
108
109 void (*ipp_program_degamma_pwl)(struct dpp *dpp_base,
110 const struct pwl_params *params);
111
112 void (*ipp_setup)(
113 struct dpp *dpp_base,
114 enum surface_pixel_format input_format,
115 enum expansion_mode mode);
116
117 void (*ipp_full_bypass)(struct dpp *dpp_base);
118
119 void (*set_cursor_attributes)(
120 struct dpp *dpp_base,
121 const struct dc_cursor_attributes *attr);
122
123 void (*set_cursor_position)(
124 struct dpp *dpp_base,
125 const struct dc_cursor_position *pos,
126 const struct dc_cursor_mi_param *param,
127 uint32_t width
128 );
129
130};
131
132
133
134#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
new file mode 100644
index 000000000000..0d186be24cf4
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#ifndef __DAL_HUBP_H__
27#define __DAL_HUBP_H__
28
29#include "mem_input.h"
30
31struct hubp {
32 struct hubp_funcs *funcs;
33 struct dc_context *ctx;
34 struct dc_plane_address request_address;
35 struct dc_plane_address current_address;
36 int inst;
37 int opp_id;
38 int mpcc_id;
39 struct dc_cursor_attributes curs_attr;
40};
41
42
43struct hubp_funcs {
44 void (*hubp_setup)(
45 struct hubp *hubp,
46 struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
47 struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
48 struct _vcs_dpi_display_rq_regs_st *rq_regs,
49 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
50
51 void (*dcc_control)(struct hubp *hubp, bool enable,
52 bool independent_64b_blks);
53 void (*mem_program_viewport)(
54 struct hubp *hubp,
55 const struct rect *viewport,
56 const struct rect *viewport_c);
57
58 bool (*hubp_program_surface_flip_and_addr)(
59 struct hubp *hubp,
60 const struct dc_plane_address *address,
61 bool flip_immediate);
62
63 void (*hubp_program_pte_vm)(
64 struct hubp *hubp,
65 enum surface_pixel_format format,
66 union dc_tiling_info *tiling_info,
67 enum dc_rotation_angle rotation);
68
69 void (*hubp_set_vm_system_aperture_settings)(
70 struct hubp *hubp,
71 struct vm_system_aperture_param *apt);
72
73 void (*hubp_set_vm_context0_settings)(
74 struct hubp *hubp,
75 const struct vm_context0_param *vm0);
76
77 void (*hubp_program_surface_config)(
78 struct hubp *hubp,
79 enum surface_pixel_format format,
80 union dc_tiling_info *tiling_info,
81 union plane_size *plane_size,
82 enum dc_rotation_angle rotation,
83 struct dc_plane_dcc_param *dcc,
84 bool horizontal_mirror);
85
86 bool (*hubp_is_flip_pending)(struct hubp *hubp);
87
88 void (*hubp_update_dchub)(struct hubp *hubp,
89 struct dchub_init_data *dh_data);
90
91 void (*set_blank)(struct hubp *hubp, bool blank);
92 void (*set_hubp_blank_en)(struct hubp *hubp, bool blank);
93
94 void (*set_cursor_attributes)(
95 struct hubp *hubp,
96 const struct dc_cursor_attributes *attr);
97
98 void (*set_cursor_position)(
99 struct hubp *hubp,
100 const struct dc_cursor_position *pos,
101 const struct dc_cursor_mi_param *param);
102
103};
104
105#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 961bbcc9202c..3d33bcda7059 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -111,7 +111,7 @@ struct link_encoder_funcs {
111 const struct dc_link_settings *link_settings, 111 const struct dc_link_settings *link_settings,
112 enum clock_source_id clock_source); 112 enum clock_source_id clock_source);
113 void (*disable_output)(struct link_encoder *link_enc, 113 void (*disable_output)(struct link_encoder *link_enc,
114 enum signal_type signal); 114 enum signal_type signal, struct dc_link *link);
115 void (*dp_set_lane_settings)(struct link_encoder *enc, 115 void (*dp_set_lane_settings)(struct link_encoder *enc,
116 const struct link_training_settings *link_settings); 116 const struct link_training_settings *link_settings);
117 void (*dp_set_phy_pattern)(struct link_encoder *enc, 117 void (*dp_set_phy_pattern)(struct link_encoder *enc,
@@ -123,10 +123,6 @@ struct link_encoder_funcs {
123 bool exit_link_training_required); 123 bool exit_link_training_required);
124 void (*psr_program_secondary_packet)(struct link_encoder *enc, 124 void (*psr_program_secondary_packet)(struct link_encoder *enc,
125 unsigned int sdp_transmit_line_num_deadline); 125 unsigned int sdp_transmit_line_num_deadline);
126 void (*backlight_control) (struct link_encoder *enc,
127 bool enable);
128 void (*power_control) (struct link_encoder *enc,
129 bool power_up);
130 void (*connect_dig_be_to_fe)(struct link_encoder *enc, 126 void (*connect_dig_be_to_fe)(struct link_encoder *enc,
131 enum engine_id engine, 127 enum engine_id engine,
132 bool connect); 128 bool connect);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
index 6cef9ad0af91..3e1e7e6a8792 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
@@ -69,8 +69,6 @@ struct mem_input {
69 struct dc_plane_address request_address; 69 struct dc_plane_address request_address;
70 struct dc_plane_address current_address; 70 struct dc_plane_address current_address;
71 int inst; 71 int inst;
72 int opp_id;
73 int mpcc_id;
74 struct stutter_modes stutter_mode; 72 struct stutter_modes stutter_mode;
75}; 73};
76 74
@@ -163,6 +161,15 @@ struct mem_input_funcs {
163 void (*set_blank)(struct mem_input *mi, bool blank); 161 void (*set_blank)(struct mem_input *mi, bool blank);
164 void (*set_hubp_blank_en)(struct mem_input *mi, bool blank); 162 void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
165 163
164 void (*set_cursor_attributes)(
165 struct mem_input *mem_input,
166 const struct dc_cursor_attributes *attr);
167
168 void (*set_cursor_position)(
169 struct mem_input *mem_input,
170 const struct dc_cursor_position *pos,
171 const struct dc_cursor_mi_param *param);
172
166}; 173};
167 174
168#endif 175#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 4bbcff48acc8..d4188b2c0626 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -29,8 +29,9 @@
29#include "opp.h" 29#include "opp.h"
30 30
31struct mpcc_cfg { 31struct mpcc_cfg {
32 struct mem_input *mi; 32 int dpp_id;
33 struct output_pixel_processor *opp; 33 int opp_id;
34 struct mpc_tree_cfg *tree_cfg;
34 unsigned int z_index; 35 unsigned int z_index;
35 36
36 struct tg_color black_color; 37 struct tg_color black_color;
@@ -44,11 +45,17 @@ struct mpc {
44}; 45};
45 46
46struct mpc_funcs { 47struct mpc_funcs {
47 void (*add)(struct mpc *mpc, struct mpcc_cfg *cfg); 48 int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
49
48 void (*remove)(struct mpc *mpc, 50 void (*remove)(struct mpc *mpc,
49 struct output_pixel_processor *opp, 51 struct mpc_tree_cfg *tree_cfg,
52 int opp_id,
50 int mpcc_inst); 53 int mpcc_inst);
54
51 void (*wait_for_idle)(struct mpc *mpc, int id); 55 void (*wait_for_idle)(struct mpc *mpc, int id);
56
57 void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg);
58
52}; 59};
53 60
54#endif 61#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
index 785d39706832..7c08bc62c1f5 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
@@ -38,6 +38,7 @@ struct transform {
38 const struct transform_funcs *funcs; 38 const struct transform_funcs *funcs;
39 struct dc_context *ctx; 39 struct dc_context *ctx;
40 int inst; 40 int inst;
41 struct dpp_caps *caps;
41 struct pwl_params regamma_params; 42 struct pwl_params regamma_params;
42}; 43};
43 44
@@ -109,6 +110,22 @@ enum graphics_gamut_adjust_type {
109 GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */ 110 GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */
110}; 111};
111 112
113enum lb_memory_config {
114 /* Enable all 3 pieces of memory */
115 LB_MEMORY_CONFIG_0 = 0,
116
117 /* Enable only the first piece of memory */
118 LB_MEMORY_CONFIG_1 = 1,
119
120 /* Enable only the second piece of memory */
121 LB_MEMORY_CONFIG_2 = 2,
122
123 /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
124 * last piece of chroma memory used for the luma storage
125 */
126 LB_MEMORY_CONFIG_3 = 3
127};
128
112struct xfm_grph_csc_adjustment { 129struct xfm_grph_csc_adjustment {
113 struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE]; 130 struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
114 enum graphics_gamut_adjust_type gamut_adjust_type; 131 enum graphics_gamut_adjust_type gamut_adjust_type;
@@ -238,6 +255,17 @@ struct transform_funcs {
238 255
239 void (*ipp_full_bypass)(struct transform *xfm_base); 256 void (*ipp_full_bypass)(struct transform *xfm_base);
240 257
258 void (*set_cursor_attributes)(
259 struct transform *xfm_base,
260 const struct dc_cursor_attributes *attr);
261
262 void (*set_cursor_position)(
263 struct transform *xfm_base,
264 const struct dc_cursor_position *pos,
265 const struct dc_cursor_mi_param *param,
266 uint32_t width
267 );
268
241}; 269};
242 270
243const uint16_t *get_filter_2tap_16p(void); 271const uint16_t *get_filter_2tap_16p(void);
@@ -251,4 +279,33 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio);
251const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio); 279const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio);
252const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio); 280const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio);
253 281
282
283/* Defines the pixel processing capability of the DSCL */
284enum dscl_data_processing_format {
285 DSCL_DATA_PRCESSING_FIXED_FORMAT, /* The DSCL processes pixel data in fixed format */
286 DSCL_DATA_PRCESSING_FLOAT_FORMAT, /* The DSCL processes pixel data in float format */
287};
288
289/*
290 * The DPP capabilities structure contains enumerations to specify the
291 * HW processing features and an associated function pointers to
292 * provide the function interface that can be overloaded for implementations
293 * based on different capabilities
294 */
295struct dpp_caps {
296 /* DSCL processing pixel data in fixed or float format */
297 enum dscl_data_processing_format dscl_data_proc_format;
298
299 /* Calculates the number of partitions in the line buffer.
300 * The implementation of this function is overloaded for
301 * different versions of DSCL LB.
302 */
303 void (*dscl_calc_lb_num_partitions)(
304 const struct scaler_data *scl_data,
305 enum lb_memory_config lb_config,
306 int *num_part_y,
307 int *num_part_c);
308};
309
310
254#endif 311#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index aae7629b1c08..8734689a9245 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -28,6 +28,7 @@
28#include "dc_types.h" 28#include "dc_types.h"
29#include "clock_source.h" 29#include "clock_source.h"
30#include "inc/hw/timing_generator.h" 30#include "inc/hw/timing_generator.h"
31#include "inc/hw/link_encoder.h"
31#include "core_status.h" 32#include "core_status.h"
32 33
33enum pipe_gating_control { 34enum pipe_gating_control {
@@ -133,7 +134,8 @@ struct hw_sequencer_funcs {
133 134
134 void (*enable_stream)(struct pipe_ctx *pipe_ctx); 135 void (*enable_stream)(struct pipe_ctx *pipe_ctx);
135 136
136 void (*disable_stream)(struct pipe_ctx *pipe_ctx); 137 void (*disable_stream)(struct pipe_ctx *pipe_ctx,
138 int option);
137 139
138 void (*unblank_stream)(struct pipe_ctx *pipe_ctx, 140 void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
139 struct dc_link_settings *link_settings); 141 struct dc_link_settings *link_settings);
@@ -174,8 +176,14 @@ struct hw_sequencer_funcs {
174 struct resource_pool *res_pool, 176 struct resource_pool *res_pool,
175 struct pipe_ctx *pipe_ctx); 177 struct pipe_ctx *pipe_ctx);
176 178
177 void (*ready_shared_resources)(struct dc *dc); 179 void (*ready_shared_resources)(struct dc *dc, struct dc_state *context);
178 void (*optimize_shared_resources)(struct dc *dc); 180 void (*optimize_shared_resources)(struct dc *dc);
181 void (*edp_power_control)(
182 struct link_encoder *enc,
183 bool enable);
184 void (*edp_backlight_control)(
185 struct dc_link *link,
186 bool enable);
179}; 187};
180 188
181void color_space_to_black_color( 189void color_space_to_black_color(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
index f7994cfc850d..f2b8c9a376d5 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
@@ -40,6 +40,10 @@ enum dc_status core_link_write_dpcd(
40 const uint8_t *data, 40 const uint8_t *data,
41 uint32_t size); 41 uint32_t size);
42 42
43struct gpio *get_hpd_gpio(struct dc_bios *dcb,
44 struct graphics_object_id link_id,
45 struct gpio_service *gpio_service);
46
43void dp_enable_link_phy( 47void dp_enable_link_phy(
44 struct dc_link *link, 48 struct dc_link *link,
45 enum signal_type signal, 49 enum signal_type signal,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 614bb691ab59..5467332faf7b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -164,4 +164,9 @@ bool pipe_need_reprogram(
164void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream, 164void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
165 struct bit_depth_reduction_params *fmt_bit_depth); 165 struct bit_depth_reduction_params *fmt_bit_depth);
166 166
167void update_audio_usage(
168 struct resource_context *res_ctx,
169 const struct resource_pool *pool,
170 struct audio *audio,
171 bool acquired);
167#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ 172#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h
index e0cd5278aae8..86170b40b5c5 100644
--- a/drivers/gpu/drm/amd/display/dc/os_types.h
+++ b/drivers/gpu/drm/amd/display/dc/os_types.h
@@ -56,5 +56,45 @@
56 56
57#endif 57#endif
58 58
59/*
60 *
61 * general debug capabilities
62 *
63 */
64#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
65
66#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
67#define ASSERT_CRITICAL(expr) do { \
68 if (WARN_ON(!(expr))) { \
69 kgdb_breakpoint(); \
70 } \
71} while (0)
72#else
73#define ASSERT_CRITICAL(expr) do { \
74 if (WARN_ON(!(expr))) { \
75 ; \
76 } \
77} while (0)
78#endif
79
80#if defined(CONFIG_DEBUG_KERNEL_DC)
81#define ASSERT(expr) ASSERT_CRITICAL(expr)
82
83#else
84#define ASSERT(expr) WARN_ON(!(expr))
85#endif
86
87#define BREAK_TO_DEBUGGER() ASSERT(0)
88
89#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
90
91#define DC_ERR(...) do { \
92 dm_error(__VA_ARGS__); \
93 BREAK_TO_DEBUGGER(); \
94} while (0)
95
96#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
97#include <asm/fpu/api.h>
98#endif
59 99
60#endif /* _OS_TYPES_H_ */ 100#endif /* _OS_TYPES_H_ */
diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
index db513abd735a..88c2bde3f039 100644
--- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c
@@ -58,7 +58,8 @@ static void virtual_link_encoder_enable_dp_mst_output(
58 58
59static void virtual_link_encoder_disable_output( 59static void virtual_link_encoder_disable_output(
60 struct link_encoder *link_enc, 60 struct link_encoder *link_enc,
61 enum signal_type signal) {} 61 enum signal_type signal,
62 struct dc_link *link) {}
62 63
63static void virtual_link_encoder_dp_set_lane_settings( 64static void virtual_link_encoder_dp_set_lane_settings(
64 struct link_encoder *enc, 65 struct link_encoder *enc,
@@ -72,14 +73,6 @@ static void virtual_link_encoder_update_mst_stream_allocation_table(
72 struct link_encoder *enc, 73 struct link_encoder *enc,
73 const struct link_mst_stream_allocation_table *table) {} 74 const struct link_mst_stream_allocation_table *table) {}
74 75
75static void virtual_link_encoder_edp_backlight_control(
76 struct link_encoder *enc,
77 bool enable) {}
78
79static void virtual_link_encoder_edp_power_control(
80 struct link_encoder *enc,
81 bool power_up) {}
82
83static void virtual_link_encoder_connect_dig_be_to_fe( 76static void virtual_link_encoder_connect_dig_be_to_fe(
84 struct link_encoder *enc, 77 struct link_encoder *enc,
85 enum engine_id engine, 78 enum engine_id engine,
@@ -105,8 +98,6 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
105 .dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern, 98 .dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
106 .update_mst_stream_allocation_table = 99 .update_mst_stream_allocation_table =
107 virtual_link_encoder_update_mst_stream_allocation_table, 100 virtual_link_encoder_update_mst_stream_allocation_table,
108 .backlight_control = virtual_link_encoder_edp_backlight_control,
109 .power_control = virtual_link_encoder_edp_power_control,
110 .connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe, 101 .connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe,
111 .destroy = virtual_link_encoder_destroy 102 .destroy = virtual_link_encoder_destroy
112}; 103};
diff --git a/drivers/gpu/drm/amd/display/include/logger_interface.h b/drivers/gpu/drm/amd/display/include/logger_interface.h
index 5aaf2dacfe38..8e1fe70097be 100644
--- a/drivers/gpu/drm/amd/display/include/logger_interface.h
+++ b/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);
44 44
45uint32_t dal_logger_destroy(struct dal_logger **logger); 45uint32_t dal_logger_destroy(struct dal_logger **logger);
46 46
47void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn);
48
47void dm_logger_write( 49void dm_logger_write(
48 struct dal_logger *logger, 50 struct dal_logger *logger,
49 enum dc_log_type log_type, 51 enum dc_log_type log_type,
@@ -157,4 +159,30 @@ void context_clock_trace(
157#define DTN_INFO_END() \ 159#define DTN_INFO_END() \
158 dm_dtn_log_end(dc_ctx) 160 dm_dtn_log_end(dc_ctx)
159 161
162#define PERFORMANCE_TRACE_START() \
163 unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx); \
164 unsigned long long perf_trc_start_log_msk = dc->ctx->logger->mask; \
165 unsigned int perf_trc_start_log_flags = dc->ctx->logger->flags.value; \
166 if (dc->debug.performance_trace) {\
167 dm_logger_flush_buffer(dc->ctx->logger, false);\
168 dc->ctx->logger->mask = 1<<LOG_PERF_TRACE;\
169 dc->ctx->logger->flags.bits.ENABLE_CONSOLE = 0;\
170 dc->ctx->logger->flags.bits.ENABLE_BUFFER = 1;\
171 }
172
173#define PERFORMANCE_TRACE_END() do {\
174 unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx);\
175 if (dc->debug.performance_trace) {\
176 dm_logger_write(dc->ctx->logger, \
177 LOG_PERF_TRACE, \
178 "%s duration: %d ticks\n", __func__,\
179 perf_trc_end_stmp - perf_trc_start_stmp); \
180 if (perf_trc_start_log_msk != 1<<LOG_PERF_TRACE) {\
181 dc->ctx->logger->mask = perf_trc_start_log_msk;\
182 dc->ctx->logger->flags.value = perf_trc_start_log_flags;\
183 dm_logger_flush_buffer(dc->ctx->logger, false);\
184 } \
185 } \
186} while (0)
187
160#endif /* __DAL_LOGGER_INTERFACE_H__ */ 188#endif /* __DAL_LOGGER_INTERFACE_H__ */
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h
index 1f22e84cedb9..e2ff8cd423d6 100644
--- a/drivers/gpu/drm/amd/display/include/logger_types.h
+++ b/drivers/gpu/drm/amd/display/include/logger_types.h
@@ -64,8 +64,7 @@ enum dc_log_type {
64 LOG_EVENT_LINK_LOSS, 64 LOG_EVENT_LINK_LOSS,
65 LOG_EVENT_UNDERFLOW, 65 LOG_EVENT_UNDERFLOW,
66 LOG_IF_TRACE, 66 LOG_IF_TRACE,
67 LOG_HW_MARKS, 67 LOG_PERF_TRACE,
68 LOG_PPLIB,
69 68
70 LOG_SECTION_TOTAL_COUNT 69 LOG_SECTION_TOTAL_COUNT
71}; 70};
@@ -131,4 +130,37 @@ struct dc_log_type_info {
131 char name[MAX_NAME_LEN]; 130 char name[MAX_NAME_LEN];
132}; 131};
133 132
133/* Structure for keeping track of offsets, buffer, etc */
134
135#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
136
137/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
138 * change log line size to 896 to meet the request.
139 */
140#define LOG_MAX_LINE_SIZE 896
141
142struct dal_logger {
143
144 /* How far into the circular buffer has been read by dsat
145 * Read offset should never cross write offset. Write \0's to
146 * read data just to be sure?
147 */
148 uint32_t buffer_read_offset;
149
150 /* How far into the circular buffer we have written
151 * Write offset should never cross read offset
152 */
153 uint32_t buffer_write_offset;
154
155 uint32_t open_count;
156
157 char *log_buffer; /* Pointer to malloc'ed buffer */
158 uint32_t log_buffer_size; /* Size of circular buffer */
159
160 uint32_t mask; /*array of masks for major elements*/
161
162 union logger_flags flags;
163 struct dc_context *ctx;
164};
165
134#endif /* __DAL_LOGGER_TYPES_H__ */ 166#endif /* __DAL_LOGGER_TYPES_H__ */