summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie2017-10-23 03:17:54 +0200
committerDave Airlie2017-10-23 03:17:54 +0200
commitaf9111336071ee9378e1db70ac8f4c2b7fcd17a1 (patch)
tree1e60c1bd032ba2bcb2e1b1d0b611195e66314bd8 /drivers/gpu
parentMerge remote-tracking branch 'pfdo/drm-next' into drm-next (diff)
parentdrm/amd/display:: Fix NULL pointer in Raven hotplug (diff)
downloadkernel-qcow2-linux-af9111336071ee9378e1db70ac8f4c2b7fcd17a1.tar.gz
kernel-qcow2-linux-af9111336071ee9378e1db70ac8f4c2b7fcd17a1.tar.xz
kernel-qcow2-linux-af9111336071ee9378e1db70ac8f4c2b7fcd17a1.zip
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. ...
Diffstat (limited to 'drivers/gpu')
-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
by default. This includes Polaris, Carrizo, Tonga, Bonaire,
and Hawaii.
+config DRM_AMD_DC_FBC
+ bool "AMD FBC - Enable Frame Buffer Compression"
+ depends on DRM_AMD_DC
+ help
+ Choose this option if you want to use frame buffer compression
+ support.
+ This is a power optimisation feature, check its availability
+ on your hardware before enabling this option.
+
+
config DRM_AMD_DC_DCN1_0
bool "DCN 1.0 Raven family"
depends on DRM_AMD_DC && X86
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)
static int dm_late_init(void *handle)
{
struct drm_device *dev = ((struct amdgpu_device *)handle)->ddev;
- int r = detect_mst_link_for_all_connectors(dev);
- return r;
+ return detect_mst_link_for_all_connectors(dev);
}
static void s3_handle_mst(struct drm_device *dev, bool suspend)
@@ -599,10 +598,7 @@ static int dm_suspend(void *handle)
WARN_ON(adev->dm.cached_state);
adev->dm.cached_state = drm_atomic_helper_suspend(adev->ddev);
- dc_set_power_state(
- dm->dc,
- DC_ACPI_CM_POWER_STATE_D3
- );
+ dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
return ret;
}
@@ -632,10 +628,7 @@ static int dm_resume(void *handle)
struct amdgpu_display_manager *dm = &adev->dm;
/* power on hardware */
- dc_set_power_state(
- dm->dc,
- DC_ACPI_CM_POWER_STATE_D0
- );
+ dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
return 0;
}
@@ -648,6 +641,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
struct drm_connector *connector;
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state;
+ struct dm_crtc_state *dm_crtc_state;
+ struct drm_plane *plane;
+ struct drm_plane_state *plane_state;
+ struct dm_plane_state *dm_plane_state;
+ struct dm_atomic_state *cached_state;
int ret = 0;
int i;
@@ -686,6 +684,34 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i)
new_crtc_state->active_changed = true;
+ cached_state = to_dm_atomic_state(adev->dm.cached_state);
+
+ /*
+ * During suspend, the cached state is saved before all streams are
+ * disabled. Refresh cached state to match actual current state before
+ * restoring it.
+ */
+ WARN_ON(kref_read(&cached_state->context->refcount) > 1);
+ dc_release_state(cached_state->context);
+
+ for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) {
+ dm_crtc_state = to_dm_crtc_state(new_crtc_state);
+ if (dm_crtc_state->stream) {
+ WARN_ON(kref_read(&dm_crtc_state->stream->refcount) > 1);
+ dc_stream_release(dm_crtc_state->stream);
+ dm_crtc_state->stream = NULL;
+ }
+ }
+
+ for_each_new_plane_in_state(adev->dm.cached_state, plane, plane_state, i) {
+ dm_plane_state = to_dm_plane_state(plane_state);
+ if (dm_plane_state->dc_state) {
+ WARN_ON(kref_read(&dm_plane_state->dc_state->refcount) > 1);
+ dc_plane_state_release(dm_plane_state->dc_state);
+ dm_plane_state->dc_state = NULL;
+ }
+ }
+
ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);
drm_atomic_state_put(adev->dm.cached_state);
@@ -860,9 +886,9 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector)
connector);
aconnector->dc_sink = sink;
- if (sink->dc_edid.length == 0)
+ if (sink->dc_edid.length == 0) {
aconnector->edid = NULL;
- else {
+ } else {
aconnector->edid =
(struct edid *) sink->dc_edid.raw_edid;
@@ -980,8 +1006,9 @@ static void dm_handle_hpd_rx_irq(struct amdgpu_dm_connector *aconnector)
dpcd_bytes_to_read);
new_irq_handled = false;
- } else
+ } else {
break;
+ }
}
if (process_count == max_process_count)
@@ -993,20 +1020,20 @@ static void handle_hpd_rx_irq(void *param)
struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
- const struct dc_link *dc_link = aconnector->dc_link;
+ struct dc_link *dc_link = aconnector->dc_link;
bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
* conflict, after implement i2c helper, this mutex should be
* retired.
*/
- if (aconnector->dc_link->type != dc_connection_mst_branch)
+ if (dc_link->type != dc_connection_mst_branch)
mutex_lock(&aconnector->hpd_lock);
- if (dc_link_handle_hpd_rx_irq(aconnector->dc_link, NULL) &&
+ if (dc_link_handle_hpd_rx_irq(dc_link, NULL) &&
!is_mst_root_connector) {
/* Downstream Port status changed. */
- if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPDRX)) {
+ if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
amdgpu_dm_update_connector_after_detect(aconnector);
@@ -1018,10 +1045,10 @@ static void handle_hpd_rx_irq(void *param)
}
}
if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
- (dc_link->type == dc_connection_mst_branch))
+ (dc_link->type == dc_connection_mst_branch))
dm_handle_hpd_rx_irq(aconnector);
- if (aconnector->dc_link->type != dc_connection_mst_branch)
+ if (dc_link->type != dc_connection_mst_branch)
mutex_unlock(&aconnector->hpd_lock);
}
@@ -1381,9 +1408,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
goto fail_free_planes;
aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL);
- if (!aencoder) {
+ if (!aencoder)
goto fail_free_connector;
- }
if (amdgpu_dm_encoder_init(dm->ddev, aencoder, i)) {
DRM_ERROR("KMS: Failed to initialize encoder\n");
@@ -1754,7 +1780,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
int r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r)) {
- DRM_ERROR("Unable to reserve buffer\n");
+ // Don't show error msg. when return -ERESTARTSYS
+ if (r != -ERESTARTSYS)
+ DRM_ERROR("Unable to reserve buffer: %d\n", r);
return r;
}
@@ -2206,11 +2234,9 @@ static void fill_audio_info(struct audio_info *audio_info,
cea_revision = drm_connector->display_info.cea_rev;
- while (i < AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS &&
- edid_caps->display_name[i]) {
- audio_info->display_name[i] = edid_caps->display_name[i];
- i++;
- }
+ strncpy(audio_info->display_name,
+ edid_caps->display_name,
+ AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1);
if (cea_revision >= 3) {
audio_info->mode_count = edid_caps->audio_mode_count;
@@ -2318,8 +2344,16 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
drm_connector = &aconnector->base;
- if (!aconnector->dc_sink)
+ if (!aconnector->dc_sink) {
+ /*
+ * Exclude MST from creating fake_sink
+ * TODO: need to enable MST into fake_sink feature
+ */
+ if (aconnector->mst_port)
+ goto stream_create_fail;
+
create_fake_sink(aconnector);
+ }
stream = dc_create_stream_for_sink(aconnector->dc_sink);
@@ -2453,7 +2487,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
* 2. This interface *is called* in context of user-mode ioctl. Which
* makes it a bad place for *any* MST-related activit. */
- if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
+ if (aconnector->base.force == DRM_FORCE_UNSPECIFIED &&
+ !aconnector->fake_enable)
connected = (aconnector->dc_sink != NULL);
else
connected = (aconnector->base.force == DRM_FORCE_ON);
@@ -2681,8 +2716,7 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
(edid->extensions + 1) * EDID_LENGTH,
&init_params);
- if (aconnector->base.force
- == DRM_FORCE_ON)
+ if (aconnector->base.force == DRM_FORCE_ON)
aconnector->dc_sink = aconnector->dc_link->local_sink ?
aconnector->dc_link->local_sink :
aconnector->dc_em_sink;
@@ -2746,7 +2780,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
stream->src.height = mode->vdisplay;
stream->dst = stream->src;
- if (dc_validate_stream(adev->dm.dc, stream))
+ if (dc_validate_stream(adev->dm.dc, stream) == DC_OK)
result = MODE_OK;
dc_stream_release(stream);
@@ -2791,7 +2825,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
if (!dm_crtc_state->stream)
return 0;
- if (dc_validate_stream(dc, dm_crtc_state->stream))
+ if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)
return 0;
return ret;
@@ -2835,13 +2869,13 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
plane->funcs->atomic_destroy_state(plane, plane->state);
amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
-
+ WARN_ON(amdgpu_state == NULL);
+
if (amdgpu_state) {
plane->state = &amdgpu_state->base;
plane->state->plane = plane;
plane->state->rotation = DRM_MODE_ROTATE_0;
- } else
- WARN_ON(1);
+ }
}
static struct drm_plane_state *
@@ -2986,7 +3020,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
if (!dm_plane_state->dc_state)
return 0;
- if (dc_validate_plane(dc, dm_plane_state->dc_state))
+ if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
return 0;
return -EINVAL;
@@ -3272,8 +3306,9 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
drm_edid_to_eld(connector, edid);
amdgpu_dm_get_native_mode(connector);
- } else
+ } else {
amdgpu_dm_connector->num_modes = 0;
+ }
}
static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
@@ -3421,7 +3456,8 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
struct dc *dc = dm->dc;
struct dc_link *link = dc_get_link_at_index(dc, link_index);
struct amdgpu_i2c_adapter *i2c;
- ((struct dc_link *)link)->priv = aconnector;
+
+ link->priv = aconnector;
DRM_DEBUG_DRIVER("%s()\n", __func__);
@@ -3661,10 +3697,10 @@ static void handle_cursor_update(struct drm_plane *plane,
return;
DRM_DEBUG_DRIVER("%s: crtc_id=%d with size %d to %d\n",
- __func__,
- amdgpu_crtc->crtc_id,
- plane->state->crtc_w,
- plane->state->crtc_h);
+ __func__,
+ amdgpu_crtc->crtc_id,
+ plane->state->crtc_w,
+ plane->state->crtc_h);
ret = get_cursor_position(plane, crtc, &position);
if (ret)
@@ -3691,14 +3727,15 @@ static void handle_cursor_update(struct drm_plane *plane,
attributes.pitch = attributes.width;
- if (!dc_stream_set_cursor_attributes(crtc_state->stream,
- &attributes))
- DRM_ERROR("DC failed to set cursor attributes\n");
+ if (crtc_state->stream) {
+ if (!dc_stream_set_cursor_attributes(crtc_state->stream,
+ &attributes))
+ DRM_ERROR("DC failed to set cursor attributes\n");
- if (crtc_state->stream)
if (!dc_stream_set_cursor_position(crtc_state->stream,
&position))
DRM_ERROR("DC failed to set cursor position\n");
+ }
}
static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
@@ -3726,7 +3763,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
*/
static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
- uint32_t target)
+ uint32_t target,
+ struct dc_state *state)
{
unsigned long flags;
uint32_t target_vblank;
@@ -3797,7 +3835,13 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
surface_updates->flip_addr = &addr;
- dc_update_planes_and_stream(adev->dm.dc, surface_updates, 1, acrtc_state->stream, NULL);
+ dc_commit_updates_for_stream(adev->dm.dc,
+ surface_updates,
+ 1,
+ acrtc_state->stream,
+ NULL,
+ &surface_updates->surface,
+ state);
DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
__func__,
@@ -3823,6 +3867,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
struct drm_crtc_state *new_pcrtc_state =
drm_atomic_get_new_crtc_state(state, pcrtc);
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
+ struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
int planes_count = 0;
unsigned long flags;
@@ -3880,7 +3925,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
amdgpu_dm_do_flip(
crtc,
fb,
- drm_crtc_vblank_count(crtc) + *wait_for_vblank);
+ drm_crtc_vblank_count(crtc) + *wait_for_vblank,
+ dm_state->context);
}
}
@@ -3900,7 +3946,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
if (false == dc_commit_planes_to_stream(dm->dc,
plane_states_constructed,
planes_count,
- dc_stream_attach))
+ dc_stream_attach,
+ dm_state->context))
dm_error("%s: Failed to attach plane!\n", __func__);
} else {
/*TODO BUG Here should go disable planes on CRTC. */
@@ -3931,6 +3978,8 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev,
if (drm_atomic_crtc_needs_modeset(new_crtc_state) && dm_old_crtc_state->stream)
manage_dm_interrupts(adev, acrtc, false);
}
+ /* Add check here for SoC's that support hardware cursor plane, to
+ * unset legacy_cursor_update */
return drm_atomic_helper_commit(dev, state, nonblock);
@@ -4120,7 +4169,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
dm->dc,
status->plane_states,
status->plane_count,
- dm_new_crtc_state->stream))
+ dm_new_crtc_state->stream,
+ dm_state->context))
dm_error("%s: Failed to update stream scaling!\n", __func__);
}
@@ -4339,7 +4389,8 @@ static int dm_update_crtcs_state(struct dc *dc,
aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
/* TODO This hack should go away */
- if (aconnector) {
+ if (aconnector && enable) {
+ // Make sure fake sink is created in plug-in scenario
new_con_state = drm_atomic_get_connector_state(state,
&aconnector->base);
@@ -4368,12 +4419,13 @@ static int dm_update_crtcs_state(struct dc *dc,
}
}
- if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream)) {
+ if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
+ dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
new_crtc_state->mode_changed = false;
DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d",
- new_crtc_state->mode_changed);
+ new_crtc_state->mode_changed);
}
@@ -4402,10 +4454,10 @@ static int dm_update_crtcs_state(struct dc *dc,
crtc->base.id);
/* i.e. reset mode */
- if (!dc_remove_stream_from_ctx(
+ if (dc_remove_stream_from_ctx(
dc,
dm_state->context,
- dm_old_crtc_state->stream)) {
+ dm_old_crtc_state->stream) != DC_OK) {
ret = -EINVAL;
goto fail;
}
@@ -4416,6 +4468,13 @@ static int dm_update_crtcs_state(struct dc *dc,
*lock_and_validation_needed = true;
} else {/* Add stream for any updated/enabled CRTC */
+ /*
+ * Quick fix to prevent NULL pointer on new_stream when
+ * added MST connectors not found in existing crtc_state in the chained mode
+ * TODO: need to dig out the root cause of that
+ */
+ if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port))
+ goto next_crtc;
if (modereset_required(new_crtc_state))
goto next_crtc;
@@ -4431,10 +4490,10 @@ static int dm_update_crtcs_state(struct dc *dc,
DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n",
crtc->base.id);
- if (!dc_add_stream_to_ctx(
+ if (dc_add_stream_to_ctx(
dc,
dm_state->context,
- dm_new_crtc_state->stream)) {
+ dm_new_crtc_state->stream) != DC_OK) {
ret = -EINVAL;
goto fail;
}
@@ -4586,7 +4645,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
struct drm_connector *connector;
struct drm_connector_state *old_con_state, *new_con_state;
struct drm_crtc *crtc;
- struct drm_crtc_state *new_crtc_state;
+ struct drm_crtc_state *old_crtc_state, *new_crtc_state;
/*
* This bool will be set for true for any modeset/reset
@@ -4595,18 +4654,34 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
bool lock_and_validation_needed = false;
ret = drm_atomic_helper_check_modeset(dev, state);
-
if (ret) {
DRM_ERROR("Atomic state validation failed with error :%d !\n", ret);
return ret;
}
/*
- * Hack: Commit needs planes right now, specifically for gamma
- * TODO rework commit to check CRTC for gamma change
+ * legacy_cursor_update should be made false for SoC's having
+ * a dedicated hardware plane for cursor in amdgpu_dm_atomic_commit(),
+ * otherwise for software cursor plane,
+ * we should not add it to list of affected planes.
*/
- for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
- if (new_crtc_state->color_mgmt_changed) {
+ if (state->legacy_cursor_update) {
+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+ if (new_crtc_state->color_mgmt_changed) {
+ ret = drm_atomic_add_affected_planes(state, crtc);
+ if (ret)
+ goto fail;
+ }
+ }
+ } else {
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ if (!new_crtc_state->enable)
+ continue;
+
+ ret = drm_atomic_add_affected_connectors(state, crtc);
+ if (ret)
+ return ret;
+
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
goto fail;
@@ -4684,7 +4759,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
- if (!dc_validate_global_state(dc, dm_state->context)) {
+ if (dc_validate_global_state(dc, dm_state->context) != DC_OK) {
ret = -EINVAL;
goto fail;
}
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,
DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
}
- if (handler_in == NULL) {
- /* Remove ALL handlers. */
+ /* Remove ALL handlers. */
+ if (handler_in == NULL)
continue;
- }
- if (handler_in == handler_temp) {
- /* Remove a SPECIFIC handler.
- * Found our handler - we can stop here. */
+ /* Remove a SPECIFIC handler.
+ * Found our handler - we can stop here. */
+ if (handler_in == handler_temp)
break;
- }
}
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
- if (handler_in != NULL && handler_removed == false) {
+ if (handler_in != NULL && handler_removed == false)
DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
handler_in);
- }
}
static bool
@@ -435,7 +432,7 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
* Disable HW interrupt for HPD and HPDRX only since FLIP and VBLANK
* will be disabled from manage_dm_interrupts on disable CRTC.
*/
- for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6RX; src++) {
+ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
@@ -462,7 +459,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
DRM_DEBUG_KMS("DM_IRQ: early resume\n");
/* re-enable short pulse interrupts HW interrupt */
- for (src = DC_IRQ_SOURCE_HPD1RX; src < DC_IRQ_SOURCE_HPD6RX + 1; src++) {
+ for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
@@ -488,7 +485,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev)
* Renable HW interrupt for HPD and only since FLIP and VBLANK
* will be enabled from manage_dm_interrupts on enable CRTC.
*/
- for (src = DC_IRQ_SOURCE_HPD1; src < DC_IRQ_SOURCE_HPD6; src++) {
+ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) {
hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head;
hnd_list_h = &adev->dm.irq_handler_list_high_tab[src];
if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h))
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 = {
.atomic_get_property = amdgpu_dm_connector_atomic_get_property
};
+static int dm_connector_update_modes(struct drm_connector *connector,
+ struct edid *edid)
+{
+ int ret;
+
+ ret = drm_add_edid_modes(connector, edid);
+ drm_edid_to_eld(connector, edid);
+
+ return ret;
+}
+
static int dm_dp_mst_get_modes(struct drm_connector *connector)
{
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
int ret = 0;
- ret = drm_add_edid_modes(&aconnector->base, aconnector->edid);
+ if (!aconnector)
+ return dm_connector_update_modes(connector, NULL);
+
+ if (!aconnector->edid) {
+ struct edid *edid;
+ struct dc_sink *dc_sink;
+ struct dc_sink_init_data init_params = {
+ .link = aconnector->dc_link,
+ .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
+ edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
- drm_edid_to_eld(&aconnector->base, aconnector->edid);
+ if (!edid) {
+ drm_mode_connector_update_edid_property(
+ &aconnector->base,
+ NULL);
+ return ret;
+ }
+
+ aconnector->edid = edid;
+
+ dc_sink = dc_link_add_remote_sink(
+ aconnector->dc_link,
+ (uint8_t *)edid,
+ (edid->extensions + 1) * EDID_LENGTH,
+ &init_params);
+
+ dc_sink->priv = aconnector;
+ aconnector->dc_sink = dc_sink;
+
+ if (aconnector->dc_sink)
+ amdgpu_dm_add_sink_to_freesync_module(
+ connector, edid);
+
+ drm_mode_connector_update_edid_property(
+ &aconnector->base, edid);
+ }
+
+ ret = dm_connector_update_modes(connector, aconnector->edid);
return ret;
}
@@ -241,9 +287,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
- drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ drm_connector_list_iter_begin(dev, &conn_iter);
+ drm_for_each_connector_iter(connector, &conn_iter) {
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->mst_port == master
&& !aconnector->port) {
@@ -253,11 +300,11 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
aconnector->port = port;
drm_mode_connector_set_path_property(connector, pathprop);
- drm_modeset_unlock(&dev->mode_config.connection_mutex);
+ drm_connector_list_iter_end(&conn_iter);
return &aconnector->base;
}
}
- drm_modeset_unlock(&dev->mode_config.connection_mutex);
+ drm_connector_list_iter_end(&conn_iter);
aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
if (!aconnector)
@@ -343,92 +390,20 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
{
struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
struct drm_device *dev = master->base.dev;
- struct amdgpu_device *adev = dev->dev_private;
- struct drm_connector *connector;
- struct amdgpu_dm_connector *aconnector;
- struct edid *edid;
- struct dc_sink *dc_sink;
-
- drm_modeset_lock_all(dev);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- aconnector = to_amdgpu_dm_connector(connector);
- if (aconnector->port &&
- aconnector->port->pdt != DP_PEER_DEVICE_NONE &&
- aconnector->port->pdt != DP_PEER_DEVICE_MST_BRANCHING &&
- !aconnector->dc_sink) {
- /*
- * This is plug in case, where port has been created but
- * sink hasn't been created yet
- */
- if (!aconnector->edid) {
- struct dc_sink_init_data init_params = {
- .link = aconnector->dc_link,
- .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST};
- edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
-
- if (!edid) {
- drm_mode_connector_update_edid_property(
- &aconnector->base,
- NULL);
- continue;
- }
-
- aconnector->edid = edid;
-
- dc_sink = dc_link_add_remote_sink(
- aconnector->dc_link,
- (uint8_t *)edid,
- (edid->extensions + 1) * EDID_LENGTH,
- &init_params);
-
- dc_sink->priv = aconnector;
- aconnector->dc_sink = dc_sink;
-
- if (aconnector->dc_sink)
- amdgpu_dm_add_sink_to_freesync_module(
- connector,
- edid);
-
- dm_restore_drm_connector_state(connector->dev, connector);
- } else
- edid = aconnector->edid;
-
- DRM_DEBUG_KMS("edid retrieved %p\n", edid);
- drm_mode_connector_update_edid_property(
- &aconnector->base,
- aconnector->edid);
- }
- }
- drm_modeset_unlock_all(dev);
-
- schedule_work(&adev->dm.mst_hotplug_work);
+ drm_kms_helper_hotplug_event(dev);
}
static void dm_dp_mst_register_connector(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = dev->dev_private;
- int i;
-
- drm_modeset_lock_all(dev);
- if (adev->mode_info.rfbdev) {
- /*Do not add if already registered in past*/
- for (i = 0; i < adev->mode_info.rfbdev->helper.connector_count; i++) {
- if (adev->mode_info.rfbdev->helper.connector_info[i]->connector
- == connector) {
- drm_modeset_unlock_all(dev);
- return;
- }
- }
+ if (adev->mode_info.rfbdev)
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
- }
else
DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
- drm_modeset_unlock_all(dev);
-
drm_connector_register(connector);
}
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 @@
#include "amdgpu_dm_irq.h"
#include "amdgpu_pm.h"
+unsigned long long dm_get_timestamp(struct dc_context *ctx)
+{
+ /* TODO: return actual timestamp */
+ return 0;
+}
+
bool dm_write_persistent_data(struct dc_context *ctx,
const struct dc_sink *sink,
const char *module_name,
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,
logger->buffer_read_offset = 0;
logger->buffer_write_offset = 0;
- logger->write_wrap_count = 0;
- logger->read_wrap_count = 0;
logger->open_count = 0;
logger->flags.bits.ENABLE_CONSOLE = 1;
@@ -162,23 +160,24 @@ static void log_to_debug_console(struct log_entry *entry)
}
/* Print everything unread existing in log_buffer to debug console*/
-static void flush_to_debug_console(struct dal_logger *logger)
+void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn)
{
- int i = logger->buffer_read_offset;
- char *string_start = &logger->log_buffer[i];
+ char *string_start = &logger->log_buffer[logger->buffer_read_offset];
- dm_output_to_console(
- "---------------- FLUSHING LOG BUFFER ----------------\n");
- while (i < logger->buffer_write_offset) {
+ if (should_warn)
+ dm_output_to_console(
+ "---------------- FLUSHING LOG BUFFER ----------------\n");
+ while (logger->buffer_read_offset < logger->buffer_write_offset) {
- if (logger->log_buffer[i] == '\0') {
+ if (logger->log_buffer[logger->buffer_read_offset] == '\0') {
dm_output_to_console("%s", string_start);
- string_start = (char *)logger->log_buffer + i + 1;
+ string_start = logger->log_buffer + logger->buffer_read_offset + 1;
}
- i++;
+ logger->buffer_read_offset++;
}
- dm_output_to_console(
- "-------------- END FLUSHING LOG BUFFER --------------\n\n");
+ if (should_warn)
+ dm_output_to_console(
+ "-------------- END FLUSHING LOG BUFFER --------------\n\n");
}
static void log_to_internal_buffer(struct log_entry *entry)
@@ -195,35 +194,17 @@ static void log_to_internal_buffer(struct log_entry *entry)
if (size > 0 && size < logger->log_buffer_size) {
- int total_free_space = 0;
- int space_before_wrap = 0;
-
- if (logger->buffer_write_offset > logger->buffer_read_offset) {
- total_free_space = logger->log_buffer_size -
- logger->buffer_write_offset +
- logger->buffer_read_offset;
- space_before_wrap = logger->log_buffer_size -
- logger->buffer_write_offset;
- } else if (logger->buffer_write_offset <
- logger->buffer_read_offset) {
- total_free_space = logger->log_buffer_size -
- logger->buffer_read_offset +
- logger->buffer_write_offset;
- space_before_wrap = total_free_space;
- } else if (logger->write_wrap_count !=
- logger->read_wrap_count) {
- /* Buffer is completely full already */
- total_free_space = 0;
- space_before_wrap = 0;
- } else {
+ int buffer_space = logger->log_buffer_size -
+ logger->buffer_write_offset;
+
+ if (logger->buffer_write_offset == logger->buffer_read_offset) {
/* Buffer is empty, start writing at beginning */
- total_free_space = logger->log_buffer_size;
- space_before_wrap = logger->log_buffer_size;
+ buffer_space = logger->log_buffer_size;
logger->buffer_write_offset = 0;
logger->buffer_read_offset = 0;
}
- if (space_before_wrap > size) {
+ if (buffer_space > size) {
/* No wrap around, copy 'size' bytes
* from 'entry->buf' to 'log_buffer'
*/
@@ -232,28 +213,12 @@ static void log_to_internal_buffer(struct log_entry *entry)
entry->buf, size);
logger->buffer_write_offset += size;
- } else if (total_free_space > size) {
- /* We have enough room without flushing,
- * but need to wrap around */
-
- int space_after_wrap = total_free_space -
- space_before_wrap;
-
- memmove(logger->log_buffer +
- logger->buffer_write_offset,
- entry->buf, space_before_wrap);
- memmove(logger->log_buffer, entry->buf +
- space_before_wrap, space_after_wrap);
-
- logger->buffer_write_offset = space_after_wrap;
- logger->write_wrap_count++;
-
} else {
/* Not enough room remaining, we should flush
* existing logs */
/* Flush existing unread logs to console */
- flush_to_debug_console(logger);
+ dm_logger_flush_buffer(logger, true);
/* Start writing to beginning of buffer */
memmove(logger->log_buffer, entry->buf, size);
@@ -325,9 +290,10 @@ void dm_logger_write(
log_heading(&entry);
size = dm_log_to_buffer(
- buffer, LOG_MAX_LINE_SIZE, msg, args);
+ buffer, LOG_MAX_LINE_SIZE - 1, msg, args);
- entry.buf_offset += size;
+ buffer[entry.buf_offset + size] = '\0';
+ entry.buf_offset += size + 1;
/* --Flush log_entry buffer-- */
/* print to kernel console */
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 @@
#ifndef __DAL_LOGGER_H__
#define __DAL_LOGGER_H__
-/* Structure for keeping track of offsets, buffer, etc */
-
-#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
-
-/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
- * change log line size to 896 to meet the request.
- */
-#define LOG_MAX_LINE_SIZE 896
-
-#include "include/logger_types.h"
-
-struct dal_logger {
-
- /* How far into the circular buffer has been read by dsat
- * Read offset should never cross write offset. Write \0's to
- * read data just to be sure?
- */
- uint32_t buffer_read_offset;
-
- /* How far into the circular buffer we have written
- * Write offset should never cross read offset
- */
- uint32_t buffer_write_offset;
-
- uint32_t write_wrap_count;
- uint32_t read_wrap_count;
-
- uint32_t open_count;
-
- char *log_buffer; /* Pointer to malloc'ed buffer */
- uint32_t log_buffer_size; /* Size of circular buffer */
-
- uint32_t mask; /*array of masks for major elements*/
-
- union logger_flags flags;
- struct dc_context *ctx;
-};
#endif /* __DAL_LOGGER_H__ */
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(
info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
info->lcd_timing.misc_info.H_REPLICATION_BY2 =
- lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2;
+ !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
info->lcd_timing.misc_info.V_REPLICATION_BY2 =
- lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2;
+ !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
info->lcd_timing.misc_info.COMPOSITE_SYNC =
- lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC;
+ !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
info->lcd_timing.misc_info.INTERLACE =
- lvds->lcd_timing.miscinfo & ATOM_INTERLACE;
+ !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
/* not provided by VBIOS*/
info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
@@ -1056,7 +1056,7 @@ static enum bp_result get_embedded_panel_info_v2_1(
info->ss_id = 0;
info->realtek_eDPToLVDS =
- (lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0);
+ !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
return BP_RESULT_OK;
}
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 @@
CFLAGS_dcn_calcs.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dcn_calc_auto.o := -mhard-float -msse -mpreferred-stack-boundary=4
-CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_dcn_calc_math.o := -mhard-float -msse -mpreferred-stack-boundary=4 -Wno-tautological-compare
BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
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 @@
#include "dcn_calc_math.h"
+float dcn_bw_mod(const float arg1, const float arg2)
+{
+ if (arg1 != arg1)
+ return arg2;
+ if (arg2 != arg2)
+ return arg1;
+ return arg1 - arg1 * ((int) (arg1 / arg2));
+}
+
+float dcn_bw_min2(const float arg1, const float arg2)
+{
+ if (arg1 != arg1)
+ return arg2;
+ if (arg2 != arg2)
+ return arg1;
+ return arg1 < arg2 ? arg1 : arg2;
+}
+
+unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
+{
+ if (arg1 != arg1)
+ return arg2;
+ if (arg2 != arg2)
+ return arg1;
+ return arg1 > arg2 ? arg1 : arg2;
+}
+float dcn_bw_max2(const float arg1, const float arg2)
+{
+ if (arg1 != arg1)
+ return arg2;
+ if (arg2 != arg2)
+ return arg1;
+ return arg1 > arg2 ? arg1 : arg2;
+}
+
float dcn_bw_floor2(const float arg, const float significance)
{
if (significance == 0)
@@ -40,6 +75,16 @@ float dcn_bw_ceil2(const float arg, const float significance)
return flr + 0.00001 >= arg ? arg : flr + significance;
}
+float dcn_bw_max3(float v1, float v2, float v3)
+{
+ return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
+}
+
+float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
+{
+ return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
+}
+
float dcn_bw_pow(float a, float exp)
{
float temp;
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 @@
#ifndef _DCN_CALC_MATH_H_
#define _DCN_CALC_MATH_H_
-static inline float dcn_bw_mod(const float arg1, const float arg2)
-{
- return arg1 - arg1 * ((int) (arg1 / arg2));
-}
-
-static inline float dcn_bw_min2(const float arg1, const float arg2)
-{
- return arg1 < arg2 ? arg1 : arg2;
-}
-
-static inline unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2)
-{
- return arg1 > arg2 ? arg1 : arg2;
-}
-
-static inline float dcn_bw_max2(const float arg1, const float arg2)
-{
- return arg1 > arg2 ? arg1 : arg2;
-}
-
-static inline float dcn_bw_max3(float v1, float v2, float v3)
-{
- return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2);
-}
-
-static inline float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5)
-{
- return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5);
-}
-
+float dcn_bw_mod(const float arg1, const float arg2);
+float dcn_bw_min2(const float arg1, const float arg2);
+unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2);
+float dcn_bw_max2(const float arg1, const float arg2);
float dcn_bw_floor2(const float arg, const float significance);
float dcn_bw_ceil2(const float arg, const float significance);
+float dcn_bw_max3(float v1, float v2, float v3);
+float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5);
float dcn_bw_pow(float a, float exp);
float dcn_bw_log(float a, float b);
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 (
}
- input->dest.vactive = pipe->stream->timing.v_addressable;
+ input->dest.vactive = pipe->stream->timing.v_addressable + pipe->stream->timing.v_border_top
+ + pipe->stream->timing.v_border_bottom;
input->dest.recout_width = pipe->plane_res.scl_data.recout.width;
input->dest.recout_height = pipe->plane_res.scl_data.recout.height;
@@ -385,10 +386,6 @@ static void pipe_ctx_to_e2e_pipe_params (
- pipe->stream->timing.v_addressable
- pipe->stream->timing.v_border_bottom
- pipe->stream->timing.v_border_top;
-
- input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total
- - pipe->stream->timing.v_addressable
- - pipe->stream->timing.v_front_porch;
input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0;
input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start;
input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset;
@@ -458,9 +455,9 @@ static void dcn_bw_calc_rq_dlg_ttu(
/*todo: soc->sr_enter_plus_exit_time??*/
dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
- dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
- extract_rq_regs(dml, rq_regs, rq_param);
- dml_rq_dlg_get_dlg_params(
+ dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
+ dml1_extract_rq_regs(dml, rq_regs, rq_param);
+ dml1_rq_dlg_get_dlg_params(
dml,
dlg_regs,
ttu_regs,
@@ -473,96 +470,6 @@ static void dcn_bw_calc_rq_dlg_ttu(
pipe->plane_state->flip_immediate);
}
-static void dcn_dml_wm_override(
- const struct dcn_bw_internal_vars *v,
- struct display_mode_lib *dml,
- struct dc_state *context,
- const struct resource_pool *pool)
-{
- int i, in_idx, active_count;
-
- struct _vcs_dpi_display_e2e_pipe_params_st *input = kzalloc(pool->pipe_count * sizeof(struct _vcs_dpi_display_e2e_pipe_params_st),
- GFP_KERNEL);
- struct wm {
- double urgent;
- struct _vcs_dpi_cstate_pstate_watermarks_st cpstate;
- double pte_meta_urgent;
- } a;
-
-
- for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
- struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
- if (!pipe->stream || !pipe->plane_state)
- continue;
-
- input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk;
- input[in_idx].clks_cfg.dispclk_mhz = v->dispclk;
- input[in_idx].clks_cfg.dppclk_mhz = v->dppclk;
- input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000;
- input[in_idx].clks_cfg.socclk_mhz = v->socclk;
- input[in_idx].clks_cfg.voltage = v->voltage_level;
- input[in_idx].dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
- input[in_idx].dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
- //input[in_idx].dout.output_standard;
- switch (v->output_deep_color[in_idx]) {
- case dcn_bw_encoder_12bpc:
- input[in_idx].dout.output_bpc = dm_out_12;
- break;
- case dcn_bw_encoder_10bpc:
- input[in_idx].dout.output_bpc = dm_out_10;
- break;
- case dcn_bw_encoder_8bpc:
- default:
- input[in_idx].dout.output_bpc = dm_out_8;
- break;
- }
- pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe);
- dml_rq_dlg_get_rq_reg(
- dml,
- &pipe->rq_regs,
- input[in_idx].pipe.src);
- in_idx++;
- }
- active_count = in_idx;
-
- a.urgent = dml_wm_urgent_e2e(dml, input, active_count);
- a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count);
- a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent);
-
- context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns =
- a.cpstate.cstate_exit_us * 1000;
- context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
- a.cpstate.cstate_enter_plus_exit_us * 1000;
- context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns =
- a.cpstate.pstate_change_us * 1000;
- context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000;
- context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000;
- context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a;
- context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a;
- context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a;
-
-
- for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
- struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
-
- if (!pipe->stream || !pipe->plane_state)
- continue;
-
- dml_rq_dlg_get_dlg_reg(dml,
- &pipe->dlg_regs,
- &pipe->ttu_regs,
- input, active_count,
- in_idx,
- true,
- true,
- v->pte_enable == dcn_bw_yes,
- pipe->plane_state->flip_immediate);
- in_idx++;
- }
- kfree(input);
-}
-
static void split_stream_across_pipes(
struct resource_context *res_ctx,
const struct resource_pool *pool,
@@ -578,8 +485,10 @@ static void split_stream_across_pipes(
secondary_pipe->pipe_idx = pipe_idx;
secondary_pipe->plane_res.mi = pool->mis[secondary_pipe->pipe_idx];
+ secondary_pipe->plane_res.hubp = pool->hubps[secondary_pipe->pipe_idx];
secondary_pipe->plane_res.ipp = pool->ipps[secondary_pipe->pipe_idx];
secondary_pipe->plane_res.xfm = pool->transforms[secondary_pipe->pipe_idx];
+ secondary_pipe->plane_res.dpp = pool->dpps[secondary_pipe->pipe_idx];
if (primary_pipe->bottom_pipe) {
ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
@@ -719,6 +628,49 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
return updated;
}
+void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
+{
+ /*
+ * disable optional pipe split by lower dispclk bounding box
+ * at DPM0
+ */
+ v->max_dispclk[0] = v->max_dppclk_vmin0p65;
+}
+
+void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
+ unsigned int pixel_rate_khz)
+{
+ float pixel_rate_mhz = pixel_rate_khz / 1000;
+
+ /*
+ * force enabling pipe split by lower dpp clock for DPM0 to just
+ * below the specify pixel_rate, so bw calc would split pipe.
+ */
+ if (pixel_rate_mhz < v->max_dppclk[0])
+ v->max_dppclk[0] = pixel_rate_mhz;
+}
+
+void hack_bounding_box(struct dcn_bw_internal_vars *v,
+ struct dc_debug *dbg,
+ struct dc_state *context)
+{
+ if (dbg->pipe_split_policy == MPC_SPLIT_AVOID) {
+ hack_disable_optional_pipe_split(v);
+ }
+
+ if (dbg->pipe_split_policy == MPC_SPLIT_AVOID_MULT_DISP &&
+ context->stream_count >= 2) {
+ hack_disable_optional_pipe_split(v);
+ }
+
+ if (context->stream_count == 1 &&
+ dbg->force_single_disp_pipe_split) {
+ struct dc_stream_state *stream0 = context->streams[0];
+
+ hack_force_pipe_split(v, stream0->timing.pix_clk_khz);
+ }
+}
+
bool dcn_validate_bandwidth(
struct dc *dc,
struct dc_state *context)
@@ -730,6 +682,7 @@ bool dcn_validate_bandwidth(
bool bw_limit_pass;
float bw_limit;
+ PERFORMANCE_TRACE_START();
if (dcn_bw_apply_registry_override(dc))
dcn_bw_sync_calcs_and_dml(dc);
@@ -850,9 +803,7 @@ bool dcn_validate_bandwidth(
v->phyclk_per_state[1] = v->phyclkv_mid0p72;
v->phyclk_per_state[0] = v->phyclkv_min0p65;
- if (dc->debug.disable_pipe_split) {
- v->max_dispclk[0] = v->max_dppclk_vmin0p65;
- }
+ hack_bounding_box(v, &dc->debug, context);
if (v->voltage_override == dcn_bw_v_max0p9) {
v->voltage_override_level = number_of_states - 1;
@@ -882,10 +833,11 @@ bool dcn_validate_bandwidth(
v->htotal[input_idx] = pipe->stream->timing.h_total;
v->vtotal[input_idx] = pipe->stream->timing.v_total;
+ v->vactive[input_idx] = pipe->stream->timing.v_addressable +
+ pipe->stream->timing.v_border_top + pipe->stream->timing.v_border_bottom;
v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total
- - pipe->stream->timing.v_addressable
+ - v->vactive[input_idx]
- pipe->stream->timing.v_front_porch;
- v->vactive[input_idx] = pipe->stream->timing.v_addressable;
v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f;
if (!pipe->plane_state) {
@@ -1006,6 +958,10 @@ bool dcn_validate_bandwidth(
else
bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9;
+ if (bw_consumed < v->fabric_and_dram_bandwidth)
+ if (dc->debug.voltage_align_fclk)
+ bw_consumed = v->fabric_and_dram_bandwidth;
+
display_pipe_configuration(v);
calc_wm_sets_and_perf_params(context, v);
context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 /
@@ -1018,9 +974,17 @@ bool dcn_validate_bandwidth(
context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin);
context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000);
context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000);
+
context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000);
if (dc->debug.max_disp_clk == true)
context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000);
+
+ if (context->bw.dcn.calc_clk.dispclk_khz <
+ dc->debug.min_disp_clk_khz) {
+ context->bw.dcn.calc_clk.dispclk_khz =
+ dc->debug.min_disp_clk_khz;
+ }
+
context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2;
for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
@@ -1108,9 +1072,6 @@ bool dcn_validate_bandwidth(
input_idx++;
}
- if (dc->debug.use_dml_wm)
- dcn_dml_wm_override(v, (struct display_mode_lib *)
- &dc->dml, context, pool);
}
if (v->voltage_level == 0) {
@@ -1129,6 +1090,8 @@ bool dcn_validate_bandwidth(
kernel_fpu_end();
+ PERFORMANCE_TRACE_END();
+
if (bw_limit_pass && v->voltage_level != 5)
return true;
else
@@ -1263,7 +1226,7 @@ unsigned int dcn_find_dcfclk_suits_all(
else
dcf_clk = dc->dcn_soc->dcfclkv_min0p65*1000;
- dm_logger_write(dc->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
"\tdcf_clk for voltage = %d\n", dcf_clk);
return dcf_clk;
}
@@ -1386,6 +1349,53 @@ void dcn_bw_notify_pplib_of_wm_ranges(struct dc *dc)
ranges.writer_wm_sets[3].min_drain_clk_khz = max_fclk_khz;
ranges.writer_wm_sets[3].max_drain_clk_khz = max_fclk_khz;
+ if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) {
+ ranges.reader_wm_sets[0].wm_inst = WM_A;
+ ranges.reader_wm_sets[0].min_drain_clk_khz = 300000;
+ ranges.reader_wm_sets[0].max_drain_clk_khz = 654000;
+ ranges.reader_wm_sets[0].min_fill_clk_khz = 800000;
+ ranges.reader_wm_sets[0].max_fill_clk_khz = 800000;
+ ranges.writer_wm_sets[0].wm_inst = WM_A;
+ ranges.writer_wm_sets[0].min_fill_clk_khz = 200000;
+ ranges.writer_wm_sets[0].max_fill_clk_khz = 757000;
+ ranges.writer_wm_sets[0].min_drain_clk_khz = 800000;
+ ranges.writer_wm_sets[0].max_drain_clk_khz = 800000;
+
+ ranges.reader_wm_sets[1].wm_inst = WM_B;
+ ranges.reader_wm_sets[1].min_drain_clk_khz = 300000;
+ ranges.reader_wm_sets[1].max_drain_clk_khz = 654000;
+ ranges.reader_wm_sets[1].min_fill_clk_khz = 933000;
+ ranges.reader_wm_sets[1].max_fill_clk_khz = 933000;
+ ranges.writer_wm_sets[1].wm_inst = WM_B;
+ ranges.writer_wm_sets[1].min_fill_clk_khz = 200000;
+ ranges.writer_wm_sets[1].max_fill_clk_khz = 757000;
+ ranges.writer_wm_sets[1].min_drain_clk_khz = 933000;
+ ranges.writer_wm_sets[1].max_drain_clk_khz = 933000;
+
+
+ ranges.reader_wm_sets[2].wm_inst = WM_C;
+ ranges.reader_wm_sets[2].min_drain_clk_khz = 300000;
+ ranges.reader_wm_sets[2].max_drain_clk_khz = 654000;
+ ranges.reader_wm_sets[2].min_fill_clk_khz = 1067000;
+ ranges.reader_wm_sets[2].max_fill_clk_khz = 1067000;
+ ranges.writer_wm_sets[2].wm_inst = WM_C;
+ ranges.writer_wm_sets[2].min_fill_clk_khz = 200000;
+ ranges.writer_wm_sets[2].max_fill_clk_khz = 757000;
+ ranges.writer_wm_sets[2].min_drain_clk_khz = 1067000;
+ ranges.writer_wm_sets[2].max_drain_clk_khz = 1067000;
+
+ ranges.reader_wm_sets[3].wm_inst = WM_D;
+ ranges.reader_wm_sets[3].min_drain_clk_khz = 300000;
+ ranges.reader_wm_sets[3].max_drain_clk_khz = 654000;
+ ranges.reader_wm_sets[3].min_fill_clk_khz = 1200000;
+ ranges.reader_wm_sets[3].max_fill_clk_khz = 1200000;
+ ranges.writer_wm_sets[3].wm_inst = WM_D;
+ ranges.writer_wm_sets[3].min_fill_clk_khz = 200000;
+ ranges.writer_wm_sets[3].max_fill_clk_khz = 757000;
+ ranges.writer_wm_sets[3].min_drain_clk_khz = 1200000;
+ ranges.writer_wm_sets[3].max_drain_clk_khz = 1200000;
+ }
+
/* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
pp->set_wm_ranges(&pp->pp_smu, &ranges);
}
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 @@
#include "bios_parser_interface.h"
#include "include/irq_service_interface.h"
#include "transform.h"
+#include "dpp.h"
#include "timing_generator.h"
#include "virtual/virtual_link_encoder.h"
@@ -47,6 +48,7 @@
#include "dc_link_ddc.h"
#include "dm_helpers.h"
#include "mem_input.h"
+#include "hubp.h"
/*******************************************************************************
@@ -332,10 +334,19 @@ static void set_dither_option(struct dc_stream_state *stream,
{
struct bit_depth_reduction_params params;
struct dc_link *link = stream->status.link;
- struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
+ struct pipe_ctx *pipes = NULL;
+ int i;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
+ stream) {
+ pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
+ break;
+ }
+ }
memset(&params, 0, sizeof(params));
- if (!stream)
+ if (!pipes)
return;
if (option > DITHER_OPTION_MAX)
return;
@@ -349,6 +360,36 @@ static void set_dither_option(struct dc_stream_state *stream,
opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
}
+void set_dpms(
+ struct dc *dc,
+ struct dc_stream_state *stream,
+ bool dpms_off)
+{
+ struct pipe_ctx *pipe_ctx = NULL;
+ int i;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
+ pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+ break;
+ }
+ }
+
+ if (!pipe_ctx) {
+ ASSERT(0);
+ return;
+ }
+
+ if (stream->dpms_off != dpms_off) {
+ stream->dpms_off = dpms_off;
+ if (dpms_off)
+ core_link_disable_stream(pipe_ctx,
+ KEEP_ACQUIRED_RESOURCE);
+ else
+ core_link_enable_stream(dc->current_state, pipe_ctx);
+ }
+}
+
static void allocate_dc_stream_funcs(struct dc *dc)
{
if (dc->hwss.set_drr != NULL) {
@@ -371,6 +412,9 @@ static void allocate_dc_stream_funcs(struct dc *dc)
dc->stream_funcs.set_dither_option =
set_dither_option;
+ dc->stream_funcs.set_dpms =
+ set_dpms;
+
dc->link_funcs.set_drive_settings =
set_drive_settings;
@@ -507,7 +551,7 @@ static bool construct(struct dc *dc,
dc_version = resource_parse_asic_id(init_params->asic_id);
dc->ctx->dce_version = dc_version;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr;
#endif
/* Resource should construct all asic specific resources.
@@ -749,7 +793,7 @@ bool dc_enable_stereo(
* Applies given context to HW and copy it into current context.
* It's up to the user to release the src context afterwards.
*/
-static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
+static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
{
struct dc_bios *dcb = dc->ctx->dc_bios;
enum dc_status result = DC_ERROR_UNEXPECTED;
@@ -763,41 +807,31 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
if (!dcb->funcs->is_accelerated_mode(dcb))
dc->hwss.enable_accelerated_mode(dc);
- dc->hwss.ready_shared_resources(dc);
-
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- pipe = &context->res_ctx.pipe_ctx[i];
- dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
- }
- result = dc->hwss.apply_ctx_to_hw(dc, context);
-
- program_timing_sync(dc, context);
-
for (i = 0; i < context->stream_count; i++) {
const struct dc_sink *sink = context->streams[i]->sink;
- for (j = 0; j < context->stream_status[i].plane_count; j++) {
- dc->hwss.apply_ctx_for_surface(
- dc, context->streams[i],
- context->stream_status[i].plane_count,
- context);
+ dc->hwss.apply_ctx_for_surface(
+ dc, context->streams[i],
+ context->stream_status[i].plane_count,
+ context);
- /*
- * enable stereo
- * TODO rework dc_enable_stereo call to work with validation sets?
- */
- for (k = 0; k < MAX_PIPES; k++) {
- pipe = &context->res_ctx.pipe_ctx[k];
-
- for (l = 0 ; pipe && l < context->stream_count; l++) {
- if (context->streams[l] &&
- context->streams[l] == pipe->stream &&
- dc->hwss.setup_stereo)
- dc->hwss.setup_stereo(pipe, dc);
- }
+ /*
+ * enable stereo
+ * TODO rework dc_enable_stereo call to work with validation sets?
+ */
+ for (k = 0; k < MAX_PIPES; k++) {
+ pipe = &context->res_ctx.pipe_ctx[k];
+
+ for (l = 0 ; pipe && l < context->stream_count; l++) {
+ if (context->streams[l] &&
+ context->streams[l] == pipe->stream &&
+ dc->hwss.setup_stereo)
+ dc->hwss.setup_stereo(pipe, dc);
}
}
+
+
CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
context->streams[i]->timing.h_addressable,
context->streams[i]->timing.v_addressable,
@@ -806,8 +840,27 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
context->streams[i]->timing.pix_clk_khz);
}
+ dc->hwss.ready_shared_resources(dc, context);
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
+ }
+ result = dc->hwss.apply_ctx_to_hw(dc, context);
+
+ program_timing_sync(dc, context);
+
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
+ for (i = 0; i < context->stream_count; i++) {
+ for (j = 0; j < MAX_PIPES; j++) {
+ pipe = &context->res_ctx.pipe_ctx[j];
+
+ if (!pipe->top_pipe && pipe->stream == context->streams[i])
+ dc->hwss.pipe_control_lock(dc, pipe, false);
+ }
+ }
+
dc_release_state(dc->current_state);
dc->current_state = context;
@@ -816,7 +869,7 @@ static bool dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
dc->hwss.optimize_shared_resources(dc);
- return (result == DC_OK);
+ return result;
}
bool dc_commit_state(struct dc *dc, struct dc_state *context)
@@ -865,16 +918,24 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
return true;
}
+/*
+ * TODO this whole function needs to go
+ *
+ * dc_surface_update is needlessly complex. See if we can just replace this
+ * with a dc_plane_state and follow the atomic model a bit more closely here.
+ */
bool dc_commit_planes_to_stream(
struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
- struct dc_stream_state *dc_stream)
+ struct dc_stream_state *dc_stream,
+ struct dc_state *state)
{
+ /* no need to dynamically allocate this. it's pretty small */
struct dc_surface_update updates[MAX_SURFACES];
- struct dc_flip_addrs flip_addr[MAX_SURFACES];
- struct dc_plane_info plane_info[MAX_SURFACES];
- struct dc_scaling_info scaling_info[MAX_SURFACES];
+ struct dc_flip_addrs *flip_addr;
+ struct dc_plane_info *plane_info;
+ struct dc_scaling_info *scaling_info;
int i;
struct dc_stream_update *stream_update =
kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
@@ -884,10 +945,14 @@ bool dc_commit_planes_to_stream(
return false;
}
+ flip_addr = kcalloc(MAX_SURFACES, sizeof(struct dc_flip_addrs),
+ GFP_KERNEL);
+ plane_info = kcalloc(MAX_SURFACES, sizeof(struct dc_plane_info),
+ GFP_KERNEL);
+ scaling_info = kcalloc(MAX_SURFACES, sizeof(struct dc_scaling_info),
+ GFP_KERNEL);
+
memset(updates, 0, sizeof(updates));
- memset(flip_addr, 0, sizeof(flip_addr));
- memset(plane_info, 0, sizeof(plane_info));
- memset(scaling_info, 0, sizeof(scaling_info));
stream_update->src = dc_stream->src;
stream_update->dst = dc_stream->dst;
@@ -920,14 +985,15 @@ bool dc_commit_planes_to_stream(
updates[i].scaling_info = &scaling_info[i];
}
- dc_update_planes_and_stream(
+ dc_commit_updates_for_stream(
dc,
updates,
new_plane_count,
- dc_stream, stream_update);
-
- dc_post_update_surfaces_to_stream(dc);
+ dc_stream, stream_update, plane_states, state);
+ kfree(flip_addr);
+ kfree(plane_info);
+ kfree(scaling_info);
kfree(stream_update);
return true;
}
@@ -1030,7 +1096,6 @@ static enum surface_update_type get_plane_info_update_type(
temp_plane_info.plane_size = u->surface->plane_size;
temp_plane_info.rotation = u->surface->rotation;
temp_plane_info.stereo_format = u->surface->stereo_format;
- temp_plane_info.tiling_info = u->surface->tiling_info;
if (surface_index == 0)
temp_plane_info.visible = u->plane_info->visible;
@@ -1043,10 +1108,26 @@ static enum surface_update_type get_plane_info_update_type(
if (pixel_format_to_bpp(u->plane_info->format) !=
pixel_format_to_bpp(u->surface->format)) {
+ /* different bytes per element will require full bandwidth
+ * and DML calculation
+ */
return UPDATE_TYPE_FULL;
- } else {
- return UPDATE_TYPE_MED;
}
+
+ if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
+ sizeof(union dc_tiling_info)) != 0) {
+ /* todo: below are HW dependent, we should add a hook to
+ * DCE/N resource and validated there.
+ */
+ if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
+ /* swizzled mode requires RQ to be setup properly,
+ * thus need to run DML to calculate RQ settings
+ */
+ return UPDATE_TYPE_FULL;
+ }
+ }
+
+ return UPDATE_TYPE_MED;
}
static enum surface_update_type get_scaling_info_update_type(
@@ -1150,192 +1231,20 @@ static struct dc_stream_status *stream_get_status(
static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
-void dc_update_planes_and_stream(struct dc *dc,
- struct dc_surface_update *srf_updates, int surface_count,
+
+static void commit_planes_for_stream(struct dc *dc,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
struct dc_stream_state *stream,
- struct dc_stream_update *stream_update)
+ struct dc_stream_update *stream_update,
+ enum surface_update_type update_type,
+ struct dc_state *context)
{
- struct dc_state *context;
int i, j;
- enum surface_update_type update_type;
- const struct dc_stream_status *stream_status;
- struct dc_context *dc_ctx = dc->ctx;
-
- stream_status = dc_stream_get_status(stream);
-
- ASSERT(stream_status);
- if (!stream_status)
- return; /* Cannot commit surface to stream that is not committed */
-
-#ifdef ENABLE_FBC
- if (srf_updates->flip_addr) {
- if (srf_updates->flip_addr->address.grph.addr.low_part == 0)
- ASSERT(0);
- }
-#endif
- context = dc->current_state;
-
- /* update current stream with the new updates */
- if (stream_update) {
- if ((stream_update->src.height != 0) &&
- (stream_update->src.width != 0))
- stream->src = stream_update->src;
-
- if ((stream_update->dst.height != 0) &&
- (stream_update->dst.width != 0))
- stream->dst = stream_update->dst;
-
- if (stream_update->out_transfer_func &&
- stream_update->out_transfer_func !=
- stream->out_transfer_func) {
- if (stream->out_transfer_func != NULL)
- dc_transfer_func_release(stream->out_transfer_func);
- dc_transfer_func_retain(stream_update->out_transfer_func);
- stream->out_transfer_func =
- stream_update->out_transfer_func;
- }
- }
-
- /* do not perform surface update if surface has invalid dimensions
- * (all zero) and no scaling_info is provided
- */
- if (surface_count > 0 &&
- srf_updates->surface->src_rect.width == 0 &&
- srf_updates->surface->src_rect.height == 0 &&
- srf_updates->surface->dst_rect.width == 0 &&
- srf_updates->surface->dst_rect.height == 0 &&
- !srf_updates->scaling_info) {
- ASSERT(false);
- return;
- }
-
- update_type = dc_check_update_surfaces_for_stream(
- dc, srf_updates, surface_count, stream_update, stream_status);
-
- if (update_type >= update_surface_trace_level)
- update_surface_trace(dc, srf_updates, surface_count);
-
- if (update_type >= UPDATE_TYPE_FULL) {
- struct dc_plane_state *new_planes[MAX_SURFACES] = {0};
-
- for (i = 0; i < surface_count; i++)
- new_planes[i] = srf_updates[i].surface;
-
- /* initialize scratch memory for building context */
- context = dc_create_state();
- if (context == NULL) {
- DC_ERROR("Failed to allocate new validate context!\n");
- return;
- }
-
- dc_resource_state_copy_construct(
- dc->current_state, context);
-
- /*remove old surfaces from context */
- if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
-
- BREAK_TO_DEBUGGER();
- goto fail;
- }
-
- /* add surface to context */
- if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
-
- BREAK_TO_DEBUGGER();
- goto fail;
- }
- }
-
- /* save update parameters into surface */
- for (i = 0; i < surface_count; i++) {
- struct dc_plane_state *surface = srf_updates[i].surface;
-
- if (srf_updates[i].flip_addr) {
- surface->address = srf_updates[i].flip_addr->address;
- surface->flip_immediate =
- srf_updates[i].flip_addr->flip_immediate;
- }
-
- if (srf_updates[i].scaling_info) {
- surface->scaling_quality =
- srf_updates[i].scaling_info->scaling_quality;
- surface->dst_rect =
- srf_updates[i].scaling_info->dst_rect;
- surface->src_rect =
- srf_updates[i].scaling_info->src_rect;
- surface->clip_rect =
- srf_updates[i].scaling_info->clip_rect;
- }
-
- if (srf_updates[i].plane_info) {
- surface->color_space =
- srf_updates[i].plane_info->color_space;
- surface->format =
- srf_updates[i].plane_info->format;
- surface->plane_size =
- srf_updates[i].plane_info->plane_size;
- surface->rotation =
- srf_updates[i].plane_info->rotation;
- surface->horizontal_mirror =
- srf_updates[i].plane_info->horizontal_mirror;
- surface->stereo_format =
- srf_updates[i].plane_info->stereo_format;
- surface->tiling_info =
- srf_updates[i].plane_info->tiling_info;
- surface->visible =
- srf_updates[i].plane_info->visible;
- surface->per_pixel_alpha =
- srf_updates[i].plane_info->per_pixel_alpha;
- surface->dcc =
- srf_updates[i].plane_info->dcc;
- }
-
- if (update_type >= UPDATE_TYPE_MED) {
- for (j = 0; j < dc->res_pool->pipe_count; j++) {
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
-
- if (pipe_ctx->plane_state != surface)
- continue;
-
- resource_build_scaling_params(pipe_ctx);
- }
- }
-
- if (srf_updates[i].gamma &&
- srf_updates[i].gamma != surface->gamma_correction) {
- if (surface->gamma_correction != NULL)
- dc_gamma_release(&surface->gamma_correction);
-
- dc_gamma_retain(srf_updates[i].gamma);
- surface->gamma_correction = srf_updates[i].gamma;
- }
-
- if (srf_updates[i].in_transfer_func &&
- srf_updates[i].in_transfer_func != surface->in_transfer_func) {
- if (surface->in_transfer_func != NULL)
- dc_transfer_func_release(
- surface->
- in_transfer_func);
-
- dc_transfer_func_retain(
- srf_updates[i].in_transfer_func);
- surface->in_transfer_func =
- srf_updates[i].in_transfer_func;
- }
-
- if (srf_updates[i].hdr_static_metadata)
- surface->hdr_static_ctx =
- *(srf_updates[i].hdr_static_metadata);
- }
if (update_type == UPDATE_TYPE_FULL) {
- if (!dc->res_pool->funcs->validate_bandwidth(dc, context)) {
- BREAK_TO_DEBUGGER();
- goto fail;
- } else {
- dc->hwss.set_bandwidth(dc, context, false);
- context_clock_trace(dc, context);
- }
+ dc->hwss.set_bandwidth(dc, context, false);
+ context_clock_trace(dc, context);
}
if (update_type > UPDATE_TYPE_FAST) {
@@ -1346,8 +1255,14 @@ void dc_update_planes_and_stream(struct dc *dc,
}
}
- if (surface_count == 0)
+ if (surface_count == 0) {
+ /*
+ * In case of turning off screen, no need to program front end a second time.
+ * just return after program front end.
+ */
dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context);
+ return;
+ }
/* Lock pipes for provided surfaces, or all active if full update*/
for (i = 0; i < surface_count; i++) {
@@ -1373,10 +1288,6 @@ void dc_update_planes_and_stream(struct dc *dc,
/* Full fe update*/
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
- struct pipe_ctx *cur_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[j];
- bool is_new_pipe_surface = cur_pipe_ctx->plane_state != pipe_ctx->plane_state;
- struct dc_cursor_position position = { 0 };
-
if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state)
continue;
@@ -1387,17 +1298,6 @@ void dc_update_planes_and_stream(struct dc *dc,
dc->hwss.apply_ctx_for_surface(
dc, pipe_ctx->stream, stream_status->plane_count, context);
}
-
- /* TODO: this is a hack w/a for switching from mpo to pipe split */
- dc_stream_set_cursor_position(pipe_ctx->stream, &position);
-
- if (is_new_pipe_surface) {
- dc->hwss.update_plane_addr(dc, pipe_ctx);
- dc->hwss.set_input_transfer_func(
- pipe_ctx, pipe_ctx->plane_state);
- dc->hwss.set_output_transfer_func(
- pipe_ctx, pipe_ctx->stream);
- }
}
if (update_type > UPDATE_TYPE_FAST)
@@ -1423,7 +1323,9 @@ void dc_update_planes_and_stream(struct dc *dc,
if (update_type == UPDATE_TYPE_FAST)
continue;
- if (srf_updates[i].in_transfer_func)
+ /* work around to program degamma regs for split pipe after set mode. */
+ if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe &&
+ pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state))
dc->hwss.set_input_transfer_func(
pipe_ctx, pipe_ctx->plane_state);
@@ -1459,16 +1361,79 @@ void dc_update_planes_and_stream(struct dc *dc,
break;
}
}
+}
- if (dc->current_state != context) {
+void dc_commit_updates_for_stream(struct dc *dc,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
+ struct dc_stream_state *stream,
+ struct dc_stream_update *stream_update,
+ struct dc_plane_state **plane_states,
+ struct dc_state *state)
+{
+ const struct dc_stream_status *stream_status;
+ enum surface_update_type update_type;
+ struct dc_state *context;
+ struct dc_context *dc_ctx = dc->ctx;
+ int i, j;
+
+ stream_status = dc_stream_get_status(stream);
+ context = dc->current_state;
+
+ update_type = dc_check_update_surfaces_for_stream(
+ dc, srf_updates, surface_count, stream_update, stream_status);
+
+ if (update_type >= update_surface_trace_level)
+ update_surface_trace(dc, srf_updates, surface_count);
+
+
+ if (update_type >= UPDATE_TYPE_FULL) {
+
+ /* initialize scratch memory for building context */
+ context = dc_create_state();
+ if (context == NULL) {
+ DC_ERROR("Failed to allocate new validate context!\n");
+ return;
+ }
+
+ dc_resource_state_copy_construct(state, context);
+ }
+
+
+ for (i = 0; i < surface_count; i++) {
+ struct dc_plane_state *surface = srf_updates[i].surface;
- /* Since memory free requires elevated IRQL, an interrupt
- * request is generated by mem free. If this happens
- * between freeing and reassigning the context, our vsync
- * interrupt will call into dc and cause a memory
- * corruption BSOD. Hence, we first reassign the context,
- * then free the old context.
+ /* TODO: On flip we don't build the state, so it still has the
+ * old address. Which is why we are updating the address here
*/
+ if (srf_updates[i].flip_addr)
+ surface->address = srf_updates[i].flip_addr->address;
+
+ if (update_type >= UPDATE_TYPE_MED) {
+ for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
+
+ if (pipe_ctx->plane_state != surface)
+ continue;
+
+ resource_build_scaling_params(pipe_ctx);
+ }
+ }
+ }
+
+ commit_planes_for_stream(
+ dc,
+ srf_updates,
+ surface_count,
+ stream,
+ stream_update,
+ update_type,
+ context);
+
+ if (update_type >= UPDATE_TYPE_FULL)
+ dc_post_update_surfaces_to_stream(dc);
+
+ if (dc->current_state != context) {
struct dc_state *old = dc->current_state;
@@ -1476,10 +1441,9 @@ void dc_update_planes_and_stream(struct dc *dc,
dc_release_state(old);
}
+
return;
-fail:
- dc_release_state(context);
}
uint8_t dc_get_current_stream_count(struct dc *dc)
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 @@
#include "dce/dce_11_0_enum.h"
#include "dce/dce_11_0_sh_mask.h"
+#define EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK 0x007C /* Copied from atombios.h */
#define LINK_INFO(...) \
dm_logger_write(dc_ctx->logger, LOG_HW_HOTPLUG, \
__VA_ARGS__)
@@ -78,14 +79,15 @@ static void destruct(struct dc_link *link)
dc_sink_release(link->remote_sinks[i]);
}
-static struct gpio *get_hpd_gpio(const struct dc_link *link)
+struct gpio *get_hpd_gpio(struct dc_bios *dcb,
+ struct graphics_object_id link_id,
+ struct gpio_service *gpio_service)
{
enum bp_result bp_result;
- struct dc_bios *dcb = link->ctx->dc_bios;
struct graphics_object_hpd_info hpd_info;
struct gpio_pin_info pin_info;
- if (dcb->funcs->get_hpd_info(dcb, link->link_id, &hpd_info) != BP_RESULT_OK)
+ if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
return NULL;
bp_result = dcb->funcs->get_gpio_pin_info(dcb,
@@ -97,7 +99,7 @@ static struct gpio *get_hpd_gpio(const struct dc_link *link)
}
return dal_gpio_service_create_irq(
- link->ctx->gpio_service,
+ gpio_service,
pin_info.offset,
pin_info.mask);
}
@@ -153,7 +155,7 @@ static bool program_hpd_filter(
}
/* Obtain HPD handle */
- hpd = get_hpd_gpio(link);
+ hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (!hpd)
return result;
@@ -186,7 +188,7 @@ static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
struct gpio *hpd_pin;
/* todo: may need to lock gpio access */
- hpd_pin = get_hpd_gpio(link);
+ hpd_pin = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd_pin == NULL)
goto hpd_gpio_failure;
@@ -496,6 +498,7 @@ static void detect_dp(
}
if (is_mst_supported(link)) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
+ link->type = dc_connection_mst_branch;
/*
* This call will initiate MST topology discovery. Which
@@ -524,12 +527,11 @@ static void detect_dp(
if (reason == DETECT_REASON_BOOT)
boot = true;
- if (dm_helpers_dp_mst_start_top_mgr(
+ if (!dm_helpers_dp_mst_start_top_mgr(
link->ctx,
link, boot)) {
- link->type = dc_connection_mst_branch;
- } else {
/* MST not supported */
+ link->type = dc_connection_single;
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
}
}
@@ -638,8 +640,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
link->dpcd_sink_count = link->dpcd_caps.sink_count.
bits.SINK_COUNT;
- else
- link->dpcd_sink_count = 1;
+ else
+ link->dpcd_sink_count = 1;
dal_ddc_service_set_transaction_type(
link->ddc,
@@ -746,6 +748,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
if (link->type == dc_connection_mst_branch) {
LINK_INFO("link=%d, mst branch is now Disconnected\n",
link->link_index);
+
dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
link->mst_stream_alloc_table.stream_count = 0;
@@ -770,7 +773,7 @@ static enum hpd_source_id get_hpd_line(
struct gpio *hpd;
enum hpd_source_id hpd_id = HPD_SOURCEID_UNKNOWN;
- hpd = get_hpd_gpio(link);
+ hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd) {
switch (dal_irq_get_source(hpd)) {
@@ -940,7 +943,7 @@ static bool construct(
goto create_fail;
}
- hpd_gpio = get_hpd_gpio(link);
+ hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
if (hpd_gpio != NULL)
link->irq_source_hpd = dal_irq_get_source(hpd_gpio);
@@ -1343,7 +1346,18 @@ static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
result = true;
break;
-
+ case ENGINE_ID_DIGD:
+ settings->slv_addr = integrated_info->dp3_ext_hdmi_slv_addr;
+ settings->reg_num = integrated_info->dp3_ext_hdmi_6g_reg_num;
+ settings->reg_num_6g = integrated_info->dp3_ext_hdmi_6g_reg_num;
+ memmove(settings->reg_settings,
+ integrated_info->dp3_ext_hdmi_reg_settings,
+ sizeof(integrated_info->dp3_ext_hdmi_reg_settings));
+ memmove(settings->reg_settings_6g,
+ integrated_info->dp3_ext_hdmi_6g_reg_settings,
+ sizeof(integrated_info->dp3_ext_hdmi_6g_reg_settings));
+ result = true;
+ break;
default:
break;
}
@@ -1680,7 +1694,9 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
is_over_340mhz = true;
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
- if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) {
+ unsigned short masked_chip_caps = pipe_ctx->stream->sink->link->chip_caps &
+ EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
+ if (masked_chip_caps == (0x2 << 2)) {
/* DP159, Retimer settings */
eng_id = pipe_ctx->stream_res.stream_enc->id;
@@ -1691,7 +1707,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
write_i2c_default_retimer_setting(pipe_ctx,
is_vga_mode, is_over_340mhz);
}
- } else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) {
+ } else if (masked_chip_caps == (0x1 << 2)) {
/* PI3EQX1204, Redriver settings */
write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
}
@@ -1782,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
else
dp_disable_link_phy_mst(link, signal);
} else
- link->link_enc->funcs->disable_output(link->link_enc, signal);
+ link->link_enc->funcs->disable_output(link->link_enc, signal, link);
}
enum dc_status dc_link_validate_mode_timing(
@@ -2319,16 +2335,20 @@ void core_link_enable_stream(
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
allocate_mst_payload(pipe_ctx);
+
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
+ core_dc->hwss.unblank_stream(pipe_ctx,
+ &pipe_ctx->stream->sink->link->cur_link_settings);
}
-void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
+void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
{
struct dc *core_dc = pipe_ctx->stream->ctx->dc;
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
- core_dc->hwss.disable_stream(pipe_ctx);
+ core_dc->hwss.disable_stream(pipe_ctx, option);
disable_link(pipe_ctx->stream->sink->link, pipe_ctx->stream->signal);
}
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)
dp_retrain_link_dp_test(link, &link_settings, false);
}
+/* TODO hbr2 compliance eye output is unstable
+ * (toggling on and off) with debugger break
+ * This caueses intermittent PHY automation failure
+ * Need to look into the root cause */
+static uint8_t force_tps4_for_cp2520 = 1;
+
static void dp_test_send_phy_test_pattern(struct dc_link *link)
{
union phy_test_pattern dpcd_test_pattern;
@@ -1758,10 +1764,16 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
break;
case PHY_TEST_PATTERN_CP2520_1:
- test_pattern = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
+ /* CP2520 pattern is unstable, temporarily use TPS4 instead */
+ test_pattern = (force_tps4_for_cp2520 == 1) ?
+ DP_TEST_PATTERN_TRAINING_PATTERN4 :
+ DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
break;
case PHY_TEST_PATTERN_CP2520_2:
- test_pattern = DP_TEST_PATTERN_CP2520_2;
+ /* CP2520 pattern is unstable, temporarily use TPS4 instead */
+ test_pattern = (force_tps4_for_cp2520 == 1) ?
+ DP_TEST_PATTERN_TRAINING_PATTERN4 :
+ DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
break;
case PHY_TEST_PATTERN_CP2520_3:
test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
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(
if (dc_is_dp_sst_signal(signal)) {
if (signal == SIGNAL_TYPE_EDP) {
- link_enc->funcs->power_control(link_enc, true);
+ link->dc->hwss.edp_power_control(link->link_enc, true);
link_enc->funcs->enable_dp_output(
link_enc,
link_settings,
clock_source);
- link_enc->funcs->backlight_control(link_enc, true);
+ link->dc->hwss.edp_backlight_control(link, true);
} else
link_enc->funcs->enable_dp_output(
link_enc,
@@ -138,12 +138,12 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
dp_receiver_power_ctrl(link, false);
if (signal == SIGNAL_TYPE_EDP) {
- link->link_enc->funcs->backlight_control(link->link_enc, false);
+ link->dc->hwss.edp_backlight_control(link, false);
edp_receiver_ready_T9(link);
- link->link_enc->funcs->disable_output(link->link_enc, signal);
- link->link_enc->funcs->power_control(link->link_enc, false);
+ link->link_enc->funcs->disable_output(link->link_enc, signal, link);
+ link->dc->hwss.edp_power_control(link->link_enc, false);
} else
- link->link_enc->funcs->disable_output(link->link_enc, signal);
+ link->link_enc->funcs->disable_output(link->link_enc, signal, link);
/* Clear current link setting.*/
memset(&link->cur_link_settings, 0,
@@ -282,11 +282,12 @@ void dp_retrain_link_dp_test(struct dc_link *link,
dp_receiver_power_ctrl(link, false);
- link->dc->hwss.disable_stream(&pipes[i]);
+ link->dc->hwss.disable_stream(&pipes[i], KEEP_ACQUIRED_RESOURCE);
link->link_enc->funcs->disable_output(
link->link_enc,
- SIGNAL_TYPE_DISPLAY_PORT);
+ SIGNAL_TYPE_DISPLAY_PORT,
+ link);
/* Clear current link setting. */
memset(&link->cur_link_settings, 0,
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 @@
#include "opp.h"
#include "timing_generator.h"
#include "transform.h"
+#include "dpp.h"
#include "core_types.h"
#include "set_mode_types.h"
#include "virtual/virtual_stream_encoder.h"
@@ -242,7 +243,10 @@ bool resource_construct(
pool->stream_enc_count++;
}
}
-
+ dc->caps.dynamic_audio = false;
+ if (pool->audio_count < pool->stream_enc_count) {
+ dc->caps.dynamic_audio = true;
+ }
for (i = 0; i < num_virtual_links; i++) {
pool->stream_enc[pool->stream_enc_count] =
virtual_stream_encoder_create(
@@ -846,12 +850,20 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
*/
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
- pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable;
- pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable;
+ pipe_ctx->plane_res.scl_data.recout.x += timing->h_border_left;
+ pipe_ctx->plane_res.scl_data.recout.y += timing->v_border_top;
+
+ pipe_ctx->plane_res.scl_data.h_active = timing->h_addressable + timing->h_border_left + timing->h_border_right;
+ pipe_ctx->plane_res.scl_data.v_active = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
/* Taps calculations */
- res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
- pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+ if (pipe_ctx->plane_res.xfm != NULL)
+ res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
+ pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+ if (pipe_ctx->plane_res.dpp != NULL)
+ res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
+ pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
if (!res) {
/* Try 24 bpp linebuffer */
@@ -859,6 +871,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+ res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
+ pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
}
if (res)
@@ -1021,9 +1036,9 @@ static int acquire_first_split_pipe(
memset(pipe_ctx, 0, sizeof(*pipe_ctx));
pipe_ctx->stream_res.tg = pool->timing_generators[i];
- pipe_ctx->plane_res.mi = pool->mis[i];
+ pipe_ctx->plane_res.hubp = pool->hubps[i];
pipe_ctx->plane_res.ipp = pool->ipps[i];
- pipe_ctx->plane_res.xfm = pool->transforms[i];
+ pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i];
pipe_ctx->pipe_idx = i;
@@ -1070,9 +1085,6 @@ bool dc_add_plane_to_context(
return false;
}
- /* retain new surfaces */
- dc_plane_state_retain(plane_state);
-
free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
@@ -1082,11 +1094,11 @@ bool dc_add_plane_to_context(
free_pipe = &context->res_ctx.pipe_ctx[pipe_idx];
}
#endif
- if (!free_pipe) {
- stream_status->plane_states[i] = NULL;
+ if (!free_pipe)
return false;
- }
+ /* retain new surfaces */
+ dc_plane_state_retain(plane_state);
free_pipe->plane_state = plane_state;
if (head_pipe != free_pipe) {
@@ -1178,8 +1190,8 @@ bool dc_remove_plane_from_context(
stream_status->plane_count--;
- /* Trim back arrays */
- for (i = 0; i < stream_status->plane_count; i++)
+ /* Start at the plane we've just released, and move all the planes one index forward to "trim" the array */
+ for (; i < stream_status->plane_count; i++)
stream_status->plane_states[i] = stream_status->plane_states[i + 1];
stream_status->plane_states[stream_status->plane_count] = NULL;
@@ -1312,6 +1324,28 @@ bool dc_is_stream_unchanged(
return true;
}
+bool dc_is_stream_scaling_unchanged(
+ struct dc_stream_state *old_stream, struct dc_stream_state *stream)
+{
+ if (old_stream == stream)
+ return true;
+
+ if (old_stream == NULL || stream == NULL)
+ return false;
+
+ if (memcmp(&old_stream->src,
+ &stream->src,
+ sizeof(struct rect)) != 0)
+ return false;
+
+ if (memcmp(&old_stream->dst,
+ &stream->dst,
+ sizeof(struct rect)) != 0)
+ return false;
+
+ return true;
+}
+
/* Maximum TMDS single link pixel clock 165MHz */
#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
@@ -1330,7 +1364,7 @@ static void update_stream_engine_usage(
}
/* TODO: release audio object */
-static void update_audio_usage(
+void update_audio_usage(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct audio *audio,
@@ -1356,8 +1390,10 @@ static int acquire_first_free_pipe(
pipe_ctx->stream_res.tg = pool->timing_generators[i];
pipe_ctx->plane_res.mi = pool->mis[i];
+ pipe_ctx->plane_res.hubp = pool->hubps[i];
pipe_ctx->plane_res.ipp = pool->ipps[i];
pipe_ctx->plane_res.xfm = pool->transforms[i];
+ pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i];
pipe_ctx->pipe_idx = i;
@@ -1415,11 +1451,16 @@ static struct audio *find_first_free_audio(
{
int i;
for (i = 0; i < pool->audio_count; i++) {
+ if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {
+ return pool->audios[i];
+ }
+ }
+ /*not found the matching one, first come first serve*/
+ for (i = 0; i < pool->audio_count; i++) {
if (res_ctx->is_audio_acquired[i] == false) {
return pool->audios[i];
}
}
-
return 0;
}
@@ -1438,7 +1479,7 @@ bool resource_is_stream_unchanged(
return false;
}
-bool dc_add_stream_to_ctx(
+enum dc_status dc_add_stream_to_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream)
@@ -1459,10 +1500,10 @@ bool dc_add_stream_to_ctx(
if (res != DC_OK)
DC_ERROR("Adding stream %p to context failed with err %d!\n", stream, res);
- return res == DC_OK;
+ return res;
}
-bool dc_remove_stream_from_ctx(
+enum dc_status dc_remove_stream_from_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream)
@@ -1632,10 +1673,11 @@ enum dc_status resource_map_pool_resources(
/* acquire new resources */
pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
if (pipe_idx < 0)
- acquire_first_split_pipe(&context->res_ctx, pool, stream);
+ pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
#endif
+
if (pipe_idx < 0)
return DC_NO_CONTROLLER_RESOURCE;
@@ -1716,17 +1758,18 @@ void dc_resource_state_construct(
dst_ctx->dis_clk = dc->res_pool->display_clock;
}
-bool dc_validate_global_state(
+enum dc_status dc_validate_global_state(
struct dc *dc,
struct dc_state *new_ctx)
{
enum dc_status result = DC_ERROR_UNEXPECTED;
int i, j;
- if (dc->res_pool->funcs->validate_global &&
- dc->res_pool->funcs->validate_global(
- dc, new_ctx) != DC_OK)
- return false;
+ if (dc->res_pool->funcs->validate_global) {
+ result = dc->res_pool->funcs->validate_global(dc, new_ctx);
+ if (result != DC_OK)
+ return result;
+ }
for (i = 0; new_ctx && i < new_ctx->stream_count; i++) {
struct dc_stream_state *stream = new_ctx->streams[i];
@@ -2713,7 +2756,7 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
fmt_bit_depth->pixel_encoding = pixel_encoding;
}
-bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
+enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
{
struct dc *core_dc = dc;
struct dc_link *link = stream->sink->link;
@@ -2737,16 +2780,16 @@ bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
link,
&stream->timing);
- return res == DC_OK;
+ return res;
}
-bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
+enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state)
{
- struct dc *core_dc = dc;
+ enum dc_status res = DC_OK;
/* TODO For now validates pixel format only */
- if (core_dc->res_pool->funcs->validate_plane)
- return core_dc->res_pool->funcs->validate_plane(plane_state) == DC_OK;
+ if (dc->res_pool->funcs->validate_plane)
+ return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps);
- return true;
+ return res;
}
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(
* Update the cursor attributes and set cursor surface address
*/
bool dc_stream_set_cursor_attributes(
- const struct dc_stream_state *stream,
+ struct dc_stream_state *stream,
const struct dc_cursor_attributes *attributes)
{
int i;
@@ -189,21 +189,51 @@ bool dc_stream_set_cursor_attributes(
return false;
}
+ if (attributes->address.quad_part == 0) {
+ dm_output_to_console("DC: Cursor address is 0!\n");
+ return false;
+ }
+
core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx;
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
- if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp)
+ if (pipe_ctx->stream != stream || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue;
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
continue;
- pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
- pipe_ctx->plane_res.ipp, attributes);
+
+ if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
+ pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
+ pipe_ctx->plane_res.ipp, attributes);
+
+ if (pipe_ctx->plane_res.hubp != NULL &&
+ pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes != NULL)
+ pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.hubp, attributes);
+
+ if (pipe_ctx->plane_res.mi != NULL &&
+ pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
+ pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.mi, attributes);
+
+
+ if (pipe_ctx->plane_res.xfm != NULL &&
+ pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
+ pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.xfm, attributes);
+
+ if (pipe_ctx->plane_res.dpp != NULL &&
+ pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes != NULL)
+ pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.dpp, attributes);
}
+ stream->cursor_attributes = *attributes;
+
return true;
}
@@ -231,6 +261,10 @@ bool dc_stream_set_cursor_position(
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+ struct mem_input *mi = pipe_ctx->plane_res.mi;
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct transform *xfm = pipe_ctx->plane_res.xfm;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_cursor_position pos_cpy = *position;
struct dc_cursor_mi_param param = {
.pixel_clk_khz = stream->timing.pix_clk_khz,
@@ -241,7 +275,9 @@ bool dc_stream_set_cursor_position(
};
if (pipe_ctx->stream != stream ||
- !pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state)
+ (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
+ !pipe_ctx->plane_state ||
+ (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue;
if (pipe_ctx->plane_state->address.type
@@ -251,7 +287,22 @@ bool dc_stream_set_cursor_position(
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
pos_cpy.enable = false;
- ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+
+ if (ipp->funcs->ipp_cursor_set_position != NULL)
+ ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+
+ if (mi != NULL && mi->funcs->set_cursor_position != NULL)
+ mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+
+ if (hubp != NULL && hubp->funcs->set_cursor_position != NULL)
+ hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+
+ if (xfm != NULL && xfm->funcs->set_cursor_position != NULL)
+ xfm->funcs->set_cursor_position(xfm, &pos_cpy, &param, hubp->curs_attr.width);
+
+ if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
+ dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
+
}
return true;
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 @@
/* DC core (private) */
#include "core_types.h"
#include "transform.h"
+#include "dpp.h"
/*******************************************************************************
* 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 @@
#include "inc/compressor.h"
#include "dml/display_mode_lib.h"
-#define DC_VER "3.1.01"
+#define DC_VER "3.1.07"
#define MAX_SURFACES 3
#define MAX_STREAMS 6
@@ -56,11 +56,12 @@ struct dc_caps {
uint32_t max_planes;
uint32_t max_downscale_ratio;
uint32_t i2c_speed_in_khz;
-
unsigned int max_cursor_size;
+ unsigned int max_video_width;
+ bool dcc_const_color;
+ bool dynamic_audio;
};
-
struct dc_dcc_surface_param {
struct dc_size surface_size;
enum surface_pixel_format format;
@@ -132,6 +133,10 @@ struct dc_stream_state_funcs {
void (*set_dither_option)(struct dc_stream_state *stream,
enum dc_dither_option option);
+
+ void (*set_dpms)(struct dc *dc,
+ struct dc_stream_state *stream,
+ bool dpms_off);
};
struct link_training_settings;
@@ -162,6 +167,23 @@ struct dc_config {
bool disable_disp_pll_sharing;
};
+enum dcc_option {
+ DCC_ENABLE = 0,
+ DCC_DISABLE = 1,
+ DCC_HALF_REQ_DISALBE = 2,
+};
+
+enum pipe_split_policy {
+ MPC_SPLIT_DYNAMIC = 0,
+ MPC_SPLIT_AVOID = 1,
+ MPC_SPLIT_AVOID_MULT_DISP = 2,
+};
+
+enum wm_report_mode {
+ WM_REPORT_DEFAULT = 0,
+ WM_REPORT_OVERRIDE = 1,
+};
+
struct dc_debug {
bool surface_visual_confirm;
bool sanity_checks;
@@ -170,14 +192,21 @@ struct dc_debug {
bool timing_trace;
bool clock_trace;
bool validation_trace;
+
+ /* stutter efficiency related */
bool disable_stutter;
- bool disable_dcc;
+ bool use_max_lb;
+ enum dcc_option disable_dcc;
+ enum pipe_split_policy pipe_split_policy;
+ bool force_single_disp_pipe_split;
+ bool voltage_align_fclk;
+
bool disable_dfs_bypass;
bool disable_dpp_power_gate;
bool disable_hubp_power_gate;
bool disable_pplib_wm_range;
- bool use_dml_wm;
- bool disable_pipe_split;
+ enum wm_report_mode pplib_wm_report_mode;
+ unsigned int min_disp_clk_khz;
int sr_exit_time_dpm0_ns;
int sr_enter_plus_exit_time_dpm0_ns;
int sr_exit_time_ns;
@@ -191,6 +220,11 @@ struct dc_debug {
bool disable_dmcu;
bool disable_psr;
bool force_abm_enable;
+ bool disable_hbup_pg;
+ bool disable_dpp_pg;
+ bool disable_stereo_support;
+ bool vsr_support;
+ bool performance_trace;
};
struct dc_state;
struct resource_pool;
@@ -233,7 +267,7 @@ struct dc {
struct dm_pp_display_configuration prev_display_config;
/* FBC compressor */
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
struct compressor *fbc_compressor;
#endif
};
@@ -268,7 +302,7 @@ struct dc_init_data {
struct dc_config flags;
uint32_t log_mask;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
uint64_t fbc_gpu_addr;
#endif
};
@@ -285,6 +319,38 @@ enum {
TRANSFER_FUNC_POINTS = 1025
};
+// Moved here from color module for linux
+enum color_transfer_func {
+ transfer_func_unknown,
+ transfer_func_srgb,
+ transfer_func_bt709,
+ transfer_func_pq2084,
+ transfer_func_pq2084_interim,
+ transfer_func_linear_0_1,
+ transfer_func_linear_0_125,
+ transfer_func_dolbyvision,
+ transfer_func_gamma_22,
+ transfer_func_gamma_26
+};
+
+enum color_color_space {
+ color_space_unsupported,
+ color_space_srgb,
+ color_space_bt601,
+ color_space_bt709,
+ color_space_xv_ycc_bt601,
+ color_space_xv_ycc_bt709,
+ color_space_xr_rgb,
+ color_space_bt2020,
+ color_space_adobe,
+ color_space_dci_p3,
+ color_space_sc_rgb_ms_ref,
+ color_space_display_native,
+ color_space_app_ctrl,
+ color_space_dolby_vision,
+ color_space_custom_coordinates
+};
+
struct dc_hdr_static_metadata {
/* display chromaticities and white point in units of 0.00001 */
unsigned int chromaticity_green_x;
@@ -365,6 +431,12 @@ struct dc_plane_state {
struct dc_gamma *gamma_correction;
struct dc_transfer_func *in_transfer_func;
+ // sourceContentAttribute cache
+ bool is_source_input_valid;
+ struct dc_hdr_static_metadata source_input_mastering_info;
+ enum color_color_space source_input_color_space;
+ enum color_transfer_func source_input_tf;
+
enum dc_color_space color_space;
enum surface_pixel_format format;
enum dc_rotation_angle rotation;
@@ -449,23 +521,6 @@ struct dc_flip_addrs {
/* TODO: add flip duration for FreeSync */
};
-/*
- * Set up surface attributes and associate to a stream
- * The surfaces parameter is an absolute set of all surface active for the stream.
- * If no surfaces are provided, the stream will be blanked; no memory read.
- * Any flip related attribute changes must be done through this interface.
- *
- * After this call:
- * Surfaces attributes are programmed and configured to be composed into stream.
- * This does not trigger a flip. No surface address is programmed.
- */
-
-bool dc_commit_planes_to_stream(
- struct dc *dc,
- struct dc_plane_state **plane_states,
- uint8_t new_plane_count,
- struct dc_stream_state *stream);
-
bool dc_post_update_surfaces_to_stream(
struct dc *dc);
@@ -554,9 +609,12 @@ struct dc_stream_state {
int phy_pix_clk;
enum signal_type signal;
+ bool dpms_off;
struct dc_stream_status status;
+ struct dc_cursor_attributes cursor_attributes;
+
/* from stream struct */
struct kref refcount;
};
@@ -569,11 +627,10 @@ struct dc_stream_update {
bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
+bool dc_is_stream_scaling_unchanged(
+ struct dc_stream_state *old_stream, struct dc_stream_state *stream);
/*
- * Setup stream attributes if no stream updates are provided
- * there will be no impact on the stream parameters
- *
* Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the stream will be blanked; no memory read.
@@ -582,14 +639,22 @@ bool dc_is_stream_unchanged(
* After this call:
* Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed.
- *
*/
-void dc_update_planes_and_stream(struct dc *dc,
- struct dc_surface_update *surface_updates, int surface_count,
+bool dc_commit_planes_to_stream(
+ struct dc *dc,
+ struct dc_plane_state **plane_states,
+ uint8_t new_plane_count,
struct dc_stream_state *dc_stream,
- struct dc_stream_update *stream_update);
+ struct dc_state *state);
+void dc_commit_updates_for_stream(struct dc *dc,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
+ struct dc_stream_state *stream,
+ struct dc_stream_update *stream_update,
+ struct dc_plane_state **plane_states,
+ struct dc_state *state);
/*
* Log the current stream state.
*/
@@ -616,12 +681,12 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
uint32_t *h_position,
uint32_t *v_position);
-bool dc_add_stream_to_ctx(
+enum dc_status dc_add_stream_to_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream);
-bool dc_remove_stream_from_ctx(
+enum dc_status dc_remove_stream_from_ctx(
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *stream);
@@ -660,11 +725,11 @@ struct dc_validation_set {
uint8_t plane_count;
};
-bool dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
+enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
-bool dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
+enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
-bool dc_validate_global_state(
+enum dc_status dc_validate_global_state(
struct dc *dc,
struct dc_state *new_ctx);
@@ -991,7 +1056,7 @@ struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
******************************************************************************/
/* TODO: Deprecated once we switch to dc_set_cursor_position */
bool dc_stream_set_cursor_attributes(
- const struct dc_stream_state *stream,
+ struct dc_stream_state *stream,
const struct dc_cursor_attributes *attributes);
bool dc_stream_set_cursor_position(
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 {
/*grow 444 video here if necessary */
};
+
+
/* Pixel format */
enum pixel_format {
/*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 {
bool created_bios;
struct gpio_service *gpio_service;
struct i2caux *i2caux;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
uint64_t fbc_gpu_addr;
#endif
};
@@ -151,6 +151,7 @@ enum dc_edid_status {
EDID_BAD_INPUT,
EDID_NO_RESPONSE,
EDID_BAD_CHECKSUM,
+ EDID_THE_SAME,
};
/* audio capability from EDID*/
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 @@
#include "hw_sequencer.h"
+#define BL_REG_LIST()\
+ SR(LVTMA_PWRSEQ_CNTL), \
+ SR(LVTMA_PWRSEQ_STATE)
+
#define HWSEQ_DCEF_REG_LIST_DCE8() \
.DCFE_CLOCK_CONTROL[0] = mmCRTC0_CRTC_DCFE_CLOCK_CONTROL, \
.DCFE_CLOCK_CONTROL[1] = mmCRTC1_CRTC_DCFE_CLOCK_CONTROL, \
@@ -86,24 +90,27 @@
SRII(BLND_CONTROL, BLND, 0),\
SRII(BLND_CONTROL, BLND, 1),\
SR(BLNDV_CONTROL),\
- HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+ HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
+ BL_REG_LIST()
#define HWSEQ_DCE8_REG_LIST() \
HWSEQ_DCEF_REG_LIST_DCE8(), \
HWSEQ_BLND_REG_LIST(), \
- HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+ HWSEQ_PIXEL_RATE_REG_LIST(CRTC),\
+ BL_REG_LIST()
#define HWSEQ_DCE10_REG_LIST() \
HWSEQ_DCEF_REG_LIST(), \
HWSEQ_BLND_REG_LIST(), \
- HWSEQ_PIXEL_RATE_REG_LIST(CRTC)
+ HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
+ BL_REG_LIST()
#define HWSEQ_ST_REG_LIST() \
HWSEQ_DCE11_REG_LIST_BASE(), \
.DCFE_CLOCK_CONTROL[2] = mmDCFEV_CLOCK_CONTROL, \
.CRTC_H_BLANK_START_END[2] = mmCRTCV_H_BLANK_START_END, \
.BLND_V_UPDATE_LOCK[2] = mmBLNDV_V_UPDATE_LOCK, \
- .BLND_CONTROL[2] = mmBLNDV_CONTROL,
+ .BLND_CONTROL[2] = mmBLNDV_CONTROL
#define HWSEQ_CZ_REG_LIST() \
HWSEQ_DCE11_REG_LIST_BASE(), \
@@ -123,16 +130,16 @@
SR(DCHUB_FB_LOCATION),\
SR(DCHUB_AGP_BASE),\
SR(DCHUB_AGP_BOT),\
- SR(DCHUB_AGP_TOP)
+ SR(DCHUB_AGP_TOP), \
+ BL_REG_LIST()
#define HWSEQ_DCE112_REG_LIST() \
HWSEQ_DCE10_REG_LIST(), \
HWSEQ_PIXEL_RATE_REG_LIST(CRTC), \
- HWSEQ_PHYPLL_REG_LIST(CRTC)
+ HWSEQ_PHYPLL_REG_LIST(CRTC), \
+ BL_REG_LIST()
#define HWSEQ_DCN_REG_LIST()\
- HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
- HWSEQ_PHYPLL_REG_LIST(OTG), \
SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 0), \
SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 1), \
SRII(OTG_GLOBAL_SYNC_STATUS, OTG, 2), \
@@ -156,23 +163,15 @@
SR(REFCLK_CNTL), \
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\
- SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
- SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\
- SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
- SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\
- SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
- SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\
SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\
SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\
- SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
- SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D),\
SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\
SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
@@ -181,32 +180,11 @@
SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
SR(DCHUBBUB_TEST_DEBUG_INDEX), \
SR(DCHUBBUB_TEST_DEBUG_DATA), \
- SR(DC_IP_REQUEST_CNTL), \
- SR(DOMAIN0_PG_CONFIG), \
- SR(DOMAIN1_PG_CONFIG), \
- SR(DOMAIN2_PG_CONFIG), \
- SR(DOMAIN3_PG_CONFIG), \
- SR(DOMAIN4_PG_CONFIG), \
- SR(DOMAIN5_PG_CONFIG), \
- SR(DOMAIN6_PG_CONFIG), \
- SR(DOMAIN7_PG_CONFIG), \
- SR(DOMAIN0_PG_STATUS), \
- SR(DOMAIN1_PG_STATUS), \
- SR(DOMAIN2_PG_STATUS), \
- SR(DOMAIN3_PG_STATUS), \
- SR(DOMAIN4_PG_STATUS), \
- SR(DOMAIN5_PG_STATUS), \
- SR(DOMAIN6_PG_STATUS), \
- SR(DOMAIN7_PG_STATUS), \
SR(DIO_MEM_PWR_CTRL), \
SR(DCCG_GATE_DISABLE_CNTL), \
SR(DCCG_GATE_DISABLE_CNTL2), \
SR(DCFCLK_CNTL),\
SR(DCFCLK_CNTL), \
- SR(D1VGA_CONTROL), \
- SR(D2VGA_CONTROL), \
- SR(D3VGA_CONTROL), \
- SR(D4VGA_CONTROL), \
/* todo: get these from GVM instead of reading registers ourselves */\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32),\
MMHUB_SR(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32),\
@@ -221,17 +199,56 @@
MMHUB_SR(MC_VM_SYSTEM_APERTURE_LOW_ADDR),\
MMHUB_SR(MC_VM_SYSTEM_APERTURE_HIGH_ADDR)
+#define HWSEQ_SR_WATERMARK_REG_LIST()\
+ SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D),\
+ SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D)
+
#define HWSEQ_DCN1_REG_LIST()\
HWSEQ_DCN_REG_LIST(), \
+ HWSEQ_SR_WATERMARK_REG_LIST(), \
+ HWSEQ_PIXEL_RATE_REG_LIST(OTG), \
+ HWSEQ_PHYPLL_REG_LIST(OTG), \
SR(DCHUBBUB_SDPIF_FB_TOP),\
SR(DCHUBBUB_SDPIF_FB_BASE),\
SR(DCHUBBUB_SDPIF_FB_OFFSET),\
SR(DCHUBBUB_SDPIF_AGP_BASE),\
SR(DCHUBBUB_SDPIF_AGP_BOT),\
- SR(DCHUBBUB_SDPIF_AGP_TOP)
-
+ SR(DCHUBBUB_SDPIF_AGP_TOP),\
+ SR(DOMAIN0_PG_CONFIG), \
+ SR(DOMAIN1_PG_CONFIG), \
+ SR(DOMAIN2_PG_CONFIG), \
+ SR(DOMAIN3_PG_CONFIG), \
+ SR(DOMAIN4_PG_CONFIG), \
+ SR(DOMAIN5_PG_CONFIG), \
+ SR(DOMAIN6_PG_CONFIG), \
+ SR(DOMAIN7_PG_CONFIG), \
+ SR(DOMAIN0_PG_STATUS), \
+ SR(DOMAIN1_PG_STATUS), \
+ SR(DOMAIN2_PG_STATUS), \
+ SR(DOMAIN3_PG_STATUS), \
+ SR(DOMAIN4_PG_STATUS), \
+ SR(DOMAIN5_PG_STATUS), \
+ SR(DOMAIN6_PG_STATUS), \
+ SR(DOMAIN7_PG_STATUS), \
+ SR(D1VGA_CONTROL), \
+ SR(D2VGA_CONTROL), \
+ SR(D3VGA_CONTROL), \
+ SR(D4VGA_CONTROL), \
+ SR(DC_IP_REQUEST_CNTL), \
+ BL_REG_LIST()
struct dce_hwseq_registers {
+
+ /* Backlight registers */
+ uint32_t LVTMA_PWRSEQ_CNTL;
+ uint32_t LVTMA_PWRSEQ_STATE;
+
uint32_t DCFE_CLOCK_CONTROL[6];
uint32_t DCFEV_CLOCK_CONTROL;
uint32_t DC_MEM_GLOBAL_PWR_REQ_CNTL;
@@ -376,20 +393,28 @@ struct dce_hwseq_registers {
HWS_SF(BLND_, V_UPDATE_LOCK, BLND_SCL_V_UPDATE_LOCK, mask_sh),\
HWS_SF(BLND_, V_UPDATE_LOCK, BLND_DCP_GRPH_SURF_V_UPDATE_LOCK, mask_sh),\
HWS_SF(BLND_, CONTROL, BLND_MODE, mask_sh),\
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
#define HWSEQ_DCE10_MASK_SH_LIST(mask_sh)\
HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE_),\
HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND_),\
- HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
+ HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_), \
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_DCE11_MASK_SH_LIST(mask_sh)\
HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
SF(DCFEV_CLOCK_CONTROL, DCFEV_CLOCK_ENABLE, mask_sh),\
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_)
#define HWSEQ_DCE112_MASK_SH_LIST(mask_sh)\
HWSEQ_DCE10_MASK_SH_LIST(mask_sh),\
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh),\
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh),\
HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_)
#define HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)\
@@ -397,14 +422,18 @@ struct dce_hwseq_registers {
SF(DCHUB_FB_LOCATION, FB_BASE, mask_sh),\
SF(DCHUB_AGP_BASE, AGP_BASE, mask_sh),\
SF(DCHUB_AGP_BOT, AGP_BOT, mask_sh),\
- SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh)
+ SF(DCHUB_AGP_TOP, AGP_TOP, mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_DCE12_MASK_SH_LIST(mask_sh)\
HWSEQ_DCEF_MASK_SH_LIST(mask_sh, DCFE0_DCFE_),\
HWSEQ_BLND_MASK_SH_LIST(mask_sh, BLND0_BLND_),\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, CRTC0_),\
HWSEQ_PHYPLL_MASK_SH_LIST(mask_sh, CRTC0_),\
- HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh)
+ HWSEQ_GFX9_DCHUB_MASK_SH_LIST(mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
@@ -416,35 +445,12 @@ struct dce_hwseq_registers {
HWS_SF(DPP_TOP0_, DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh), \
HWS_SF(OPP_PIPE0_, OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh),\
HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \
- HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
- HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
- HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
- HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
- HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, mask_sh), \
+ HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \
+ HWS_SF(, DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \
HWS_SF(, DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \
HWS_SF(, DCFCLK_CNTL, DCFCLK_GATE_DIS, mask_sh)
@@ -468,7 +474,34 @@ struct dce_hwseq_registers {
HWS_SF(, VM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, PHYSICAL_PAGE_ADDR_LO32, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, PHYSICAL_PAGE_NUMBER_MSB, mask_sh),\
HWS_SF(, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, PHYSICAL_PAGE_NUMBER_LSB, mask_sh),\
- HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh)
+ HWS_SF(, MC_VM_SYSTEM_APERTURE_LOW_ADDR, LOGICAL_ADDR, mask_sh),\
+ HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_CONFIG, DOMAIN0_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_CONFIG, DOMAIN1_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_CONFIG, DOMAIN2_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_CONFIG, DOMAIN3_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN4_PG_CONFIG, DOMAIN4_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN5_PG_CONFIG, DOMAIN5_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN6_PG_CONFIG, DOMAIN6_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_FORCEON, mask_sh), \
+ HWS_SF(, DOMAIN7_PG_CONFIG, DOMAIN7_POWER_GATE, mask_sh), \
+ HWS_SF(, DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN1_PG_STATUS, DOMAIN1_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN2_PG_STATUS, DOMAIN2_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN3_PG_STATUS, DOMAIN3_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN4_PG_STATUS, DOMAIN4_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN5_PG_STATUS, DOMAIN5_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN6_PG_STATUS, DOMAIN6_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
+ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
+ HWS_SF(, LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, mask_sh)
#define HWSEQ_REG_FIELD_LIST(type) \
type DCFE_CLOCK_ENABLE; \
@@ -498,7 +531,9 @@ struct dce_hwseq_registers {
type PHYSICAL_PAGE_NUMBER_LSB;\
type LOGICAL_ADDR; \
type ENABLE_L1_TLB;\
- type SYSTEM_ACCESS_MODE;
+ type SYSTEM_ACCESS_MODE;\
+ type LVTMA_BLON;\
+ type LVTMA_PWRSEQ_TARGET_STATE_R;
#define HWSEQ_DCN_REG_FIELD_LIST(type) \
type VUPDATE_NO_LOCK_EVENT_CLEAR; \
@@ -524,6 +559,8 @@ struct dce_hwseq_registers {
type DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE;\
type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_VALUE;\
type DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE;\
+ type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE;\
+ type DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE;\
type DCHUBBUB_ARB_SAT_LEVEL;\
type DCHUBBUB_ARB_MIN_REQ_OUTSTAND;\
type OPP_PIPE_CLOCK_EN;\
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 @@
#define CTX \
ipp_dce->base.ctx
+
static void dce_ipp_cursor_set_position(
struct input_pixel_processor *ipp,
const struct dc_cursor_position *position,
@@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
}
+
static void dce_ipp_program_prescale(
struct input_pixel_processor *ipp,
struct ipp_prescale_params *params)
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 @@
#define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
#define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
-/* all values are in milliseconds */
-/* For eDP, after power-up/power/down,
- * 300/500 msec max. delay from LCDVCC to black video generation */
-#define PANEL_POWER_UP_TIMEOUT 300
-#define PANEL_POWER_DOWN_TIMEOUT 500
-#define HPD_CHECK_INTERVAL 10
-
/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
#define TMDS_MIN_PIXEL_CLOCK 25000
/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
@@ -122,8 +115,6 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
.psr_program_dp_dphy_fast_training =
dce110_psr_program_dp_dphy_fast_training,
.psr_program_secondary_packet = dce110_psr_program_secondary_packet,
- .backlight_control = dce110_link_encoder_edp_backlight_control,
- .power_control = dce110_link_encoder_edp_power_control,
.connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
.enable_hpd = dce110_link_encoder_enable_hpd,
.disable_hpd = dce110_link_encoder_disable_hpd,
@@ -493,165 +484,6 @@ static void configure_encoder(
REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
}
-static bool is_panel_powered_on(struct dce110_link_encoder *enc110)
-{
- bool ret;
- uint32_t value;
-
- REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
- ret = value;
-
- return ret == 1;
-}
-
-
-/* TODO duplicate of dc_link.c version */
-static struct gpio *get_hpd_gpio(const struct link_encoder *enc)
-{
- enum bp_result bp_result;
- struct dc_bios *dcb = enc->ctx->dc_bios;
- struct graphics_object_hpd_info hpd_info;
- struct gpio_pin_info pin_info;
-
- if (dcb->funcs->get_hpd_info(dcb, enc->connector, &hpd_info) != BP_RESULT_OK)
- return NULL;
-
- bp_result = dcb->funcs->get_gpio_pin_info(dcb,
- hpd_info.hpd_int_gpio_uid, &pin_info);
-
- if (bp_result != BP_RESULT_OK) {
- ASSERT(bp_result == BP_RESULT_NORECORD);
- return NULL;
- }
-
- return dal_gpio_service_create_irq(
- enc->ctx->gpio_service,
- pin_info.offset,
- pin_info.mask);
-}
-
-/*
- * @brief
- * eDP only.
- */
-static void link_encoder_edp_wait_for_hpd_ready(
- struct dce110_link_encoder *enc110,
- bool power_up)
-{
- struct dc_context *ctx = enc110->base.ctx;
- struct graphics_object_id connector = enc110->base.connector;
- struct gpio *hpd;
- bool edp_hpd_high = false;
- uint32_t time_elapsed = 0;
- uint32_t timeout = power_up ?
- PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
-
- if (dal_graphics_object_id_get_connector_id(connector) !=
- CONNECTOR_ID_EDP) {
- BREAK_TO_DEBUGGER();
- return;
- }
-
- if (!power_up)
- /* from KV, we will not HPD low after turning off VCC -
- * instead, we will check the SW timer in power_up(). */
- return;
-
- /* when we power on/off the eDP panel,
- * we need to wait until SENSE bit is high/low */
-
- /* obtain HPD */
- /* TODO what to do with this? */
- hpd = get_hpd_gpio(&enc110->base);
-
- if (!hpd) {
- BREAK_TO_DEBUGGER();
- return;
- }
-
- dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
-
- /* wait until timeout or panel detected */
-
- do {
- uint32_t detected = 0;
-
- dal_gpio_get_value(hpd, &detected);
-
- if (!(detected ^ power_up)) {
- edp_hpd_high = true;
- break;
- }
-
- msleep(HPD_CHECK_INTERVAL);
-
- time_elapsed += HPD_CHECK_INTERVAL;
- } while (time_elapsed < timeout);
-
- dal_gpio_close(hpd);
-
- dal_gpio_destroy_irq(&hpd);
-
- if (false == edp_hpd_high) {
- dm_logger_write(ctx->logger, LOG_ERROR,
- "%s: wait timed out!\n", __func__);
- }
-}
-
-/*
- * @brief
- * eDP only. Control the power of the eDP panel.
- */
-void dce110_link_encoder_edp_power_control(
- struct link_encoder *enc,
- bool power_up)
-{
- struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
- struct dc_context *ctx = enc110->base.ctx;
- struct bp_transmitter_control cntl = { 0 };
- enum bp_result bp_result;
-
- if (dal_graphics_object_id_get_connector_id(enc110->base.connector) !=
- CONNECTOR_ID_EDP) {
- BREAK_TO_DEBUGGER();
- return;
- }
-
- if ((power_up && !is_panel_powered_on(enc110)) ||
- (!power_up && is_panel_powered_on(enc110))) {
-
- /* Send VBIOS command to prompt eDP panel power */
-
- dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
- "%s: Panel Power action: %s\n",
- __func__, (power_up ? "On":"Off"));
-
- cntl.action = power_up ?
- TRANSMITTER_CONTROL_POWER_ON :
- TRANSMITTER_CONTROL_POWER_OFF;
- cntl.transmitter = enc110->base.transmitter;
- cntl.connector_obj_id = enc110->base.connector;
- cntl.coherent = false;
- cntl.lanes_number = LANE_COUNT_FOUR;
- cntl.hpd_sel = enc110->base.hpd_source;
-
- bp_result = link_transmitter_control(enc110, &cntl);
-
- if (BP_RESULT_OK != bp_result) {
-
- dm_logger_write(ctx->logger, LOG_ERROR,
- "%s: Panel Power bp_result: %d\n",
- __func__, bp_result);
- }
- } else {
- dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
- "%s: Skipping Panel Power action: %s\n",
- __func__, (power_up ? "On":"Off"));
- }
-
- link_encoder_edp_wait_for_hpd_ready(enc110, true);
-}
-
static void aux_initialize(
struct dce110_link_encoder *enc110)
{
@@ -674,16 +506,6 @@ static void aux_initialize(
}
-/*todo: cloned in stream enc, fix*/
-static bool is_panel_backlight_on(struct dce110_link_encoder *enc110)
-{
- uint32_t value;
-
- REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
-
- return value;
-}
-
void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
bool exit_link_training_required)
{
@@ -718,69 +540,6 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
DP_SEC_GSP0_PRIORITY, 1);
}
-/*todo: cloned in stream enc, fix*/
-/*
- * @brief
- * eDP only. Control the backlight of the eDP panel
- */
-void dce110_link_encoder_edp_backlight_control(
- struct link_encoder *enc,
- bool enable)
-{
- struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
- struct dc_context *ctx = enc110->base.ctx;
- struct bp_transmitter_control cntl = { 0 };
-
- if (dal_graphics_object_id_get_connector_id(enc110->base.connector)
- != CONNECTOR_ID_EDP) {
- BREAK_TO_DEBUGGER();
- return;
- }
-
- if (enable && is_panel_backlight_on(enc110)) {
- dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
- "%s: panel already powered up. Do nothing.\n",
- __func__);
- return;
- }
-
- if (!enable && !is_panel_backlight_on(enc110)) {
- dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
- "%s: panel already powered down. Do nothing.\n",
- __func__);
- return;
- }
-
- /* Send VBIOS command to control eDP panel backlight */
-
- dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
- "%s: backlight action: %s\n",
- __func__, (enable ? "On":"Off"));
-
- cntl.action = enable ?
- TRANSMITTER_CONTROL_BACKLIGHT_ON :
- TRANSMITTER_CONTROL_BACKLIGHT_OFF;
- /*cntl.engine_id = ctx->engine;*/
- cntl.transmitter = enc110->base.transmitter;
- cntl.connector_obj_id = enc110->base.connector;
- /*todo: unhardcode*/
- cntl.lanes_number = LANE_COUNT_FOUR;
- cntl.hpd_sel = enc110->base.hpd_source;
-
- /* For eDP, the following delays might need to be considered
- * after link training completed:
- * idle period - min. accounts for required BS-Idle pattern,
- * max. allows for source frame synchronization);
- * 50 msec max. delay from valid video data from source
- * to video on dislpay or backlight enable.
- *
- * Disable the delay for now.
- * Enable it in the future if necessary.
- */
- /* dc_service_sleep_in_milliseconds(50); */
- link_transmitter_control(enc110, &cntl);
-}
-
static bool is_dig_enabled(const struct dce110_link_encoder *enc110)
{
uint32_t value;
@@ -998,11 +757,6 @@ void dce110_link_encoder_construct(
enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
}
- dm_logger_write(init_data->ctx->logger, LOG_I2C_AUX,
- "Using channel: %s [%d]\n",
- DECODE_CHANNEL_ID(init_data->channel),
- init_data->channel);
-
/* Override features with DCE-specific values */
if (BP_RESULT_OK == bp_funcs->get_encoder_cap_info(
enc110->base.ctx->dc_bios, enc110->base.id,
@@ -1092,7 +846,7 @@ void dce110_link_encoder_hw_init(
ASSERT(result == BP_RESULT_OK);
} else if (enc110->base.connector.id == CONNECTOR_ID_EDP) {
- enc->funcs->power_control(&enc110->base, true);
+ ctx->dc->hwss.edp_power_control(enc, true);
}
aux_initialize(enc110);
@@ -1279,7 +1033,8 @@ void dce110_link_encoder_enable_dp_mst_output(
*/
void dce110_link_encoder_disable_output(
struct link_encoder *enc,
- enum signal_type signal)
+ enum signal_type signal,
+ struct dc_link *link)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
struct dc_context *ctx = enc110->base.ctx;
@@ -1291,7 +1046,7 @@ void dce110_link_encoder_disable_output(
return;
}
if (enc110->base.connector.id == CONNECTOR_ID_EDP)
- dce110_link_encoder_edp_backlight_control(enc, false);
+ ctx->dc->hwss.edp_backlight_control(link, false);
/* Power-down RX and disable GPU PHY should be paired.
* Disabling PHY without powering down RX may cause
* symbol lock loss, on which we will get DP Sink interrupt. */
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 @@
SRI(DC_HPD_CONTROL, HPD, id)
#define LE_COMMON_REG_LIST_BASE(id) \
- SR(LVTMA_PWRSEQ_CNTL), \
- SR(LVTMA_PWRSEQ_STATE), \
SR(DMCU_RAM_ACCESS_CTRL), \
SR(DMCU_IRAM_RD_CTRL), \
SR(DMCU_IRAM_RD_DATA), \
@@ -104,8 +102,7 @@
LE_COMMON_REG_LIST_BASE(id), \
SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
- SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \
- SR(DMU_MEM_PWR_CNTL)
+ SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
struct dce110_link_enc_aux_registers {
uint32_t AUX_CONTROL;
@@ -117,10 +114,6 @@ struct dce110_link_enc_hpd_registers {
};
struct dce110_link_enc_registers {
- /* Backlight registers */
- uint32_t LVTMA_PWRSEQ_CNTL;
- uint32_t LVTMA_PWRSEQ_STATE;
-
/* DMCU registers */
uint32_t MASTER_COMM_DATA_REG1;
uint32_t MASTER_COMM_DATA_REG2;
@@ -236,7 +229,8 @@ void dce110_link_encoder_enable_dp_mst_output(
/* disable PHY output */
void dce110_link_encoder_disable_output(
struct link_encoder *link_enc,
- enum signal_type signal);
+ enum signal_type signal,
+ struct dc_link *link);
/* set DP lane settings */
void dce110_link_encoder_dp_set_lane_settings(
@@ -252,14 +246,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table(
struct link_encoder *enc,
const struct link_mst_stream_allocation_table *table);
-void dce110_link_encoder_edp_backlight_control(
- struct link_encoder *enc,
- bool enable);
-
-void dce110_link_encoder_edp_power_control(
- struct link_encoder *enc,
- bool power_up);
-
void dce110_link_encoder_connect_dig_be_to_fe(
struct link_encoder *enc,
enum engine_id engine,
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(
enum surface_pixel_format format)
{
uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */
- uint32_t grph_depth, grph_format;
+ uint32_t grph_depth = 0, grph_format = 0;
uint32_t sign = 0, floating = 0;
if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
@@ -685,9 +685,6 @@ void dce_mem_input_construct(
dce_mi->regs = regs;
dce_mi->shifts = mi_shift;
dce_mi->masks = mi_mask;
-
- dce_mi->base.mpcc_id = 0xf;
- dce_mi->base.opp_id = 0xf;
}
void dce112_mem_input_construct(
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)
*pool = NULL;
}
-enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state)
+enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
{
if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
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(
uint8_t num_virtual_links,
struct dc *dc);
-enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state);
+enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps);
enum dc_status dce100_add_stream_to_ctx(
struct dc *dc,
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,
compressor->base.lpt_channels_num = 0;
compressor->base.attached_inst = 0;
compressor->base.is_enabled = false;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
compressor->base.funcs = &dce110_compressor_funcs;
#endif
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 @@
#include "dce110_hw_sequencer.h"
#include "dce110_timing_generator.h"
#include "dce/dce_hwseq.h"
+#include "gpio_service_interface.h"
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
#include "dce110_compressor.h"
#endif
@@ -45,10 +46,10 @@
#include "transform.h"
#include "stream_encoder.h"
#include "link_encoder.h"
+#include "link_hwss.h"
#include "clock_source.h"
#include "abm.h"
#include "audio.h"
-#include "dce/dce_hwseq.h"
#include "reg_helper.h"
/* include DCE11 register header files */
@@ -56,6 +57,24 @@
#include "dce/dce_11_0_sh_mask.h"
#include "custom_float.h"
+/*
+ * All values are in milliseconds;
+ * For eDP, after power-up/power/down,
+ * 300/500 msec max. delay from LCDVCC to black video generation
+ */
+#define PANEL_POWER_UP_TIMEOUT 300
+#define PANEL_POWER_DOWN_TIMEOUT 500
+#define HPD_CHECK_INTERVAL 10
+
+#define CTX \
+ hws->ctx
+#define REG(reg)\
+ hws->regs->reg
+
+#undef FN
+#define FN(reg_name, field_name) \
+ hws->shifts->field_name, hws->masks->field_name
+
struct dce110_hw_seq_reg_offsets {
uint32_t crtc;
};
@@ -761,10 +780,216 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
}
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
+/*todo: cloned in stream enc, fix*/
+static bool is_panel_backlight_on(struct dce_hwseq *hws)
+{
+ uint32_t value;
+
+ REG_GET(LVTMA_PWRSEQ_CNTL, LVTMA_BLON, &value);
+
+ return value;
+}
+
+static bool is_panel_powered_on(struct dce_hwseq *hws)
+{
+ uint32_t value;
+
+ REG_GET(LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R, &value);
+ return value == 1;
+}
+
+static enum bp_result link_transmitter_control(
+ struct dc_bios *bios,
+ struct bp_transmitter_control *cntl)
+{
+ enum bp_result result;
+
+ result = bios->funcs->transmitter_control(bios, cntl);
+
+ return result;
+}
+
+/*
+ * @brief
+ * eDP only.
+ */
+void hwss_edp_wait_for_hpd_ready(
+ struct link_encoder *enc,
+ bool power_up)
+{
+ struct dc_context *ctx = enc->ctx;
+ struct graphics_object_id connector = enc->connector;
+ struct gpio *hpd;
+ bool edp_hpd_high = false;
+ uint32_t time_elapsed = 0;
+ uint32_t timeout = power_up ?
+ PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
+
+ if (dal_graphics_object_id_get_connector_id(connector)
+ != CONNECTOR_ID_EDP) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ if (!power_up)
+ /*
+ * From KV, we will not HPD low after turning off VCC -
+ * instead, we will check the SW timer in power_up().
+ */
+ return;
+
+ /*
+ * When we power on/off the eDP panel,
+ * we need to wait until SENSE bit is high/low.
+ */
+
+ /* obtain HPD */
+ /* TODO what to do with this? */
+ hpd = get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service);
+
+ if (!hpd) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
+
+ /* wait until timeout or panel detected */
+
+ do {
+ uint32_t detected = 0;
+
+ dal_gpio_get_value(hpd, &detected);
+
+ if (!(detected ^ power_up)) {
+ edp_hpd_high = true;
+ break;
+ }
+
+ msleep(HPD_CHECK_INTERVAL);
+
+ time_elapsed += HPD_CHECK_INTERVAL;
+ } while (time_elapsed < timeout);
+
+ dal_gpio_close(hpd);
+
+ dal_gpio_destroy_irq(&hpd);
+
+ if (false == edp_hpd_high) {
+ dm_logger_write(ctx->logger, LOG_ERROR,
+ "%s: wait timed out!\n", __func__);
+ }
+}
+
+void hwss_edp_power_control(
+ struct link_encoder *enc,
+ bool power_up)
+{
+ struct dc_context *ctx = enc->ctx;
+ struct dce_hwseq *hwseq = ctx->dc->hwseq;
+ struct bp_transmitter_control cntl = { 0 };
+ enum bp_result bp_result;
+
+
+ if (dal_graphics_object_id_get_connector_id(enc->connector)
+ != CONNECTOR_ID_EDP) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ if (power_up != is_panel_powered_on(hwseq)) {
+ /* Send VBIOS command to prompt eDP panel power */
+
+ dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+ "%s: Panel Power action: %s\n",
+ __func__, (power_up ? "On":"Off"));
+
+ cntl.action = power_up ?
+ TRANSMITTER_CONTROL_POWER_ON :
+ TRANSMITTER_CONTROL_POWER_OFF;
+ cntl.transmitter = enc->transmitter;
+ cntl.connector_obj_id = enc->connector;
+ cntl.coherent = false;
+ cntl.lanes_number = LANE_COUNT_FOUR;
+ cntl.hpd_sel = enc->hpd_source;
+
+ bp_result = link_transmitter_control(ctx->dc_bios, &cntl);
+
+ if (bp_result != BP_RESULT_OK)
+ dm_logger_write(ctx->logger, LOG_ERROR,
+ "%s: Panel Power bp_result: %d\n",
+ __func__, bp_result);
+ } else {
+ dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+ "%s: Skipping Panel Power action: %s\n",
+ __func__, (power_up ? "On":"Off"));
+ }
+
+ hwss_edp_wait_for_hpd_ready(enc, true);
+}
+
+/*todo: cloned in stream enc, fix*/
+/*
+ * @brief
+ * eDP only. Control the backlight of the eDP panel
+ */
+void hwss_edp_backlight_control(
+ struct dc_link *link,
+ bool enable)
+{
+ struct dce_hwseq *hws = link->dc->hwseq;
+ struct dc_context *ctx = link->dc->ctx;
+ struct bp_transmitter_control cntl = { 0 };
+
+ if (dal_graphics_object_id_get_connector_id(link->link_id)
+ != CONNECTOR_ID_EDP) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ if (enable && is_panel_backlight_on(hws)) {
+ dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+ "%s: panel already powered up. Do nothing.\n",
+ __func__);
+ return;
+ }
+
+ /* Send VBIOS command to control eDP panel backlight */
+
+ dm_logger_write(ctx->logger, LOG_HW_RESUME_S3,
+ "%s: backlight action: %s\n",
+ __func__, (enable ? "On":"Off"));
+
+ cntl.action = enable ?
+ TRANSMITTER_CONTROL_BACKLIGHT_ON :
+ TRANSMITTER_CONTROL_BACKLIGHT_OFF;
+
+ /*cntl.engine_id = ctx->engine;*/
+ cntl.transmitter = link->link_enc->transmitter;
+ cntl.connector_obj_id = link->link_enc->connector;
+ /*todo: unhardcode*/
+ cntl.lanes_number = LANE_COUNT_FOUR;
+ cntl.hpd_sel = link->link_enc->hpd_source;
+
+ /* For eDP, the following delays might need to be considered
+ * after link training completed:
+ * idle period - min. accounts for required BS-Idle pattern,
+ * max. allows for source frame synchronization);
+ * 50 msec max. delay from valid video data from source
+ * to video on dislpay or backlight enable.
+ *
+ * Disable the delay for now.
+ * Enable it in the future if necessary.
+ */
+ /* dc_service_sleep_in_milliseconds(50); */
+ link_transmitter_control(link->dc->ctx->dc_bios, &cntl);
+}
+
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
{
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
+ struct dc *dc = pipe_ctx->stream->ctx->dc;
if (pipe_ctx->stream_res.audio) {
pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
@@ -775,6 +1000,13 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
else
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
pipe_ctx->stream_res.stream_enc);
+ /*don't free audio if it is from retrain or internal disable stream*/
+ if (option == FREE_ACQUIRED_RESOURCE && dc->caps.dynamic_audio == true) {
+ /*we have to dynamic arbitrate the audio endpoints*/
+ pipe_ctx->stream_res.audio = NULL;
+ /*we free the resource, need reset is_audio_acquired*/
+ update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, pipe_ctx->stream_res.audio, false);
+ }
/* TODO: notify audio driver for if audio modes list changed
* add audio mode list change flag */
@@ -798,7 +1030,7 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
/* blank at encoder level */
if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
if (pipe_ctx->stream->sink->link->connector_signal == SIGNAL_TYPE_EDP)
- link->link_enc->funcs->backlight_control(link->link_enc, false);
+ hwss_edp_backlight_control(link, false);
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
}
link->link_enc->funcs->connect_dig_be_to_fe(
@@ -820,7 +1052,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
params.link_settings.link_rate = link_settings->link_rate;
pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
if (link->connector_signal == SIGNAL_TYPE_EDP)
- link->link_enc->funcs->backlight_control(link->link_enc, true);
+ hwss_edp_backlight_control(link, true);
}
@@ -1132,33 +1364,21 @@ static enum dc_status apply_single_controller_ctx_to_hw(
resource_build_info_frame(pipe_ctx);
dce110_update_info_frame(pipe_ctx);
if (!pipe_ctx_old->stream) {
- core_link_enable_stream(context, pipe_ctx);
-
-
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
- dce110_unblank_stream(pipe_ctx,
- &stream->sink->link->cur_link_settings);
+ if (!pipe_ctx->stream->dpms_off)
+ core_link_enable_stream(context, pipe_ctx);
}
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
- /* program_scaler and allocate_mem_input are not new asic */
- if ((!pipe_ctx_old ||
- memcmp(&pipe_ctx_old->plane_res.scl_data, &pipe_ctx->plane_res.scl_data,
- sizeof(struct scaler_data)) != 0) &&
- pipe_ctx->plane_state) {
- program_scaler(dc, pipe_ctx);
- }
/* mst support - use total stream count */
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
- if (pipe_ctx->plane_res.mi->funcs->allocate_mem_input != NULL)
-#endif
+ if (pipe_ctx->plane_res.mi != NULL) {
pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
- pipe_ctx->plane_res.mi,
- stream->timing.h_total,
- stream->timing.v_total,
- stream->timing.pix_clk_khz,
- context->stream_count);
+ pipe_ctx->plane_res.mi,
+ stream->timing.h_total,
+ stream->timing.v_total,
+ stream->timing.pix_clk_khz,
+ context->stream_count);
+ }
pipe_ctx->stream->sink->link->psr_enabled = false;
@@ -1171,6 +1391,16 @@ static void power_down_encoders(struct dc *dc)
{
int i;
enum connector_id connector_id;
+ enum signal_type signal = SIGNAL_TYPE_NONE;
+
+ /* do not know BIOS back-front mapping, simply blank all. It will not
+ * hurt for non-DP
+ */
+ for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
+ dc->res_pool->stream_enc[i]->funcs->dp_blank(
+ dc->res_pool->stream_enc[i]);
+ }
+
for (i = 0; i < dc->link_count; i++) {
connector_id = dal_graphics_object_id_get_connector_id(dc->links[i]->link_id);
if ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
@@ -1178,10 +1408,12 @@ static void power_down_encoders(struct dc *dc)
if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
dp_receiver_power_ctrl(dc->links[i], false);
+ if (connector_id == CONNECTOR_ID_EDP)
+ signal = SIGNAL_TYPE_EDP;
}
dc->links[i]->link_enc->funcs->disable_output(
- dc->links[i]->link_enc, SIGNAL_TYPE_NONE);
+ dc->links[i]->link_enc, signal, dc->links[i]);
}
}
@@ -1218,7 +1450,7 @@ static void power_down_all_hw_blocks(struct dc *dc)
power_down_clock_sources(dc);
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
#endif
@@ -1325,7 +1557,7 @@ static void set_safe_displaymarks(
SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK };
for (i = 0; i < MAX_PIPES; i++) {
- if (res_ctx->pipe_ctx[i].stream == NULL)
+ if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL)
continue;
res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks(
@@ -1334,6 +1566,7 @@ static void set_safe_displaymarks(
max_marks,
max_marks,
MAX_WATERMARK);
+
if (i == underlay_idx)
res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks(
res_ctx->pipe_ctx[i].plane_res.mi,
@@ -1341,6 +1574,7 @@ static void set_safe_displaymarks(
max_marks,
max_marks,
MAX_WATERMARK);
+
}
}
@@ -1391,7 +1625,7 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
if (events->cursor_update)
value |= 0x2;
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
value |= 0x84;
#endif
@@ -1521,7 +1755,7 @@ static void apply_min_clocks(
}
}
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
/*
* Check if FBC can be enabled
@@ -1644,7 +1878,10 @@ static void dce110_reset_hw_ctx_wrap(
pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
struct clock_source *old_clk = pipe_ctx_old->clock_source;
- core_link_disable_stream(pipe_ctx_old);
+ /* disable already, no need to disable again */
+ if (pipe_ctx->stream && !pipe_ctx->stream->dpms_off)
+ core_link_disable_stream(pipe_ctx_old, FREE_ACQUIRED_RESOURCE);
+
pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true);
if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) {
dm_error("DC: failed to blank crtc!\n");
@@ -1713,7 +1950,7 @@ enum dc_status dce110_apply_ctx_to_hw(
set_safe_displaymarks(&context->res_ctx, dc->res_pool);
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
#endif
@@ -1889,6 +2126,7 @@ enum dc_status dce110_apply_ctx_to_hw(
return status;
}
+ /* pplib is notified if disp_num changed */
dc->hwss.set_bandwidth(dc, context, true);
/* to save power */
@@ -1896,7 +2134,7 @@ enum dc_status dce110_apply_ctx_to_hw(
dcb->funcs->set_scratch_critical_state(dcb, false);
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
enable_fbc(dc, context);
@@ -2305,7 +2543,7 @@ static void init_hw(struct dc *dc)
abm->funcs->init_backlight(abm);
abm->funcs->abm_init(abm);
}
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
if (dc->fbc_compressor)
dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor);
#endif
@@ -2490,6 +2728,8 @@ static void dce110_program_front_end_for_pipe(
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
struct xfm_grph_csc_adjustment adjust;
struct out_csc_color_matrix tbl_entry;
+ struct pipe_ctx *cur_pipe_ctx =
+ &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
unsigned int i;
memset(&tbl_entry, 0, sizeof(tbl_entry));
@@ -2553,6 +2793,15 @@ static void dce110_program_front_end_for_pipe(
program_scaler(dc, pipe_ctx);
+#if defined(CONFIG_DRM_AMD_DC_FBC)
+ if (dc->fbc_compressor && old_pipe->stream) {
+ if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
+ dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
+ else
+ enable_fbc(dc, dc->current_state);
+ }
+#endif
+
mi->funcs->mem_input_program_surface_config(
mi,
plane_state->format,
@@ -2571,6 +2820,14 @@ static void dce110_program_front_end_for_pipe(
&plane_state->tiling_info,
plane_state->rotation);
+ /* Moved programming gamma from dc to hwss */
+ if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
+ dc->hwss.set_input_transfer_func(
+ pipe_ctx, pipe_ctx->plane_state);
+ dc->hwss.set_output_transfer_func(
+ pipe_ctx, pipe_ctx->stream);
+ }
+
dm_logger_write(dc->ctx->logger, LOG_SURFACE,
"Pipe:%d 0x%x: addr hi:0x%x, "
"addr low:0x%x, "
@@ -2683,7 +2940,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
}
}
-static void ready_shared_resources(struct dc *dc) {}
+static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
static void optimize_shared_resources(struct dc *dc) {}
@@ -2720,7 +2977,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect,
.ready_shared_resources = ready_shared_resources,
.optimize_shared_resources = optimize_shared_resources,
-
+ .edp_backlight_control = hwss_edp_backlight_control,
+ .edp_power_control = hwss_edp_power_control,
};
void dce110_hw_sequencer_construct(struct dc *dc)
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(
void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
-void dce110_disable_stream(struct pipe_ctx *pipe_ctx);
+void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option);
void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings);
@@ -68,5 +68,14 @@ void dce110_fill_display_configs(
uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
void dp_receiver_power_ctrl(struct dc_link *link, bool on);
+
+void hwss_edp_power_control(
+ struct link_encoder *enc,
+ bool power_up);
+
+void hwss_edp_backlight_control(
+ struct dc_link *link,
+ bool enable);
+
#endif /* __DC_HWSS_DCE110_H__ */
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 @@
#include "dce/dce_abm.h"
#include "dce/dce_dmcu.h"
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
#include "dce110/dce110_compressor.h"
#endif
@@ -849,7 +849,7 @@ static bool dce110_validate_bandwidth(
static bool dce110_validate_surface_sets(
struct dc_state *context)
{
- int i;
+ int i, j;
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
@@ -858,14 +858,27 @@ static bool dce110_validate_surface_sets(
if (context->stream_status[i].plane_count > 2)
return false;
- if ((context->stream_status[i].plane_states[i]->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) &&
- (context->stream_status[i].plane_states[i]->src_rect.width > 1920 ||
- context->stream_status[i].plane_states[i]->src_rect.height > 1080))
- return false;
+ for (j = 0; j < context->stream_status[i].plane_count; j++) {
+ struct dc_plane_state *plane =
+ context->stream_status[i].plane_states[j];
- /* irrespective of plane format, stream should be RGB encoded */
- if (context->streams[i]->timing.pixel_encoding != PIXEL_ENCODING_RGB)
- return false;
+ /* underlay validation */
+ if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+
+ if ((plane->src_rect.width > 1920 ||
+ plane->src_rect.height > 1080))
+ return false;
+
+ /* irrespective of plane format,
+ * stream should be RGB encoded
+ */
+ if (context->streams[i]->timing.pixel_encoding
+ != PIXEL_ENCODING_RGB)
+ return false;
+
+ }
+
+ }
}
return true;
@@ -1266,7 +1279,7 @@ static bool construct(
}
}
-#ifdef ENABLE_FBC
+#if defined(CONFIG_DRM_AMD_DC_FBC)
dc->fbc_compressor = dce110_compressor_create(ctx);
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 @@
DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \
dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \
- dcn10_mem_input.o dcn10_mpc.o \
- dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_dpp_cm_helper.o
+ dcn10_hubp.o dcn10_mpc.o \
+ dcn10_dpp_dscl.o dcn10_dpp_cm.o dcn10_cm_common.o
AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10))
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 @@
#include "reg_helper.h"
#include "dcn10_dpp.h"
-#include "dcn10_dpp_cm_helper.h"
+#include "dcn10_cm_common.h"
#define REG(reg) reg
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 @@
*
*/
-#ifndef __DAL_DPP_DCN10_CM_HELPER_H__
-#define __DAL_DPP_DCN10_CM_HELPER_H__
+#ifndef __DAL_DCN10_CM_COMMON_H__
+#define __DAL_DCN10_CM_COMMON_H__
#define TF_HELPER_REG_FIELD_LIST(type) \
type exp_region0_lut_offset; \
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 @@
#define BLACK_OFFSET_CBCR 0x8000
#define REG(reg)\
- xfm->tf_regs->reg
+ dpp->tf_regs->reg
#define CTX \
- xfm->base.ctx
+ dpp->base.ctx
#undef FN
#define FN(reg_name, field_name) \
- xfm->tf_shift->field_name, xfm->tf_mask->field_name
+ dpp->tf_shift->field_name, dpp->tf_mask->field_name
enum pixel_format_description {
PIXEL_FORMAT_FIXED = 0,
@@ -99,7 +99,7 @@ enum gamut_remap_select {
};
/* Program gamut remap in bypass mode */
-void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
+void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp)
{
REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
CM_GAMUT_REMAP_MODE, 0);
@@ -110,7 +110,7 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm)
bool dpp_get_optimal_number_of_taps(
- struct transform *xfm,
+ struct dpp *dpp,
struct scaler_data *scl_data,
const struct scaling_taps *in_taps)
{
@@ -154,28 +154,29 @@ bool dpp_get_optimal_number_of_taps(
else
scl_data->taps.h_taps_c = in_taps->h_taps_c;
- if (!xfm->ctx->dc->debug.always_scale) {
+ if (!dpp->ctx->dc->debug.always_scale) {
if (IDENTITY_RATIO(scl_data->ratios.horz))
scl_data->taps.h_taps = 1;
if (IDENTITY_RATIO(scl_data->ratios.vert))
scl_data->taps.v_taps = 1;
- if (IDENTITY_RATIO(scl_data->ratios.horz_c))
- scl_data->taps.h_taps_c = 1;
- if (IDENTITY_RATIO(scl_data->ratios.vert_c))
- scl_data->taps.v_taps_c = 1;
+ /*
+ * Spreadsheet doesn't handle taps_c is one properly,
+ * need to force Chroma to always be scaled to pass
+ * bandwidth validation.
+ */
}
return true;
}
-void dpp_reset(struct transform *xfm_base)
+void dpp_reset(struct dpp *dpp_base)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
- xfm->filter_h_c = NULL;
- xfm->filter_v_c = NULL;
- xfm->filter_h = NULL;
- xfm->filter_v = NULL;
+ dpp->filter_h_c = NULL;
+ dpp->filter_v_c = NULL;
+ dpp->filter_h = NULL;
+ dpp->filter_v = NULL;
/* set boundary mode to 0 */
REG_SET(DSCL_CONTROL, 0, SCL_BOUNDARY_MODE, 0);
@@ -183,28 +184,28 @@ void dpp_reset(struct transform *xfm_base)
-static void dcn10_dpp_cm_set_regamma_pwl(
- struct transform *xfm_base, const struct pwl_params *params)
+static void dpp1_cm_set_regamma_pwl(
+ struct dpp *dpp_base, const struct pwl_params *params)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
- dcn10_dpp_cm_power_on_regamma_lut(xfm_base, true);
- dcn10_dpp_cm_configure_regamma_lut(xfm_base, xfm->is_write_to_ram_a_safe);
+ dpp1_cm_power_on_regamma_lut(dpp_base, true);
+ dpp1_cm_configure_regamma_lut(dpp_base, dpp->is_write_to_ram_a_safe);
- if (xfm->is_write_to_ram_a_safe)
- dcn10_dpp_cm_program_regamma_luta_settings(xfm_base, params);
+ if (dpp->is_write_to_ram_a_safe)
+ dpp1_cm_program_regamma_luta_settings(dpp_base, params);
else
- dcn10_dpp_cm_program_regamma_lutb_settings(xfm_base, params);
+ dpp1_cm_program_regamma_lutb_settings(dpp_base, params);
- dcn10_dpp_cm_program_regamma_lut(
- xfm_base, params->rgb_resulted, params->hw_points_num);
+ dpp1_cm_program_regamma_lut(
+ dpp_base, params->rgb_resulted, params->hw_points_num);
}
-static void dcn10_dpp_cm_set_regamma_mode(
- struct transform *xfm_base,
+static void dpp1_cm_set_regamma_mode(
+ struct dpp *dpp_base,
enum opp_regamma mode)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
uint32_t re_mode = 0;
uint32_t obuf_bypass = 0; /* need for pipe split */
uint32_t obuf_hupscale = 0;
@@ -220,8 +221,8 @@ static void dcn10_dpp_cm_set_regamma_mode(
re_mode = 2;
break;
case OPP_REGAMMA_USER:
- re_mode = xfm->is_write_to_ram_a_safe ? 3 : 4;
- xfm->is_write_to_ram_a_safe = !xfm->is_write_to_ram_a_safe;
+ re_mode = dpp->is_write_to_ram_a_safe ? 3 : 4;
+ dpp->is_write_to_ram_a_safe = !dpp->is_write_to_ram_a_safe;
break;
default:
break;
@@ -233,7 +234,7 @@ static void dcn10_dpp_cm_set_regamma_mode(
OBUF_H_2X_UPSCALE_EN, obuf_hupscale);
}
-static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
+static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
enum pixel_format_description *fmt)
{
@@ -246,11 +247,11 @@ static void ippn10_setup_format_flags(enum surface_pixel_format input_format,\
*fmt = PIXEL_FORMAT_FIXED;
}
-static void ippn10_set_degamma_format_float(
- struct transform *xfm_base,
+static void dpp1_set_degamma_format_float(
+ struct dpp *dpp_base,
bool is_float)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (is_float) {
REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3);
@@ -261,8 +262,8 @@ static void ippn10_set_degamma_format_float(
}
}
-void ippn10_cnv_setup (
- struct transform *xfm_base,
+void dpp1_cnv_setup (
+ struct dpp *dpp_base,
enum surface_pixel_format input_format,
enum expansion_mode mode)
{
@@ -272,10 +273,10 @@ void ippn10_cnv_setup (
enum dc_color_space color_space;
enum dcn10_input_csc_select select;
bool is_float;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
bool force_disable_cursor = false;
- ippn10_setup_format_flags(input_format, &fmt);
+ dpp1_setup_format_flags(input_format, &fmt);
alpha_en = 1;
pixel_format = 0;
color_space = COLOR_SPACE_SRGB;
@@ -303,7 +304,7 @@ void ippn10_cnv_setup (
break;
}
- ippn10_set_degamma_format_float(xfm_base, is_float);
+ dpp1_set_degamma_format_float(dpp_base, is_float);
switch (input_format) {
case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
@@ -361,7 +362,7 @@ void ippn10_cnv_setup (
CNVC_SURFACE_PIXEL_FORMAT, pixel_format);
REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
- ippn10_program_input_csc(xfm_base, color_space, select);
+ dpp1_program_input_csc(dpp_base, color_space, select);
if (force_disable_cursor) {
REG_UPDATE(CURSOR_CONTROL,
@@ -371,54 +372,110 @@ void ippn10_cnv_setup (
}
}
-static const struct transform_funcs dcn10_dpp_funcs = {
- .transform_reset = dpp_reset,
- .transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale,
- .transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
- .transform_set_gamut_remap = dcn10_dpp_cm_set_gamut_remap,
- .opp_set_csc_adjustment = dcn10_dpp_cm_set_output_csc_adjustment,
- .opp_set_csc_default = dcn10_dpp_cm_set_output_csc_default,
- .opp_power_on_regamma_lut = dcn10_dpp_cm_power_on_regamma_lut,
- .opp_program_regamma_lut = dcn10_dpp_cm_program_regamma_lut,
- .opp_configure_regamma_lut = dcn10_dpp_cm_configure_regamma_lut,
- .opp_program_regamma_lutb_settings = dcn10_dpp_cm_program_regamma_lutb_settings,
- .opp_program_regamma_luta_settings = dcn10_dpp_cm_program_regamma_luta_settings,
- .opp_program_regamma_pwl = dcn10_dpp_cm_set_regamma_pwl,
- .opp_set_regamma_mode = dcn10_dpp_cm_set_regamma_mode,
- .ipp_set_degamma = ippn10_set_degamma,
- .ipp_program_input_lut = ippn10_program_input_lut,
- .ipp_program_degamma_pwl = ippn10_set_degamma_pwl,
- .ipp_setup = ippn10_cnv_setup,
- .ipp_full_bypass = ippn10_full_bypass,
+void dpp1_set_cursor_attributes(
+ struct dpp *dpp_base,
+ const struct dc_cursor_attributes *attr)
+{
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ enum dc_cursor_color_format color_format = attr->color_format;
+
+ REG_UPDATE_2(CURSOR0_CONTROL,
+ CUR0_MODE, color_format,
+ CUR0_EXPANSION_MODE, 0);
+
+ if (color_format == CURSOR_MODE_MONO) {
+ /* todo: clarify what to program these to */
+ REG_UPDATE(CURSOR0_COLOR0,
+ CUR0_COLOR0, 0x00000000);
+ REG_UPDATE(CURSOR0_COLOR1,
+ CUR0_COLOR1, 0xFFFFFFFF);
+ }
+
+ /* TODO: Fixed vs float */
+
+ REG_UPDATE_3(FORMAT_CONTROL,
+ CNVC_BYPASS, 0,
+ FORMAT_CONTROL__ALPHA_EN, 1,
+ FORMAT_EXPANSION_MODE, 0);
+}
+
+
+void dpp1_set_cursor_position(
+ struct dpp *dpp_base,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param,
+ uint32_t width)
+{
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
+ uint32_t cur_en = pos->enable ? 1 : 0;
+
+ if (src_x_offset >= (int)param->viewport_width)
+ cur_en = 0; /* not visible beyond right edge*/
+
+ if (src_x_offset + (int)width < 0)
+ cur_en = 0; /* not visible beyond left edge*/
+
+ REG_UPDATE(CURSOR0_CONTROL,
+ CUR0_ENABLE, cur_en);
+
+}
+
+static const struct dpp_funcs dcn10_dpp_funcs = {
+ .dpp_reset = dpp_reset,
+ .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
+ .dpp_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps,
+ .dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
+ .opp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment,
+ .opp_set_csc_default = dpp1_cm_set_output_csc_default,
+ .opp_power_on_regamma_lut = dpp1_cm_power_on_regamma_lut,
+ .opp_program_regamma_lut = dpp1_cm_program_regamma_lut,
+ .opp_configure_regamma_lut = dpp1_cm_configure_regamma_lut,
+ .opp_program_regamma_lutb_settings = dpp1_cm_program_regamma_lutb_settings,
+ .opp_program_regamma_luta_settings = dpp1_cm_program_regamma_luta_settings,
+ .opp_program_regamma_pwl = dpp1_cm_set_regamma_pwl,
+ .opp_set_regamma_mode = dpp1_cm_set_regamma_mode,
+ .ipp_set_degamma = dpp1_set_degamma,
+ .ipp_program_input_lut = dpp1_program_input_lut,
+ .ipp_program_degamma_pwl = dpp1_set_degamma_pwl,
+ .ipp_setup = dpp1_cnv_setup,
+ .ipp_full_bypass = dpp1_full_bypass,
+ .set_cursor_attributes = dpp1_set_cursor_attributes,
+ .set_cursor_position = dpp1_set_cursor_position,
};
+static struct dpp_caps dcn10_dpp_cap = {
+ .dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT,
+ .dscl_calc_lb_num_partitions = dpp1_dscl_calc_lb_num_partitions,
+};
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
-void dcn10_dpp_construct(
- struct dcn10_dpp *xfm,
+void dpp1_construct(
+ struct dcn10_dpp *dpp,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_dpp_registers *tf_regs,
const struct dcn_dpp_shift *tf_shift,
const struct dcn_dpp_mask *tf_mask)
{
- xfm->base.ctx = ctx;
+ dpp->base.ctx = ctx;
- xfm->base.inst = inst;
- xfm->base.funcs = &dcn10_dpp_funcs;
+ dpp->base.inst = inst;
+ dpp->base.funcs = &dcn10_dpp_funcs;
+ dpp->base.caps = &dcn10_dpp_cap;
- xfm->tf_regs = tf_regs;
- xfm->tf_shift = tf_shift;
- xfm->tf_mask = tf_mask;
+ dpp->tf_regs = tf_regs;
+ dpp->tf_shift = tf_shift;
+ dpp->tf_mask = tf_mask;
- xfm->lb_pixel_depth_supported =
+ dpp->lb_pixel_depth_supported =
LB_PIXEL_DEPTH_18BPP |
LB_PIXEL_DEPTH_24BPP |
LB_PIXEL_DEPTH_30BPP;
- xfm->lb_bits_per_entry = LB_BITS_PER_ENTRY;
- xfm->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
+ dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
+ dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
}
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 @@
#ifndef __DAL_DPP_DCN10_H__
#define __DAL_DPP_DCN10_H__
-#include "transform.h"
+#include "dpp.h"
-#define TO_DCN10_DPP(transform)\
- container_of(transform, struct dcn10_dpp, base)
+#define TO_DCN10_DPP(dpp)\
+ container_of(dpp, struct dcn10_dpp, base)
/* TODO: Use correct number of taps. Using polaris values for now */
#define LB_TOTAL_NUMBER_OF_ENTRIES 5124
@@ -112,7 +112,9 @@
SRI(CM_DGAM_CONTROL, CM, id), \
SRI(FORMAT_CONTROL, CNVC_CFG, id), \
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
- SRI(CURSOR0_CONTROL, CNVC_CUR, id)
+ SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
+ SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
+ SRI(CURSOR0_COLOR1, CNVC_CUR, id)
@@ -162,7 +164,8 @@
SRI(CM_IGAM_LUT_RW_CONTROL, CM, id), \
SRI(CM_IGAM_LUT_RW_INDEX, CM, id), \
SRI(CM_IGAM_LUT_SEQ_COLOR, CM, id), \
- SRI(CURSOR_CONTROL, CURSOR, id)
+ SRI(CURSOR_CONTROL, CURSOR, id), \
+ SRI(CM_CMOUT_CONTROL, CM, id)
#define TF_REG_LIST_SH_MASK_DCN(mask_sh)\
@@ -302,7 +305,9 @@
TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
- TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh)
+ TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
+ TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
+ TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@@ -397,6 +402,7 @@
TF_SF(CM0_CM_CONTROL, CM_BYPASS_EN, mask_sh), \
TF_SF(CM0_CM_IGAM_LUT_SEQ_COLOR, CM_IGAM_LUT_SEQ_COLOR, mask_sh), \
TF_SF(CNVC_CFG0_FORMAT_CONTROL, OUTPUT_FP, mask_sh), \
+ TF_SF(CM0_CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
@@ -545,6 +551,7 @@
type CM_RGAM_RAMA_EXP_REGION33_LUT_OFFSET; \
type CM_RGAM_RAMA_EXP_REGION33_NUM_SEGMENTS; \
type CM_RGAM_LUT_MODE; \
+ type CM_CMOUT_ROUND_TRUNC_MODE; \
type OBUF_BYPASS; \
type OBUF_H_2X_UPSCALE_EN; \
type CM_BLNDGAM_LUT_MODE; \
@@ -989,7 +996,9 @@
type CUR0_EXPANSION_MODE; \
type CUR0_ENABLE; \
type CM_BYPASS; \
- type FORMAT_CONTROL__ALPHA_EN
+ type FORMAT_CONTROL__ALPHA_EN; \
+ type CUR0_COLOR0; \
+ type CUR0_COLOR1
@@ -1075,6 +1084,7 @@ struct dcn_dpp_registers {
uint32_t CM_RGAM_RAMA_REGION_0_1;
uint32_t CM_RGAM_RAMA_REGION_32_33;
uint32_t CM_RGAM_CONTROL;
+ uint32_t CM_CMOUT_CONTROL;
uint32_t OBUF_CONTROL;
uint32_t CM_BLNDGAM_LUT_WRITE_EN_MASK;
uint32_t CM_BLNDGAM_CONTROL;
@@ -1237,10 +1247,12 @@ struct dcn_dpp_registers {
uint32_t CNVC_SURFACE_PIXEL_FORMAT;
uint32_t CURSOR_CONTROL;
uint32_t CURSOR0_CONTROL;
+ uint32_t CURSOR0_COLOR0;
+ uint32_t CURSOR0_COLOR1;
};
struct dcn10_dpp {
- struct transform base;
+ struct dpp base;
const struct dcn_dpp_registers *tf_regs;
const struct dcn_dpp_shift *tf_shift;
@@ -1256,107 +1268,116 @@ struct dcn10_dpp {
bool is_write_to_ram_a_safe;
};
-
-
enum dcn10_input_csc_select {
INPUT_CSC_SELECT_BYPASS = 0,
INPUT_CSC_SELECT_ICSC,
INPUT_CSC_SELECT_COMA
};
-void ippn10_degamma_ram_select(
- struct transform *xfm_base,
+bool dpp1_dscl_is_lb_conf_valid(
+ int ceil_vratio,
+ int num_partitions,
+ int vtaps);
+
+void dpp1_dscl_calc_lb_num_partitions(
+ const struct scaler_data *scl_data,
+ enum lb_memory_config lb_config,
+ int *num_part_y,
+ int *num_part_c);
+
+void dpp1_degamma_ram_select(
+ struct dpp *dpp_base,
bool use_ram_a);
-void ippn10_program_degamma_luta_settings(
- struct transform *xfm_base,
+void dpp1_program_degamma_luta_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params);
-void ippn10_program_degamma_lutb_settings(
- struct transform *xfm_base,
+void dpp1_program_degamma_lutb_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params);
-void ippn10_program_degamma_lut(
- struct transform *xfm_base,
+void dpp1_program_degamma_lut(
+ struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num,
bool is_ram_a);
-void ippn10_power_on_degamma_lut(
- struct transform *xfm_base,
+void dpp1_power_on_degamma_lut(
+ struct dpp *dpp_base,
bool power_on);
-void ippn10_program_input_csc(
- struct transform *xfm_base,
+void dpp1_program_input_csc(
+ struct dpp *dpp_base,
enum dc_color_space color_space,
enum dcn10_input_csc_select select);
-void ippn10_program_input_lut(
- struct transform *xfm_base,
+void dpp1_program_input_lut(
+ struct dpp *dpp_base,
const struct dc_gamma *gamma);
-void ippn10_full_bypass(struct transform *xfm_base);
+void dpp1_full_bypass(struct dpp *dpp_base);
-void ippn10_set_degamma(
- struct transform *xfm_base,
+void dpp1_set_degamma(
+ struct dpp *dpp_base,
enum ipp_degamma_mode mode);
-void ippn10_set_degamma_pwl(struct transform *xfm_base,
+void dpp1_set_degamma_pwl(struct dpp *dpp_base,
const struct pwl_params *params);
bool dpp_get_optimal_number_of_taps(
- struct transform *xfm,
+ struct dpp *dpp,
struct scaler_data *scl_data,
const struct scaling_taps *in_taps);
-void dpp_reset(struct transform *xfm_base);
+void dpp_reset(struct dpp *dpp_base);
-void dcn10_dpp_cm_program_regamma_lut(
- struct transform *xfm_base,
+void dpp1_cm_program_regamma_lut(
+ struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num);
-void dcn10_dpp_cm_power_on_regamma_lut(
- struct transform *xfm_base,
+void dpp1_cm_power_on_regamma_lut(
+ struct dpp *dpp_base,
bool power_on);
-void dcn10_dpp_cm_configure_regamma_lut(
- struct transform *xfm_base,
+void dpp1_cm_configure_regamma_lut(
+ struct dpp *dpp_base,
bool is_ram_a);
/*program re gamma RAM A*/
-void dcn10_dpp_cm_program_regamma_luta_settings(
- struct transform *xfm_base,
+void dpp1_cm_program_regamma_luta_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params);
/*program re gamma RAM B*/
-void dcn10_dpp_cm_program_regamma_lutb_settings(
- struct transform *xfm_base,
+void dpp1_cm_program_regamma_lutb_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params);
-void dcn10_dpp_cm_set_output_csc_adjustment(
- struct transform *xfm_base,
+void dpp1_cm_set_output_csc_adjustment(
+ struct dpp *dpp_base,
const struct out_csc_color_matrix *tbl_entry);
-void dcn10_dpp_cm_set_output_csc_default(
- struct transform *xfm_base,
+void dpp1_cm_set_output_csc_default(
+ struct dpp *dpp_base,
const struct default_adjustment *default_adjust);
-void dcn10_dpp_cm_set_gamut_remap(
- struct transform *xfm,
- const struct xfm_grph_csc_adjustment *adjust);
+void dpp1_cm_set_gamut_remap(
+ struct dpp *dpp,
+ const struct dpp_grph_csc_adjustment *adjust);
-void dcn10_dpp_dscl_set_scaler_manual_scale(
- struct transform *xfm_base,
+void dpp1_dscl_set_scaler_manual_scale(
+ struct dpp *dpp_base,
const struct scaler_data *scl_data);
-void ippn10_cnv_setup (
- struct transform *xfm_base,
+void dpp1_cnv_setup (
+ struct dpp *dpp_base,
enum surface_pixel_format input_format,
enum expansion_mode mode);
-void ippn10_full_bypass(struct transform *xfm_base);
+void dpp1_full_bypass(struct dpp *dpp_base);
-void dcn10_dpp_construct(struct dcn10_dpp *xfm110,
+void dpp1_construct(struct dcn10_dpp *dpp1,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_dpp_registers *tf_regs,
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 @@
#include "reg_helper.h"
#include "dcn10_dpp.h"
-#include "dcn10_dpp_cm_helper.h"
#include "basics/conversion.h"
+#include "dcn10_cm_common.h"
#define NUM_PHASES 64
#define HORZ_MAX_TAPS 8
@@ -40,14 +40,14 @@
#define BLACK_OFFSET_CBCR 0x8000
#define REG(reg)\
- xfm->tf_regs->reg
+ dpp->tf_regs->reg
#define CTX \
- xfm->base.ctx
+ dpp->base.ctx
#undef FN
#define FN(reg_name, field_name) \
- xfm->tf_shift->field_name, xfm->tf_mask->field_name
+ dpp->tf_shift->field_name, dpp->tf_mask->field_name
struct dcn10_input_csc_matrix {
enum dc_color_space color_space;
@@ -120,7 +120,7 @@ static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = {
static void program_gamut_remap(
- struct dcn10_dpp *xfm,
+ struct dcn10_dpp *dpp,
const uint16_t *regval,
enum gamut_remap_select select)
{
@@ -146,10 +146,10 @@ static void program_gamut_remap(
break;
}
- gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_GAMUT_REMAP_C11;
- gam_regs.masks.csc_c11 = xfm->tf_mask->CM_GAMUT_REMAP_C11;
- gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_GAMUT_REMAP_C12;
- gam_regs.masks.csc_c12 = xfm->tf_mask->CM_GAMUT_REMAP_C12;
+ gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
+ gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11;
+ gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
+ gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
if (select == GAMUT_REMAP_COEFF) {
@@ -157,7 +157,7 @@ static void program_gamut_remap(
gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
regval,
&gam_regs);
@@ -167,7 +167,7 @@ static void program_gamut_remap(
gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
regval,
&gam_regs);
@@ -177,7 +177,7 @@ static void program_gamut_remap(
gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
regval,
&gam_regs);
}
@@ -188,15 +188,15 @@ static void program_gamut_remap(
}
-void dcn10_dpp_cm_set_gamut_remap(
- struct transform *xfm,
- const struct xfm_grph_csc_adjustment *adjust)
+void dpp1_cm_set_gamut_remap(
+ struct dpp *dpp_base,
+ const struct dpp_grph_csc_adjustment *adjust)
{
- struct dcn10_dpp *dcn_xfm = TO_DCN10_DPP(xfm);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
/* Bypass if type is bypass or hw */
- program_gamut_remap(dcn_xfm, NULL, GAMUT_REMAP_BYPASS);
+ program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS);
else {
struct fixed31_32 arr_matrix[12];
uint16_t arr_reg_val[12];
@@ -219,16 +219,16 @@ void dcn10_dpp_cm_set_gamut_remap(
convert_float_matrix(
arr_reg_val, arr_matrix, 12);
- program_gamut_remap(dcn_xfm, arr_reg_val, GAMUT_REMAP_COEFF);
+ program_gamut_remap(dpp, arr_reg_val, GAMUT_REMAP_COEFF);
}
}
-void dcn10_dpp_cm_set_output_csc_default(
- struct transform *xfm_base,
+void dpp1_cm_set_output_csc_default(
+ struct dpp *dpp_base,
const struct default_adjustment *default_adjust)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
uint32_t ocsc_mode = 0;
if (default_adjust != NULL) {
@@ -260,35 +260,35 @@ void dcn10_dpp_cm_set_output_csc_default(
}
-static void dcn10_dpp_cm_get_reg_field(
- struct dcn10_dpp *xfm,
+static void dpp1_cm_get_reg_field(
+ struct dcn10_dpp *dpp,
struct xfer_func_reg *reg)
{
- reg->shifts.exp_region0_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
- reg->masks.exp_region0_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
- reg->shifts.exp_region0_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
- reg->masks.exp_region0_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
- reg->shifts.exp_region1_lut_offset = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
- reg->masks.exp_region1_lut_offset = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
- reg->shifts.exp_region1_num_segments = xfm->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
- reg->masks.exp_region1_num_segments = xfm->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
-
- reg->shifts.field_region_end = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
- reg->masks.field_region_end = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
- reg->shifts.field_region_end_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
- reg->masks.field_region_end_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
- reg->shifts.field_region_end_base = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
- reg->masks.field_region_end_base = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
- reg->shifts.field_region_linear_slope = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
- reg->masks.field_region_linear_slope = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
- reg->shifts.exp_region_start = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
- reg->masks.exp_region_start = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
- reg->shifts.exp_resion_start_segment = xfm->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
- reg->masks.exp_resion_start_segment = xfm->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+ reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+ reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+ reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+ reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+ reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+ reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+ reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+ reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+
+ reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B;
+ reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B;
+ reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
+ reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B;
+ reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
+ reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B;
+ reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+ reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+ reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B;
+ reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B;
+ reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+ reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
}
-static void dcn10_dpp_cm_program_color_matrix(
- struct dcn10_dpp *xfm,
+static void dpp1_cm_program_color_matrix(
+ struct dcn10_dpp *dpp,
const struct out_csc_color_matrix *tbl_entry)
{
uint32_t mode;
@@ -301,10 +301,10 @@ static void dcn10_dpp_cm_program_color_matrix(
return;
}
- gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_OCSC_C11;
- gam_regs.masks.csc_c11 = xfm->tf_mask->CM_OCSC_C11;
- gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_OCSC_C12;
- gam_regs.masks.csc_c12 = xfm->tf_mask->CM_OCSC_C12;
+ gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
+ gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11;
+ gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
+ gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12;
if (mode == 4) {
@@ -312,7 +312,7 @@ static void dcn10_dpp_cm_program_color_matrix(
gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
tbl_entry->regval,
&gam_regs);
@@ -322,17 +322,17 @@ static void dcn10_dpp_cm_program_color_matrix(
gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
tbl_entry->regval,
&gam_regs);
}
}
-void dcn10_dpp_cm_set_output_csc_adjustment(
- struct transform *xfm_base,
+void dpp1_cm_set_output_csc_adjustment(
+ struct dpp *dpp_base,
const struct out_csc_color_matrix *tbl_entry)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
//enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
uint32_t ocsc_mode = 4;
@@ -364,26 +364,26 @@ void dcn10_dpp_cm_set_output_csc_adjustment(
*/
REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
- dcn10_dpp_cm_program_color_matrix(xfm, tbl_entry);
+ dpp1_cm_program_color_matrix(dpp, tbl_entry);
}
-void dcn10_dpp_cm_power_on_regamma_lut(
- struct transform *xfm_base,
+void dpp1_cm_power_on_regamma_lut(
+ struct dpp *dpp_base,
bool power_on)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_SET(CM_MEM_PWR_CTRL, 0,
RGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
}
-void dcn10_dpp_cm_program_regamma_lut(
- struct transform *xfm_base,
+void dpp1_cm_program_regamma_lut(
+ struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num)
{
uint32_t i;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
for (i = 0 ; i < num; i++) {
REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].red_reg);
REG_SET(CM_RGAM_LUT_DATA, 0, CM_RGAM_LUT_DATA, rgb[i].green_reg);
@@ -400,11 +400,11 @@ void dcn10_dpp_cm_program_regamma_lut(
}
-void dcn10_dpp_cm_configure_regamma_lut(
- struct transform *xfm_base,
+void dpp1_cm_configure_regamma_lut(
+ struct dpp *dpp_base,
bool is_ram_a)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_UPDATE(CM_RGAM_LUT_WRITE_EN_MASK,
CM_RGAM_LUT_WRITE_EN_MASK, 7);
@@ -414,14 +414,14 @@ void dcn10_dpp_cm_configure_regamma_lut(
}
/*program re gamma RAM A*/
-void dcn10_dpp_cm_program_regamma_luta_settings(
- struct transform *xfm_base,
+void dpp1_cm_program_regamma_luta_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+ dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_RGAM_RAMA_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_RGAM_RAMA_START_CNTL_G);
@@ -438,19 +438,19 @@ void dcn10_dpp_cm_program_regamma_luta_settings(
gam_regs.region_start = REG(CM_RGAM_RAMA_REGION_0_1);
gam_regs.region_end = REG(CM_RGAM_RAMA_REGION_32_33);
- cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+ cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
/*program re gamma RAM B*/
-void dcn10_dpp_cm_program_regamma_lutb_settings(
- struct transform *xfm_base,
+void dpp1_cm_program_regamma_lutb_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+ dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_RGAM_RAMB_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_RGAM_RAMB_START_CNTL_G);
@@ -467,15 +467,15 @@ void dcn10_dpp_cm_program_regamma_lutb_settings(
gam_regs.region_start = REG(CM_RGAM_RAMB_REGION_0_1);
gam_regs.region_end = REG(CM_RGAM_RAMB_REGION_32_33);
- cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+ cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
-void ippn10_program_input_csc(
- struct transform *xfm_base,
+void dpp1_program_input_csc(
+ struct dpp *dpp_base,
enum dc_color_space color_space,
enum dcn10_input_csc_select select)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
int i;
int arr_size = sizeof(dcn10_input_csc_matrix)/sizeof(struct dcn10_input_csc_matrix);
const uint16_t *regval = NULL;
@@ -503,10 +503,10 @@ void ippn10_program_input_csc(
REG_SET(CM_ICSC_CONTROL, 0,
CM_ICSC_MODE, selection);
- gam_regs.shifts.csc_c11 = xfm->tf_shift->CM_ICSC_C11;
- gam_regs.masks.csc_c11 = xfm->tf_mask->CM_ICSC_C11;
- gam_regs.shifts.csc_c12 = xfm->tf_shift->CM_ICSC_C12;
- gam_regs.masks.csc_c12 = xfm->tf_mask->CM_ICSC_C12;
+ gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
+ gam_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
+ gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
+ gam_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
if (select == INPUT_CSC_SELECT_ICSC) {
@@ -515,7 +515,7 @@ void ippn10_program_input_csc(
gam_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
regval,
&gam_regs);
} else {
@@ -524,21 +524,21 @@ void ippn10_program_input_csc(
gam_regs.csc_c33_c34 = REG(CM_COMA_C33_C34);
cm_helper_program_color_matrices(
- xfm->base.ctx,
+ dpp->base.ctx,
regval,
&gam_regs);
}
}
/*program de gamma RAM B*/
-void ippn10_program_degamma_lutb_settings(
- struct transform *xfm_base,
+void dpp1_program_degamma_lutb_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+ dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_DGAM_RAMB_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_DGAM_RAMB_START_CNTL_G);
@@ -556,18 +556,18 @@ void ippn10_program_degamma_lutb_settings(
gam_regs.region_end = REG(CM_DGAM_RAMB_REGION_14_15);
- cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+ cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
/*program de gamma RAM A*/
-void ippn10_program_degamma_luta_settings(
- struct transform *xfm_base,
+void dpp1_program_degamma_luta_settings(
+ struct dpp *dpp_base,
const struct pwl_params *params)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dcn10_dpp_cm_get_reg_field(xfm, &gam_regs);
+ dpp1_cm_get_reg_field(dpp, &gam_regs);
gam_regs.start_cntl_b = REG(CM_DGAM_RAMA_START_CNTL_B);
gam_regs.start_cntl_g = REG(CM_DGAM_RAMA_START_CNTL_G);
@@ -584,34 +584,35 @@ void ippn10_program_degamma_luta_settings(
gam_regs.region_start = REG(CM_DGAM_RAMA_REGION_0_1);
gam_regs.region_end = REG(CM_DGAM_RAMA_REGION_14_15);
- cm_helper_program_xfer_func(xfm->base.ctx, params, &gam_regs);
+ cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
}
-void ippn10_power_on_degamma_lut(
- struct transform *xfm_base,
+void dpp1_power_on_degamma_lut(
+ struct dpp *dpp_base,
bool power_on)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_SET(CM_MEM_PWR_CTRL, 0,
SHARED_MEM_PWR_DIS, power_on == true ? 0:1);
}
-static void ippn10_enable_cm_block(
- struct transform *xfm_base)
+static void dpp1_enable_cm_block(
+ struct dpp *dpp_base)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ REG_UPDATE(CM_CMOUT_CONTROL, CM_CMOUT_ROUND_TRUNC_MODE, 8);
REG_UPDATE(CM_CONTROL, CM_BYPASS_EN, 0);
}
-void ippn10_set_degamma(
- struct transform *xfm_base,
+void dpp1_set_degamma(
+ struct dpp *dpp_base,
enum ipp_degamma_mode mode)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
- ippn10_enable_cm_block(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ dpp1_enable_cm_block(dpp_base);
switch (mode) {
case IPP_DEGAMMA_MODE_BYPASS:
@@ -630,11 +631,11 @@ void ippn10_set_degamma(
}
}
-void ippn10_degamma_ram_select(
- struct transform *xfm_base,
+void dpp1_degamma_ram_select(
+ struct dpp *dpp_base,
bool use_ram_a)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
if (use_ram_a)
REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
@@ -643,13 +644,13 @@ void ippn10_degamma_ram_select(
}
-static bool ippn10_degamma_ram_inuse(
- struct transform *xfm_base,
+static bool dpp1_degamma_ram_inuse(
+ struct dpp *dpp_base,
bool *ram_a_inuse)
{
bool ret = false;
uint32_t status_reg = 0;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
&status_reg);
@@ -664,15 +665,15 @@ static bool ippn10_degamma_ram_inuse(
return ret;
}
-void ippn10_program_degamma_lut(
- struct transform *xfm_base,
+void dpp1_program_degamma_lut(
+ struct dpp *dpp_base,
const struct pwl_result_data *rgb,
uint32_t num,
bool is_ram_a)
{
uint32_t i;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_HOST_EN, 0);
REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
CM_DGAM_LUT_WRITE_EN_MASK, 7);
@@ -694,27 +695,27 @@ void ippn10_program_degamma_lut(
}
}
-void ippn10_set_degamma_pwl(struct transform *xfm_base,
+void dpp1_set_degamma_pwl(struct dpp *dpp_base,
const struct pwl_params *params)
{
bool is_ram_a = true;
- ippn10_power_on_degamma_lut(xfm_base, true);
- ippn10_enable_cm_block(xfm_base);
- ippn10_degamma_ram_inuse(xfm_base, &is_ram_a);
+ dpp1_power_on_degamma_lut(dpp_base, true);
+ dpp1_enable_cm_block(dpp_base);
+ dpp1_degamma_ram_inuse(dpp_base, &is_ram_a);
if (is_ram_a == true)
- ippn10_program_degamma_lutb_settings(xfm_base, params);
+ dpp1_program_degamma_lutb_settings(dpp_base, params);
else
- ippn10_program_degamma_luta_settings(xfm_base, params);
+ dpp1_program_degamma_luta_settings(dpp_base, params);
- ippn10_program_degamma_lut(xfm_base, params->rgb_resulted,
+ dpp1_program_degamma_lut(dpp_base, params->rgb_resulted,
params->hw_points_num, !is_ram_a);
- ippn10_degamma_ram_select(xfm_base, !is_ram_a);
+ dpp1_degamma_ram_select(dpp_base, !is_ram_a);
}
-void ippn10_full_bypass(struct transform *xfm_base)
+void dpp1_full_bypass(struct dpp *dpp_base)
{
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
/* Input pixel format: ARGB8888 */
REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
@@ -727,19 +728,19 @@ void ippn10_full_bypass(struct transform *xfm_base)
FORMAT_EXPANSION_MODE, 0);
/* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */
- if (xfm->tf_mask->CM_BYPASS_EN)
+ if (dpp->tf_mask->CM_BYPASS_EN)
REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1);
/* Setting degamma bypass for now */
REG_SET(CM_DGAM_CONTROL, 0, CM_DGAM_LUT_MODE, 0);
}
-static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
+static bool dpp1_ingamma_ram_inuse(struct dpp *dpp_base,
bool *ram_a_inuse)
{
bool in_use = false;
uint32_t status_reg = 0;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
REG_GET(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_DGAM_CONFIG_STATUS,
&status_reg);
@@ -765,19 +766,19 @@ static bool ippn10_ingamma_ram_inuse(struct transform *xfm_base,
* In the future, this function should support additional input gamma methods,
* such as piecewise linear mapping, and input gamma bypass.
*/
-void ippn10_program_input_lut(
- struct transform *xfm_base,
+void dpp1_program_input_lut(
+ struct dpp *dpp_base,
const struct dc_gamma *gamma)
{
int i;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
bool rama_occupied = false;
uint32_t ram_num;
// Power on LUT memory.
REG_SET(CM_MEM_PWR_CTRL, 0, SHARED_MEM_PWR_DIS, 1);
- ippn10_enable_cm_block(xfm_base);
+ dpp1_enable_cm_block(dpp_base);
// Determine whether to use RAM A or RAM B
- ippn10_ingamma_ram_inuse(xfm_base, &rama_occupied);
+ dpp1_ingamma_ram_inuse(dpp_base, &rama_occupied);
if (!rama_occupied)
REG_UPDATE(CM_IGAM_LUT_RW_CONTROL, CM_IGAM_LUT_SEL, 0);
else
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 @@
#include "dcn10_dpp.h"
#include "basics/conversion.h"
+
#define NUM_PHASES 64
#define HORZ_MAX_TAPS 8
#define VERT_MAX_TAPS 8
@@ -39,14 +40,14 @@
#define BLACK_OFFSET_CBCR 0x8000
#define REG(reg)\
- xfm->tf_regs->reg
+ dpp->tf_regs->reg
#define CTX \
- xfm->base.ctx
+ dpp->base.ctx
#undef FN
#define FN(reg_name, field_name) \
- xfm->tf_shift->field_name, xfm->tf_mask->field_name
+ dpp->tf_shift->field_name, dpp->tf_mask->field_name
enum dcn10_coef_filter_type_sel {
SCL_COEF_LUMA_VERT_FILTER = 0,
@@ -57,22 +58,6 @@ enum dcn10_coef_filter_type_sel {
SCL_COEF_ALPHA_HORZ_FILTER = 5
};
-enum lb_memory_config {
- /* Enable all 3 pieces of memory */
- LB_MEMORY_CONFIG_0 = 0,
-
- /* Enable only the first piece of memory */
- LB_MEMORY_CONFIG_1 = 1,
-
- /* Enable only the second piece of memory */
- LB_MEMORY_CONFIG_2 = 2,
-
- /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
- * last piece of chroma memory used for the luma storage
- */
- LB_MEMORY_CONFIG_3 = 3
-};
-
enum dscl_autocal_mode {
AUTOCAL_MODE_OFF = 0,
@@ -100,8 +85,8 @@ enum dscl_mode_sel {
DSCL_MODE_DSCL_BYPASS = 6
};
-static void dpp_set_overscan(
- struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_overscan(
+ struct dcn10_dpp *dpp,
const struct scaler_data *data)
{
uint32_t left = data->recout.x;
@@ -128,8 +113,8 @@ static void dpp_set_overscan(
EXT_OVERSCAN_TOP, top);
}
-static void dpp_set_otg_blank(
- struct dcn10_dpp *xfm, const struct scaler_data *data)
+static void dpp1_dscl_set_otg_blank(
+ struct dcn10_dpp *dpp, const struct scaler_data *data)
{
uint32_t h_blank_start = data->h_active;
uint32_t h_blank_end = 0;
@@ -145,7 +130,7 @@ static void dpp_set_otg_blank(
OTG_V_BLANK_END, v_blank_end);
}
-static int get_pixel_depth_val(enum lb_pixel_depth depth)
+static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)
{
if (depth == LB_PIXEL_DEPTH_30BPP)
return 0; /* 10 bpc */
@@ -161,23 +146,36 @@ static int get_pixel_depth_val(enum lb_pixel_depth depth)
}
}
-static enum dscl_mode_sel get_dscl_mode(
- const struct scaler_data *data, bool dbg_always_scale)
+static bool dpp1_dscl_is_video_format(enum pixel_format format)
{
- const long long one = dal_fixed31_32_one.value;
- bool ycbcr = false;
- bool format420 = false;
+ if (format >= PIXEL_FORMAT_VIDEO_BEGIN
+ && format <= PIXEL_FORMAT_VIDEO_END)
+ return true;
+ else
+ return false;
+}
- if (data->format == PIXEL_FORMAT_FP16)
- return DSCL_MODE_DSCL_BYPASS;
+static bool dpp1_dscl_is_420_format(enum pixel_format format)
+{
+ if (format == PIXEL_FORMAT_420BPP8 ||
+ format == PIXEL_FORMAT_420BPP10)
+ return true;
+ else
+ return false;
+}
- if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN
- && data->format <= PIXEL_FORMAT_VIDEO_END)
- ycbcr = true;
+static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
+ struct dpp *dpp_base,
+ const struct scaler_data *data,
+ bool dbg_always_scale)
+{
+ const long long one = dal_fixed31_32_one.value;
- if (data->format == PIXEL_FORMAT_420BPP8 ||
- data->format == PIXEL_FORMAT_420BPP10)
- format420 = true;
+ if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
+ /* DSCL is processing data in fixed format */
+ if (data->format == PIXEL_FORMAT_FP16)
+ return DSCL_MODE_DSCL_BYPASS;
+ }
if (data->ratios.horz.value == one
&& data->ratios.vert.value == one
@@ -186,8 +184,8 @@ static enum dscl_mode_sel get_dscl_mode(
&& !dbg_always_scale)
return DSCL_MODE_SCALING_444_BYPASS;
- if (!format420) {
- if (ycbcr)
+ if (!dpp1_dscl_is_420_format(data->format)) {
+ if (dpp1_dscl_is_video_format(data->format))
return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
else
return DSCL_MODE_SCALING_444_RGB_ENABLE;
@@ -200,16 +198,17 @@ static enum dscl_mode_sel get_dscl_mode(
return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
}
-static void dpp_set_lb(
- struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_lb(
+ struct dcn10_dpp *dpp,
const struct line_buffer_params *lb_params,
enum lb_memory_config mem_size_config)
{
- uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth);
- uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
-
/* LB */
- if (xfm->tf_mask->PIXEL_DEPTH) {
+ if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
+ /* DSCL caps: pixel data processed in fixed format */
+ uint32_t pixel_depth = dpp1_dscl_get_pixel_depth_val(lb_params->depth);
+ uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
+
REG_SET_7(LB_DATA_FORMAT, 0,
PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */
PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */
@@ -225,7 +224,7 @@ static void dpp_set_lb(
LB_MAX_PARTITIONS, 63);
}
-static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
+static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
{
if (taps == 8)
return get_filter_8tap_64p(ratio);
@@ -250,8 +249,8 @@ static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
}
}
-static void dpp_set_scaler_filter(
- struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_scaler_filter(
+ struct dcn10_dpp *dpp,
uint32_t taps,
enum dcn10_coef_filter_type_sel filter_type,
const uint16_t *filter)
@@ -288,8 +287,8 @@ static void dpp_set_scaler_filter(
}
-static void dpp_set_scl_filter(
- struct dcn10_dpp *xfm,
+static void dpp1_dscl_set_scl_filter(
+ struct dcn10_dpp *dpp,
const struct scaler_data *scl_data,
bool chroma_coef_mode)
{
@@ -307,10 +306,10 @@ static void dpp_set_scl_filter(
h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3
&& scl_data->taps.h_taps_c < 3
- && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1);
+ && (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1);
v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3
&& scl_data->taps.v_taps_c < 3
- && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1);
+ && (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1);
h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0;
v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0;
@@ -326,56 +325,56 @@ static void dpp_set_scl_filter(
if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) {
bool filter_updated = false;
- filter_h = get_filter_coeffs_64p(
+ filter_h = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.h_taps, scl_data->ratios.horz);
- filter_v = get_filter_coeffs_64p(
+ filter_v = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.v_taps, scl_data->ratios.vert);
- filter_updated = (filter_h && (filter_h != xfm->filter_h))
- || (filter_v && (filter_v != xfm->filter_v));
+ filter_updated = (filter_h && (filter_h != dpp->filter_h))
+ || (filter_v && (filter_v != dpp->filter_v));
if (chroma_coef_mode) {
- filter_h_c = get_filter_coeffs_64p(
+ filter_h_c = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
- filter_v_c = get_filter_coeffs_64p(
+ filter_v_c = dpp1_dscl_get_filter_coeffs_64p(
scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
- filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c))
- || (filter_v_c && (filter_v_c != xfm->filter_v_c));
+ filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c))
+ || (filter_v_c && (filter_v_c != dpp->filter_v_c));
}
if (filter_updated) {
uint32_t scl_mode = REG_READ(SCL_MODE);
if (!h_2tap_hardcode_coef_en && filter_h) {
- dpp_set_scaler_filter(
- xfm, scl_data->taps.h_taps,
+ dpp1_dscl_set_scaler_filter(
+ dpp, scl_data->taps.h_taps,
SCL_COEF_LUMA_HORZ_FILTER, filter_h);
}
- xfm->filter_h = filter_h;
+ dpp->filter_h = filter_h;
if (!v_2tap_hardcode_coef_en && filter_v) {
- dpp_set_scaler_filter(
- xfm, scl_data->taps.v_taps,
+ dpp1_dscl_set_scaler_filter(
+ dpp, scl_data->taps.v_taps,
SCL_COEF_LUMA_VERT_FILTER, filter_v);
}
- xfm->filter_v = filter_v;
+ dpp->filter_v = filter_v;
if (chroma_coef_mode) {
if (!h_2tap_hardcode_coef_en && filter_h_c) {
- dpp_set_scaler_filter(
- xfm, scl_data->taps.h_taps_c,
+ dpp1_dscl_set_scaler_filter(
+ dpp, scl_data->taps.h_taps_c,
SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
}
if (!v_2tap_hardcode_coef_en && filter_v_c) {
- dpp_set_scaler_filter(
- xfm, scl_data->taps.v_taps_c,
+ dpp1_dscl_set_scaler_filter(
+ dpp, scl_data->taps.v_taps_c,
SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
}
}
- xfm->filter_h_c = filter_h_c;
- xfm->filter_v_c = filter_v_c;
+ dpp->filter_h_c = filter_h_c;
+ dpp->filter_v_c = filter_v_c;
coef_ram_current = get_reg_field_value_ex(
- scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
- xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
+ scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
+ dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
/* Swap coefficient RAM and set chroma coefficient mode */
REG_SET_2(SCL_MODE, scl_mode,
@@ -385,7 +384,7 @@ static void dpp_set_scl_filter(
}
}
-static int get_lb_depth_bpc(enum lb_pixel_depth depth)
+static int dpp1_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth)
{
if (depth == LB_PIXEL_DEPTH_30BPP)
return 10;
@@ -401,7 +400,7 @@ static int get_lb_depth_bpc(enum lb_pixel_depth depth)
}
}
-static void calc_lb_num_partitions(
+void dpp1_dscl_calc_lb_num_partitions(
const struct scaler_data *scl_data,
enum lb_memory_config lb_config,
int *num_part_y,
@@ -411,7 +410,7 @@ static void calc_lb_num_partitions(
scl_data->viewport.width : scl_data->recout.width;
int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
scl_data->viewport_c.width : scl_data->recout.width;
- int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth);
+ int lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
@@ -426,6 +425,7 @@ static void calc_lb_num_partitions(
lb_memory_size_c = 1088;
lb_memory_size_a = 1312;
} else if (lb_config == LB_MEMORY_CONFIG_3) {
+ /* 420 mode: using 3rd mem from Y, Cr and Cb */
lb_memory_size = 816 + 1088 + 848 + 848 + 848;
lb_memory_size_c = 816 + 1088;
lb_memory_size_a = 984 + 1312 + 456;
@@ -449,7 +449,7 @@ static void calc_lb_num_partitions(
}
-static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
+bool dpp1_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
{
if (ceil_vratio > 2)
return vtaps <= (num_partitions - ceil_vratio + 2);
@@ -458,7 +458,7 @@ static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
}
/*find first match configuration which meets the min required lb size*/
-static enum lb_memory_config dpp10_find_lb_memory_config(
+static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *dpp,
const struct scaler_data *scl_data)
{
int num_part_y, num_part_c;
@@ -466,75 +466,67 @@ static enum lb_memory_config dpp10_find_lb_memory_config(
int vtaps_c = scl_data->taps.v_taps_c;
int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert);
int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c);
+ enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
+
+ if (dpp->base.ctx->dc->debug.use_max_lb)
+ return mem_cfg;
- calc_lb_num_partitions(
+ dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
- if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
+ if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+ && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
return LB_MEMORY_CONFIG_1;
- calc_lb_num_partitions(
+ dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c);
- if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
+ if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+ && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
return LB_MEMORY_CONFIG_2;
if (scl_data->format == PIXEL_FORMAT_420BPP8
|| scl_data->format == PIXEL_FORMAT_420BPP10) {
- calc_lb_num_partitions(
+ dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c);
- if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
+ if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+ && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
return LB_MEMORY_CONFIG_3;
}
- calc_lb_num_partitions(
+ dpp->base.caps->dscl_calc_lb_num_partitions(
scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c);
/*Ensure we can support the requested number of vtaps*/
- ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
+ ASSERT(dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
+ && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
return LB_MEMORY_CONFIG_0;
}
-/*find first match configuration which meets the min required lb size*/
-static enum lb_memory_config find_lb_memory_config(struct dcn10_dpp *xfm,
- const struct scaler_data *scl_data)
-{
- enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0;
-
- if (xfm->tf_mask->PIXEL_DEPTH) {
- mem_cfg = dpp10_find_lb_memory_config(scl_data);
- }
- return mem_cfg;
-}
-
-void dpp_set_scaler_auto_scale(
- struct transform *xfm_base,
+void dpp1_dscl_set_scaler_auto_scale(
+ struct dpp *dpp_base,
const struct scaler_data *scl_data)
{
enum lb_memory_config lb_config;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
- enum dscl_mode_sel dscl_mode = get_dscl_mode(
- scl_data, xfm_base->ctx->dc->debug.always_scale);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
+ dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
- dpp_set_overscan(xfm, scl_data);
+ dpp1_dscl_set_overscan(dpp, scl_data);
- dpp_set_otg_blank(xfm, scl_data);
+ dpp1_dscl_set_otg_blank(dpp, scl_data);
REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
if (dscl_mode == DSCL_MODE_DSCL_BYPASS)
return;
- lb_config = find_lb_memory_config(xfm, scl_data);
- dpp_set_lb(xfm, &scl_data->lb_params, lb_config);
+ lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
+ dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
return;
@@ -562,12 +554,12 @@ void dpp_set_scaler_auto_scale(
SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
- dpp_set_scl_filter(xfm, scl_data, ycbcr);
+ dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
}
-static void dpp_set_manual_ratio_init(
- struct dcn10_dpp *xfm, const struct scaler_data *data)
+static void dpp1_dscl_set_manual_ratio_init(
+ struct dcn10_dpp *dpp, const struct scaler_data *data)
{
uint32_t init_frac = 0;
uint32_t init_int = 0;
@@ -626,8 +618,8 @@ static void dpp_set_manual_ratio_init(
-static void dpp_set_recout(
- struct dcn10_dpp *xfm, const struct rect *recout)
+static void dpp1_dscl_set_recout(
+ struct dcn10_dpp *dpp, const struct rect *recout)
{
REG_SET_2(RECOUT_START, 0,
/* First pixel of RECOUT */
@@ -640,24 +632,24 @@ static void dpp_set_recout(
RECOUT_WIDTH, recout->width,
/* Number of RECOUT vertical lines */
RECOUT_HEIGHT, recout->height
- - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 *
- (xfm->base.inst + 1));
+ - dpp->base.ctx->dc->debug.surface_visual_confirm * 4 *
+ (dpp->base.inst + 1));
}
/* Main function to program scaler and line buffer in manual scaling mode */
-void dcn10_dpp_dscl_set_scaler_manual_scale(
- struct transform *xfm_base,
+void dpp1_dscl_set_scaler_manual_scale(
+ struct dpp *dpp_base,
const struct scaler_data *scl_data)
{
enum lb_memory_config lb_config;
- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
- enum dscl_mode_sel dscl_mode = get_dscl_mode(
- scl_data, xfm_base->ctx->dc->debug.always_scale);
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
+ dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
&& scl_data->format <= PIXEL_FORMAT_VIDEO_END;
/* Recout */
- dpp_set_recout(xfm, &scl_data->recout);
+ dpp1_dscl_set_recout(dpp, &scl_data->recout);
/* MPC Size */
REG_SET_2(MPC_SIZE, 0,
@@ -673,8 +665,8 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
return;
/* LB */
- lb_config = find_lb_memory_config(xfm, scl_data);
- dpp_set_lb(xfm, &scl_data->lb_params, lb_config);
+ lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
+ dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
return;
@@ -697,7 +689,7 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
/* Manually calculate scale ratio and init values */
- dpp_set_manual_ratio_init(xfm, scl_data);
+ dpp1_dscl_set_manual_ratio_init(dpp, scl_data);
/* HTaps/VTaps */
REG_SET_4(SCL_TAP_CONTROL, 0,
@@ -706,5 +698,5 @@ void dcn10_dpp_dscl_set_scaler_manual_scale(
SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
- dpp_set_scl_filter(xfm, scl_data, ycbcr);
+ dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
}
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 @@
*/
#include "dm_services.h"
#include "dce_calcs.h"
-#include "dcn10_mem_input.h"
#include "reg_helper.h"
#include "basics/conversion.h"
+#include "dcn10_hubp.h"
#define REG(reg)\
- mi->mi_regs->reg
+ hubp1->mi_regs->reg
#define CTX \
- mi->base.ctx
+ hubp1->base.ctx
#undef FN
#define FN(reg_name, field_name) \
- mi->mi_shift->field_name, mi->mi_mask->field_name
+ hubp1->mi_shift->field_name, hubp1->mi_mask->field_name
-static void min10_set_blank(struct mem_input *mem_input, bool blank)
+void hubp1_set_blank(struct hubp *hubp, bool blank)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
uint32_t blank_en = blank ? 1 : 0;
REG_UPDATE_2(DCHUBP_CNTL,
@@ -51,24 +51,24 @@ static void min10_set_blank(struct mem_input *mem_input, bool blank)
REG_WAIT(DCHUBP_CNTL,
HUBP_NO_OUTSTANDING_REQ, 1,
1, 200);
- mem_input->mpcc_id = 0xf;
- mem_input->opp_id = 0xf;
+ hubp->mpcc_id = 0xf;
+ hubp->opp_id = 0xf;
}
}
-static void min10_set_hubp_blank_en(struct mem_input *mem_input, bool blank)
+static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
uint32_t blank_en = blank ? 1 : 0;
REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
}
-static void min10_vready_workaround(struct mem_input *mem_input,
+static void hubp1_vready_workaround(struct hubp *hubp,
struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
{
uint32_t value = 0;
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* set HBUBREQ_DEBUG_DB[12] = 1 */
value = REG_READ(HUBPREQ_DEBUG_DB);
@@ -87,8 +87,8 @@ static void min10_vready_workaround(struct mem_input *mem_input,
REG_WRITE(HUBPREQ_DEBUG_DB, value);
}
-static void min10_program_tiling(
- struct dcn10_mem_input *mi,
+void hubp1_program_tiling(
+ struct dcn10_hubp *hubp1,
const union dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
{
@@ -107,8 +107,8 @@ static void min10_program_tiling(
PIPE_ALIGNED, info->gfx9.pipe_aligned);
}
-static void min10_program_size_and_rotation(
- struct dcn10_mem_input *mi,
+void hubp1_program_size_and_rotation(
+ struct dcn10_hubp *hubp1,
enum dc_rotation_angle rotation,
enum surface_pixel_format format,
const union plane_size *plane_size,
@@ -169,8 +169,8 @@ static void min10_program_size_and_rotation(
H_MIRROR_EN, mirror);
}
-static void min10_program_pixel_format(
- struct dcn10_mem_input *mi,
+void hubp1_program_pixel_format(
+ struct dcn10_hubp *hubp1,
enum surface_pixel_format format)
{
uint32_t red_bar = 3;
@@ -245,12 +245,12 @@ static void min10_program_pixel_format(
/* don't see the need of program the xbar in DCN 1.0 */
}
-static bool min10_program_surface_flip_and_addr(
- struct mem_input *mem_input,
+bool hubp1_program_surface_flip_and_addr(
+ struct hubp *hubp,
const struct dc_plane_address *address,
bool flip_immediate)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* program flip type */
REG_SET(DCSURF_FLIP_CONTROL, 0,
@@ -387,28 +387,28 @@ static bool min10_program_surface_flip_and_addr(
break;
}
- mem_input->request_address = *address;
+ hubp->request_address = *address;
if (flip_immediate)
- mem_input->current_address = *address;
+ hubp->current_address = *address;
return true;
}
-static void min10_dcc_control(struct mem_input *mem_input, bool enable,
+void hubp1_dcc_control(struct hubp *hubp, bool enable,
bool independent_64b_blks)
{
uint32_t dcc_en = enable ? 1 : 0;
uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
PRIMARY_SURFACE_DCC_EN, dcc_en,
PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
}
-static void min10_program_surface_config(
- struct mem_input *mem_input,
+void hubp1_program_surface_config(
+ struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
union plane_size *plane_size,
@@ -416,20 +416,20 @@ static void min10_program_surface_config(
struct dc_plane_dcc_param *dcc,
bool horizontal_mirror)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
- min10_dcc_control(mem_input, dcc->enable, dcc->grph.independent_64b_blks);
- min10_program_tiling(mi, tiling_info, format);
- min10_program_size_and_rotation(
- mi, rotation, format, plane_size, dcc, horizontal_mirror);
- min10_program_pixel_format(mi, format);
+ hubp1_dcc_control(hubp, dcc->enable, dcc->grph.independent_64b_blks);
+ hubp1_program_tiling(hubp1, tiling_info, format);
+ hubp1_program_size_and_rotation(
+ hubp1, rotation, format, plane_size, dcc, horizontal_mirror);
+ hubp1_program_pixel_format(hubp1, format);
}
-static void min10_program_requestor(
- struct mem_input *mem_input,
+void hubp1_program_requestor(
+ struct hubp *hubp,
struct _vcs_dpi_display_rq_regs_st *rq_regs)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
REG_UPDATE(HUBPRET_CONTROL,
DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
@@ -459,12 +459,12 @@ static void min10_program_requestor(
}
-static void min10_program_deadline(
- struct mem_input *mem_input,
+void hubp1_program_deadline(
+ struct hubp *hubp,
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* DLG - Per hubp */
REG_SET_2(BLANK_OFFSET_0, 0,
@@ -580,8 +580,8 @@ static void min10_program_deadline(
ttu_attr->refcyc_per_req_delivery_pre_c);
}
-static void min10_setup(
- struct mem_input *mem_input,
+static void hubp1_setup(
+ struct hubp *hubp,
struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
@@ -590,27 +590,15 @@ static void min10_setup(
/* otg is locked when this func is called. Register are double buffered.
* disable the requestors is not needed
*/
- min10_program_requestor(mem_input, rq_regs);
- min10_program_deadline(mem_input, dlg_attr, ttu_attr);
- min10_vready_workaround(mem_input, pipe_dest);
+ hubp1_program_requestor(hubp, rq_regs);
+ hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
+ hubp1_vready_workaround(hubp, pipe_dest);
}
-static void min10_program_display_marks(
- struct mem_input *mem_input,
- struct dce_watermarks nbp,
- struct dce_watermarks stutter,
- struct dce_watermarks urgent,
- uint32_t total_dest_line_time_ns)
-{
- /* only for dce
- * dcn use only program_watermarks
- */
-}
-
-static bool min10_is_flip_pending(struct mem_input *mem_input)
+bool hubp1_is_flip_pending(struct hubp *hubp)
{
uint32_t flip_pending = 0;
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
struct dc_plane_address earliest_inuse_address;
REG_GET(DCSURF_FLIP_CONTROL,
@@ -625,17 +613,20 @@ static bool min10_is_flip_pending(struct mem_input *mem_input)
if (flip_pending)
return true;
- if (earliest_inuse_address.grph.addr.quad_part != mem_input->request_address.grph.addr.quad_part)
+ if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
return true;
- mem_input->current_address = mem_input->request_address;
+ hubp->current_address = hubp->request_address;
return false;
}
-static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
+uint32_t aperture_default_system = 1;
+uint32_t context0_default_system; /* = 0;*/
+
+static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
struct vm_system_aperture_param *apt)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
@@ -645,7 +636,7 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
- MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, 1, /* 1 = system physical memory */
+ MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system, /* 1 = system physical memory */
MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part);
@@ -661,10 +652,10 @@ static void min10_set_vm_system_aperture_settings(struct mem_input *mem_input,
MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
}
-static void min10_set_vm_context0_settings(struct mem_input *mem_input,
+static void hubp1_set_vm_context0_settings(struct hubp *hubp,
const struct vm_context0_param *vm0)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
/* pte base */
REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part);
@@ -684,9 +675,9 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
/* fault handling */
- REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
- VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->fault_default.high_part);
- /* VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, 0 */
+ REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
+ VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
+ VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
@@ -696,12 +687,12 @@ static void min10_set_vm_context0_settings(struct mem_input *mem_input,
SYSTEM_ACCESS_MODE, 3);
}
-static void min_set_viewport(
- struct mem_input *mem_input,
+void min_set_viewport(
+ struct hubp *hubp,
const struct rect *viewport,
const struct rect *viewport_c)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
PRI_VIEWPORT_WIDTH, viewport->width,
@@ -730,7 +721,7 @@ static void min_set_viewport(
PRI_VIEWPORT_Y_START_C, viewport_c->y);
}
-void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
+void hubp1_read_state(struct dcn10_hubp *hubp1,
struct dcn_hubp_state *s)
{
REG_GET(DCSURF_SURFACE_CONFIG,
@@ -766,41 +757,204 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
}
-static struct mem_input_funcs dcn10_mem_input_funcs = {
- .mem_input_program_display_marks = min10_program_display_marks,
- .mem_input_program_surface_flip_and_addr =
- min10_program_surface_flip_and_addr,
- .mem_input_program_surface_config =
- min10_program_surface_config,
- .mem_input_is_flip_pending = min10_is_flip_pending,
- .mem_input_setup = min10_setup,
- .mem_input_set_vm_system_aperture_settings = min10_set_vm_system_aperture_settings,
- .mem_input_set_vm_context0_settings = min10_set_vm_context0_settings,
- .set_blank = min10_set_blank,
- .dcc_control = min10_dcc_control,
+enum cursor_pitch {
+ CURSOR_PITCH_64_PIXELS = 0,
+ CURSOR_PITCH_128_PIXELS,
+ CURSOR_PITCH_256_PIXELS
+};
+
+enum cursor_lines_per_chunk {
+ CURSOR_LINE_PER_CHUNK_2 = 1,
+ CURSOR_LINE_PER_CHUNK_4,
+ CURSOR_LINE_PER_CHUNK_8,
+ CURSOR_LINE_PER_CHUNK_16
+};
+
+static bool ippn10_cursor_program_control(
+ struct dcn10_hubp *hubp1,
+ bool pixel_data_invert,
+ enum dc_cursor_color_format color_format)
+{
+ if (REG(CURSOR_SETTINS))
+ REG_SET_2(CURSOR_SETTINS, 0,
+ /* no shift of the cursor HDL schedule */
+ CURSOR0_DST_Y_OFFSET, 0,
+ /* used to shift the cursor chunk request deadline */
+ CURSOR0_CHUNK_HDL_ADJUST, 3);
+ else
+ REG_SET_2(CURSOR_SETTINGS, 0,
+ /* no shift of the cursor HDL schedule */
+ CURSOR0_DST_Y_OFFSET, 0,
+ /* used to shift the cursor chunk request deadline */
+ CURSOR0_CHUNK_HDL_ADJUST, 3);
+
+ return true;
+}
+
+static enum cursor_pitch ippn10_get_cursor_pitch(
+ unsigned int pitch)
+{
+ enum cursor_pitch hw_pitch;
+
+ switch (pitch) {
+ case 64:
+ hw_pitch = CURSOR_PITCH_64_PIXELS;
+ break;
+ case 128:
+ hw_pitch = CURSOR_PITCH_128_PIXELS;
+ break;
+ case 256:
+ hw_pitch = CURSOR_PITCH_256_PIXELS;
+ break;
+ default:
+ DC_ERR("Invalid cursor pitch of %d. "
+ "Only 64/128/256 is supported on DCN.\n", pitch);
+ hw_pitch = CURSOR_PITCH_64_PIXELS;
+ break;
+ }
+ return hw_pitch;
+}
+
+static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
+ unsigned int cur_width,
+ enum dc_cursor_color_format format)
+{
+ enum cursor_lines_per_chunk line_per_chunk;
+
+ if (format == CURSOR_MODE_MONO)
+ /* impl B. expansion in CUR Buffer reader */
+ line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
+ else if (cur_width <= 32)
+ line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
+ else if (cur_width <= 64)
+ line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
+ else if (cur_width <= 128)
+ line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
+ else
+ line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
+
+ return line_per_chunk;
+}
+
+void hubp1_cursor_set_attributes(
+ struct hubp *hubp,
+ const struct dc_cursor_attributes *attr)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+ enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
+ enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
+ attr->width, attr->color_format);
+
+ hubp->curs_attr = *attr;
+
+ REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
+ CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
+ REG_UPDATE(CURSOR_SURFACE_ADDRESS,
+ CURSOR_SURFACE_ADDRESS, attr->address.low_part);
+
+ REG_UPDATE_2(CURSOR_SIZE,
+ CURSOR_WIDTH, attr->width,
+ CURSOR_HEIGHT, attr->height);
+ REG_UPDATE_3(CURSOR_CONTROL,
+ CURSOR_MODE, attr->color_format,
+ CURSOR_PITCH, hw_pitch,
+ CURSOR_LINES_PER_CHUNK, lpc);
+ ippn10_cursor_program_control(hubp1,
+ attr->attribute_flags.bits.INVERT_PIXEL_DATA,
+ attr->color_format);
+}
+
+void hubp1_cursor_set_position(
+ struct hubp *hubp,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+ int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
+ uint32_t cur_en = pos->enable ? 1 : 0;
+ uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
+
+ /*
+ * Guard aganst cursor_set_position() from being called with invalid
+ * attributes
+ *
+ * TODO: Look at combining cursor_set_position() and
+ * cursor_set_attributes() into cursor_update()
+ */
+ if (hubp->curs_attr.address.quad_part == 0)
+ return;
+
+ dst_x_offset *= param->ref_clk_khz;
+ dst_x_offset /= param->pixel_clk_khz;
+
+ ASSERT(param->h_scale_ratio.value);
+
+ if (param->h_scale_ratio.value)
+ dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
+ dal_fixed31_32_from_int(dst_x_offset),
+ param->h_scale_ratio));
+
+ if (src_x_offset >= (int)param->viewport_width)
+ cur_en = 0; /* not visible beyond right edge*/
+
+ if (src_x_offset + (int)hubp->curs_attr.width < 0)
+ cur_en = 0; /* not visible beyond left edge*/
+
+ if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+ hubp1_cursor_set_attributes(hubp, &hubp->curs_attr);
+ REG_UPDATE(CURSOR_CONTROL,
+ CURSOR_ENABLE, cur_en);
+
+ REG_SET_2(CURSOR_POSITION, 0,
+ CURSOR_X_POSITION, pos->x,
+ CURSOR_Y_POSITION, pos->y);
+
+ REG_SET_2(CURSOR_HOT_SPOT, 0,
+ CURSOR_HOT_SPOT_X, pos->x_hotspot,
+ CURSOR_HOT_SPOT_Y, pos->y_hotspot);
+
+ REG_SET(CURSOR_DST_OFFSET, 0,
+ CURSOR_DST_X_OFFSET, dst_x_offset);
+ /* TODO Handle surface pixel formats other than 4:4:4 */
+}
+
+static struct hubp_funcs dcn10_hubp_funcs = {
+ .hubp_program_surface_flip_and_addr =
+ hubp1_program_surface_flip_and_addr,
+ .hubp_program_surface_config =
+ hubp1_program_surface_config,
+ .hubp_is_flip_pending = hubp1_is_flip_pending,
+ .hubp_setup = hubp1_setup,
+ .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
+ .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
+ .set_blank = hubp1_set_blank,
+ .dcc_control = hubp1_dcc_control,
.mem_program_viewport = min_set_viewport,
- .set_hubp_blank_en = min10_set_hubp_blank_en,
+ .set_hubp_blank_en = hubp1_set_hubp_blank_en,
+ .set_cursor_attributes = hubp1_cursor_set_attributes,
+ .set_cursor_position = hubp1_cursor_set_position,
};
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
-void dcn10_mem_input_construct(
- struct dcn10_mem_input *mi,
+void dcn10_hubp_construct(
+ struct dcn10_hubp *hubp1,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_mi_registers *mi_regs,
const struct dcn_mi_shift *mi_shift,
const struct dcn_mi_mask *mi_mask)
{
- mi->base.funcs = &dcn10_mem_input_funcs;
- mi->base.ctx = ctx;
- mi->mi_regs = mi_regs;
- mi->mi_shift = mi_shift;
- mi->mi_mask = mi_mask;
- mi->base.inst = inst;
- mi->base.opp_id = 0xf;
- mi->base.mpcc_id = 0xf;
+ hubp1->base.funcs = &dcn10_hubp_funcs;
+ hubp1->base.ctx = ctx;
+ hubp1->mi_regs = mi_regs;
+ hubp1->mi_shift = mi_shift;
+ hubp1->mi_mask = mi_mask;
+ hubp1->base.inst = inst;
+ hubp1->base.opp_id = 0xf;
+ hubp1->base.mpcc_id = 0xf;
}
+
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 @@
#ifndef __DC_MEM_INPUT_DCN10_H__
#define __DC_MEM_INPUT_DCN10_H__
-#include "mem_input.h"
-
-#define TO_DCN10_MEM_INPUT(mi)\
- container_of(mi, struct dcn10_mem_input, base)
+#include "hubp.h"
+#define TO_DCN10_HUBP(hubp)\
+ container_of(hubp, struct dcn10_hubp, base)
#define MI_REG_LIST_DCN(id)\
SRI(DCHUBP_CNTL, HUBP, id),\
@@ -118,7 +117,17 @@
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
SR(DCHUBBUB_SDPIF_FB_BASE),\
- SR(DCHUBBUB_SDPIF_FB_OFFSET)
+ SR(DCHUBBUB_SDPIF_FB_OFFSET),\
+ SRI(CURSOR_SETTINS, HUBPREQ, id), \
+ SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
+ SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
+ SRI(CURSOR_SIZE, CURSOR, id), \
+ SRI(CURSOR_CONTROL, CURSOR, id), \
+ SRI(CURSOR_POSITION, CURSOR, id), \
+ SRI(CURSOR_HOT_SPOT, CURSOR, id), \
+ SRI(CURSOR_DST_OFFSET, CURSOR, id)
+
+
struct dcn_mi_registers {
uint32_t DCHUBP_CNTL;
@@ -215,6 +224,15 @@ struct dcn_mi_registers {
uint32_t DCN_VM_AGP_BASE;
uint32_t DCN_VM_AGP_BOT;
uint32_t DCN_VM_AGP_TOP;
+ uint32_t CURSOR_SETTINS;
+ uint32_t CURSOR_SETTINGS;
+ uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
+ uint32_t CURSOR_SURFACE_ADDRESS;
+ uint32_t CURSOR_SIZE;
+ uint32_t CURSOR_CONTROL;
+ uint32_t CURSOR_POSITION;
+ uint32_t CURSOR_HOT_SPOT;
+ uint32_t CURSOR_DST_OFFSET;
};
#define MI_SF(reg_name, field_name, post_fix)\
@@ -351,6 +369,7 @@ struct dcn_mi_registers {
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, mask_sh),\
+ MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mask_sh),\
@@ -360,7 +379,23 @@ struct dcn_mi_registers {
MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
- MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh)
+ MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
+ MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
+ MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
+ MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
#define DCN_MI_REG_FIELD_LIST(type) \
type HUBP_BLANK_EN;\
@@ -488,6 +523,7 @@ struct dcn_mi_registers {
type VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB;\
type VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB;\
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB;\
+ type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM;\
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\
type ENABLE_L1_TLB;\
type SYSTEM_ACCESS_MODE;\
@@ -521,7 +557,24 @@ struct dcn_mi_registers {
type PHYSICAL_PAGE_ADDR_LO32;\
type PHYSICAL_PAGE_NUMBER_MSB;\
type PHYSICAL_PAGE_NUMBER_LSB;\
- type LOGICAL_ADDR
+ type LOGICAL_ADDR;\
+ type CURSOR0_DST_Y_OFFSET; \
+ type CURSOR0_CHUNK_HDL_ADJUST; \
+ type CURSOR_SURFACE_ADDRESS_HIGH; \
+ type CURSOR_SURFACE_ADDRESS; \
+ type CURSOR_WIDTH; \
+ type CURSOR_HEIGHT; \
+ type CURSOR_MODE; \
+ type CURSOR_2X_MAGNIFY; \
+ type CURSOR_PITCH; \
+ type CURSOR_LINES_PER_CHUNK; \
+ type CURSOR_ENABLE; \
+ type CURSOR_X_POSITION; \
+ type CURSOR_Y_POSITION; \
+ type CURSOR_HOT_SPOT_X; \
+ type CURSOR_HOT_SPOT_Y; \
+ type CURSOR_DST_X_OFFSET; \
+ type OUTPUT_FP
struct dcn_mi_shift {
DCN_MI_REG_FIELD_LIST(uint8_t);
@@ -531,21 +584,83 @@ struct dcn_mi_mask {
DCN_MI_REG_FIELD_LIST(uint32_t);
};
-struct dcn10_mem_input {
- struct mem_input base;
+struct dcn10_hubp {
+ struct hubp base;
const struct dcn_mi_registers *mi_regs;
const struct dcn_mi_shift *mi_shift;
const struct dcn_mi_mask *mi_mask;
};
-void dcn10_mem_input_construct(
- struct dcn10_mem_input *mi,
+void hubp1_program_surface_config(
+ struct hubp *hubp,
+ enum surface_pixel_format format,
+ union dc_tiling_info *tiling_info,
+ union plane_size *plane_size,
+ enum dc_rotation_angle rotation,
+ struct dc_plane_dcc_param *dcc,
+ bool horizontal_mirror);
+
+void hubp1_program_deadline(
+ struct hubp *hubp,
+ struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
+ struct _vcs_dpi_display_ttu_regs_st *ttu_attr);
+
+void hubp1_program_requestor(
+ struct hubp *hubp,
+ struct _vcs_dpi_display_rq_regs_st *rq_regs);
+
+void hubp1_program_pixel_format(
+ struct dcn10_hubp *hubp,
+ enum surface_pixel_format format);
+
+void hubp1_program_size_and_rotation(
+ struct dcn10_hubp *hubp,
+ enum dc_rotation_angle rotation,
+ enum surface_pixel_format format,
+ const union plane_size *plane_size,
+ struct dc_plane_dcc_param *dcc,
+ bool horizontal_mirror);
+
+void hubp1_program_tiling(
+ struct dcn10_hubp *hubp,
+ const union dc_tiling_info *info,
+ const enum surface_pixel_format pixel_format);
+
+void hubp1_dcc_control(struct hubp *hubp,
+ bool enable,
+ bool independent_64b_blks);
+
+bool hubp1_program_surface_flip_and_addr(
+ struct hubp *hubp,
+ const struct dc_plane_address *address,
+ bool flip_immediate);
+
+bool hubp1_is_flip_pending(struct hubp *hubp);
+
+void hubp1_cursor_set_attributes(
+ struct hubp *hubp,
+ const struct dc_cursor_attributes *attr);
+
+void hubp1_cursor_set_position(
+ struct hubp *hubp,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param);
+
+void hubp1_set_blank(struct hubp *hubp, bool blank);
+
+void min_set_viewport(struct hubp *hubp,
+ const struct rect *viewport,
+ const struct rect *viewport_c);
+
+void dcn10_hubp_construct(
+ struct dcn10_hubp *hubp1,
struct dc_context *ctx,
uint32_t inst,
const struct dcn_mi_registers *mi_regs,
const struct dcn_mi_shift *mi_shift,
const struct dcn_mi_mask *mi_mask);
+
struct dcn_hubp_state {
uint32_t pixel_format;
uint32_t inuse_addr_hi;
@@ -562,7 +677,7 @@ struct dcn_hubp_state {
uint32_t qos_level_low_wm;
uint32_t qos_level_high_wm;
};
-void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
+void hubp1_read_state(struct dcn10_hubp *hubp1,
struct dcn_hubp_state *s);
#endif
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 @@
#include "dce110/dce110_hw_sequencer.h"
#include "dce/dce_hwseq.h"
#include "abm.h"
-#include "dcn10/dcn10_mem_input.h"
#include "dcn10/dcn10_timing_generator.h"
#include "dcn10/dcn10_dpp.h"
#include "dcn10/dcn10_mpc.h"
@@ -41,6 +40,7 @@
#include "mpc.h"
#include "reg_helper.h"
#include "custom_float.h"
+#include "dcn10_hubp.h"
#define CTX \
hws->ctx
@@ -172,10 +172,10 @@ static void dcn10_log_hw_state(struct dc *dc)
"min_ttu_vblank \t qos_low_wm \t qos_high_wm \n");
for (i = 0; i < pool->pipe_count; i++) {
- struct mem_input *mi = pool->mis[i];
+ struct hubp *hubp = pool->hubps[i];
struct dcn_hubp_state s;
- dcn10_mem_input_read_state(TO_DCN10_MEM_INPUT(mi), &s);
+ hubp1_read_state(TO_DCN10_HUBP(hubp), &s);
DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t "
"%xh \t %xh \t %xh \t "
@@ -245,15 +245,19 @@ static void verify_allow_pstate_change_high(
{
/* pstate latency is ~20us so if we wait over 40us and pstate allow
* still not asserted, we are probably stuck and going to hang
+ *
+ * TODO: Figure out why it takes ~100us on linux
+ * pstate takes around ~100us on linux. Unknown currently as to
+ * why it takes that long on linux
*/
- static unsigned int pstate_wait_timeout_us = 40;
+ static unsigned int pstate_wait_timeout_us = 200;
+ static unsigned int pstate_wait_expected_timeout_us = 40;
static unsigned int max_sampled_pstate_wait_us; /* data collection */
static bool forced_pstate_allow; /* help with revert wa */
static bool should_log_hw_state; /* prevent hw state log by default */
unsigned int debug_index = 0x7;
unsigned int debug_data;
- unsigned int force_allow_pstate = 0x30;
unsigned int i;
if (forced_pstate_allow) {
@@ -261,7 +265,9 @@ static void verify_allow_pstate_change_high(
* we verify_allow_pstate_change_high. so disable force
* here so we can check status
*/
- REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, 0);
+ REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 0,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 0);
forced_pstate_allow = false;
}
@@ -292,9 +298,15 @@ static void verify_allow_pstate_change_high(
for (i = 0; i < pstate_wait_timeout_us; i++) {
debug_data = REG_READ(DCHUBBUB_TEST_DEBUG_DATA);
- if (debug_data & (1 << 30))
- return;
+ if (debug_data & (1 << 30)) {
+
+ if (i > pstate_wait_expected_timeout_us)
+ dm_logger_write(hws->ctx->logger, LOG_WARNING,
+ "pstate took longer than expected ~%dus\n",
+ i);
+ return;
+ }
if (max_sampled_pstate_wait_us < i)
max_sampled_pstate_wait_us = i;
@@ -304,13 +316,18 @@ static void verify_allow_pstate_change_high(
/* force pstate allow to prevent system hang
* and break to debugger to investigate
*/
- REG_WRITE(DCHUBBUB_ARB_DRAM_STATE_CNTL, force_allow_pstate);
+ REG_UPDATE_2(DCHUBBUB_ARB_DRAM_STATE_CNTL,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, 1,
+ DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, 1);
forced_pstate_allow = true;
if (should_log_hw_state) {
dcn10_log_hw_state(hws->ctx->dc);
}
+ dm_logger_write(hws->ctx->logger, LOG_WARNING,
+ "pstate TEST_DEBUG_DATA: 0x%X\n",
+ debug_data);
BREAK_TO_DEBUGGER();
}
@@ -451,7 +468,7 @@ static void program_watermarks(
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.urgent_ns, prog_wm_value);
@@ -459,38 +476,37 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->a.pte_meta_urgent_ns, prog_wm_value);
+ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) {
+ prog_wm_value = convert_and_clamp(
+ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
-
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
-
-
- prog_wm_value = convert_and_clamp(
- watermarks->a.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_EXIT_WATERMARK_A calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ prog_wm_value = convert_and_clamp(
+ watermarks->a.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_EXIT_WATERMARK_A calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ }
prog_wm_value = convert_and_clamp(
watermarks->a.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n",
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -500,7 +516,7 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->b.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.urgent_ns, prog_wm_value);
@@ -510,36 +526,38 @@ static void program_watermarks(
watermarks->b.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->b.pte_meta_urgent_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_ENTER_WATERMARK_B calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) {
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_ENTER_WATERMARK_B calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->b.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_EXIT_WATERMARK_B calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ prog_wm_value = convert_and_clamp(
+ watermarks->b.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_EXIT_WATERMARK_B calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ }
prog_wm_value = convert_and_clamp(
watermarks->b.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n"
"HW register value = 0x%x\n",
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -548,7 +566,7 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->c.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.urgent_ns, prog_wm_value);
@@ -558,37 +576,38 @@ static void program_watermarks(
watermarks->c.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->c.pte_meta_urgent_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_ENTER_WATERMARK_C calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) {
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_ENTER_WATERMARK_C calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->c.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_EXIT_WATERMARK_C calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
-
+ prog_wm_value = convert_and_clamp(
+ watermarks->c.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_EXIT_WATERMARK_C calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ }
prog_wm_value = convert_and_clamp(
watermarks->c.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n"
"HW register value = 0x%x\n",
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -597,7 +616,7 @@ static void program_watermarks(
prog_wm_value = convert_and_clamp(
watermarks->d.urgent_ns, refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.urgent_ns, prog_wm_value);
@@ -606,37 +625,39 @@ static void program_watermarks(
watermarks->d.pte_meta_urgent_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n",
watermarks->d.pte_meta_urgent_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_ENTER_WATERMARK_D calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
+ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) {
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_ENTER_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
- prog_wm_value = convert_and_clamp(
- watermarks->d.cstate_pstate.cstate_exit_ns,
- refclk_mhz, 0x1fffff);
- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
- "SR_EXIT_WATERMARK_D calculated =%d\n"
- "HW register value = 0x%x\n",
- watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ prog_wm_value = convert_and_clamp(
+ watermarks->d.cstate_pstate.cstate_exit_ns,
+ refclk_mhz, 0x1fffff);
+ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
+ "SR_EXIT_WATERMARK_D calculated =%d\n"
+ "HW register value = 0x%x\n",
+ watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
+ }
prog_wm_value = convert_and_clamp(
watermarks->d.cstate_pstate.pstate_change_ns,
refclk_mhz, 0x1fffff);
REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
- dm_logger_write(hws->ctx->logger, LOG_HW_MARKS,
+ dm_logger_write(hws->ctx->logger, LOG_BANDWIDTH_CALCS,
"DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n\n",
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
@@ -771,20 +792,22 @@ static void power_on_plane(
struct dce_hwseq *hws,
int plane_id)
{
- REG_SET(DC_IP_REQUEST_CNTL, 0,
- IP_REQUEST_EN, 1);
- dpp_pg_control(hws, plane_id, true);
- hubp_pg_control(hws, plane_id, true);
- REG_SET(DC_IP_REQUEST_CNTL, 0,
- IP_REQUEST_EN, 0);
- dm_logger_write(hws->ctx->logger, LOG_DEBUG,
- "Un-gated front end for pipe %d\n", plane_id);
+ if (REG(DC_IP_REQUEST_CNTL)) {
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 1);
+ dpp_pg_control(hws, plane_id, true);
+ hubp_pg_control(hws, plane_id, true);
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 0);
+ dm_logger_write(hws->ctx->logger, LOG_DEBUG,
+ "Un-gated front end for pipe %d\n", plane_id);
+ }
}
static void undo_DEGVIDCN10_253_wa(struct dc *dc)
{
struct dce_hwseq *hws = dc->hwseq;
- struct mem_input *mi = dc->res_pool->mis[0];
+ struct hubp *hubp = dc->res_pool->hubps[0];
int pwr_status = 0;
REG_GET(DOMAIN0_PG_STATUS, DOMAIN0_PGFSM_PWR_STATUS, &pwr_status);
@@ -792,7 +815,7 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
if (pwr_status == 2)
return;
- mi->funcs->set_blank(mi, true);
+ hubp->funcs->set_blank(hubp, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
@@ -802,17 +825,13 @@ static void undo_DEGVIDCN10_253_wa(struct dc *dc)
IP_REQUEST_EN, 0);
}
-static void ready_shared_resources(struct dc *dc)
-{
- if (dc->current_state->stream_count == 0 &&
- !dc->debug.disable_stutter)
- undo_DEGVIDCN10_253_wa(dc);
-}
-
static void apply_DEGVIDCN10_253_wa(struct dc *dc)
{
struct dce_hwseq *hws = dc->hwseq;
- struct mem_input *mi = dc->res_pool->mis[0];
+ struct hubp *hubp = dc->res_pool->hubps[0];
+
+ if (dc->debug.disable_stutter)
+ return;
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
@@ -821,14 +840,7 @@ static void apply_DEGVIDCN10_253_wa(struct dc *dc)
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
- mi->funcs->set_hubp_blank_en(mi, false);
-}
-
-static void optimize_shared_resources(struct dc *dc)
-{
- if (dc->current_state->stream_count == 0 &&
- !dc->debug.disable_stutter)
- apply_DEGVIDCN10_253_wa(dc);
+ hubp->funcs->set_hubp_blank_en(hubp, false);
}
static void bios_golden_init(struct dc *dc)
@@ -887,12 +899,13 @@ static void dcn10_init_hw(struct dc *dc)
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
- struct transform *xfm = dc->res_pool->transforms[i];
+ struct dpp *dpp = dc->res_pool->dpps[i];
struct timing_generator *tg = dc->res_pool->timing_generators[i];
- xfm->funcs->transform_reset(xfm);
+ dpp->funcs->dpp_reset(dpp);
dc->res_pool->mpc->funcs->remove(
- dc->res_pool->mpc, dc->res_pool->opps[i], i);
+ dc->res_pool->mpc, &(dc->res_pool->opps[i]->mpc_tree),
+ dc->res_pool->opps[i]->inst, i);
/* Blank controller using driver code instead of
* command table.
@@ -1028,12 +1041,11 @@ static void reset_back_end_for_pipe(
return;
}
- /* TODOFPGA break core_link_disable_stream into 2 functions:
- * disable_stream and disable_link. disable_link will disable PHYPLL
- * which is used by otg. Move disable_link after disable_crtc
- */
- if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
- core_link_disable_stream(pipe_ctx);
+ if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
+ /* DPMS may already disable */
+ if (!pipe_ctx->stream->dpms_off)
+ core_link_disable_stream(pipe_ctx, FREE_ACQUIRED_RESOURCE);
+ }
/* by upper caller loop, parent pipe: pipe0, will be reset last.
* back end share by all pipes and will be disable only when disable
@@ -1062,7 +1074,7 @@ static void reset_back_end_for_pipe(
static void plane_atomic_disconnect(struct dc *dc,
int fe_idx)
{
- struct mem_input *mi = dc->res_pool->mis[fe_idx];
+ struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc;
int opp_id, z_idx;
int mpcc_id = -1;
@@ -1086,11 +1098,12 @@ static void plane_atomic_disconnect(struct dc *dc,
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
- mi->funcs->dcc_control(mi, false, false);
+ hubp->funcs->dcc_control(hubp, false, false);
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
- mpc->funcs->remove(mpc, dc->res_pool->opps[opp_id], fe_idx);
+ mpc->funcs->remove(mpc, &(dc->res_pool->opps[opp_id]->mpc_tree),
+ dc->res_pool->opps[opp_id]->inst, fe_idx);
}
/* disable HW used by plane.
@@ -1099,20 +1112,20 @@ static void plane_atomic_disable(struct dc *dc,
int fe_idx)
{
struct dce_hwseq *hws = dc->hwseq;
- struct mem_input *mi = dc->res_pool->mis[fe_idx];
+ struct hubp *hubp = dc->res_pool->hubps[fe_idx];
struct mpc *mpc = dc->res_pool->mpc;
- int opp_id = mi->opp_id;
+ int opp_id = hubp->opp_id;
if (opp_id == 0xf)
return;
- mpc->funcs->wait_for_idle(mpc, mi->mpcc_id);
- dc->res_pool->opps[mi->opp_id]->mpcc_disconnect_pending[mi->mpcc_id] = false;
+ mpc->funcs->wait_for_idle(mpc, hubp->mpcc_id);
+ dc->res_pool->opps[hubp->opp_id]->mpcc_disconnect_pending[hubp->mpcc_id] = false;
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: atomic disable finished on mpcc %d]\n",
fe_idx);*/
- mi->funcs->set_blank(mi, true);
+ hubp->funcs->set_blank(hubp, true);
if (dc->debug.sanity_checks)
verify_allow_pstate_change_high(dc->hwseq);
@@ -1137,20 +1150,22 @@ static void plane_atomic_disable(struct dc *dc,
static void plane_atomic_power_down(struct dc *dc, int fe_idx)
{
struct dce_hwseq *hws = dc->hwseq;
- struct transform *xfm = dc->res_pool->transforms[fe_idx];
-
- REG_SET(DC_IP_REQUEST_CNTL, 0,
- IP_REQUEST_EN, 1);
- dpp_pg_control(hws, fe_idx, false);
- hubp_pg_control(hws, fe_idx, false);
- xfm->funcs->transform_reset(xfm);
- REG_SET(DC_IP_REQUEST_CNTL, 0,
- IP_REQUEST_EN, 0);
- dm_logger_write(dc->ctx->logger, LOG_DEBUG,
- "Power gated front end %d\n", fe_idx);
-
- if (dc->debug.sanity_checks)
- verify_allow_pstate_change_high(dc->hwseq);
+ struct dpp *dpp = dc->res_pool->dpps[fe_idx];
+
+ if (REG(DC_IP_REQUEST_CNTL)) {
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 1);
+ dpp_pg_control(hws, fe_idx, false);
+ hubp_pg_control(hws, fe_idx, false);
+ dpp->funcs->dpp_reset(dpp);
+ REG_SET(DC_IP_REQUEST_CNTL, 0,
+ IP_REQUEST_EN, 0);
+ dm_logger_write(dc->ctx->logger, LOG_DEBUG,
+ "Power gated front end %d\n", fe_idx);
+
+ if (dc->debug.sanity_checks)
+ verify_allow_pstate_change_high(dc->hwseq);
+ }
}
@@ -1160,7 +1175,7 @@ static void reset_front_end(
{
struct dce_hwseq *hws = dc->hwseq;
struct timing_generator *tg;
- int opp_id = dc->res_pool->mis[fe_idx]->opp_id;
+ int opp_id = dc->res_pool->hubps[fe_idx]->opp_id;
/*Already reset*/
if (opp_id == 0xf)
@@ -1192,7 +1207,7 @@ static void reset_front_end(
static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
{
struct dce_hwseq *hws = dc->hwseq;
- struct transform *xfm = dc->res_pool->transforms[fe_idx];
+ struct dpp *dpp = dc->res_pool->dpps[fe_idx];
reset_front_end(dc, fe_idx);
@@ -1200,7 +1215,7 @@ static void dcn10_power_down_fe(struct dc *dc, int fe_idx)
IP_REQUEST_EN, 1);
dpp_pg_control(hws, fe_idx, false);
hubp_pg_control(hws, fe_idx, false);
- xfm->funcs->transform_reset(xfm);
+ dpp->funcs->dpp_reset(dpp);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
dm_logger_write(dc->ctx->logger, LOG_DEBUG,
@@ -1275,6 +1290,9 @@ static void reset_hw_ctx_wrap(
if (!pipe_ctx_old->stream)
continue;
+ if (pipe_ctx_old->top_pipe)
+ continue;
+
if (!pipe_ctx->stream ||
pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
struct clock_source *old_clk = pipe_ctx_old->clock_source;
@@ -1339,8 +1357,8 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
if (plane_state == NULL)
return;
addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);
- pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr(
- pipe_ctx->plane_res.mi,
+ pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(
+ pipe_ctx->plane_res.hubp,
&plane_state->address,
plane_state->flip_immediate);
plane_state->status.requested_address = plane_state->address;
@@ -1351,34 +1369,34 @@ static void dcn10_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
static bool dcn10_set_input_transfer_func(
struct pipe_ctx *pipe_ctx, const struct dc_plane_state *plane_state)
{
- struct transform *xfm_base = pipe_ctx->plane_res.xfm;
+ struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
const struct dc_transfer_func *tf = NULL;
bool result = true;
- if (xfm_base == NULL)
+ if (dpp_base == NULL)
return false;
if (plane_state->in_transfer_func)
tf = plane_state->in_transfer_func;
if (plane_state->gamma_correction && dce_use_lut(plane_state))
- xfm_base->funcs->ipp_program_input_lut(xfm_base,
+ dpp_base->funcs->ipp_program_input_lut(dpp_base,
plane_state->gamma_correction);
if (tf == NULL)
- xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS);
+ dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
else if (tf->type == TF_TYPE_PREDEFINED) {
switch (tf->tf) {
case TRANSFER_FUNCTION_SRGB:
- xfm_base->funcs->ipp_set_degamma(xfm_base,
+ dpp_base->funcs->ipp_set_degamma(dpp_base,
IPP_DEGAMMA_MODE_HW_sRGB);
break;
case TRANSFER_FUNCTION_BT709:
- xfm_base->funcs->ipp_set_degamma(xfm_base,
+ dpp_base->funcs->ipp_set_degamma(dpp_base,
IPP_DEGAMMA_MODE_HW_xvYCC);
break;
case TRANSFER_FUNCTION_LINEAR:
- xfm_base->funcs->ipp_set_degamma(xfm_base,
+ dpp_base->funcs->ipp_set_degamma(dpp_base,
IPP_DEGAMMA_MODE_BYPASS);
break;
case TRANSFER_FUNCTION_PQ:
@@ -1389,7 +1407,7 @@ static bool dcn10_set_input_transfer_func(
break;
}
} else if (tf->type == TF_TYPE_BYPASS) {
- xfm_base->funcs->ipp_set_degamma(xfm_base, IPP_DEGAMMA_MODE_BYPASS);
+ dpp_base->funcs->ipp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
} else {
/*TF_TYPE_DISTRIBUTED_POINTS*/
result = false;
@@ -1716,25 +1734,25 @@ static bool dcn10_set_output_transfer_func(
struct pipe_ctx *pipe_ctx,
const struct dc_stream_state *stream)
{
- struct transform *xfm = pipe_ctx->plane_res.xfm;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
- if (xfm == NULL)
+ if (dpp == NULL)
return false;
- xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
+ dpp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
if (stream->out_transfer_func &&
stream->out_transfer_func->type ==
TF_TYPE_PREDEFINED &&
stream->out_transfer_func->tf ==
TRANSFER_FUNCTION_SRGB) {
- xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
+ dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_SRGB);
} else if (dcn10_translate_regamma_to_hw_format(
- stream->out_transfer_func, &xfm->regamma_params)) {
- xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
- xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
+ stream->out_transfer_func, &dpp->regamma_params)) {
+ dpp->funcs->opp_program_regamma_pwl(dpp, &dpp->regamma_params);
+ dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_USER);
} else {
- xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
+ dpp->funcs->opp_set_regamma_mode(dpp, OPP_REGAMMA_BYPASS);
}
return true;
@@ -1745,8 +1763,8 @@ static void dcn10_pipe_control_lock(
struct pipe_ctx *pipe,
bool lock)
{
- struct mem_input *mi = NULL;
- mi = dc->res_pool->mis[pipe->pipe_idx];
+ struct hubp *hubp = NULL;
+ hubp = dc->res_pool->hubps[pipe->pipe_idx];
/* use TG master update lock to lock everything on the TG
* therefore only top pipe need to lock
*/
@@ -1997,10 +2015,11 @@ static void dcn10_power_on_fe(
plane_state->dst_rect.height);
dm_logger_write(dc->ctx->logger, LOG_DC,
- "Pipe %d: width, height, x, y\n"
+ "Pipe %d: width, height, x, y format:%d\n"
"viewport:%d, %d, %d, %d\n"
"recout: %d, %d, %d, %d\n",
pipe_ctx->pipe_idx,
+ plane_state->format,
pipe_ctx->plane_res.scl_data.viewport.width,
pipe_ctx->plane_res.scl_data.viewport.height,
pipe_ctx->plane_res.scl_data.viewport.x,
@@ -2019,7 +2038,7 @@ static void dcn10_power_on_fe(
static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
{
- struct xfm_grph_csc_adjustment adjust;
+ struct dpp_grph_csc_adjustment adjust;
memset(&adjust, 0, sizeof(adjust));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -2055,7 +2074,7 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
gamut_remap_matrix.matrix[10];
}
- pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
+ pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
}
@@ -2077,7 +2096,7 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
tbl_entry.color_space = color_space;
//tbl_entry.regval = matrix;
- pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.xfm, &tbl_entry);
+ pipe_ctx->plane_res.dpp->funcs->opp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry);
}
}
static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
@@ -2167,7 +2186,7 @@ static void dcn10_get_surface_visual_confirm_color(
}
}
-static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
+static void mmhub_read_vm_system_aperture_settings(struct dcn10_hubp *hubp1,
struct vm_system_aperture_param *apt,
struct dce_hwseq *hws)
{
@@ -2192,7 +2211,7 @@ static void mmhub_read_vm_system_aperture_settings(struct dcn10_mem_input *mi,
}
/* Temporary read settings, future will get values from kmd directly */
-static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
+static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1,
struct vm_context0_param *vm0,
struct dce_hwseq *hws)
{
@@ -2236,22 +2255,22 @@ static void mmhub_read_vm_context0_settings(struct dcn10_mem_input *mi,
vm0->pte_base.quad_part -= fb_offset.quad_part;
}
-static void dcn10_program_pte_vm(struct mem_input *mem_input,
+static void dcn10_program_pte_vm(struct hubp *hubp,
enum surface_pixel_format format,
union dc_tiling_info *tiling_info,
enum dc_rotation_angle rotation,
struct dce_hwseq *hws)
{
- struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
struct vm_system_aperture_param apt = { {{ 0 } } };
struct vm_context0_param vm0 = { { { 0 } } };
- mmhub_read_vm_system_aperture_settings(mi, &apt, hws);
- mmhub_read_vm_context0_settings(mi, &vm0, hws);
+ mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws);
+ mmhub_read_vm_context0_settings(hubp1, &vm0, hws);
- mem_input->funcs->mem_input_set_vm_system_aperture_settings(mem_input, &apt);
- mem_input->funcs->mem_input_set_vm_context0_settings(mem_input, &vm0);
+ hubp->funcs->hubp_set_vm_system_aperture_settings(hubp, &apt);
+ hubp->funcs->hubp_set_vm_context0_settings(hubp, &vm0);
}
static void update_dchubp_dpp(
@@ -2260,11 +2279,10 @@ static void update_dchubp_dpp(
struct dc_state *context)
{
struct dce_hwseq *hws = dc->hwseq;
- struct mem_input *mi = pipe_ctx->plane_res.mi;
- struct transform *xfm = pipe_ctx->plane_res.xfm;
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
union plane_size size = plane_state->plane_size;
- struct default_adjustment ocsc = {0};
struct mpcc_cfg mpcc_cfg = {0};
struct pipe_ctx *top_pipe;
bool per_pixel_alpha = plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;
@@ -2286,10 +2304,8 @@ static void update_dchubp_dpp(
*/
REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst);
- dc->hwss.update_plane_addr(dc, pipe_ctx);
-
- mi->funcs->mem_input_setup(
- mi,
+ hubp->funcs->hubp_setup(
+ hubp,
&pipe_ctx->dlg_regs,
&pipe_ctx->ttu_regs,
&pipe_ctx->rq_regs,
@@ -2299,19 +2315,20 @@ static void update_dchubp_dpp(
if (dc->config.gpu_vm_support)
dcn10_program_pte_vm(
- pipe_ctx->plane_res.mi,
+ pipe_ctx->plane_res.hubp,
plane_state->format,
&plane_state->tiling_info,
plane_state->rotation,
hws
);
- xfm->funcs->ipp_setup(xfm,
+ dpp->funcs->ipp_setup(dpp,
plane_state->format,
EXPANSION_MODE_ZERO);
- mpcc_cfg.mi = mi;
- mpcc_cfg.opp = pipe_ctx->stream_res.opp;
+ mpcc_cfg.dpp_id = hubp->inst;
+ mpcc_cfg.opp_id = pipe_ctx->stream_res.opp->inst;
+ mpcc_cfg.tree_cfg = &(pipe_ctx->stream_res.opp->mpc_tree);
for (top_pipe = pipe_ctx->top_pipe; top_pipe; top_pipe = top_pipe->top_pipe)
mpcc_cfg.z_index++;
if (dc->debug.surface_visual_confirm)
@@ -2328,25 +2345,27 @@ static void update_dchubp_dpp(
mpcc_cfg.pre_multiplied_alpha = is_rgb_cspace(
pipe_ctx->stream->output_color_space)
&& per_pixel_alpha;
- dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
+ hubp->mpcc_id = dc->res_pool->mpc->funcs->add(dc->res_pool->mpc, &mpcc_cfg);
+ hubp->opp_id = mpcc_cfg.opp_id;
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = per_pixel_alpha;
pipe_ctx->plane_res.scl_data.lb_params.depth = LB_PIXEL_DEPTH_30BPP;
/* scaler configuration */
- pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(
- pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data);
- mi->funcs->mem_program_viewport(mi,
+ pipe_ctx->plane_res.dpp->funcs->dpp_set_scaler(
+ pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data);
+
+ hubp->funcs->mem_program_viewport(hubp,
&pipe_ctx->plane_res.scl_data.viewport, &pipe_ctx->plane_res.scl_data.viewport_c);
/*gamut remap*/
program_gamut_remap(pipe_ctx);
- /*TODO add adjustments parameters*/
- ocsc.out_color_space = pipe_ctx->stream->output_color_space;
- pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(pipe_ctx->plane_res.xfm, &ocsc);
+ program_csc_matrix(pipe_ctx,
+ pipe_ctx->stream->output_color_space,
+ pipe_ctx->stream->csc_color_matrix.matrix);
- mi->funcs->mem_input_program_surface_config(
- mi,
+ hubp->funcs->hubp_program_surface_config(
+ hubp,
plane_state->format,
&plane_state->tiling_info,
&size,
@@ -2354,8 +2373,10 @@ static void update_dchubp_dpp(
&plane_state->dcc,
plane_state->horizontal_mirror);
+ dc->hwss.update_plane_addr(dc, pipe_ctx);
+
if (is_pipe_tree_visible(pipe_ctx))
- mi->funcs->set_blank(mi, false);
+ hubp->funcs->set_blank(hubp, false);
}
@@ -2393,6 +2414,10 @@ static void program_all_pipe_in_tree(
}
if (pipe_ctx->plane_state != NULL) {
+ struct dc_cursor_position position = { 0 };
+ struct pipe_ctx *cur_pipe_ctx =
+ &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
+
dcn10_power_on_fe(dc, pipe_ctx, context);
/* temporary dcn1 wa:
@@ -2407,6 +2432,19 @@ static void program_all_pipe_in_tree(
toggle_watermark_change_req(dc->hwseq);
update_dchubp_dpp(dc, pipe_ctx, context);
+
+ /* TODO: this is a hack w/a for switching from mpo to pipe split */
+ dc_stream_set_cursor_position(pipe_ctx->stream, &position);
+
+ dc_stream_set_cursor_attributes(pipe_ctx->stream,
+ &pipe_ctx->stream->cursor_attributes);
+
+ if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
+ dc->hwss.set_input_transfer_func(
+ pipe_ctx, pipe_ctx->plane_state);
+ dc->hwss.set_output_transfer_func(
+ pipe_ctx, pipe_ctx->stream);
+ }
}
if (dc->debug.sanity_checks) {
@@ -2445,6 +2483,30 @@ static void dcn10_pplib_apply_display_requirements(
dc->prev_display_config = *pp_display_cfg;
}
+static void optimize_shared_resources(struct dc *dc)
+{
+ if (dc->current_state->stream_count == 0) {
+ apply_DEGVIDCN10_253_wa(dc);
+ /* S0i2 message */
+ dcn10_pplib_apply_display_requirements(dc, dc->current_state);
+ }
+
+ if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
+ dcn_bw_notify_pplib_of_wm_ranges(dc);
+}
+
+static void ready_shared_resources(struct dc *dc, struct dc_state *context)
+{
+ if (dc->current_state->stream_count == 0 &&
+ !dc->debug.disable_stutter)
+ undo_DEGVIDCN10_253_wa(dc);
+
+ /* S0i2 message */
+ if (dc->current_state->stream_count == 0 &&
+ context->stream_count != 0)
+ dcn10_pplib_apply_display_requirements(dc, context);
+}
+
static void dcn10_apply_ctx_for_surface(
struct dc *dc,
const struct dc_stream_state *stream,
@@ -2494,7 +2556,7 @@ static void dcn10_apply_ctx_for_surface(
*/
if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) {
- if (pipe_ctx->plane_res.mi->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
+ if (pipe_ctx->plane_res.hubp->opp_id != 0xf && pipe_ctx->stream_res.tg->inst == be_idx) {
dcn10_power_down_fe(dc, pipe_ctx->pipe_idx);
/*
* power down fe will unlock when calling reset, need
@@ -2518,9 +2580,10 @@ static void dcn10_apply_ctx_for_surface(
/* reset mpc */
dc->res_pool->mpc->funcs->remove(
dc->res_pool->mpc,
- old_pipe_ctx->stream_res.opp,
+ &(old_pipe_ctx->stream_res.opp->mpc_tree),
+ old_pipe_ctx->stream_res.opp->inst,
old_pipe_ctx->pipe_idx);
- old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.mi->mpcc_id] = true;
+ old_pipe_ctx->stream_res.opp->mpcc_disconnect_pending[old_pipe_ctx->plane_res.hubp->mpcc_id] = true;
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: apply_ctx disconnect pending on mpcc %d]\n",
@@ -2532,6 +2595,7 @@ static void dcn10_apply_ctx_for_surface(
old_pipe_ctx->top_pipe = NULL;
old_pipe_ctx->bottom_pipe = NULL;
old_pipe_ctx->plane_state = NULL;
+ old_pipe_ctx->stream = NULL;
dm_logger_write(dc->ctx->logger, LOG_DC,
"Reset mpcc for pipe %d\n",
@@ -2803,7 +2867,7 @@ static void dcn10_wait_for_mpcc_disconnect(
if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i]) {
res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, i);
pipe_ctx->stream_res.opp->mpcc_disconnect_pending[i] = false;
- res_pool->mis[i]->funcs->set_blank(res_pool->mis[i], true);
+ res_pool->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
i);*/
@@ -2834,11 +2898,11 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
return;
plane_state->status.is_flip_pending =
- pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending(
- pipe_ctx->plane_res.mi);
+ pipe_ctx->plane_res.hubp->funcs->hubp_is_flip_pending(
+ pipe_ctx->plane_res.hubp);
- plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address;
- if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
+ plane_state->status.current_address = pipe_ctx->plane_res.hubp->current_address;
+ if (pipe_ctx->plane_res.hubp->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO &&
tg->funcs->is_stereo_left_eye) {
plane_state->status.is_right_eye =
!tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg);
@@ -2882,6 +2946,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect,
.ready_shared_resources = ready_shared_resources,
.optimize_shared_resources = optimize_shared_resources,
+ .edp_backlight_control = hwss_edp_backlight_control,
+ .edp_power_control = hwss_edp_power_control
};
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 @@
#define CTX \
ippn10->base.ctx
-static bool ippn10_cursor_program_control(
- struct dcn10_ipp *ippn10,
- bool pixel_data_invert,
- enum dc_cursor_color_format color_format)
-{
- if (REG(CURSOR_SETTINS))
- REG_SET_2(CURSOR_SETTINS, 0,
- /* no shift of the cursor HDL schedule */
- CURSOR0_DST_Y_OFFSET, 0,
- /* used to shift the cursor chunk request deadline */
- CURSOR0_CHUNK_HDL_ADJUST, 3);
- else
- REG_SET_2(CURSOR_SETTINGS, 0,
- /* no shift of the cursor HDL schedule */
- CURSOR0_DST_Y_OFFSET, 0,
- /* used to shift the cursor chunk request deadline */
- CURSOR0_CHUNK_HDL_ADJUST, 3);
-
- REG_UPDATE_2(CURSOR0_CONTROL,
- CUR0_MODE, color_format,
- CUR0_EXPANSION_MODE, 0);
-
- if (color_format == CURSOR_MODE_MONO) {
- /* todo: clarify what to program these to */
- REG_UPDATE(CURSOR0_COLOR0,
- CUR0_COLOR0, 0x00000000);
- REG_UPDATE(CURSOR0_COLOR1,
- CUR0_COLOR1, 0xFFFFFFFF);
- }
-
- /* TODO: Fixed vs float */
-
- REG_UPDATE_3(FORMAT_CONTROL,
- CNVC_BYPASS, 0,
- ALPHA_EN, 1,
- FORMAT_EXPANSION_MODE, 0);
-
- return true;
-}
-
-enum cursor_pitch {
- CURSOR_PITCH_64_PIXELS = 0,
- CURSOR_PITCH_128_PIXELS,
- CURSOR_PITCH_256_PIXELS
-};
-
-enum cursor_lines_per_chunk {
- CURSOR_LINE_PER_CHUNK_2 = 1,
- CURSOR_LINE_PER_CHUNK_4,
- CURSOR_LINE_PER_CHUNK_8,
- CURSOR_LINE_PER_CHUNK_16
-};
-
-static enum cursor_pitch ippn10_get_cursor_pitch(
- unsigned int pitch)
-{
- enum cursor_pitch hw_pitch;
-
- switch (pitch) {
- case 64:
- hw_pitch = CURSOR_PITCH_64_PIXELS;
- break;
- case 128:
- hw_pitch = CURSOR_PITCH_128_PIXELS;
- break;
- case 256:
- hw_pitch = CURSOR_PITCH_256_PIXELS;
- break;
- default:
- DC_ERR("Invalid cursor pitch of %d. "
- "Only 64/128/256 is supported on DCN.\n", pitch);
- hw_pitch = CURSOR_PITCH_64_PIXELS;
- break;
- }
- return hw_pitch;
-}
-
-static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
- unsigned int cur_width,
- enum dc_cursor_color_format format)
-{
- enum cursor_lines_per_chunk line_per_chunk;
-
- if (format == CURSOR_MODE_MONO)
- /* impl B. expansion in CUR Buffer reader */
- line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
- else if (cur_width <= 32)
- line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
- else if (cur_width <= 64)
- line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
- else if (cur_width <= 128)
- line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
- else
- line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
-
- return line_per_chunk;
-}
-
-static void ippn10_cursor_set_attributes(
- struct input_pixel_processor *ipp,
- const struct dc_cursor_attributes *attr)
-{
- struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
- enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
- enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
- attr->width, attr->color_format);
-
- ippn10->curs_attr = *attr;
-
- REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
- CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
- REG_UPDATE(CURSOR_SURFACE_ADDRESS,
- CURSOR_SURFACE_ADDRESS, attr->address.low_part);
-
- REG_UPDATE_2(CURSOR_SIZE,
- CURSOR_WIDTH, attr->width,
- CURSOR_HEIGHT, attr->height);
- REG_UPDATE_3(CURSOR_CONTROL,
- CURSOR_MODE, attr->color_format,
- CURSOR_PITCH, hw_pitch,
- CURSOR_LINES_PER_CHUNK, lpc);
- ippn10_cursor_program_control(ippn10,
- attr->attribute_flags.bits.INVERT_PIXEL_DATA,
- attr->color_format);
-}
-
-static void ippn10_cursor_set_position(
- struct input_pixel_processor *ipp,
- const struct dc_cursor_position *pos,
- const struct dc_cursor_mi_param *param)
-{
- struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
- int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
- uint32_t cur_en = pos->enable ? 1 : 0;
- uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
-
- /*
- * Guard aganst cursor_set_position() from being called with invalid
- * attributes
- *
- * TODO: Look at combining cursor_set_position() and
- * cursor_set_attributes() into cursor_update()
- */
- if (ippn10->curs_attr.address.quad_part == 0)
- return;
-
- dst_x_offset *= param->ref_clk_khz;
- dst_x_offset /= param->pixel_clk_khz;
-
- ASSERT(param->h_scale_ratio.value);
-
- if (param->h_scale_ratio.value)
- dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
- dal_fixed31_32_from_int(dst_x_offset),
- param->h_scale_ratio));
-
- if (src_x_offset >= (int)param->viewport_width)
- cur_en = 0; /* not visible beyond right edge*/
-
- if (src_x_offset + (int)ippn10->curs_attr.width < 0)
- cur_en = 0; /* not visible beyond left edge*/
-
- if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
- ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
- REG_UPDATE(CURSOR_CONTROL,
- CURSOR_ENABLE, cur_en);
- REG_UPDATE(CURSOR0_CONTROL,
- CUR0_ENABLE, cur_en);
-
- REG_SET_2(CURSOR_POSITION, 0,
- CURSOR_X_POSITION, pos->x,
- CURSOR_Y_POSITION, pos->y);
-
- REG_SET_2(CURSOR_HOT_SPOT, 0,
- CURSOR_HOT_SPOT_X, pos->x_hotspot,
- CURSOR_HOT_SPOT_Y, pos->y_hotspot);
-
- REG_SET(CURSOR_DST_OFFSET, 0,
- CURSOR_DST_X_OFFSET, dst_x_offset);
- /* TODO Handle surface pixel formats other than 4:4:4 */
-}
-
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
@@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
}
static const struct ipp_funcs dcn10_ipp_funcs = {
- .ipp_cursor_set_attributes = ippn10_cursor_set_attributes,
- .ipp_cursor_set_position = ippn10_cursor_set_position,
- .ipp_set_degamma = NULL,
- .ipp_program_input_lut = NULL,
- .ipp_full_bypass = NULL,
- .ipp_setup = NULL,
- .ipp_program_degamma_pwl = NULL,
.ipp_destroy = dcn10_ipp_destroy
};
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(
MPCC_BG_B_CB, bg_b_cb);
}
-static void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
+void mpc10_assert_idle_mpcc(struct mpc *mpc, int id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
@@ -116,19 +116,21 @@ static void mpc10_assert_mpcc_idle_before_connect(struct dcn10_mpc *mpc10, int i
}
}
-static void mpc10_mpcc_remove(
+void mpc10_mpcc_remove(
struct mpc *mpc,
- struct output_pixel_processor *opp,
+ struct mpc_tree_cfg *tree_cfg,
+ int opp_id,
int dpp_id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
int mpcc_id, z_idx;
- for (z_idx = 0; z_idx < opp->mpc_tree.num_pipes; z_idx++)
- if (opp->mpc_tree.dpp[z_idx] == dpp_id)
+ /* find z_idx for the dpp to be removed */
+ for (z_idx = 0; z_idx < tree_cfg->num_pipes; z_idx++)
+ if (tree_cfg->dpp[z_idx] == dpp_id)
break;
- if (z_idx == opp->mpc_tree.num_pipes) {
+ if (z_idx == tree_cfg->num_pipes) {
/* In case of resume from S3/S4, remove mpcc from bios left over */
REG_SET(MPCC_OPP_ID[dpp_id], 0,
MPCC_OPP_ID, 0xf);
@@ -139,7 +141,7 @@ static void mpc10_mpcc_remove(
return;
}
- mpcc_id = opp->mpc_tree.mpcc[z_idx];
+ mpcc_id = tree_cfg->mpcc[z_idx];
REG_SET(MPCC_OPP_ID[mpcc_id], 0,
MPCC_OPP_ID, 0xf);
@@ -149,82 +151,101 @@ static void mpc10_mpcc_remove(
MPCC_BOT_SEL, 0xf);
if (z_idx > 0) {
- int top_mpcc_id = opp->mpc_tree.mpcc[z_idx - 1];
+ int top_mpcc_id = tree_cfg->mpcc[z_idx - 1];
- if (z_idx + 1 < opp->mpc_tree.num_pipes)
+ if (z_idx + 1 < tree_cfg->num_pipes)
+ /* mpcc to be removed is in the middle of the tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
- MPCC_BOT_SEL, opp->mpc_tree.mpcc[z_idx + 1]);
+ MPCC_BOT_SEL, tree_cfg->mpcc[z_idx + 1]);
else {
+ /* mpcc to be removed is at the bottom of the tree */
REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
MPCC_BOT_SEL, 0xf);
REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
MPCC_MODE, MODE_TOP_ONLY);
}
- } else if (opp->mpc_tree.num_pipes > 1)
- REG_SET(MUX[opp->inst], 0,
- MPC_OUT_MUX, opp->mpc_tree.mpcc[z_idx + 1]);
+ } else if (tree_cfg->num_pipes > 1)
+ /* mpcc to be removed is at the top of the tree */
+ REG_SET(MUX[opp_id], 0,
+ MPC_OUT_MUX, tree_cfg->mpcc[z_idx + 1]);
else
- REG_SET(MUX[opp->inst], 0, MPC_OUT_MUX, 0xf);
+ /* mpcc to be removed is the only one in the tree */
+ REG_SET(MUX[opp_id], 0, MPC_OUT_MUX, 0xf);
+ /* mark this mpcc as not in use */
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
- opp->mpc_tree.num_pipes--;
- for (; z_idx < opp->mpc_tree.num_pipes; z_idx++) {
- opp->mpc_tree.dpp[z_idx] = opp->mpc_tree.dpp[z_idx + 1];
- opp->mpc_tree.mpcc[z_idx] = opp->mpc_tree.mpcc[z_idx + 1];
+ tree_cfg->num_pipes--;
+ for (; z_idx < tree_cfg->num_pipes; z_idx++) {
+ tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx + 1];
+ tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx + 1];
}
- opp->mpc_tree.dpp[opp->mpc_tree.num_pipes] = 0xdeadbeef;
- opp->mpc_tree.mpcc[opp->mpc_tree.num_pipes] = 0xdeadbeef;
+ tree_cfg->dpp[tree_cfg->num_pipes] = 0xdeadbeef;
+ tree_cfg->mpcc[tree_cfg->num_pipes] = 0xdeadbeef;
}
-static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
+static void mpc10_add_to_tree_cfg(
+ struct mpc *mpc,
+ struct mpcc_cfg *cfg,
+ int mpcc_id)
{
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+ int mpcc_mode = MODE_TOP_ONLY;
+ int position = cfg->z_index;
+ struct mpc_tree_cfg *tree_cfg = cfg->tree_cfg;
int alpha_blnd_mode = cfg->per_pixel_alpha ?
BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
- int mpcc_mode = MODE_TOP_ONLY;
- int mpcc_id, z_idx;
+ int z_idx;
- ASSERT(cfg->z_index < mpc10->num_mpcc);
+ REG_SET(MPCC_OPP_ID[mpcc_id], 0,
+ MPCC_OPP_ID, cfg->opp_id);
- for (z_idx = 0; z_idx < cfg->opp->mpc_tree.num_pipes; z_idx++)
- if (cfg->opp->mpc_tree.dpp[z_idx] == cfg->mi->inst)
- break;
- if (z_idx == cfg->opp->mpc_tree.num_pipes) {
- ASSERT(cfg->z_index <= cfg->opp->mpc_tree.num_pipes);
- mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
- /*todo: remove hack*/
- mpcc_id = cfg->mi->inst;
- ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
+ REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
+ MPCC_TOP_SEL, cfg->dpp_id);
- if (mpc->ctx->dc->debug.sanity_checks)
- mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
- } else {
- ASSERT(cfg->z_index < cfg->opp->mpc_tree.num_pipes);
- mpcc_id = cfg->opp->mpc_tree.mpcc[z_idx];
- mpc10_mpcc_remove(mpc, cfg->opp, cfg->mi->inst);
- }
+ if (position == 0) {
+ /* idle dpp/mpcc is added to the top layer of tree */
- REG_SET(MPCC_OPP_ID[mpcc_id], 0,
- MPCC_OPP_ID, cfg->opp->inst);
+ if (tree_cfg->num_pipes > 0) {
+ /* get instance of previous top mpcc */
+ int prev_top_mpcc_id = tree_cfg->mpcc[0];
- REG_SET(MPCC_TOP_SEL[mpcc_id], 0,
- MPCC_TOP_SEL, cfg->mi->inst);
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
+ MPCC_BOT_SEL, prev_top_mpcc_id);
+ mpcc_mode = MODE_BLEND;
+ }
- if (cfg->z_index > 0) {
- int top_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index - 1];
+ /* opp will get new output. from new added mpcc */
+ REG_SET(MUX[cfg->opp_id], 0, MPC_OUT_MUX, mpcc_id);
- REG_SET(MPCC_BOT_SEL[top_mpcc_id], 0,
+ } else if (position == tree_cfg->num_pipes) {
+ /* idle dpp/mpcc is added to the bottom layer of tree */
+
+ /* get instance of previous bottom mpcc, set to middle layer */
+ int prev_bot_mpcc_id = tree_cfg->mpcc[tree_cfg->num_pipes - 1];
+
+ REG_SET(MPCC_BOT_SEL[prev_bot_mpcc_id], 0,
MPCC_BOT_SEL, mpcc_id);
- REG_UPDATE(MPCC_CONTROL[top_mpcc_id],
+ REG_UPDATE(MPCC_CONTROL[prev_bot_mpcc_id],
MPCC_MODE, MODE_BLEND);
- } else
- REG_SET(MUX[cfg->opp->inst], 0, MPC_OUT_MUX, mpcc_id);
- if (cfg->z_index < cfg->opp->mpc_tree.num_pipes) {
- int bot_mpcc_id = cfg->opp->mpc_tree.mpcc[cfg->z_index];
+ /* mpcc_id become new bottom mpcc*/
+ REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
+ MPCC_BOT_SEL, 0xf);
+
+ } else {
+ /* idle dpp/mpcc is added to middle of tree */
+ int above_mpcc_id = tree_cfg->mpcc[position - 1];
+ int below_mpcc_id = tree_cfg->mpcc[position];
+ /* mpcc above new mpcc_id has new bottom mux*/
+ REG_SET(MPCC_BOT_SEL[above_mpcc_id], 0,
+ MPCC_BOT_SEL, mpcc_id);
+ REG_UPDATE(MPCC_CONTROL[above_mpcc_id],
+ MPCC_MODE, MODE_BLEND);
+
+ /* mpcc_id bottom mux is from below mpcc*/
REG_SET(MPCC_BOT_SEL[mpcc_id], 0,
- MPCC_BOT_SEL, bot_mpcc_id);
+ MPCC_BOT_SEL, below_mpcc_id);
mpcc_mode = MODE_BLEND;
}
@@ -234,24 +255,91 @@ static void mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha,
MPCC_BLND_ACTIVE_OVERLAP_ONLY, false);
+ /* update mpc_tree_cfg with new mpcc */
+ for (z_idx = tree_cfg->num_pipes; z_idx > position; z_idx--) {
+ tree_cfg->dpp[z_idx] = tree_cfg->dpp[z_idx - 1];
+ tree_cfg->mpcc[z_idx] = tree_cfg->mpcc[z_idx - 1];
+ }
+ tree_cfg->dpp[position] = cfg->dpp_id;
+ tree_cfg->mpcc[position] = mpcc_id;
+ tree_cfg->num_pipes++;
+}
+
+int mpc10_mpcc_add(struct mpc *mpc, struct mpcc_cfg *cfg)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+ int mpcc_id, z_idx;
+
+ ASSERT(cfg->z_index < mpc10->num_mpcc);
+
+ /* check in dpp already exists in mpc tree */
+ for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
+ if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
+ break;
+ if (z_idx == cfg->tree_cfg->num_pipes) {
+ ASSERT(cfg->z_index <= cfg->tree_cfg->num_pipes);
+ mpcc_id = mpc10_get_idle_mpcc_id(mpc10);
+
+ /*
+ * TODO: remove hack
+ * Note: currently there is a bug in init_hw such that
+ * on resume from hibernate, BIOS sets up MPCC0, and
+ * we do mpcc_remove but the mpcc cannot go to idle
+ * after remove. This cause us to pick mpcc1 here,
+ * which causes a pstate hang for yet unknown reason.
+ */
+ mpcc_id = cfg->dpp_id;
+ /* end hack*/
+
+ ASSERT(!(mpc10->mpcc_in_use_mask & 1 << mpcc_id));
+
+ if (mpc->ctx->dc->debug.sanity_checks)
+ mpc10_assert_mpcc_idle_before_connect(mpc10, mpcc_id);
+ } else {
+ ASSERT(cfg->z_index < cfg->tree_cfg->num_pipes);
+ mpcc_id = cfg->tree_cfg->mpcc[z_idx];
+ mpc10_mpcc_remove(mpc, cfg->tree_cfg, cfg->opp_id, cfg->dpp_id);
+ }
+
+ /* add dpp/mpcc pair to mpc_tree_cfg and update mpcc registers */
+ mpc10_add_to_tree_cfg(mpc, cfg, mpcc_id);
+
+ /* set background color */
mpc10_set_bg_color(mpc10, &cfg->black_color, mpcc_id);
+ /* mark this mpcc as in use */
mpc10->mpcc_in_use_mask |= 1 << mpcc_id;
- for (z_idx = cfg->opp->mpc_tree.num_pipes; z_idx > cfg->z_index; z_idx--) {
- cfg->opp->mpc_tree.dpp[z_idx] = cfg->opp->mpc_tree.dpp[z_idx - 1];
- cfg->opp->mpc_tree.mpcc[z_idx] = cfg->opp->mpc_tree.mpcc[z_idx - 1];
- }
- cfg->opp->mpc_tree.dpp[cfg->z_index] = cfg->mi->inst;
- cfg->opp->mpc_tree.mpcc[cfg->z_index] = mpcc_id;
- cfg->opp->mpc_tree.num_pipes++;
- cfg->mi->opp_id = cfg->opp->inst;
- cfg->mi->mpcc_id = mpcc_id;
+
+ return mpcc_id;
+}
+
+void mpc10_update_blend_mode(
+ struct mpc *mpc,
+ struct mpcc_cfg *cfg)
+{
+ struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
+ int mpcc_id, z_idx;
+ int alpha_blnd_mode = cfg->per_pixel_alpha ?
+ BLND_PP_ALPHA : BLND_GLOBAL_ALPHA;
+
+ /* find z_idx for the dpp that requires blending mode update*/
+ for (z_idx = 0; z_idx < cfg->tree_cfg->num_pipes; z_idx++)
+ if (cfg->tree_cfg->dpp[z_idx] == cfg->dpp_id)
+ break;
+
+ ASSERT(z_idx < cfg->tree_cfg->num_pipes);
+ mpcc_id = cfg->tree_cfg->mpcc[z_idx];
+
+ REG_UPDATE_2(MPCC_CONTROL[mpcc_id],
+ MPCC_ALPHA_BLND_MODE, alpha_blnd_mode,
+ MPCC_ALPHA_MULTIPLIED_MODE, cfg->pre_multiplied_alpha);
}
const struct mpc_funcs dcn10_mpc_funcs = {
.add = mpc10_mpcc_add,
.remove = mpc10_mpcc_remove,
- .wait_for_idle = mpc10_assert_idle_mpcc
+ .wait_for_idle = mpc10_assert_idle_mpcc,
+ .update_blend_mode = mpc10_update_blend_mode,
};
void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
@@ -272,3 +360,4 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpc10,
mpc10->mpcc_in_use_mask = 0;
mpc10->num_mpcc = num_mpcc;
}
+
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 @@
#define MAX_OPP 6
#define MPC_COMMON_REG_LIST_DCN1_0(inst) \
- SRII(MUX, MPC_OUT, inst),\
SRII(MPCC_TOP_SEL, MPCC, inst),\
SRII(MPCC_BOT_SEL, MPCC, inst),\
SRII(MPCC_CONTROL, MPCC, inst),\
@@ -45,17 +44,19 @@
SRII(MPCC_BG_B_CB, MPCC, inst),\
SRII(MPCC_BG_B_CB, MPCC, inst)
-struct dcn_mpc_registers {
- uint32_t MPCC_TOP_SEL[MAX_MPCC];
- uint32_t MPCC_BOT_SEL[MAX_MPCC];
- uint32_t MPCC_CONTROL[MAX_MPCC];
- uint32_t MPCC_STATUS[MAX_MPCC];
- uint32_t MPCC_OPP_ID[MAX_MPCC];
- uint32_t MPCC_BG_G_Y[MAX_MPCC];
- uint32_t MPCC_BG_R_CR[MAX_MPCC];
- uint32_t MPCC_BG_B_CB[MAX_MPCC];
+#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
+ SRII(MUX, MPC_OUT, inst)
+
+#define MPC_COMMON_REG_VARIABLE_LIST \
+ uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
+ uint32_t MPCC_BOT_SEL[MAX_MPCC]; \
+ uint32_t MPCC_CONTROL[MAX_MPCC]; \
+ uint32_t MPCC_STATUS[MAX_MPCC]; \
+ uint32_t MPCC_OPP_ID[MAX_MPCC]; \
+ uint32_t MPCC_BG_G_Y[MAX_MPCC]; \
+ uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
+ uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
uint32_t MUX[MAX_OPP];
-};
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
@@ -87,6 +88,10 @@ struct dcn_mpc_registers {
type MPCC_BG_B_CB;\
type MPC_OUT_MUX;
+struct dcn_mpc_registers {
+ MPC_COMMON_REG_VARIABLE_LIST
+};
+
struct dcn_mpc_shift {
MPC_REG_FIELD_LIST(uint8_t)
};
@@ -112,4 +117,22 @@ void dcn10_mpc_construct(struct dcn10_mpc *mpcc10,
const struct dcn_mpc_mask *mpc_mask,
int num_mpcc);
+int mpc10_mpcc_add(
+ struct mpc *mpc,
+ struct mpcc_cfg *cfg);
+
+void mpc10_mpcc_remove(
+ struct mpc *mpc,
+ struct mpc_tree_cfg *tree_cfg,
+ int opp_id,
+ int dpp_id);
+
+void mpc10_assert_idle_mpcc(
+ struct mpc *mpc,
+ int id);
+
+void mpc10_update_blend_mode(
+ struct mpc *mpc,
+ struct mpcc_cfg *cfg);
+
#endif
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 @@
#include "dce/dce_stream_encoder.h"
#include "dce/dce_clocks.h"
#include "dce/dce_clock_source.h"
-#include "dcn10/dcn10_mem_input.h"
#include "dce/dce_audio.h"
#include "dce/dce_hwseq.h"
#include "../virtual/virtual_stream_encoder.h"
#include "dce110/dce110_resource.h"
#include "dce112/dce112_resource.h"
+#include "dcn10_hubp.h"
#include "vega10/soc15ip.h"
@@ -329,7 +329,11 @@ static const struct dcn_mpc_registers mpc_regs = {
MPC_COMMON_REG_LIST_DCN1_0(0),
MPC_COMMON_REG_LIST_DCN1_0(1),
MPC_COMMON_REG_LIST_DCN1_0(2),
- MPC_COMMON_REG_LIST_DCN1_0(3)
+ MPC_COMMON_REG_LIST_DCN1_0(3),
+ MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(0),
+ MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(1),
+ MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(2),
+ MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(3)
};
static const struct dcn_mpc_shift mpc_shift = {
@@ -414,22 +418,24 @@ static const struct resource_caps res_cap = {
};
static const struct dc_debug debug_defaults_drv = {
- .disable_dcc = false,
.sanity_checks = true,
.disable_dmcu = true,
.force_abm_enable = false,
.timing_trace = false,
.clock_trace = true,
- /* spread sheet doesn't handle taps_c is one properly,
- * need to enable scaler for video surface to pass
- * bandwidth validation.*/
- .always_scale = true,
+
+ .min_disp_clk_khz = 300000,
+
.disable_pplib_clock_request = true,
.disable_pplib_wm_range = false,
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
- .use_dml_wm = false,
- .disable_pipe_split = true
-#endif
+ .pplib_wm_report_mode = WM_REPORT_DEFAULT,
+ .pipe_split_policy = MPC_SPLIT_AVOID_MULT_DISP,
+ .force_single_disp_pipe_split = true,
+ .disable_dcc = DCC_ENABLE,
+ .voltage_align_fclk = true,
+ .disable_stereo_support = true,
+ .vsr_support = true,
+ .performance_trace = false,
};
static const struct dc_debug debug_defaults_diags = {
@@ -438,21 +444,17 @@ static const struct dc_debug debug_defaults_diags = {
.timing_trace = true,
.clock_trace = true,
.disable_stutter = true,
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
.disable_pplib_clock_request = true,
- .disable_pplib_wm_range = true,
- .use_dml_wm = false,
- .disable_pipe_split = false
-#endif
+ .disable_pplib_wm_range = true
};
-static void dcn10_dpp_destroy(struct transform **xfm)
+static void dcn10_dpp_destroy(struct dpp **dpp)
{
- kfree(TO_DCN10_DPP(*xfm));
- *xfm = NULL;
+ kfree(TO_DCN10_DPP(*dpp));
+ *dpp = NULL;
}
-static struct transform *dcn10_dpp_create(
+static struct dpp *dcn10_dpp_create(
struct dc_context *ctx,
uint32_t inst)
{
@@ -462,8 +464,8 @@ static struct transform *dcn10_dpp_create(
if (!dpp)
return NULL;
- dcn10_dpp_construct(dpp, ctx, inst,
- &tf_regs[inst], &tf_shift, &tf_mask);
+ dpp1_construct(dpp, ctx, inst,
+ &tf_regs[inst], &tf_shift, &tf_mask);
return &dpp->base;
}
@@ -702,15 +704,15 @@ static void destruct(struct dcn10_resource_pool *pool)
if (pool->base.opps[i] != NULL)
pool->base.opps[i]->funcs->opp_destroy(&pool->base.opps[i]);
- if (pool->base.transforms[i] != NULL)
- dcn10_dpp_destroy(&pool->base.transforms[i]);
+ if (pool->base.dpps[i] != NULL)
+ dcn10_dpp_destroy(&pool->base.dpps[i]);
if (pool->base.ipps[i] != NULL)
pool->base.ipps[i]->funcs->ipp_destroy(&pool->base.ipps[i]);
- if (pool->base.mis[i] != NULL) {
- kfree(TO_DCN10_MEM_INPUT(pool->base.mis[i]));
- pool->base.mis[i] = NULL;
+ if (pool->base.hubps[i] != NULL) {
+ kfree(TO_DCN10_HUBP(pool->base.hubps[i]));
+ pool->base.hubps[i] = NULL;
}
if (pool->base.irqs != NULL) {
@@ -757,19 +759,19 @@ static void destruct(struct dcn10_resource_pool *pool)
kfree(pool->base.pp_smu);
}
-static struct mem_input *dcn10_mem_input_create(
+static struct hubp *dcn10_hubp_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn10_mem_input *mem_inputn10 =
- kzalloc(sizeof(struct dcn10_mem_input), GFP_KERNEL);
+ struct dcn10_hubp *hubp1 =
+ kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL);
- if (!mem_inputn10)
+ if (!hubp1)
return NULL;
- dcn10_mem_input_construct(mem_inputn10, ctx, inst,
- &mi_regs[inst], &mi_shift, &mi_mask);
- return &mem_inputn10->base;
+ dcn10_hubp_construct(hubp1, ctx, inst,
+ &mi_regs[inst], &mi_shift, &mi_mask);
+ return &hubp1->base;
}
static void get_pixel_clock_parameters(
@@ -922,9 +924,9 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
idle_pipe->stream_res.tg = head_pipe->stream_res.tg;
idle_pipe->stream_res.opp = head_pipe->stream_res.opp;
- idle_pipe->plane_res.mi = pool->mis[idle_pipe->pipe_idx];
+ idle_pipe->plane_res.hubp = pool->hubps[idle_pipe->pipe_idx];
idle_pipe->plane_res.ipp = pool->ipps[idle_pipe->pipe_idx];
- idle_pipe->plane_res.xfm = pool->transforms[idle_pipe->pipe_idx];
+ idle_pipe->plane_res.dpp = pool->dpps[idle_pipe->pipe_idx];
return idle_pipe;
}
@@ -1085,7 +1087,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
memset(output, 0, sizeof(*output));
- if (dc->debug.disable_dcc)
+ if (dc->debug.disable_dcc == DCC_DISABLE)
return false;
if (!dcc_support_pixel_format(input->format,
@@ -1129,6 +1131,10 @@ static bool get_dcc_compression_cap(const struct dc *dc,
dcc_control = dcc_control__128_128_xxx;
}
+ if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
+ dcc_control != dcc_control__256_256_xxx)
+ return false;
+
switch (dcc_control) {
case dcc_control__256_256_xxx:
output->grph.rgb.max_uncompressed_blk_size = 256;
@@ -1146,6 +1152,7 @@ static bool get_dcc_compression_cap(const struct dc *dc,
output->grph.rgb.independent_64b_blks = true;
break;
}
+
output->capable = true;
output->const_color_support = false;
@@ -1162,6 +1169,15 @@ static void dcn10_destroy_resource_pool(struct resource_pool **pool)
*pool = NULL;
}
+static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
+{
+ if (plane_state->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
+ && caps->max_video_width != 0
+ && plane_state->src_rect.width > caps->max_video_width)
+ return DC_FAIL_SURFACE_VALIDATE;
+
+ return DC_OK;
+}
static struct dc_cap_funcs cap_funcs = {
.get_dcc_compression_cap = get_dcc_compression_cap
@@ -1173,6 +1189,7 @@ static struct resource_funcs dcn10_res_pool_funcs = {
.validate_guaranteed = dcn10_validate_guaranteed,
.validate_bandwidth = dcn_validate_bandwidth,
.acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
+ .validate_plane = dcn10_validate_plane,
.add_stream_to_ctx = dcn10_add_stream_to_ctx
};
@@ -1212,6 +1229,7 @@ static bool construct(
/* max pipe num for ASIC before check pipe fuses */
pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
+ dc->caps.max_video_width = 3840;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 256;
@@ -1345,8 +1363,8 @@ static bool construct(
if ((pipe_fuses & (1 << i)) != 0)
continue;
- pool->base.mis[j] = dcn10_mem_input_create(ctx, i);
- if (pool->base.mis[j] == NULL) {
+ pool->base.hubps[j] = dcn10_hubp_create(ctx, i);
+ if (pool->base.hubps[j] == NULL) {
BREAK_TO_DEBUGGER();
dm_error(
"DC: failed to create memory input!\n");
@@ -1361,8 +1379,8 @@ static bool construct(
goto ipp_create_fail;
}
- pool->base.transforms[j] = dcn10_dpp_create(ctx, i);
- if (pool->base.transforms[j] == NULL) {
+ pool->base.dpps[j] = dcn10_dpp_create(ctx, i);
+ if (pool->base.dpps[j] == NULL) {
BREAK_TO_DEBUGGER();
dm_error(
"DC: failed to create dpp!\n");
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 @@
#include "reg_helper.h"
#include "dcn10_timing_generator.h"
+#include "dc.h"
#define REG(reg)\
tgn10->tg_regs->reg
@@ -299,6 +300,17 @@ static void tgn10_program_timing(
static void tgn10_unblank_crtc(struct timing_generator *tg)
{
struct dcn10_timing_generator *tgn10 = DCN10TG_FROM_TG(tg);
+ uint32_t vertical_interrupt_enable = 0;
+
+ REG_GET(OTG_VERTICAL_INTERRUPT2_CONTROL,
+ OTG_VERTICAL_INTERRUPT2_INT_ENABLE, &vertical_interrupt_enable);
+
+ /* temporary work around for vertical interrupt, once vertical interrupt enabled,
+ * this check will be removed.
+ */
+ if (vertical_interrupt_enable)
+ REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
+ OTG_BLANK_DATA_DOUBLE_BUFFER_EN, 1);
REG_UPDATE_2(OTG_BLANK_CONTROL,
OTG_BLANK_DATA_EN, 0,
@@ -487,6 +499,9 @@ static bool tgn10_validate_timing(
timing->timing_3d_format != TIMING_3D_FORMAT_INBAND_FA)
return false;
+ if (timing->timing_3d_format != TIMING_3D_FORMAT_NONE &&
+ tg->ctx->dc->debug.disable_stereo_support)
+ return false;
/* Temporarily blocking interlacing mode until it's supported */
if (timing->flags.INTERLACE == 1)
return false;
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 @@
SRI(OTG_NOM_VERT_POSITION, OTG, inst),\
SRI(OTG_BLACK_COLOR, OTG, inst),\
SRI(OTG_CLOCK_CONTROL, OTG, inst),\
+ SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\
SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\
SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\
SRI(OPTC_DATA_SOURCE_SELECT, ODM, inst),\
SRI(OPTC_INPUT_GLOBAL_CONTROL, ODM, inst),\
SRI(OPPBUF_CONTROL, OPPBUF, inst),\
SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, inst),\
- SRI(CONTROL, VTG, inst),\
- SR(D1VGA_CONTROL),\
- SR(D2VGA_CONTROL),\
- SR(D3VGA_CONTROL),\
- SR(D4VGA_CONTROL)
+ SRI(CONTROL, VTG, inst)
#define TG_COMMON_REG_LIST_DCN1_0(inst) \
TG_COMMON_REG_LIST_DCN(inst),\
@@ -121,6 +118,7 @@ struct dcn_tg_registers {
uint32_t OTG_TEST_PATTERN_CONTROL;
uint32_t OTG_TEST_PATTERN_COLOR;
uint32_t OTG_CLOCK_CONTROL;
+ uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL;
uint32_t OTG_VERTICAL_INTERRUPT2_POSITION;
uint32_t OPTC_INPUT_CLOCK_CONTROL;
uint32_t OPTC_DATA_SOURCE_SELECT;
@@ -128,11 +126,6 @@ struct dcn_tg_registers {
uint32_t OPPBUF_CONTROL;
uint32_t OPPBUF_3D_PARAMETERS_0;
uint32_t CONTROL;
- /*todo: move VGA to HWSS */
- uint32_t D1VGA_CONTROL;
- uint32_t D2VGA_CONTROL;
- uint32_t D3VGA_CONTROL;
- uint32_t D4VGA_CONTROL;
};
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -205,6 +198,7 @@ struct dcn_tg_registers {
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\
SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\
+ SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\
SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\
SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_ON, mask_sh),\
@@ -311,6 +305,7 @@ struct dcn_tg_registers {
type OTG_CLOCK_EN;\
type OTG_CLOCK_ON;\
type OTG_CLOCK_GATE_DIS;\
+ type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\
type OTG_VERTICAL_INTERRUPT2_LINE_START;\
type OPTC_INPUT_CLK_EN;\
type OPTC_INPUT_CLK_ON;\
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 @@
#undef DEPRECATED
-/*
- *
- * general debug capabilities
- *
- */
-#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
-
-#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
-#define ASSERT_CRITICAL(expr) do { \
- if (WARN_ON(!(expr))) { \
- kgdb_breakpoint(); \
- } \
-} while (0)
-#else
-#define ASSERT_CRITICAL(expr) do { \
- if (WARN_ON(!(expr))) { \
- ; \
- } \
-} while (0)
-#endif
-
-#if defined(CONFIG_DEBUG_KERNEL_DC)
-#define ASSERT(expr) ASSERT_CRITICAL(expr)
-
-#else
-#define ASSERT(expr) WARN_ON(!(expr))
-#endif
-
-#define BREAK_TO_DEBUGGER() ASSERT(0)
-
-#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
-
-#define DC_ERR(...) do { \
- dm_error(__VA_ARGS__); \
- BREAK_TO_DEBUGGER(); \
-} while (0)
-
-#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
-#include <asm/fpu/api.h>
-#endif
-
-#define dm_alloc(size) kzalloc(size, GFP_KERNEL)
-#define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
-#define dm_free(ptr) kfree(ptr)
-
irq_handler_idx dm_register_interrupt(
struct dc_context *ctx,
struct dc_interrupt_params *int_params,
@@ -418,6 +373,8 @@ bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
#define dm_log_to_buffer(buffer, size, fmt, args)\
vsnprintf(buffer, size, fmt, args)
+unsigned long long dm_get_timestamp(struct dc_context *ctx);
+
/*
* Debug and verification hooks
*/
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 @@
# It provides the general basic services required by other DAL
# subcomponents.
+CFLAGS_display_mode_vba.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_mode_lib.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_pipe_clocks.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
+CFLAGS_dml1_display_rq_dlg_calc.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_display_rq_dlg_helpers.o := -mhard-float -msse -mpreferred-stack-boundary=4
-CFLAGS_display_watermark.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4
CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4
+
DML = display_mode_lib.o display_rq_dlg_calc.o \
- display_rq_dlg_helpers.o display_watermark.o \
- soc_bounding_box.o dml_common_defs.o
+ display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
+ soc_bounding_box.o dml_common_defs.o display_mode_vba.o
AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
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 @@
#ifndef __DC_FEATURES_H__
#define __DC_FEATURES_H__
+// local features
#define DC__PRESENT 1
#define DC__PRESENT__1 1
#define DC__NUM_DPP 4
+#define DC__VOLTAGE_STATES 7
#define DC__NUM_DPP__4 1
#define DC__NUM_DPP__0_PRESENT 1
#define DC__NUM_DPP__1_PRESENT 1
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 @@
*/
#ifndef __DISPLAY_MODE_ENUMS_H__
#define __DISPLAY_MODE_ENUMS_H__
+
enum output_encoder_class {
- dm_dp = 0,
- dm_hdmi = 1,
- dm_wb = 2
+ dm_dp = 0, dm_hdmi = 1, dm_wb = 2, dm_edp
};
enum output_format_class {
- dm_444 = 0,
- dm_420 = 1
+ dm_444 = 0, dm_420 = 1, dm_n422, dm_s422
};
enum source_format_class {
dm_444_16 = 0,
@@ -40,18 +38,16 @@ enum source_format_class {
dm_420_8 = 3,
dm_420_10 = 4,
dm_422_8 = 5,
- dm_422_10 = 6
+ dm_422_10 = 6,
+ dm_444_8 = 7,
+ dm_mono_8,
+ dm_mono_16
};
enum output_bpc_class {
- dm_out_6 = 0,
- dm_out_8 = 1,
- dm_out_10 = 2,
- dm_out_12 = 3,
- dm_out_16 = 4
+ dm_out_6 = 0, dm_out_8 = 1, dm_out_10 = 2, dm_out_12 = 3, dm_out_16 = 4
};
enum scan_direction_class {
- dm_horz = 0,
- dm_vert = 1
+ dm_horz = 0, dm_vert = 1
};
enum dm_swizzle_mode {
dm_sw_linear = 0,
@@ -84,28 +80,32 @@ enum dm_swizzle_mode {
dm_sw_SPARE_14 = 27,
dm_sw_SPARE_15 = 28,
dm_sw_var_s_x = 29,
- dm_sw_var_d_x = 30
+ dm_sw_var_d_x = 30,
+ dm_sw_64kb_r_x,
+ dm_sw_gfx7_2d_thin_lvp,
+ dm_sw_gfx7_2d_thin_gl
};
enum lb_depth {
- dm_lb_10 = 30,
- dm_lb_8 = 24,
- dm_lb_6 = 18,
- dm_lb_12 = 36
+ dm_lb_10 = 0, dm_lb_8 = 1, dm_lb_6 = 2, dm_lb_12 = 3, dm_lb_16
};
enum voltage_state {
- dm_vmin = 0,
- dm_vmid = 1,
- dm_vnom = 2,
- dm_vmax = 3,
- dm_vmax_exceeded = 4
+ dm_vmin = 0, dm_vmid = 1, dm_vnom = 2, dm_vmax = 3
};
enum source_macro_tile_size {
- dm_4k_tile = 0,
- dm_64k_tile = 1,
- dm_256k_tile = 2
+ dm_4k_tile = 0, dm_64k_tile = 1, dm_256k_tile = 2
};
enum cursor_bpp {
- dm_cur_2bit = 0,
- dm_cur_32bit = 1
+ dm_cur_2bit = 0, dm_cur_32bit = 1, dm_cur_64bit = 2
};
+enum clock_change_support {
+ dm_dram_clock_change_uninitialized = 0,
+ dm_dram_clock_change_vactive,
+ dm_dram_clock_change_vblank,
+ dm_dram_clock_change_unsupported
+};
+
+enum output_standard {
+ dm_std_uninitialized = 0, dm_std_cvtr2, dm_std_cvt
+};
+
#endif
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 @@
*/
#include "display_mode_lib.h"
+#include "dc_features.h"
static void set_soc_bounding_box(struct _vcs_dpi_soc_bounding_box_st *soc, enum dml_project project)
{
@@ -126,21 +127,11 @@ static void set_ip_params(struct _vcs_dpi_ip_params_st *ip, enum dml_project pro
}
}
-static void set_mode_evaluation(struct _vcs_dpi_mode_evaluation_st *me, enum dml_project project)
-{
- if (project == DML_PROJECT_RAVEN1) {
- me->voltage_override = dm_vmin;
- } else {
- BREAK_TO_DEBUGGER(); /* Invalid Project Specified */
- }
-}
-
void dml_init_instance(struct display_mode_lib *lib, enum dml_project project)
{
if (lib->project != project) {
set_soc_bounding_box(&lib->soc, project);
set_ip_params(&lib->ip, project);
- set_mode_evaluation(&lib->me, project);
lib->project = project;
}
}
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 @@
#ifndef __DISPLAY_MODE_LIB_H__
#define __DISPLAY_MODE_LIB_H__
+
#include "dml_common_defs.h"
#include "soc_bounding_box.h"
-#include "display_watermark.h"
+#include "display_mode_vba.h"
#include "display_rq_dlg_calc.h"
-#include "display_mode_support.h"
+#include "dml1_display_rq_dlg_calc.h"
enum dml_project {
DML_PROJECT_UNDEFINED,
@@ -39,10 +40,8 @@ enum dml_project {
struct display_mode_lib {
struct _vcs_dpi_ip_params_st ip;
struct _vcs_dpi_soc_bounding_box_st soc;
- struct _vcs_dpi_mode_evaluation_st me;
enum dml_project project;
- struct dml_ms_internal_vars vars;
- struct _vcs_dpi_wm_calc_pipe_params_st wm_param[DC__NUM_PIPES__MAX];
+ struct vba_vars_st vba;
struct dal_logger *logger;
};
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 @@
#ifndef __DISPLAY_MODE_STRUCTS_H__
#define __DISPLAY_MODE_STRUCTS_H__
+typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
+typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
+typedef struct _vcs_dpi_ip_params_st ip_params_st;
+typedef struct _vcs_dpi_display_pipe_source_params_st display_pipe_source_params_st;
+typedef struct _vcs_dpi_display_output_params_st display_output_params_st;
+typedef struct _vcs_dpi_display_bandwidth_st display_bandwidth_st;
+typedef struct _vcs_dpi_scaler_ratio_depth_st scaler_ratio_depth_st;
+typedef struct _vcs_dpi_scaler_taps_st scaler_taps_st;
+typedef struct _vcs_dpi_display_pipe_dest_params_st display_pipe_dest_params_st;
+typedef struct _vcs_dpi_display_pipe_params_st display_pipe_params_st;
+typedef struct _vcs_dpi_display_clocks_and_cfg_st display_clocks_and_cfg_st;
+typedef struct _vcs_dpi_display_e2e_pipe_params_st display_e2e_pipe_params_st;
+typedef struct _vcs_dpi_dchub_buffer_sizing_st dchub_buffer_sizing_st;
+typedef struct _vcs_dpi_watermarks_perf_st watermarks_perf_st;
+typedef struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_watermarks_st;
+typedef struct _vcs_dpi_wm_calc_pipe_params_st wm_calc_pipe_params_st;
+typedef struct _vcs_dpi_vratio_pre_st vratio_pre_st;
+typedef struct _vcs_dpi_display_data_rq_misc_params_st display_data_rq_misc_params_st;
+typedef struct _vcs_dpi_display_data_rq_sizing_params_st display_data_rq_sizing_params_st;
+typedef struct _vcs_dpi_display_data_rq_dlg_params_st display_data_rq_dlg_params_st;
+typedef struct _vcs_dpi_display_cur_rq_dlg_params_st display_cur_rq_dlg_params_st;
+typedef struct _vcs_dpi_display_rq_dlg_params_st display_rq_dlg_params_st;
+typedef struct _vcs_dpi_display_rq_sizing_params_st display_rq_sizing_params_st;
+typedef struct _vcs_dpi_display_rq_misc_params_st display_rq_misc_params_st;
+typedef struct _vcs_dpi_display_rq_params_st display_rq_params_st;
+typedef struct _vcs_dpi_display_dlg_regs_st display_dlg_regs_st;
+typedef struct _vcs_dpi_display_ttu_regs_st display_ttu_regs_st;
+typedef struct _vcs_dpi_display_data_rq_regs_st display_data_rq_regs_st;
+typedef struct _vcs_dpi_display_rq_regs_st display_rq_regs_st;
+typedef struct _vcs_dpi_display_dlg_sys_params_st display_dlg_sys_params_st;
+typedef struct _vcs_dpi_display_dlg_prefetch_param_st display_dlg_prefetch_param_st;
+typedef struct _vcs_dpi_display_pipe_clock_st display_pipe_clock_st;
+typedef struct _vcs_dpi_display_arb_params_st display_arb_params_st;
+
struct _vcs_dpi_voltage_scaling_st {
+ int state;
+ double dscclk_mhz;
double dcfclk_mhz;
+ double socclk_mhz;
+ double dram_speed_mhz;
+ double fabricclk_mhz;
double dispclk_mhz;
- double dppclk_mhz;
double dram_bw_per_chan_gbps;
double phyclk_mhz;
- double socclk_mhz;
+ double dppclk_mhz;
};
-struct _vcs_dpi_soc_bounding_box_st {
- double sr_exit_time_us;
- double sr_enter_plus_exit_time_us;
- double urgent_latency_us;
- double writeback_latency_us;
- double ideal_dram_bw_after_urgent_percent;
- unsigned int max_request_size_bytes;
- struct _vcs_dpi_voltage_scaling_st vmin;
- struct _vcs_dpi_voltage_scaling_st vmid;
- struct _vcs_dpi_voltage_scaling_st vnom;
- struct _vcs_dpi_voltage_scaling_st vmax;
- double downspread_percent;
- double dram_page_open_time_ns;
- double dram_rw_turnaround_time_ns;
- double dram_return_buffer_per_channel_bytes;
- unsigned int round_trip_ping_latency_dcfclk_cycles;
- unsigned int urgent_out_of_order_return_per_channel_bytes;
- unsigned int channel_interleave_bytes;
- unsigned int num_banks;
- unsigned int num_chans;
- unsigned int vmm_page_size_bytes;
- double dram_clock_change_latency_us;
- double writeback_dram_clock_change_latency_us;
- unsigned int return_bus_width_bytes;
-};
-
-struct _vcs_dpi_ip_params_st {
- unsigned int rob_buffer_size_kbytes;
- unsigned int det_buffer_size_kbytes;
- unsigned int dpte_buffer_size_in_pte_reqs;
- unsigned int dpp_output_buffer_pixels;
- unsigned int opp_output_buffer_lines;
- unsigned int pixel_chunk_size_kbytes;
- unsigned char pte_enable;
- unsigned int pte_chunk_size_kbytes;
- unsigned int meta_chunk_size_kbytes;
- unsigned int writeback_chunk_size_kbytes;
- unsigned int line_buffer_size_bits;
- unsigned int max_line_buffer_lines;
+struct _vcs_dpi_soc_bounding_box_st {
+ double sr_exit_time_us;
+ double sr_enter_plus_exit_time_us;
+ double urgent_latency_us;
+ double writeback_latency_us;
+ double ideal_dram_bw_after_urgent_percent;
+ unsigned int max_request_size_bytes;
+ struct _vcs_dpi_voltage_scaling_st vmin;
+ struct _vcs_dpi_voltage_scaling_st vmid;
+ struct _vcs_dpi_voltage_scaling_st vnom;
+ struct _vcs_dpi_voltage_scaling_st vmax;
+ double downspread_percent;
+ double dram_page_open_time_ns;
+ double dram_rw_turnaround_time_ns;
+ double dram_return_buffer_per_channel_bytes;
+ double dram_channel_width_bytes;
+ double fabric_datapath_to_dcn_data_return_bytes;
+ double dcn_downspread_percent;
+ double dispclk_dppclk_vco_speed_mhz;
+ double dfs_vco_period_ps;
+ unsigned int round_trip_ping_latency_dcfclk_cycles;
+ unsigned int urgent_out_of_order_return_per_channel_bytes;
+ unsigned int channel_interleave_bytes;
+ unsigned int num_banks;
+ unsigned int num_chans;
+ unsigned int vmm_page_size_bytes;
+ double dram_clock_change_latency_us;
+ double writeback_dram_clock_change_latency_us;
+ unsigned int return_bus_width_bytes;
+ unsigned int voltage_override;
+ double xfc_bus_transport_time_us;
+ double xfc_xbuf_latency_tolerance_us;
+ struct _vcs_dpi_voltage_scaling_st clock_limits[7];
+};
+
+struct _vcs_dpi_ip_params_st {
+ unsigned int max_inter_dcn_tile_repeaters;
+ unsigned int num_dsc;
+ unsigned int odm_capable;
+ unsigned int rob_buffer_size_kbytes;
+ unsigned int det_buffer_size_kbytes;
+ unsigned int dpte_buffer_size_in_pte_reqs;
+ unsigned int pde_proc_buffer_size_64k_reqs;
+ unsigned int dpp_output_buffer_pixels;
+ unsigned int opp_output_buffer_lines;
+ unsigned int pixel_chunk_size_kbytes;
+ unsigned char pte_enable;
+ unsigned int pte_chunk_size_kbytes;
+ unsigned int meta_chunk_size_kbytes;
+ unsigned int writeback_chunk_size_kbytes;
+ unsigned int line_buffer_size_bits;
+ unsigned int max_line_buffer_lines;
+ unsigned int writeback_luma_buffer_size_kbytes;
+ unsigned int writeback_chroma_buffer_size_kbytes;
+ unsigned int writeback_chroma_line_buffer_width_pixels;
+ unsigned int max_page_table_levels;
+ unsigned int max_num_dpp;
+ unsigned int max_num_otg;
+ unsigned int cursor_chunk_size;
+ unsigned int cursor_buffer_size;
+ unsigned int max_num_wb;
+ unsigned int max_dchub_pscl_bw_pix_per_clk;
+ unsigned int max_pscl_lb_bw_pix_per_clk;
+ unsigned int max_lb_vscl_bw_pix_per_clk;
+ unsigned int max_vscl_hscl_bw_pix_per_clk;
+ double max_hscl_ratio;
+ double max_vscl_ratio;
+ unsigned int hscl_mults;
+ unsigned int vscl_mults;
+ unsigned int max_hscl_taps;
+ unsigned int max_vscl_taps;
+ unsigned int xfc_supported;
+ unsigned int ptoi_supported;
+ unsigned int xfc_fill_constant_bytes;
+ double dispclk_ramp_margin_percent;
+ double xfc_fill_bw_overhead_percent;
+ double underscan_factor;
+ unsigned int min_vblank_lines;
+ unsigned int dppclk_delay_subtotal;
+ unsigned int dispclk_delay_subtotal;
+ unsigned int dcfclk_cstate_latency;
+ unsigned int dppclk_delay_scl;
+ unsigned int dppclk_delay_scl_lb_only;
+ unsigned int dppclk_delay_cnvc_formatter;
+ unsigned int dppclk_delay_cnvc_cursor;
+ unsigned int is_line_buffer_bpp_fixed;
+ unsigned int line_buffer_fixed_bpp;
+ unsigned int dcc_supported;
+
unsigned int IsLineBufferBppFixed;
unsigned int LineBufferFixedBpp;
- unsigned int writeback_luma_buffer_size_kbytes;
- unsigned int writeback_chroma_buffer_size_kbytes;
- unsigned int max_num_dpp;
- unsigned int max_num_wb;
- unsigned int max_dchub_pscl_bw_pix_per_clk;
- unsigned int max_pscl_lb_bw_pix_per_clk;
- unsigned int max_lb_vscl_bw_pix_per_clk;
- unsigned int max_vscl_hscl_bw_pix_per_clk;
- double max_hscl_ratio;
- double max_vscl_ratio;
- unsigned int hscl_mults;
- unsigned int vscl_mults;
- unsigned int max_hscl_taps;
- unsigned int max_vscl_taps;
- double dispclk_ramp_margin_percent;
- double underscan_factor;
- unsigned int min_vblank_lines;
- unsigned int dppclk_delay_subtotal;
- unsigned int dispclk_delay_subtotal;
- unsigned int dcfclk_cstate_latency;
- unsigned int max_inter_dcn_tile_repeaters;
unsigned int can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
unsigned int bug_forcing_LC_req_same_size_fixed;
};
-struct _vcs_dpi_display_pipe_source_params_st {
- int source_format;
- unsigned char dcc;
- unsigned int dcc_rate;
- unsigned char vm;
- int source_scan;
- int sw_mode;
- int macro_tile_size;
- unsigned char is_display_sw;
- unsigned int viewport_width;
- unsigned int viewport_height;
- unsigned int viewport_width_c;
- unsigned int viewport_height_c;
- unsigned int data_pitch;
- unsigned int data_pitch_c;
- unsigned int meta_pitch;
- unsigned int meta_pitch_c;
- unsigned int cur0_src_width;
- int cur0_bpp;
- unsigned char is_hsplit;
- unsigned int hsplit_grp;
-};
-
-struct _vcs_dpi_display_output_params_st {
- int output_bpc;
- int output_type;
- int output_format;
- int output_standard;
-};
-
-struct _vcs_dpi_display_bandwidth_st {
- double total_bw_consumed_gbps;
- double guaranteed_urgent_return_bw_gbps;
-};
-
-struct _vcs_dpi_scaler_ratio_depth_st {
- double hscl_ratio;
- double vscl_ratio;
- double hscl_ratio_c;
- double vscl_ratio_c;
- double vinit;
- double vinit_c;
- double vinit_bot;
- double vinit_bot_c;
- int lb_depth;
-};
-
-struct _vcs_dpi_scaler_taps_st {
- unsigned int htaps;
- unsigned int vtaps;
- unsigned int htaps_c;
- unsigned int vtaps_c;
-};
-
-struct _vcs_dpi_display_pipe_dest_params_st {
- unsigned int recout_width;
- unsigned int recout_height;
- unsigned int full_recout_width;
- unsigned int full_recout_height;
- unsigned int hblank_start;
- unsigned int hblank_end;
- unsigned int vblank_start;
- unsigned int vblank_end;
- unsigned int htotal;
- unsigned int vtotal;
- unsigned int vactive;
- unsigned int vstartup_start;
- unsigned int vupdate_offset;
- unsigned int vupdate_width;
- unsigned int vready_offset;
- unsigned int vsync_plus_back_porch;
- unsigned char interlaced;
- unsigned char underscan;
- double pixel_rate_mhz;
- unsigned char syncronized_vblank_all_planes;
-};
-
-struct _vcs_dpi_display_pipe_params_st {
- struct _vcs_dpi_display_pipe_source_params_st src;
- struct _vcs_dpi_display_pipe_dest_params_st dest;
- struct _vcs_dpi_scaler_ratio_depth_st scale_ratio_depth;
- struct _vcs_dpi_scaler_taps_st scale_taps;
-};
-
-struct _vcs_dpi_display_clocks_and_cfg_st {
- int voltage;
- double dppclk_mhz;
- double refclk_mhz;
- double dispclk_mhz;
- double dcfclk_mhz;
- double socclk_mhz;
-};
-
-struct _vcs_dpi_display_e2e_pipe_params_st {
- struct _vcs_dpi_display_pipe_params_st pipe;
- struct _vcs_dpi_display_output_params_st dout;
- struct _vcs_dpi_display_clocks_and_cfg_st clks_cfg;
-};
-
-struct _vcs_dpi_dchub_buffer_sizing_st {
- unsigned int swath_width_y;
- unsigned int swath_height_y;
- unsigned int swath_height_c;
- unsigned int detail_buffer_size_y;
-};
-
-struct _vcs_dpi_watermarks_perf_st {
- double stutter_eff_in_active_region_percent;
- double urgent_latency_supported_us;
- double non_urgent_latency_supported_us;
- double dram_clock_change_margin_us;
- double dram_access_eff_percent;
-};
-
-struct _vcs_dpi_cstate_pstate_watermarks_st {
- double cstate_exit_us;
- double cstate_enter_plus_exit_us;
- double pstate_change_us;
-};
-
-struct _vcs_dpi_wm_calc_pipe_params_st {
- unsigned int num_dpp;
- int voltage;
- int output_type;
- double dcfclk_mhz;
- double socclk_mhz;
- double dppclk_mhz;
- double pixclk_mhz;
- unsigned char interlace_en;
- unsigned char pte_enable;
- unsigned char dcc_enable;
- double dcc_rate;
- double bytes_per_pixel_c;
- double bytes_per_pixel_y;
- unsigned int swath_width_y;
- unsigned int swath_height_y;
- unsigned int swath_height_c;
- unsigned int det_buffer_size_y;
- double h_ratio;
- double v_ratio;
- unsigned int h_taps;
- unsigned int h_total;
- unsigned int v_total;
- unsigned int v_active;
- unsigned int e2e_index;
- double display_pipe_line_delivery_time;
- double read_bw;
- unsigned int lines_in_det_y;
- unsigned int lines_in_det_y_rounded_down_to_swath;
- double full_det_buffering_time;
- double dcfclk_deepsleep_mhz_per_plane;
-};
-
-struct _vcs_dpi_vratio_pre_st {
- double vratio_pre_l;
- double vratio_pre_c;
-};
-
-struct _vcs_dpi_display_data_rq_misc_params_st {
- unsigned int full_swath_bytes;
- unsigned int stored_swath_bytes;
- unsigned int blk256_height;
- unsigned int blk256_width;
- unsigned int req_height;
- unsigned int req_width;
-};
-
-struct _vcs_dpi_display_data_rq_sizing_params_st {
- unsigned int chunk_bytes;
- unsigned int min_chunk_bytes;
- unsigned int meta_chunk_bytes;
- unsigned int min_meta_chunk_bytes;
- unsigned int mpte_group_bytes;
- unsigned int dpte_group_bytes;
-};
-
-struct _vcs_dpi_display_data_rq_dlg_params_st {
- unsigned int swath_width_ub;
- unsigned int swath_height;
- unsigned int req_per_swath_ub;
- unsigned int meta_pte_bytes_per_frame_ub;
- unsigned int dpte_req_per_row_ub;
- unsigned int dpte_groups_per_row_ub;
- unsigned int dpte_row_height;
- unsigned int dpte_bytes_per_row_ub;
- unsigned int meta_chunks_per_row_ub;
- unsigned int meta_req_per_row_ub;
- unsigned int meta_row_height;
- unsigned int meta_bytes_per_row_ub;
-};
-
-struct _vcs_dpi_display_cur_rq_dlg_params_st {
- unsigned char enable;
- unsigned int swath_height;
- unsigned int req_per_line;
-};
-
-struct _vcs_dpi_display_rq_dlg_params_st {
- struct _vcs_dpi_display_data_rq_dlg_params_st rq_l;
- struct _vcs_dpi_display_data_rq_dlg_params_st rq_c;
- struct _vcs_dpi_display_cur_rq_dlg_params_st rq_cur0;
-};
-
-struct _vcs_dpi_display_rq_sizing_params_st {
- struct _vcs_dpi_display_data_rq_sizing_params_st rq_l;
- struct _vcs_dpi_display_data_rq_sizing_params_st rq_c;
-};
-
-struct _vcs_dpi_display_rq_misc_params_st {
- struct _vcs_dpi_display_data_rq_misc_params_st rq_l;
- struct _vcs_dpi_display_data_rq_misc_params_st rq_c;
-};
-
-struct _vcs_dpi_display_rq_params_st {
- unsigned char yuv420;
- unsigned char yuv420_10bpc;
- struct _vcs_dpi_display_rq_misc_params_st misc;
- struct _vcs_dpi_display_rq_sizing_params_st sizing;
- struct _vcs_dpi_display_rq_dlg_params_st dlg;
-};
-
-struct _vcs_dpi_display_dlg_regs_st {
- unsigned int refcyc_h_blank_end;
- unsigned int dlg_vblank_end;
- unsigned int min_dst_y_next_start;
- unsigned int refcyc_per_htotal;
- unsigned int refcyc_x_after_scaler;
- unsigned int dst_y_after_scaler;
- unsigned int dst_y_prefetch;
- unsigned int dst_y_per_vm_vblank;
- unsigned int dst_y_per_row_vblank;
- unsigned int ref_freq_to_pix_freq;
- unsigned int vratio_prefetch;
- unsigned int vratio_prefetch_c;
- unsigned int refcyc_per_pte_group_vblank_l;
- unsigned int refcyc_per_pte_group_vblank_c;
- unsigned int refcyc_per_meta_chunk_vblank_l;
- unsigned int refcyc_per_meta_chunk_vblank_c;
- unsigned int dst_y_per_pte_row_nom_l;
- unsigned int dst_y_per_pte_row_nom_c;
- unsigned int refcyc_per_pte_group_nom_l;
- unsigned int refcyc_per_pte_group_nom_c;
- unsigned int dst_y_per_meta_row_nom_l;
- unsigned int dst_y_per_meta_row_nom_c;
- unsigned int refcyc_per_meta_chunk_nom_l;
- unsigned int refcyc_per_meta_chunk_nom_c;
- unsigned int refcyc_per_line_delivery_pre_l;
- unsigned int refcyc_per_line_delivery_pre_c;
- unsigned int refcyc_per_line_delivery_l;
- unsigned int refcyc_per_line_delivery_c;
- unsigned int chunk_hdl_adjust_cur0;
-};
-
-struct _vcs_dpi_display_ttu_regs_st {
- unsigned int qos_level_low_wm;
- unsigned int qos_level_high_wm;
- unsigned int min_ttu_vblank;
- unsigned int qos_level_flip;
- unsigned int refcyc_per_req_delivery_l;
- unsigned int refcyc_per_req_delivery_c;
- unsigned int refcyc_per_req_delivery_cur0;
- unsigned int refcyc_per_req_delivery_pre_l;
- unsigned int refcyc_per_req_delivery_pre_c;
- unsigned int refcyc_per_req_delivery_pre_cur0;
- unsigned int qos_level_fixed_l;
- unsigned int qos_level_fixed_c;
- unsigned int qos_level_fixed_cur0;
- unsigned int qos_ramp_disable_l;
- unsigned int qos_ramp_disable_c;
- unsigned int qos_ramp_disable_cur0;
-};
-
-struct _vcs_dpi_display_data_rq_regs_st {
- unsigned int chunk_size;
- unsigned int min_chunk_size;
- unsigned int meta_chunk_size;
- unsigned int min_meta_chunk_size;
- unsigned int dpte_group_size;
- unsigned int mpte_group_size;
- unsigned int swath_height;
- unsigned int pte_row_height_linear;
-};
-
-struct _vcs_dpi_display_rq_regs_st {
- struct _vcs_dpi_display_data_rq_regs_st rq_regs_l;
- struct _vcs_dpi_display_data_rq_regs_st rq_regs_c;
- unsigned int drq_expansion_mode;
- unsigned int prq_expansion_mode;
- unsigned int mrq_expansion_mode;
- unsigned int crq_expansion_mode;
- unsigned int plane1_base_address;
-};
-
-struct _vcs_dpi_display_dlg_sys_params_st {
- double t_mclk_wm_us;
- double t_urg_wm_us;
- double t_sr_wm_us;
- double t_extra_us;
- double t_srx_delay_us;
- double deepsleep_dcfclk_mhz;
- double total_flip_bw;
- unsigned int total_flip_bytes;
-};
-
-struct _vcs_dpi_display_dlg_prefetch_param_st {
- double prefetch_bw;
- unsigned int flip_bytes;
-};
-
-struct _vcs_dpi_display_pipe_clock_st {
- double dcfclk_mhz;
- double dispclk_mhz;
- double dppclk_mhz[4];
- unsigned char dppclk_div[4];
-};
-
-struct _vcs_dpi_display_arb_params_st {
- int max_req_outstanding;
- int min_req_outstanding;
- int sat_level_us;
-};
-
-struct _vcs_dpi_mode_evaluation_st {
- int voltage_override;
+struct _vcs_dpi_display_xfc_params_st {
+ double xfc_tslv_vready_offset_us;
+ double xfc_tslv_vupdate_width_us;
+ double xfc_tslv_vupdate_offset_us;
+ int xfc_slv_chunk_size_bytes;
+};
+
+struct _vcs_dpi_display_pipe_source_params_st {
+ int source_format;
+ unsigned char dcc;
+ unsigned int dcc_override;
+ unsigned int dcc_rate;
+ unsigned char dcc_use_global;
+ unsigned char vm;
+ unsigned char vm_levels_force_en;
+ unsigned int vm_levels_force;
+ int source_scan;
+ int sw_mode;
+ int macro_tile_size;
+ unsigned char is_display_sw;
+ unsigned int viewport_width;
+ unsigned int viewport_height;
+ unsigned int viewport_y_y;
+ unsigned int viewport_y_c;
+ unsigned int viewport_width_c;
+ unsigned int viewport_height_c;
+ unsigned int data_pitch;
+ unsigned int data_pitch_c;
+ unsigned int meta_pitch;
+ unsigned int meta_pitch_c;
+ unsigned int cur0_src_width;
+ int cur0_bpp;
+ unsigned int cur1_src_width;
+ int cur1_bpp;
+ int num_cursors;
+ unsigned char is_hsplit;
+ unsigned char dynamic_metadata_enable;
+ unsigned int dynamic_metadata_lines_before_active;
+ unsigned int dynamic_metadata_xmit_bytes;
+ unsigned int hsplit_grp;
+ unsigned char xfc_enable;
+ unsigned char xfc_slave;
+ struct _vcs_dpi_display_xfc_params_st xfc_params;
+};
+struct writeback_st {
+ int wb_src_height;
+ int wb_dst_width;
+ int wb_dst_height;
+ int wb_pixel_format;
+ int wb_htaps_luma;
+ int wb_vtaps_luma;
+ int wb_htaps_chroma;
+ int wb_vtaps_chroma;
+ int wb_hratio;
+ int wb_vratio;
+};
+
+struct _vcs_dpi_display_output_params_st {
+ int dp_lanes;
+ int output_bpp;
+ int dsc_enable;
+ int wb_enable;
+ int output_bpc;
+ int output_type;
+ int output_format;
+ int output_standard;
+ int dsc_slices;
+ struct writeback_st wb;
+};
+
+struct _vcs_dpi_display_bandwidth_st {
+ double total_bw_consumed_gbps;
+ double guaranteed_urgent_return_bw_gbps;
+};
+
+struct _vcs_dpi_scaler_ratio_depth_st {
+ double hscl_ratio;
+ double vscl_ratio;
+ double hscl_ratio_c;
+ double vscl_ratio_c;
+ double vinit;
+ double vinit_c;
+ double vinit_bot;
+ double vinit_bot_c;
+ int lb_depth;
+ int scl_enable;
+};
+
+struct _vcs_dpi_scaler_taps_st {
+ unsigned int htaps;
+ unsigned int vtaps;
+ unsigned int htaps_c;
+ unsigned int vtaps_c;
+};
+
+struct _vcs_dpi_display_pipe_dest_params_st {
+ unsigned int recout_width;
+ unsigned int recout_height;
+ unsigned int full_recout_width;
+ unsigned int full_recout_height;
+ unsigned int hblank_start;
+ unsigned int hblank_end;
+ unsigned int vblank_start;
+ unsigned int vblank_end;
+ unsigned int htotal;
+ unsigned int vtotal;
+ unsigned int vactive;
+ unsigned int hactive;
+ unsigned int vstartup_start;
+ unsigned int vupdate_offset;
+ unsigned int vupdate_width;
+ unsigned int vready_offset;
+ unsigned char interlaced;
+ unsigned char underscan;
+ double pixel_rate_mhz;
+ unsigned char synchronized_vblank_all_planes;
+ unsigned char otg_inst;
+ unsigned char odm_split_cnt;
+ unsigned char odm_combine;
+};
+
+struct _vcs_dpi_display_pipe_params_st {
+ display_pipe_source_params_st src;
+ display_pipe_dest_params_st dest;
+ scaler_ratio_depth_st scale_ratio_depth;
+ scaler_taps_st scale_taps;
+};
+
+struct _vcs_dpi_display_clocks_and_cfg_st {
+ int voltage;
+ double dppclk_mhz;
+ double refclk_mhz;
+ double dispclk_mhz;
+ double dcfclk_mhz;
+ double socclk_mhz;
+};
+
+struct _vcs_dpi_display_e2e_pipe_params_st {
+ display_pipe_params_st pipe;
+ display_output_params_st dout;
+ display_clocks_and_cfg_st clks_cfg;
+};
+
+struct _vcs_dpi_dchub_buffer_sizing_st {
+ unsigned int swath_width_y;
+ unsigned int swath_height_y;
+ unsigned int swath_height_c;
+ unsigned int detail_buffer_size_y;
+};
+
+struct _vcs_dpi_watermarks_perf_st {
+ double stutter_eff_in_active_region_percent;
+ double urgent_latency_supported_us;
+ double non_urgent_latency_supported_us;
+ double dram_clock_change_margin_us;
+ double dram_access_eff_percent;
+};
+
+struct _vcs_dpi_cstate_pstate_watermarks_st {
+ double cstate_exit_us;
+ double cstate_enter_plus_exit_us;
+ double pstate_change_us;
+};
+
+struct _vcs_dpi_wm_calc_pipe_params_st {
+ unsigned int num_dpp;
+ int voltage;
+ int output_type;
+ double dcfclk_mhz;
+ double socclk_mhz;
+ double dppclk_mhz;
+ double pixclk_mhz;
+ unsigned char interlace_en;
+ unsigned char pte_enable;
+ unsigned char dcc_enable;
+ double dcc_rate;
+ double bytes_per_pixel_c;
+ double bytes_per_pixel_y;
+ unsigned int swath_width_y;
+ unsigned int swath_height_y;
+ unsigned int swath_height_c;
+ unsigned int det_buffer_size_y;
+ double h_ratio;
+ double v_ratio;
+ unsigned int h_taps;
+ unsigned int h_total;
+ unsigned int v_total;
+ unsigned int v_active;
+ unsigned int e2e_index;
+ double display_pipe_line_delivery_time;
+ double read_bw;
+ unsigned int lines_in_det_y;
+ unsigned int lines_in_det_y_rounded_down_to_swath;
+ double full_det_buffering_time;
+ double dcfclk_deepsleep_mhz_per_plane;
+};
+
+struct _vcs_dpi_vratio_pre_st {
+ double vratio_pre_l;
+ double vratio_pre_c;
+};
+
+struct _vcs_dpi_display_data_rq_misc_params_st {
+ unsigned int full_swath_bytes;
+ unsigned int stored_swath_bytes;
+ unsigned int blk256_height;
+ unsigned int blk256_width;
+ unsigned int req_height;
+ unsigned int req_width;
+};
+
+struct _vcs_dpi_display_data_rq_sizing_params_st {
+ unsigned int chunk_bytes;
+ unsigned int min_chunk_bytes;
+ unsigned int meta_chunk_bytes;
+ unsigned int min_meta_chunk_bytes;
+ unsigned int mpte_group_bytes;
+ unsigned int dpte_group_bytes;
+};
+
+struct _vcs_dpi_display_data_rq_dlg_params_st {
+ unsigned int swath_width_ub;
+ unsigned int swath_height;
+ unsigned int req_per_swath_ub;
+ unsigned int meta_pte_bytes_per_frame_ub;
+ unsigned int dpte_req_per_row_ub;
+ unsigned int dpte_groups_per_row_ub;
+ unsigned int dpte_row_height;
+ unsigned int dpte_bytes_per_row_ub;
+ unsigned int meta_chunks_per_row_ub;
+ unsigned int meta_req_per_row_ub;
+ unsigned int meta_row_height;
+ unsigned int meta_bytes_per_row_ub;
+};
+
+struct _vcs_dpi_display_cur_rq_dlg_params_st {
+ unsigned char enable;
+ unsigned int swath_height;
+ unsigned int req_per_line;
+};
+
+struct _vcs_dpi_display_rq_dlg_params_st {
+ display_data_rq_dlg_params_st rq_l;
+ display_data_rq_dlg_params_st rq_c;
+ display_cur_rq_dlg_params_st rq_cur0;
+};
+
+struct _vcs_dpi_display_rq_sizing_params_st {
+ display_data_rq_sizing_params_st rq_l;
+ display_data_rq_sizing_params_st rq_c;
+};
+
+struct _vcs_dpi_display_rq_misc_params_st {
+ display_data_rq_misc_params_st rq_l;
+ display_data_rq_misc_params_st rq_c;
+};
+
+struct _vcs_dpi_display_rq_params_st {
+ unsigned char yuv420;
+ unsigned char yuv420_10bpc;
+ display_rq_misc_params_st misc;
+ display_rq_sizing_params_st sizing;
+ display_rq_dlg_params_st dlg;
+};
+
+struct _vcs_dpi_display_dlg_regs_st {
+ unsigned int refcyc_h_blank_end;
+ unsigned int dlg_vblank_end;
+ unsigned int min_dst_y_next_start;
+ unsigned int refcyc_per_htotal;
+ unsigned int refcyc_x_after_scaler;
+ unsigned int dst_y_after_scaler;
+ unsigned int dst_y_prefetch;
+ unsigned int dst_y_per_vm_vblank;
+ unsigned int dst_y_per_row_vblank;
+ unsigned int dst_y_per_vm_flip;
+ unsigned int dst_y_per_row_flip;
+ unsigned int ref_freq_to_pix_freq;
+ unsigned int vratio_prefetch;
+ unsigned int vratio_prefetch_c;
+ unsigned int refcyc_per_pte_group_vblank_l;
+ unsigned int refcyc_per_pte_group_vblank_c;
+ unsigned int refcyc_per_meta_chunk_vblank_l;
+ unsigned int refcyc_per_meta_chunk_vblank_c;
+ unsigned int refcyc_per_pte_group_flip_l;
+ unsigned int refcyc_per_pte_group_flip_c;
+ unsigned int refcyc_per_meta_chunk_flip_l;
+ unsigned int refcyc_per_meta_chunk_flip_c;
+ unsigned int dst_y_per_pte_row_nom_l;
+ unsigned int dst_y_per_pte_row_nom_c;
+ unsigned int refcyc_per_pte_group_nom_l;
+ unsigned int refcyc_per_pte_group_nom_c;
+ unsigned int dst_y_per_meta_row_nom_l;
+ unsigned int dst_y_per_meta_row_nom_c;
+ unsigned int refcyc_per_meta_chunk_nom_l;
+ unsigned int refcyc_per_meta_chunk_nom_c;
+ unsigned int refcyc_per_line_delivery_pre_l;
+ unsigned int refcyc_per_line_delivery_pre_c;
+ unsigned int refcyc_per_line_delivery_l;
+ unsigned int refcyc_per_line_delivery_c;
+ unsigned int chunk_hdl_adjust_cur0;
+ unsigned int chunk_hdl_adjust_cur1;
+ unsigned int vready_after_vcount0;
+ unsigned int dst_y_offset_cur0;
+ unsigned int dst_y_offset_cur1;
+ unsigned int xfc_reg_transfer_delay;
+ unsigned int xfc_reg_precharge_delay;
+ unsigned int xfc_reg_remote_surface_flip_latency;
+ unsigned int xfc_reg_prefetch_margin;
+ unsigned int dst_y_delta_drq_limit;
+};
+
+struct _vcs_dpi_display_ttu_regs_st {
+ unsigned int qos_level_low_wm;
+ unsigned int qos_level_high_wm;
+ unsigned int min_ttu_vblank;
+ unsigned int qos_level_flip;
+ unsigned int refcyc_per_req_delivery_l;
+ unsigned int refcyc_per_req_delivery_c;
+ unsigned int refcyc_per_req_delivery_cur0;
+ unsigned int refcyc_per_req_delivery_cur1;
+ unsigned int refcyc_per_req_delivery_pre_l;
+ unsigned int refcyc_per_req_delivery_pre_c;
+ unsigned int refcyc_per_req_delivery_pre_cur0;
+ unsigned int refcyc_per_req_delivery_pre_cur1;
+ unsigned int qos_level_fixed_l;
+ unsigned int qos_level_fixed_c;
+ unsigned int qos_level_fixed_cur0;
+ unsigned int qos_level_fixed_cur1;
+ unsigned int qos_ramp_disable_l;
+ unsigned int qos_ramp_disable_c;
+ unsigned int qos_ramp_disable_cur0;
+ unsigned int qos_ramp_disable_cur1;
+};
+
+struct _vcs_dpi_display_data_rq_regs_st {
+ unsigned int chunk_size;
+ unsigned int min_chunk_size;
+ unsigned int meta_chunk_size;
+ unsigned int min_meta_chunk_size;
+ unsigned int dpte_group_size;
+ unsigned int mpte_group_size;
+ unsigned int swath_height;
+ unsigned int pte_row_height_linear;
+};
+
+struct _vcs_dpi_display_rq_regs_st {
+ display_data_rq_regs_st rq_regs_l;
+ display_data_rq_regs_st rq_regs_c;
+ unsigned int drq_expansion_mode;
+ unsigned int prq_expansion_mode;
+ unsigned int mrq_expansion_mode;
+ unsigned int crq_expansion_mode;
+ unsigned int plane1_base_address;
+};
+
+struct _vcs_dpi_display_dlg_sys_params_st {
+ double t_mclk_wm_us;
+ double t_urg_wm_us;
+ double t_sr_wm_us;
+ double t_extra_us;
+ double mem_trip_us;
+ double t_srx_delay_us;
+ double deepsleep_dcfclk_mhz;
+ double total_flip_bw;
+ unsigned int total_flip_bytes;
+};
+
+struct _vcs_dpi_display_dlg_prefetch_param_st {
+ double prefetch_bw;
+ unsigned int flip_bytes;
+};
+
+struct _vcs_dpi_display_pipe_clock_st {
+ double dcfclk_mhz;
+ double dispclk_mhz;
+ double socclk_mhz;
+ double dscclk_mhz[6];
+ double dppclk_mhz[6];
+};
+
+struct _vcs_dpi_display_arb_params_st {
+ int max_req_outstanding;
+ int min_req_outstanding;
+ int sat_level_us;
};
#endif /*__DISPLAY_MODE_STRUCTS_H__*/
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 @@
-/*
- * Copyright 2017 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-#ifndef __DISPLAY_MODE_SUPPORT_H__
-#define __DISPLAY_MODE_SUPPORT_H__
-
-#include "dml_common_defs.h"
-
-struct display_mode_lib;
-
-#define NumberOfStates 4
-#define NumberOfStatesPlusTwo (NumberOfStates+2)
-
-struct dml_ms_internal_vars {
- double ScaleRatioSupport;
- double SourceFormatPixelAndScanSupport;
- double TotalReadBandwidthConsumedGBytePerSecond;
- double TotalWriteBandwidthConsumedGBytePerSecond;
- double TotalBandwidthConsumedGBytePerSecond;
- double DCCEnabledInAnyPlane;
- double ReturnBWToDCNPerState;
- double CriticalPoint;
- double WritebackLatencySupport;
- double RequiredOutputBW;
- double TotalNumberOfActiveWriteback;
- double TotalAvailableWritebackSupport;
- double MaximumSwathWidth;
- double NumberOfDPPRequiredForDETSize;
- double NumberOfDPPRequiredForLBSize;
- double MinDispclkUsingSingleDPP;
- double MinDispclkUsingDualDPP;
- double ViewportSizeSupport;
- double SwathWidthGranularityY;
- double RoundedUpMaxSwathSizeBytesY;
- double SwathWidthGranularityC;
- double RoundedUpMaxSwathSizeBytesC;
- double LinesInDETLuma;
- double LinesInDETChroma;
- double EffectiveLBLatencyHidingSourceLinesLuma;
- double EffectiveLBLatencyHidingSourceLinesChroma;
- double EffectiveDETLBLinesLuma;
- double EffectiveDETLBLinesChroma;
- double ProjectedDCFCLKDeepSleep;
- double MetaReqHeightY;
- double MetaReqWidthY;
- double MetaSurfaceWidthY;
- double MetaSurfaceHeightY;
- double MetaPteBytesPerFrameY;
- double MetaRowBytesY;
- double MacroTileBlockSizeBytesY;
- double MacroTileBlockHeightY;
- double DataPTEReqHeightY;
- double DataPTEReqWidthY;
- double DPTEBytesPerRowY;
- double MetaReqHeightC;
- double MetaReqWidthC;
- double MetaSurfaceWidthC;
- double MetaSurfaceHeightC;
- double MetaPteBytesPerFrameC;
- double MetaRowBytesC;
- double MacroTileBlockSizeBytesC;
- double MacroTileBlockHeightC;
- double MacroTileBlockWidthC;
- double DataPTEReqHeightC;
- double DataPTEReqWidthC;
- double DPTEBytesPerRowC;
- double VInitY;
- double MaxPartialSwY;
- double VInitC;
- double MaxPartialSwC;
- double dst_x_after_scaler;
- double dst_y_after_scaler;
- double TimeCalc;
- double VUpdateOffset;
- double TotalRepeaterDelay;
- double VUpdateWidth;
- double VReadyOffset;
- double TimeSetup;
- double ExtraLatency;
- double MaximumVStartup;
- double BWAvailableForImmediateFlip;
- double TotalImmediateFlipBytes;
- double TimeForMetaPTEWithImmediateFlip;
- double TimeForMetaPTEWithoutImmediateFlip;
- double TimeForMetaAndDPTERowWithImmediateFlip;
- double TimeForMetaAndDPTERowWithoutImmediateFlip;
- double LineTimesToRequestPrefetchPixelDataWithImmediateFlip;
- double LineTimesToRequestPrefetchPixelDataWithoutImmediateFlip;
- double MaximumReadBandwidthWithPrefetchWithImmediateFlip;
- double MaximumReadBandwidthWithPrefetchWithoutImmediateFlip;
- double VoltageOverrideLevel;
- double VoltageLevelWithImmediateFlip;
- double VoltageLevelWithoutImmediateFlip;
- double ImmediateFlipSupported;
- double VoltageLevel;
- double DCFCLK;
- double FabricAndDRAMBandwidth;
- double SwathWidthYSingleDPP[DC__NUM_PIPES__MAX];
- double BytePerPixelInDETY[DC__NUM_PIPES__MAX];
- double BytePerPixelInDETC[DC__NUM_PIPES__MAX];
- double ReadBandwidth[DC__NUM_PIPES__MAX];
- double WriteBandwidth[DC__NUM_PIPES__MAX];
- double DCFCLKPerState[NumberOfStatesPlusTwo];
- double FabricAndDRAMBandwidthPerState[NumberOfStatesPlusTwo];
- double ReturnBWPerState[NumberOfStatesPlusTwo];
- double BandwidthSupport[NumberOfStatesPlusTwo];
- double UrgentRoundTripAndOutOfOrderLatencyPerState[NumberOfStatesPlusTwo];
- double ROBSupport[NumberOfStatesPlusTwo];
- double RequiredPHYCLK[DC__NUM_PIPES__MAX];
- double DIOSupport[NumberOfStatesPlusTwo];
- double PHYCLKPerState[NumberOfStatesPlusTwo];
- double PSCL_FACTOR[DC__NUM_PIPES__MAX];
- double PSCL_FACTOR_CHROMA[DC__NUM_PIPES__MAX];
- double MinDPPCLKUsingSingleDPP[DC__NUM_PIPES__MAX];
- double Read256BlockHeightY[DC__NUM_PIPES__MAX];
- double Read256BlockWidthY[DC__NUM_PIPES__MAX];
- double Read256BlockHeightC[DC__NUM_PIPES__MAX];
- double Read256BlockWidthC[DC__NUM_PIPES__MAX];
- double MaxSwathHeightY[DC__NUM_PIPES__MAX];
- double MaxSwathHeightC[DC__NUM_PIPES__MAX];
- double MinSwathHeightY[DC__NUM_PIPES__MAX];
- double MinSwathHeightC[DC__NUM_PIPES__MAX];
- double NumberOfDPPRequiredForDETAndLBSize[DC__NUM_PIPES__MAX];
- double TotalNumberOfActiveDPP[NumberOfStatesPlusTwo * 2];
- double RequiredDISPCLK[NumberOfStatesPlusTwo * 2];
- double DISPCLK_DPPCLK_Support[NumberOfStatesPlusTwo * 2];
- double MaxDispclk[NumberOfStatesPlusTwo];
- double MaxDppclk[NumberOfStatesPlusTwo];
- double NoOfDPP[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double TotalAvailablePipesSupport[NumberOfStatesPlusTwo * 2];
- double SwathWidthYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double SwathHeightYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double SwathHeightCPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double DETBufferSizeYPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double UrgentLatencySupportUsPerState[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double UrgentLatencySupport[NumberOfStatesPlusTwo * 2];
- double TotalNumberOfDCCActiveDPP[NumberOfStatesPlusTwo * 2];
- double DPTEBytesPerRow[DC__NUM_PIPES__MAX];
- double MetaPTEBytesPerFrame[DC__NUM_PIPES__MAX];
- double MetaRowBytes[DC__NUM_PIPES__MAX];
- double PrefillY[DC__NUM_PIPES__MAX];
- double MaxNumSwY[DC__NUM_PIPES__MAX];
- double PrefetchLinesY[DC__NUM_PIPES__MAX];
- double PrefillC[DC__NUM_PIPES__MAX];
- double MaxNumSwC[DC__NUM_PIPES__MAX];
- double PrefetchLinesC[DC__NUM_PIPES__MAX];
- double LineTimesForPrefetch[DC__NUM_PIPES__MAX];
- double PrefetchBW[DC__NUM_PIPES__MAX];
- double LinesForMetaPTEWithImmediateFlip[DC__NUM_PIPES__MAX];
- double LinesForMetaPTEWithoutImmediateFlip[DC__NUM_PIPES__MAX];
- double LinesForMetaAndDPTERowWithImmediateFlip[DC__NUM_PIPES__MAX];
- double LinesForMetaAndDPTERowWithoutImmediateFlip[DC__NUM_PIPES__MAX];
- double VRatioPreYWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double VRatioPreCWithImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double RequiredPrefetchPixelDataBWWithImmediateFlip[NumberOfStatesPlusTwo * 2
- * DC__NUM_PIPES__MAX];
- double VRatioPreYWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double VRatioPreCWithoutImmediateFlip[NumberOfStatesPlusTwo * 2 * DC__NUM_PIPES__MAX];
- double RequiredPrefetchPixelDataBWWithoutImmediateFlip[NumberOfStatesPlusTwo * 2
- * DC__NUM_PIPES__MAX];
- double PrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
- double PrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
- double VRatioInPrefetchSupportedWithImmediateFlip[NumberOfStatesPlusTwo * 2];
- double VRatioInPrefetchSupportedWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
- double ModeSupportWithImmediateFlip[NumberOfStatesPlusTwo * 2];
- double ModeSupportWithoutImmediateFlip[NumberOfStatesPlusTwo * 2];
- double RequiredDISPCLKPerRatio[2];
- double DPPPerPlanePerRatio[2 * DC__NUM_PIPES__MAX];
- double DISPCLK_DPPCLK_SupportPerRatio[2];
- struct _vcs_dpi_wm_calc_pipe_params_st planes[DC__NUM_PIPES__MAX];
-};
-
-#endif
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 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "display_mode_lib.h"
+#include "display_mode_vba.h"
+
+#include "dml_inline_defs.h"
+
+static const unsigned int NumberOfStates = DC__VOLTAGE_STATES;
+
+static void fetch_socbb_params(struct display_mode_lib *mode_lib);
+static void fetch_ip_params(struct display_mode_lib *mode_lib);
+static void fetch_pipe_params(struct display_mode_lib *mode_lib);
+static void recalculate_params(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes);
+static void recalculate(struct display_mode_lib *mode_lib);
+static double adjust_ReturnBW(
+ struct display_mode_lib *mode_lib,
+ double ReturnBW,
+ bool DCCEnabledAnyPlane,
+ double ReturnBandwidthToDCN);
+static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
+static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
+static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+ struct display_mode_lib *mode_lib);
+static unsigned int dscceComputeDelay(
+ unsigned int bpc,
+ double bpp,
+ unsigned int sliceWidth,
+ unsigned int numSlices,
+ enum output_format_class pixelFormat);
+static unsigned int dscComputeDelay(enum output_format_class pixelFormat);
+// Super monster function with some 45 argument
+static bool CalculatePrefetchSchedule(
+ struct display_mode_lib *mode_lib,
+ double DPPCLK,
+ double DISPCLK,
+ double PixelClock,
+ double DCFClkDeepSleep,
+ unsigned int DSCDelay,
+ unsigned int DPPPerPlane,
+ bool ScalerEnabled,
+ unsigned int NumberOfCursors,
+ double DPPCLKDelaySubtotal,
+ double DPPCLKDelaySCL,
+ double DPPCLKDelaySCLLBOnly,
+ double DPPCLKDelayCNVCFormater,
+ double DPPCLKDelayCNVCCursor,
+ double DISPCLKDelaySubtotal,
+ unsigned int ScalerRecoutWidth,
+ enum output_format_class OutputFormat,
+ unsigned int VBlank,
+ unsigned int HTotal,
+ unsigned int MaxInterDCNTileRepeaters,
+ unsigned int VStartup,
+ unsigned int PageTableLevels,
+ bool VirtualMemoryEnable,
+ bool DynamicMetadataEnable,
+ unsigned int DynamicMetadataLinesBeforeActiveRequired,
+ unsigned int DynamicMetadataTransmittedBytes,
+ bool DCCEnable,
+ double UrgentLatency,
+ double UrgentExtraLatency,
+ double TCalc,
+ unsigned int PDEAndMetaPTEBytesFrame,
+ unsigned int MetaRowByte,
+ unsigned int PixelPTEBytesPerRow,
+ double PrefetchSourceLinesY,
+ unsigned int SwathWidthY,
+ double BytePerPixelDETY,
+ double VInitPreFillY,
+ unsigned int MaxNumSwathY,
+ double PrefetchSourceLinesC,
+ double BytePerPixelDETC,
+ double VInitPreFillC,
+ unsigned int MaxNumSwathC,
+ unsigned int SwathHeightY,
+ unsigned int SwathHeightC,
+ double TWait,
+ bool XFCEnabled,
+ double XFCRemoteSurfaceFlipDelay,
+ bool InterlaceEnable,
+ bool ProgressiveToInterlaceUnitInOPP,
+ double *DSTXAfterScaler,
+ double *DSTYAfterScaler,
+ double *DestinationLinesForPrefetch,
+ double *PrefetchBandwidth,
+ double *DestinationLinesToRequestVMInVBlank,
+ double *DestinationLinesToRequestRowInVBlank,
+ double *VRatioPrefetchY,
+ double *VRatioPrefetchC,
+ double *RequiredPrefetchPixDataBW,
+ unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+ double *Tno_bw,
+ unsigned int *VUpdateOffsetPix,
+ unsigned int *VUpdateWidthPix,
+ unsigned int *VReadyOffsetPix);
+static double RoundToDFSGranularityUp(double Clock, double VCOSpeed);
+static double RoundToDFSGranularityDown(double Clock, double VCOSpeed);
+static double CalculatePrefetchSourceLines(
+ struct display_mode_lib *mode_lib,
+ double VRatio,
+ double vtaps,
+ bool Interlace,
+ bool ProgressiveToInterlaceUnitInOPP,
+ unsigned int SwathHeight,
+ unsigned int ViewportYStart,
+ double *VInitPreFill,
+ unsigned int *MaxNumSwath);
+static unsigned int CalculateVMAndRowBytes(
+ struct display_mode_lib *mode_lib,
+ bool DCCEnable,
+ unsigned int BlockHeight256Bytes,
+ unsigned int BlockWidth256Bytes,
+ enum source_format_class SourcePixelFormat,
+ unsigned int SurfaceTiling,
+ unsigned int BytePerPixel,
+ enum scan_direction_class ScanDirection,
+ unsigned int ViewportWidth,
+ unsigned int ViewportHeight,
+ unsigned int SwathWidthY,
+ bool VirtualMemoryEnable,
+ unsigned int VMMPageSize,
+ unsigned int PTEBufferSizeInRequests,
+ unsigned int PDEProcessingBufIn64KBReqs,
+ unsigned int Pitch,
+ unsigned int DCCMetaPitch,
+ unsigned int *MacroTileWidth,
+ unsigned int *MetaRowByte,
+ unsigned int *PixelPTEBytesPerRow,
+ bool *PTEBufferSizeNotExceeded,
+ unsigned int *dpte_row_height,
+ unsigned int *meta_row_height);
+static double CalculateTWait(
+ unsigned int PrefetchMode,
+ double DRAMClockChangeLatency,
+ double UrgentLatency,
+ double SREnterPlusExitTime);
+static double CalculateRemoteSurfaceFlipDelay(
+ struct display_mode_lib *mode_lib,
+ double VRatio,
+ double SwathWidth,
+ double Bpp,
+ double LineTime,
+ double XFCTSlvVupdateOffset,
+ double XFCTSlvVupdateWidth,
+ double XFCTSlvVreadyOffset,
+ double XFCXBUFLatencyTolerance,
+ double XFCFillBWOverhead,
+ double XFCSlvChunkSize,
+ double XFCBusTransportTime,
+ double TCalc,
+ double TWait,
+ double *SrcActiveDrainRate,
+ double *TInitXFill,
+ double *TslvChk);
+static double CalculateWriteBackDISPCLK(
+ enum source_format_class WritebackPixelFormat,
+ double PixelClock,
+ double WritebackHRatio,
+ double WritebackVRatio,
+ unsigned int WritebackLumaHTaps,
+ unsigned int WritebackLumaVTaps,
+ unsigned int WritebackChromaHTaps,
+ unsigned int WritebackChromaVTaps,
+ double WritebackDestinationWidth,
+ unsigned int HTotal,
+ unsigned int WritebackChromaLineBufferWidth);
+static void CalculateActiveRowBandwidth(
+ bool VirtualMemoryEnable,
+ enum source_format_class SourcePixelFormat,
+ double VRatio,
+ bool DCCEnable,
+ double LineTime,
+ unsigned int MetaRowByteLuma,
+ unsigned int MetaRowByteChroma,
+ unsigned int meta_row_height_luma,
+ unsigned int meta_row_height_chroma,
+ unsigned int PixelPTEBytesPerRowLuma,
+ unsigned int PixelPTEBytesPerRowChroma,
+ unsigned int dpte_row_height_luma,
+ unsigned int dpte_row_height_chroma,
+ double *meta_row_bw,
+ double *dpte_row_bw,
+ double *qual_row_bw);
+static void CalculateFlipSchedule(
+ struct display_mode_lib *mode_lib,
+ double UrgentExtraLatency,
+ double UrgentLatency,
+ unsigned int MaxPageTableLevels,
+ bool VirtualMemoryEnable,
+ double BandwidthAvailableForImmediateFlip,
+ unsigned int TotImmediateFlipBytes,
+ enum source_format_class SourcePixelFormat,
+ unsigned int ImmediateFlipBytes,
+ double LineTime,
+ double Tno_bw,
+ double VRatio,
+ double PDEAndMetaPTEBytesFrame,
+ unsigned int MetaRowByte,
+ unsigned int PixelPTEBytesPerRow,
+ bool DCCEnable,
+ unsigned int dpte_row_height,
+ unsigned int meta_row_height,
+ double qual_row_bw,
+ double *DestinationLinesToRequestVMInImmediateFlip,
+ double *DestinationLinesToRequestRowInImmediateFlip,
+ double *final_flip_bw,
+ bool *ImmediateFlipSupportedForPipe);
+static double CalculateWriteBackDelay(
+ enum source_format_class WritebackPixelFormat,
+ double WritebackHRatio,
+ double WritebackVRatio,
+ unsigned int WritebackLumaHTaps,
+ unsigned int WritebackLumaVTaps,
+ unsigned int WritebackChromaHTaps,
+ unsigned int WritebackChromaVTaps,
+ unsigned int WritebackDestinationWidth);
+static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib);
+static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp);
+static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
+
+void set_prefetch_mode(
+ struct display_mode_lib *mode_lib,
+ bool cstate_en,
+ bool pstate_en,
+ bool ignore_viewport_pos,
+ bool immediate_flip_support)
+{
+ unsigned int prefetch_mode;
+
+ if (cstate_en && pstate_en)
+ prefetch_mode = 0;
+ else if (cstate_en)
+ prefetch_mode = 1;
+ else
+ prefetch_mode = 2;
+ if (prefetch_mode != mode_lib->vba.PrefetchMode
+ || ignore_viewport_pos != mode_lib->vba.IgnoreViewportPositioning
+ || immediate_flip_support != mode_lib->vba.ImmediateFlipSupport) {
+ DTRACE(
+ " Prefetch mode has changed from %i to %i. Recalculating.",
+ prefetch_mode,
+ mode_lib->vba.PrefetchMode);
+ mode_lib->vba.PrefetchMode = prefetch_mode;
+ mode_lib->vba.IgnoreViewportPositioning = ignore_viewport_pos;
+ mode_lib->vba.ImmediateFlipSupport = immediate_flip_support;
+ recalculate(mode_lib);
+ }
+}
+
+unsigned int dml_get_voltage_level(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes)
+{
+ bool need_recalculate = memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
+ || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
+ || num_pipes != mode_lib->vba.cache_num_pipes
+ || memcmp(pipes, mode_lib->vba.cache_pipes,
+ sizeof(display_e2e_pipe_params_st) * num_pipes) != 0;
+
+ mode_lib->vba.soc = mode_lib->soc;
+ mode_lib->vba.ip = mode_lib->ip;
+ memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
+ mode_lib->vba.cache_num_pipes = num_pipes;
+
+ if (need_recalculate && pipes[0].clks_cfg.dppclk_mhz != 0)
+ recalculate(mode_lib);
+ else {
+ fetch_socbb_params(mode_lib);
+ fetch_ip_params(mode_lib);
+ fetch_pipe_params(mode_lib);
+ }
+ ModeSupportAndSystemConfigurationFull(mode_lib);
+
+ return mode_lib->vba.VoltageLevel;
+}
+
+#define dml_get_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes) \
+{ \
+ recalculate_params(mode_lib, pipes, num_pipes); \
+ return var; \
+}
+
+dml_get_attr_func(clk_dcf_deepsleep, mode_lib->vba.DCFClkDeepSleep);
+dml_get_attr_func(wm_urgent, mode_lib->vba.UrgentWatermark);
+dml_get_attr_func(wm_memory_trip, mode_lib->vba.MemoryTripWatermark);
+dml_get_attr_func(wm_writeback_urgent, mode_lib->vba.WritebackUrgentWatermark);
+dml_get_attr_func(wm_stutter_exit, mode_lib->vba.StutterExitWatermark);
+dml_get_attr_func(wm_stutter_enter_exit, mode_lib->vba.StutterEnterPlusExitWatermark);
+dml_get_attr_func(wm_dram_clock_change, mode_lib->vba.DRAMClockChangeWatermark);
+dml_get_attr_func(wm_writeback_dram_clock_change, mode_lib->vba.WritebackDRAMClockChangeWatermark);
+dml_get_attr_func(wm_xfc_underflow, mode_lib->vba.UrgentWatermark); // xfc_underflow maps to urgent
+dml_get_attr_func(stutter_efficiency, mode_lib->vba.StutterEfficiency);
+dml_get_attr_func(stutter_efficiency_no_vblank, mode_lib->vba.StutterEfficiencyNotIncludingVBlank);
+dml_get_attr_func(urgent_latency, mode_lib->vba.MinUrgentLatencySupportUs);
+dml_get_attr_func(urgent_extra_latency, mode_lib->vba.UrgentExtraLatency);
+dml_get_attr_func(nonurgent_latency, mode_lib->vba.NonUrgentLatencyTolerance);
+dml_get_attr_func(
+ dram_clock_change_latency,
+ mode_lib->vba.MinActiveDRAMClockChangeLatencySupported);
+dml_get_attr_func(dispclk_calculated, mode_lib->vba.DISPCLK_calculated);
+dml_get_attr_func(total_data_read_bw, mode_lib->vba.TotalDataReadBandwidth);
+dml_get_attr_func(return_bw, mode_lib->vba.ReturnBW);
+dml_get_attr_func(tcalc, mode_lib->vba.TCalc);
+
+#define dml_get_pipe_attr_func(attr, var) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe) \
+{\
+ unsigned int which_plane; \
+ recalculate_params(mode_lib, pipes, num_pipes); \
+ which_plane = mode_lib->vba.pipe_plane[which_pipe]; \
+ return var[which_plane]; \
+}
+
+dml_get_pipe_attr_func(dsc_delay, mode_lib->vba.DSCDelay);
+dml_get_pipe_attr_func(dppclk_calculated, mode_lib->vba.DPPCLK_calculated);
+dml_get_pipe_attr_func(dscclk_calculated, mode_lib->vba.DSCCLK_calculated);
+dml_get_pipe_attr_func(min_ttu_vblank, mode_lib->vba.MinTTUVBlank);
+dml_get_pipe_attr_func(vratio_prefetch_l, mode_lib->vba.VRatioPrefetchY);
+dml_get_pipe_attr_func(vratio_prefetch_c, mode_lib->vba.VRatioPrefetchC);
+dml_get_pipe_attr_func(dst_x_after_scaler, mode_lib->vba.DSTXAfterScaler);
+dml_get_pipe_attr_func(dst_y_after_scaler, mode_lib->vba.DSTYAfterScaler);
+dml_get_pipe_attr_func(dst_y_per_vm_vblank, mode_lib->vba.DestinationLinesToRequestVMInVBlank);
+dml_get_pipe_attr_func(dst_y_per_row_vblank, mode_lib->vba.DestinationLinesToRequestRowInVBlank);
+dml_get_pipe_attr_func(dst_y_prefetch, mode_lib->vba.DestinationLinesForPrefetch);
+dml_get_pipe_attr_func(dst_y_per_vm_flip, mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip);
+dml_get_pipe_attr_func(
+ dst_y_per_row_flip,
+ mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip);
+
+dml_get_pipe_attr_func(xfc_transfer_delay, mode_lib->vba.XFCTransferDelay);
+dml_get_pipe_attr_func(xfc_precharge_delay, mode_lib->vba.XFCPrechargeDelay);
+dml_get_pipe_attr_func(xfc_remote_surface_flip_latency, mode_lib->vba.XFCRemoteSurfaceFlipLatency);
+dml_get_pipe_attr_func(xfc_prefetch_margin, mode_lib->vba.XFCPrefetchMargin);
+
+unsigned int get_vstartup_calculated(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes,
+ unsigned int which_pipe)
+{
+ unsigned int which_plane;
+
+ recalculate_params(mode_lib, pipes, num_pipes);
+ which_plane = mode_lib->vba.pipe_plane[which_pipe];
+ return mode_lib->vba.VStartup[which_plane];
+}
+
+double get_total_immediate_flip_bytes(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes)
+{
+ recalculate_params(mode_lib, pipes, num_pipes);
+ return mode_lib->vba.TotImmediateFlipBytes;
+}
+
+double get_total_immediate_flip_bw(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes)
+{
+ recalculate_params(mode_lib, pipes, num_pipes);
+ return mode_lib->vba.ImmediateFlipBW;
+}
+
+double get_total_prefetch_bw(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes)
+{
+ unsigned int k;
+ double total_prefetch_bw = 0.0;
+
+ recalculate_params(mode_lib, pipes, num_pipes);
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+ total_prefetch_bw += mode_lib->vba.PrefetchBandwidth[k];
+ return total_prefetch_bw;
+}
+
+static void fetch_socbb_params(struct display_mode_lib *mode_lib)
+{
+ soc_bounding_box_st *soc = &mode_lib->vba.soc;
+ unsigned int i;
+
+ // SOC Bounding Box Parameters
+ mode_lib->vba.ReturnBusWidth = soc->return_bus_width_bytes;
+ mode_lib->vba.NumberOfChannels = soc->num_chans;
+ mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency =
+ soc->ideal_dram_bw_after_urgent_percent; // there's always that one bastard variable that's so long it throws everything out of alignment!
+ mode_lib->vba.UrgentLatency = soc->urgent_latency_us;
+ mode_lib->vba.RoundTripPingLatencyCycles = soc->round_trip_ping_latency_dcfclk_cycles;
+ mode_lib->vba.UrgentOutOfOrderReturnPerChannel =
+ soc->urgent_out_of_order_return_per_channel_bytes;
+ mode_lib->vba.WritebackLatency = soc->writeback_latency_us;
+ mode_lib->vba.SRExitTime = soc->sr_exit_time_us;
+ mode_lib->vba.SREnterPlusExitTime = soc->sr_enter_plus_exit_time_us;
+ mode_lib->vba.DRAMClockChangeLatency = soc->dram_clock_change_latency_us;
+ mode_lib->vba.Downspreading = soc->downspread_percent;
+ mode_lib->vba.DRAMChannelWidth = soc->dram_channel_width_bytes; // new!
+ mode_lib->vba.FabricDatapathToDCNDataReturn = soc->fabric_datapath_to_dcn_data_return_bytes; // new!
+ mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading = soc->dcn_downspread_percent; // new
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed = soc->dispclk_dppclk_vco_speed_mhz; // new
+ mode_lib->vba.VMMPageSize = soc->vmm_page_size_bytes;
+ // Set the voltage scaling clocks as the defaults. Most of these will
+ // be set to different values by the test
+ for (i = 0; i < DC__VOLTAGE_STATES; i++)
+ if (soc->clock_limits[i].state == mode_lib->vba.VoltageLevel)
+ break;
+
+ mode_lib->vba.DCFCLK = soc->clock_limits[i].dcfclk_mhz;
+ mode_lib->vba.SOCCLK = soc->clock_limits[i].socclk_mhz;
+ mode_lib->vba.DRAMSpeed = soc->clock_limits[i].dram_speed_mhz;
+ mode_lib->vba.FabricClock = soc->clock_limits[i].fabricclk_mhz;
+
+ mode_lib->vba.XFCBusTransportTime = soc->xfc_bus_transport_time_us;
+ mode_lib->vba.XFCXBUFLatencyTolerance = soc->xfc_xbuf_latency_tolerance_us;
+
+ mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp = false;
+ mode_lib->vba.MaxHSCLRatio = 4;
+ mode_lib->vba.MaxVSCLRatio = 4;
+ mode_lib->vba.MaxNumWriteback = 0; /*TODO*/
+ mode_lib->vba.WritebackLumaAndChromaScalingSupported = true;
+ mode_lib->vba.Cursor64BppSupport = true;
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.DCFCLKPerState[i] = soc->clock_limits[i].dcfclk_mhz;
+ mode_lib->vba.FabricClockPerState[i] = soc->clock_limits[i].fabricclk_mhz;
+ mode_lib->vba.SOCCLKPerState[i] = soc->clock_limits[i].socclk_mhz;
+ mode_lib->vba.PHYCLKPerState[i] = soc->clock_limits[i].phyclk_mhz;
+ mode_lib->vba.MaxDppclk[i] = soc->clock_limits[i].dppclk_mhz;
+ mode_lib->vba.MaxDSCCLK[i] = soc->clock_limits[i].dscclk_mhz;
+ mode_lib->vba.DRAMSpeedPerState[i] = soc->clock_limits[i].dram_speed_mhz;
+ mode_lib->vba.MaxDispclk[i] = soc->clock_limits[i].dispclk_mhz;
+ }
+}
+
+static void fetch_ip_params(struct display_mode_lib *mode_lib)
+{
+ ip_params_st *ip = &mode_lib->vba.ip;
+
+ // IP Parameters
+ mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
+ mode_lib->vba.MaxNumOTG = ip->max_num_otg;
+ mode_lib->vba.CursorChunkSize = ip->cursor_chunk_size;
+ mode_lib->vba.CursorBufferSize = ip->cursor_buffer_size;
+
+ mode_lib->vba.MaxDCHUBToPSCLThroughput = ip->max_dchub_pscl_bw_pix_per_clk;
+ mode_lib->vba.MaxPSCLToLBThroughput = ip->max_pscl_lb_bw_pix_per_clk;
+ mode_lib->vba.ROBBufferSizeInKByte = ip->rob_buffer_size_kbytes;
+ mode_lib->vba.DETBufferSizeInKByte = ip->det_buffer_size_kbytes;
+ mode_lib->vba.PixelChunkSizeInKByte = ip->pixel_chunk_size_kbytes;
+ mode_lib->vba.MetaChunkSize = ip->meta_chunk_size_kbytes;
+ mode_lib->vba.PTEChunkSize = ip->pte_chunk_size_kbytes;
+ mode_lib->vba.WritebackChunkSize = ip->writeback_chunk_size_kbytes;
+ mode_lib->vba.LineBufferSize = ip->line_buffer_size_bits;
+ mode_lib->vba.MaxLineBufferLines = ip->max_line_buffer_lines;
+ mode_lib->vba.PTEBufferSizeInRequests = ip->dpte_buffer_size_in_pte_reqs;
+ mode_lib->vba.DPPOutputBufferPixels = ip->dpp_output_buffer_pixels;
+ mode_lib->vba.OPPOutputBufferLines = ip->opp_output_buffer_lines;
+ mode_lib->vba.WritebackInterfaceLumaBufferSize = ip->writeback_luma_buffer_size_kbytes;
+ mode_lib->vba.WritebackInterfaceChromaBufferSize = ip->writeback_chroma_buffer_size_kbytes;
+ mode_lib->vba.WritebackChromaLineBufferWidth =
+ ip->writeback_chroma_line_buffer_width_pixels;
+ mode_lib->vba.MaxPageTableLevels = ip->max_page_table_levels;
+ mode_lib->vba.MaxInterDCNTileRepeaters = ip->max_inter_dcn_tile_repeaters;
+ mode_lib->vba.NumberOfDSC = ip->num_dsc;
+ mode_lib->vba.ODMCapability = ip->odm_capable;
+ mode_lib->vba.DISPCLKRampingMargin = ip->dispclk_ramp_margin_percent;
+
+ mode_lib->vba.XFCSupported = ip->xfc_supported;
+ mode_lib->vba.XFCFillBWOverhead = ip->xfc_fill_bw_overhead_percent;
+ mode_lib->vba.XFCFillConstant = ip->xfc_fill_constant_bytes;
+ mode_lib->vba.DPPCLKDelaySubtotal = ip->dppclk_delay_subtotal;
+ mode_lib->vba.DPPCLKDelaySCL = ip->dppclk_delay_scl;
+ mode_lib->vba.DPPCLKDelaySCLLBOnly = ip->dppclk_delay_scl_lb_only;
+ mode_lib->vba.DPPCLKDelayCNVCFormater = ip->dppclk_delay_cnvc_formatter;
+ mode_lib->vba.DPPCLKDelayCNVCCursor = ip->dppclk_delay_cnvc_cursor;
+ mode_lib->vba.DISPCLKDelaySubtotal = ip->dispclk_delay_subtotal;
+
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP = ip->ptoi_supported;
+
+ mode_lib->vba.PDEProcessingBufIn64KBReqs = ip->pde_proc_buffer_size_64k_reqs;
+}
+
+static void fetch_pipe_params(struct display_mode_lib *mode_lib)
+{
+ display_e2e_pipe_params_st *pipes = mode_lib->vba.cache_pipes;
+ ip_params_st *ip = &mode_lib->vba.ip;
+
+ unsigned int OTGInstPlane[DC__NUM_DPP__MAX];
+ unsigned int j, k;
+ bool PlaneVisited[DC__NUM_DPP__MAX];
+ bool visited[DC__NUM_DPP__MAX];
+
+ // Convert Pipes to Planes
+ for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k)
+ visited[k] = false;
+
+ mode_lib->vba.NumberOfActivePlanes = 0;
+ for (j = 0; j < mode_lib->vba.cache_num_pipes; ++j) {
+ display_pipe_source_params_st *src = &pipes[j].pipe.src;
+ display_pipe_dest_params_st *dst = &pipes[j].pipe.dest;
+ scaler_ratio_depth_st *scl = &pipes[j].pipe.scale_ratio_depth;
+ scaler_taps_st *taps = &pipes[j].pipe.scale_taps;
+ display_output_params_st *dout = &pipes[j].dout;
+ display_clocks_and_cfg_st *clks = &pipes[j].clks_cfg;
+
+ if (visited[j])
+ continue;
+ visited[j] = true;
+
+ mode_lib->vba.pipe_plane[j] = mode_lib->vba.NumberOfActivePlanes;
+
+ mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes] = 1;
+ mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes] =
+ (enum scan_direction_class) (src->source_scan);
+ mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] =
+ src->viewport_width;
+ mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] =
+ src->viewport_height;
+ mode_lib->vba.ViewportYStartY[mode_lib->vba.NumberOfActivePlanes] =
+ src->viewport_y_y;
+ mode_lib->vba.ViewportYStartC[mode_lib->vba.NumberOfActivePlanes] =
+ src->viewport_y_c;
+ mode_lib->vba.PitchY[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch;
+ mode_lib->vba.PitchC[mode_lib->vba.NumberOfActivePlanes] = src->data_pitch_c;
+ mode_lib->vba.DCCMetaPitchY[mode_lib->vba.NumberOfActivePlanes] = src->meta_pitch;
+ mode_lib->vba.HRatio[mode_lib->vba.NumberOfActivePlanes] = scl->hscl_ratio;
+ mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] = scl->vscl_ratio;
+ mode_lib->vba.ScalerEnabled[mode_lib->vba.NumberOfActivePlanes] = scl->scl_enable;
+ mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes] = dst->interlaced;
+ if (mode_lib->vba.Interlace[mode_lib->vba.NumberOfActivePlanes])
+ mode_lib->vba.VRatio[mode_lib->vba.NumberOfActivePlanes] *= 2.0;
+ mode_lib->vba.htaps[mode_lib->vba.NumberOfActivePlanes] = taps->htaps;
+ mode_lib->vba.vtaps[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps;
+ mode_lib->vba.HTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->htaps_c;
+ mode_lib->vba.VTAPsChroma[mode_lib->vba.NumberOfActivePlanes] = taps->vtaps_c;
+ mode_lib->vba.HTotal[mode_lib->vba.NumberOfActivePlanes] = dst->htotal;
+ mode_lib->vba.VTotal[mode_lib->vba.NumberOfActivePlanes] = dst->vtotal;
+ mode_lib->vba.DCCEnable[mode_lib->vba.NumberOfActivePlanes] =
+ src->dcc_use_global ?
+ ip->dcc_supported : src->dcc && ip->dcc_supported;
+ mode_lib->vba.DCCRate[mode_lib->vba.NumberOfActivePlanes] = src->dcc_rate;
+ mode_lib->vba.SourcePixelFormat[mode_lib->vba.NumberOfActivePlanes] =
+ (enum source_format_class) (src->source_format);
+ mode_lib->vba.HActive[mode_lib->vba.NumberOfActivePlanes] = dst->hactive;
+ mode_lib->vba.VActive[mode_lib->vba.NumberOfActivePlanes] = dst->vactive;
+ mode_lib->vba.SurfaceTiling[mode_lib->vba.NumberOfActivePlanes] =
+ (enum dm_swizzle_mode) (src->sw_mode);
+ mode_lib->vba.ScalerRecoutWidth[mode_lib->vba.NumberOfActivePlanes] =
+ dst->recout_width; // TODO: or should this be full_recout_width???...maybe only when in hsplit mode?
+ mode_lib->vba.ODMCombineEnabled[mode_lib->vba.NumberOfActivePlanes] =
+ dst->odm_combine;
+ mode_lib->vba.OutputFormat[mode_lib->vba.NumberOfActivePlanes] =
+ (enum output_format_class) (dout->output_format);
+ mode_lib->vba.Output[mode_lib->vba.NumberOfActivePlanes] =
+ (enum output_encoder_class) (dout->output_type);
+ mode_lib->vba.OutputBpp[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
+ mode_lib->vba.OutputLinkDPLanes[mode_lib->vba.NumberOfActivePlanes] =
+ dout->dp_lanes;
+ mode_lib->vba.DSCEnabled[mode_lib->vba.NumberOfActivePlanes] = dout->dsc_enable;
+ mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] =
+ dout->dsc_slices;
+ mode_lib->vba.DSCInputBitPerComponent[mode_lib->vba.NumberOfActivePlanes] =
+ dout->output_bpc == 0 ? 12 : dout->output_bpc;
+ mode_lib->vba.WritebackEnable[mode_lib->vba.NumberOfActivePlanes] = dout->wb_enable;
+ mode_lib->vba.WritebackSourceHeight[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_src_height;
+ mode_lib->vba.WritebackDestinationWidth[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_dst_width;
+ mode_lib->vba.WritebackDestinationHeight[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_dst_height;
+ mode_lib->vba.WritebackPixelFormat[mode_lib->vba.NumberOfActivePlanes] =
+ (enum source_format_class) (dout->wb.wb_pixel_format);
+ mode_lib->vba.WritebackLumaHTaps[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_htaps_luma;
+ mode_lib->vba.WritebackLumaVTaps[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_vtaps_luma;
+ mode_lib->vba.WritebackChromaHTaps[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_htaps_chroma;
+ mode_lib->vba.WritebackChromaVTaps[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_vtaps_chroma;
+ mode_lib->vba.WritebackHRatio[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_hratio;
+ mode_lib->vba.WritebackVRatio[mode_lib->vba.NumberOfActivePlanes] =
+ dout->wb.wb_vratio;
+
+ mode_lib->vba.DynamicMetadataEnable[mode_lib->vba.NumberOfActivePlanes] =
+ src->dynamic_metadata_enable;
+ mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[mode_lib->vba.NumberOfActivePlanes] =
+ src->dynamic_metadata_lines_before_active;
+ mode_lib->vba.DynamicMetadataTransmittedBytes[mode_lib->vba.NumberOfActivePlanes] =
+ src->dynamic_metadata_xmit_bytes;
+
+ mode_lib->vba.XFCEnabled[mode_lib->vba.NumberOfActivePlanes] = src->xfc_enable
+ && ip->xfc_supported;
+ mode_lib->vba.XFCSlvChunkSize = src->xfc_params.xfc_slv_chunk_size_bytes;
+ mode_lib->vba.XFCTSlvVupdateOffset = src->xfc_params.xfc_tslv_vupdate_offset_us;
+ mode_lib->vba.XFCTSlvVupdateWidth = src->xfc_params.xfc_tslv_vupdate_width_us;
+ mode_lib->vba.XFCTSlvVreadyOffset = src->xfc_params.xfc_tslv_vready_offset_us;
+ mode_lib->vba.PixelClock[mode_lib->vba.NumberOfActivePlanes] = dst->pixel_rate_mhz;
+ mode_lib->vba.DPPCLK[mode_lib->vba.NumberOfActivePlanes] = clks->dppclk_mhz;
+ if (ip->is_line_buffer_bpp_fixed)
+ mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] =
+ ip->line_buffer_fixed_bpp;
+ else {
+ unsigned int lb_depth;
+
+ switch (scl->lb_depth) {
+ case dm_lb_6:
+ lb_depth = 18;
+ break;
+ case dm_lb_8:
+ lb_depth = 24;
+ break;
+ case dm_lb_10:
+ lb_depth = 30;
+ break;
+ case dm_lb_12:
+ lb_depth = 36;
+ break;
+ case dm_lb_16:
+ lb_depth = 48;
+ break;
+ default:
+ lb_depth = 36;
+ }
+ mode_lib->vba.LBBitPerPixel[mode_lib->vba.NumberOfActivePlanes] = lb_depth;
+ }
+ mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes] = 0;
+ // The DML spreadsheet assumes that the two cursors utilize the same amount of bandwidth. We'll
+ // calculate things a little more accurately
+ for (k = 0; k < DC__NUM_CURSOR__MAX; ++k) {
+ switch (k) {
+ case 0:
+ mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][0] =
+ CursorBppEnumToBits(
+ (enum cursor_bpp) (src->cur0_bpp));
+ mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][0] =
+ src->cur0_src_width;
+ if (src->cur0_src_width > 0)
+ mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
+ break;
+ case 1:
+ mode_lib->vba.CursorBPP[mode_lib->vba.NumberOfActivePlanes][1] =
+ CursorBppEnumToBits(
+ (enum cursor_bpp) (src->cur1_bpp));
+ mode_lib->vba.CursorWidth[mode_lib->vba.NumberOfActivePlanes][1] =
+ src->cur1_src_width;
+ if (src->cur1_src_width > 0)
+ mode_lib->vba.NumberOfCursors[mode_lib->vba.NumberOfActivePlanes]++;
+ break;
+ default:
+ dml_print(
+ "ERROR: Number of cursors specified exceeds supported maximum\n")
+ ;
+ }
+ }
+
+ OTGInstPlane[mode_lib->vba.NumberOfActivePlanes] = dst->otg_inst;
+
+ if (dst->odm_combine && !src->is_hsplit)
+ dml_print(
+ "ERROR: ODM Combine is specified but is_hsplit has not be specified for pipe %i\n",
+ j);
+
+ if (src->is_hsplit) {
+ for (k = j + 1; k < mode_lib->vba.cache_num_pipes; ++k) {
+ display_pipe_source_params_st *src_k = &pipes[k].pipe.src;
+ display_output_params_st *dout_k = &pipes[k].dout;
+
+ if (src_k->is_hsplit && !visited[k]
+ && src->hsplit_grp == src_k->hsplit_grp) {
+ mode_lib->vba.pipe_plane[k] =
+ mode_lib->vba.NumberOfActivePlanes;
+ mode_lib->vba.DPPPerPlane[mode_lib->vba.NumberOfActivePlanes]++;
+ if (mode_lib->vba.SourceScan[mode_lib->vba.NumberOfActivePlanes]
+ == dm_horz)
+ mode_lib->vba.ViewportWidth[mode_lib->vba.NumberOfActivePlanes] +=
+ src_k->viewport_width;
+ else
+ mode_lib->vba.ViewportHeight[mode_lib->vba.NumberOfActivePlanes] +=
+ src_k->viewport_height;
+
+ mode_lib->vba.NumberOfDSCSlices[mode_lib->vba.NumberOfActivePlanes] +=
+ dout_k->dsc_slices;
+ visited[k] = true;
+ }
+ }
+ }
+
+ mode_lib->vba.NumberOfActivePlanes++;
+ }
+
+ // handle overlays through dml_ml->vba.BlendingAndTiming
+ // dml_ml->vba.BlendingAndTiming tells you which instance to look at to get timing, the so called 'master'
+
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+ PlaneVisited[j] = false;
+
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+ for (k = j + 1; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (!PlaneVisited[k] && OTGInstPlane[j] == OTGInstPlane[k]) {
+ // doesn't matter, so choose the smaller one
+ mode_lib->vba.BlendingAndTiming[j] = j;
+ PlaneVisited[j] = true;
+ mode_lib->vba.BlendingAndTiming[k] = j;
+ PlaneVisited[k] = true;
+ }
+ }
+
+ if (!PlaneVisited[j]) {
+ mode_lib->vba.BlendingAndTiming[j] = j;
+ PlaneVisited[j] = true;
+ }
+ }
+
+ // TODO: dml_ml->vba.ODMCombineEnabled => 2 * dml_ml->vba.DPPPerPlane...actually maybe not since all pipes are specified
+ // Do we want the dscclk to automatically be halved? Guess not since the value is specified
+
+ mode_lib->vba.SynchronizedVBlank = pipes[0].pipe.dest.synchronized_vblank_all_planes;
+ for (k = 1; k < mode_lib->vba.cache_num_pipes; ++k)
+ ASSERT(mode_lib->vba.SynchronizedVBlank == pipes[k].pipe.dest.synchronized_vblank_all_planes);
+
+ mode_lib->vba.VirtualMemoryEnable = false;
+ mode_lib->vba.OverridePageTableLevels = 0;
+
+ for (k = 0; k < mode_lib->vba.cache_num_pipes; ++k) {
+ mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable
+ || !!pipes[k].pipe.src.vm;
+ mode_lib->vba.OverridePageTableLevels =
+ (pipes[k].pipe.src.vm_levels_force_en
+ && mode_lib->vba.OverridePageTableLevels
+ < pipes[k].pipe.src.vm_levels_force) ?
+ pipes[k].pipe.src.vm_levels_force :
+ mode_lib->vba.OverridePageTableLevels;
+ }
+
+ if (mode_lib->vba.OverridePageTableLevels)
+ mode_lib->vba.MaxPageTableLevels = mode_lib->vba.OverridePageTableLevels;
+
+ mode_lib->vba.VirtualMemoryEnable = mode_lib->vba.VirtualMemoryEnable && !!ip->pte_enable;
+
+ mode_lib->vba.FabricAndDRAMBandwidth = dml_min(
+ mode_lib->vba.DRAMSpeed * mode_lib->vba.NumberOfChannels
+ * mode_lib->vba.DRAMChannelWidth,
+ mode_lib->vba.FabricClock * mode_lib->vba.FabricDatapathToDCNDataReturn)
+ / 1000.0;
+
+ // TODO: Must be consistent across all pipes
+ // DCCProgrammingAssumesScanDirectionUnknown = src.dcc_scan_dir_unknown;
+}
+
+static void recalculate(struct display_mode_lib *mode_lib)
+{
+ ModeSupportAndSystemConfiguration(mode_lib);
+ PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
+ DisplayPipeConfiguration(mode_lib);
+ DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(mode_lib);
+}
+
+// in wm mode we pull the parameters needed from the display_e2e_pipe_params_st structs
+// rather than working them out as in recalculate_ms
+static void recalculate_params(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes)
+{
+ // This is only safe to use memcmp because there are non-POD types in struct display_mode_lib
+ if (memcmp(&mode_lib->soc, &mode_lib->vba.soc, sizeof(mode_lib->vba.soc)) != 0
+ || memcmp(&mode_lib->ip, &mode_lib->vba.ip, sizeof(mode_lib->vba.ip)) != 0
+ || num_pipes != mode_lib->vba.cache_num_pipes
+ || memcmp(
+ pipes,
+ mode_lib->vba.cache_pipes,
+ sizeof(display_e2e_pipe_params_st) * num_pipes) != 0) {
+ mode_lib->vba.soc = mode_lib->soc;
+ mode_lib->vba.ip = mode_lib->ip;
+ memcpy(mode_lib->vba.cache_pipes, pipes, sizeof(*pipes) * num_pipes);
+ mode_lib->vba.cache_num_pipes = num_pipes;
+ recalculate(mode_lib);
+ }
+}
+
+static void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
+{
+ soc_bounding_box_st *soc = &mode_lib->vba.soc;
+ unsigned int i, k;
+ unsigned int total_pipes = 0;
+
+ mode_lib->vba.VoltageLevel = mode_lib->vba.cache_pipes[0].clks_cfg.voltage;
+ for (i = 1; i < mode_lib->vba.cache_num_pipes; ++i)
+ ASSERT(mode_lib->vba.VoltageLevel == -1 || mode_lib->vba.VoltageLevel == mode_lib->vba.cache_pipes[i].clks_cfg.voltage);
+
+ mode_lib->vba.DCFCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dcfclk_mhz;
+ mode_lib->vba.SOCCLK = mode_lib->vba.cache_pipes[0].clks_cfg.socclk_mhz;
+
+ if (mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz > 0.0)
+ mode_lib->vba.DISPCLK = mode_lib->vba.cache_pipes[0].clks_cfg.dispclk_mhz;
+ else
+ mode_lib->vba.DISPCLK = soc->clock_limits[mode_lib->vba.VoltageLevel].dispclk_mhz;
+
+ fetch_socbb_params(mode_lib);
+ fetch_ip_params(mode_lib);
+ fetch_pipe_params(mode_lib);
+
+ // Total Available Pipes Support Check
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+ total_pipes += mode_lib->vba.DPPPerPlane[k];
+ ASSERT(total_pipes <= DC__NUM_DPP__MAX);
+}
+
+static double adjust_ReturnBW(
+ struct display_mode_lib *mode_lib,
+ double ReturnBW,
+ bool DCCEnabledAnyPlane,
+ double ReturnBandwidthToDCN)
+{
+ double CriticalCompression;
+
+ if (DCCEnabledAnyPlane
+ && ReturnBandwidthToDCN
+ > mode_lib->vba.DCFCLK * mode_lib->vba.ReturnBusWidth / 4.0)
+ ReturnBW =
+ dml_min(
+ ReturnBW,
+ ReturnBandwidthToDCN * 4
+ * (1.0
+ - mode_lib->vba.UrgentLatency
+ / ((mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024
+ / ReturnBandwidthToDCN
+ - mode_lib->vba.DCFCLK
+ * mode_lib->vba.ReturnBusWidth
+ / 4)
+ + mode_lib->vba.UrgentLatency));
+
+ CriticalCompression = 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK
+ * mode_lib->vba.UrgentLatency
+ / (ReturnBandwidthToDCN * mode_lib->vba.UrgentLatency
+ + (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024);
+
+ if (DCCEnabledAnyPlane && CriticalCompression > 1.0 && CriticalCompression < 4.0)
+ ReturnBW =
+ dml_min(
+ ReturnBW,
+ 4.0 * ReturnBandwidthToDCN
+ * (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024
+ * mode_lib->vba.ReturnBusWidth
+ * mode_lib->vba.DCFCLK
+ * mode_lib->vba.UrgentLatency
+ / dml_pow(
+ (ReturnBandwidthToDCN
+ * mode_lib->vba.UrgentLatency
+ + (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024),
+ 2));
+
+ return ReturnBW;
+}
+
+static unsigned int dscceComputeDelay(
+ unsigned int bpc,
+ double bpp,
+ unsigned int sliceWidth,
+ unsigned int numSlices,
+ enum output_format_class pixelFormat)
+{
+ // valid bpc = source bits per component in the set of {8, 10, 12}
+ // valid bpp = increments of 1/16 of a bit
+ // min = 6/7/8 in N420/N422/444, respectively
+ // max = such that compression is 1:1
+ //valid sliceWidth = number of pixels per slice line, must be less than or equal to 5184/numSlices (or 4096/numSlices in 420 mode)
+ //valid numSlices = number of slices in the horiziontal direction per DSC engine in the set of {1, 2, 3, 4}
+ //valid pixelFormat = pixel/color format in the set of {:N444_RGB, :S422, :N422, :N420}
+
+ // fixed value
+ unsigned int rcModelSize = 8192;
+
+ // N422/N420 operate at 2 pixels per clock
+ unsigned int pixelsPerClock, lstall, D, initalXmitDelay, w, s, ix, wx, p, l0, a, ax, l,
+ Delay, pixels;
+
+ if (pixelFormat == dm_n422 || pixelFormat == dm_420)
+ pixelsPerClock = 2;
+ // #all other modes operate at 1 pixel per clock
+ else
+ pixelsPerClock = 1;
+
+ //initial transmit delay as per PPS
+ initalXmitDelay = dml_round(rcModelSize / 2.0 / bpp / pixelsPerClock);
+
+ //compute ssm delay
+ if (bpc == 8)
+ D = 81;
+ else if (bpc == 10)
+ D = 89;
+ else
+ D = 113;
+
+ //divide by pixel per cycle to compute slice width as seen by DSC
+ w = sliceWidth / pixelsPerClock;
+
+ //422 mode has an additional cycle of delay
+ if (pixelFormat == dm_s422)
+ s = 1;
+ else
+ s = 0;
+
+ //main calculation for the dscce
+ ix = initalXmitDelay + 45;
+ wx = (w + 2) / 3;
+ p = 3 * wx - w;
+ l0 = ix / w;
+ a = ix + p * l0;
+ ax = (a + 2) / 3 + D + 6 + 1;
+ l = (ax + wx - 1) / wx;
+ if ((ix % w) == 0 && p != 0)
+ lstall = 1;
+ else
+ lstall = 0;
+ Delay = l * wx * (numSlices - 1) + ax + s + lstall + 22;
+
+ //dsc processes 3 pixel containers per cycle and a container can contain 1 or 2 pixels
+ pixels = Delay * 3 * pixelsPerClock;
+ return pixels;
+}
+
+static unsigned int dscComputeDelay(enum output_format_class pixelFormat)
+{
+ unsigned int Delay = 0;
+
+ if (pixelFormat == dm_420) {
+ // sfr
+ Delay = Delay + 2;
+ // dsccif
+ Delay = Delay + 0;
+ // dscc - input deserializer
+ Delay = Delay + 3;
+ // dscc gets pixels every other cycle
+ Delay = Delay + 2;
+ // dscc - input cdc fifo
+ Delay = Delay + 12;
+ // dscc gets pixels every other cycle
+ Delay = Delay + 13;
+ // dscc - cdc uncertainty
+ Delay = Delay + 2;
+ // dscc - output cdc fifo
+ Delay = Delay + 7;
+ // dscc gets pixels every other cycle
+ Delay = Delay + 3;
+ // dscc - cdc uncertainty
+ Delay = Delay + 2;
+ // dscc - output serializer
+ Delay = Delay + 1;
+ // sft
+ Delay = Delay + 1;
+ } else if (pixelFormat == dm_n422) {
+ // sfr
+ Delay = Delay + 2;
+ // dsccif
+ Delay = Delay + 1;
+ // dscc - input deserializer
+ Delay = Delay + 5;
+ // dscc - input cdc fifo
+ Delay = Delay + 25;
+ // dscc - cdc uncertainty
+ Delay = Delay + 2;
+ // dscc - output cdc fifo
+ Delay = Delay + 10;
+ // dscc - cdc uncertainty
+ Delay = Delay + 2;
+ // dscc - output serializer
+ Delay = Delay + 1;
+ // sft
+ Delay = Delay + 1;
+ } else {
+ // sfr
+ Delay = Delay + 2;
+ // dsccif
+ Delay = Delay + 0;
+ // dscc - input deserializer
+ Delay = Delay + 3;
+ // dscc - input cdc fifo
+ Delay = Delay + 12;
+ // dscc - cdc uncertainty
+ Delay = Delay + 2;
+ // dscc - output cdc fifo
+ Delay = Delay + 7;
+ // dscc - output serializer
+ Delay = Delay + 1;
+ // dscc - cdc uncertainty
+ Delay = Delay + 2;
+ // sft
+ Delay = Delay + 1;
+ }
+
+ return Delay;
+}
+
+static bool CalculatePrefetchSchedule(
+ struct display_mode_lib *mode_lib,
+ double DPPCLK,
+ double DISPCLK,
+ double PixelClock,
+ double DCFClkDeepSleep,
+ unsigned int DSCDelay,
+ unsigned int DPPPerPlane,
+ bool ScalerEnabled,
+ unsigned int NumberOfCursors,
+ double DPPCLKDelaySubtotal,
+ double DPPCLKDelaySCL,
+ double DPPCLKDelaySCLLBOnly,
+ double DPPCLKDelayCNVCFormater,
+ double DPPCLKDelayCNVCCursor,
+ double DISPCLKDelaySubtotal,
+ unsigned int ScalerRecoutWidth,
+ enum output_format_class OutputFormat,
+ unsigned int VBlank,
+ unsigned int HTotal,
+ unsigned int MaxInterDCNTileRepeaters,
+ unsigned int VStartup,
+ unsigned int PageTableLevels,
+ bool VirtualMemoryEnable,
+ bool DynamicMetadataEnable,
+ unsigned int DynamicMetadataLinesBeforeActiveRequired,
+ unsigned int DynamicMetadataTransmittedBytes,
+ bool DCCEnable,
+ double UrgentLatency,
+ double UrgentExtraLatency,
+ double TCalc,
+ unsigned int PDEAndMetaPTEBytesFrame,
+ unsigned int MetaRowByte,
+ unsigned int PixelPTEBytesPerRow,
+ double PrefetchSourceLinesY,
+ unsigned int SwathWidthY,
+ double BytePerPixelDETY,
+ double VInitPreFillY,
+ unsigned int MaxNumSwathY,
+ double PrefetchSourceLinesC,
+ double BytePerPixelDETC,
+ double VInitPreFillC,
+ unsigned int MaxNumSwathC,
+ unsigned int SwathHeightY,
+ unsigned int SwathHeightC,
+ double TWait,
+ bool XFCEnabled,
+ double XFCRemoteSurfaceFlipDelay,
+ bool InterlaceEnable,
+ bool ProgressiveToInterlaceUnitInOPP,
+ double *DSTXAfterScaler,
+ double *DSTYAfterScaler,
+ double *DestinationLinesForPrefetch,
+ double *PrefetchBandwidth,
+ double *DestinationLinesToRequestVMInVBlank,
+ double *DestinationLinesToRequestRowInVBlank,
+ double *VRatioPrefetchY,
+ double *VRatioPrefetchC,
+ double *RequiredPrefetchPixDataBW,
+ unsigned int *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+ double *Tno_bw,
+ unsigned int *VUpdateOffsetPix,
+ unsigned int *VUpdateWidthPix,
+ unsigned int *VReadyOffsetPix)
+{
+ bool MyError = false;
+ unsigned int DPPCycles, DISPCLKCycles;
+ double DSTTotalPixelsAfterScaler, TotalRepeaterDelayTime;
+ double Tdm, LineTime, Tsetup;
+ double dst_y_prefetch_equ;
+ double Tsw_oto;
+ double prefetch_bw_oto;
+ double Tvm_oto;
+ double Tr0_oto;
+ double Tpre_oto;
+ double dst_y_prefetch_oto;
+ double TimeForFetchingMetaPTE = 0;
+ double TimeForFetchingRowInVBlank = 0;
+ double LinesToRequestPrefetchPixelData = 0;
+
+ if (ScalerEnabled)
+ DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCL;
+ else
+ DPPCycles = DPPCLKDelaySubtotal + DPPCLKDelaySCLLBOnly;
+
+ DPPCycles = DPPCycles + DPPCLKDelayCNVCFormater + NumberOfCursors * DPPCLKDelayCNVCCursor;
+
+ DISPCLKCycles = DISPCLKDelaySubtotal;
+
+ if (DPPCLK == 0.0 || DISPCLK == 0.0)
+ return true;
+
+ *DSTXAfterScaler = DPPCycles * PixelClock / DPPCLK + DISPCLKCycles * PixelClock / DISPCLK
+ + DSCDelay;
+
+ if (DPPPerPlane > 1)
+ *DSTXAfterScaler = *DSTXAfterScaler + ScalerRecoutWidth;
+
+ if (OutputFormat == dm_420 || (InterlaceEnable && ProgressiveToInterlaceUnitInOPP))
+ *DSTYAfterScaler = 1;
+ else
+ *DSTYAfterScaler = 0;
+
+ DSTTotalPixelsAfterScaler = ((double) (*DSTYAfterScaler * HTotal)) + *DSTXAfterScaler;
+ *DSTYAfterScaler = dml_floor(DSTTotalPixelsAfterScaler / HTotal, 1);
+ *DSTXAfterScaler = DSTTotalPixelsAfterScaler - ((double) (*DSTYAfterScaler * HTotal));
+
+ *VUpdateOffsetPix = dml_ceil(HTotal / 4.0, 1);
+ TotalRepeaterDelayTime = MaxInterDCNTileRepeaters * (2.0 / DPPCLK + 3.0 / DISPCLK);
+ *VUpdateWidthPix = (14.0 / DCFClkDeepSleep + 12.0 / DPPCLK + TotalRepeaterDelayTime)
+ * PixelClock;
+
+ *VReadyOffsetPix = dml_max(
+ 150.0 / DPPCLK,
+ TotalRepeaterDelayTime + 20.0 / DCFClkDeepSleep + 10.0 / DPPCLK)
+ * PixelClock;
+
+ Tsetup = (double) (*VUpdateOffsetPix + *VUpdateWidthPix + *VReadyOffsetPix) / PixelClock;
+
+ LineTime = (double) HTotal / PixelClock;
+
+ if (DynamicMetadataEnable) {
+ double Tdmbf, Tdmec, Tdmsks;
+
+ Tdm = dml_max(0.0, UrgentExtraLatency - TCalc);
+ Tdmbf = DynamicMetadataTransmittedBytes / 4.0 / DISPCLK;
+ Tdmec = LineTime;
+ if (DynamicMetadataLinesBeforeActiveRequired == 0)
+ Tdmsks = VBlank * LineTime / 2.0;
+ else
+ Tdmsks = DynamicMetadataLinesBeforeActiveRequired * LineTime;
+ if (InterlaceEnable && !ProgressiveToInterlaceUnitInOPP)
+ Tdmsks = Tdmsks / 2;
+ if (VStartup * LineTime
+ < Tsetup + TWait + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) {
+ MyError = true;
+ *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = (Tsetup + TWait
+ + UrgentExtraLatency + Tdmbf + Tdmec + Tdmsks) / LineTime;
+ } else
+ *VStartupRequiredWhenNotEnoughTimeForDynamicMetadata = 0.0;
+ } else
+ Tdm = 0;
+
+ if (VirtualMemoryEnable) {
+ if (PageTableLevels == 4)
+ *Tno_bw = UrgentExtraLatency + UrgentLatency;
+ else if (PageTableLevels == 3)
+ *Tno_bw = UrgentExtraLatency;
+ else
+ *Tno_bw = 0;
+ } else if (DCCEnable)
+ *Tno_bw = LineTime;
+ else
+ *Tno_bw = LineTime / 4;
+
+ dst_y_prefetch_equ = VStartup - dml_max(TCalc + TWait, XFCRemoteSurfaceFlipDelay) / LineTime
+ - (Tsetup + Tdm) / LineTime
+ - (*DSTYAfterScaler + *DSTXAfterScaler / HTotal);
+
+ Tsw_oto = dml_max(PrefetchSourceLinesY, PrefetchSourceLinesC) * LineTime;
+
+ prefetch_bw_oto = (MetaRowByte + PixelPTEBytesPerRow
+ + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+ + PrefetchSourceLinesC * SwathWidthY / 2 * dml_ceil(BytePerPixelDETC, 2))
+ / Tsw_oto;
+
+ if (VirtualMemoryEnable == true) {
+ Tvm_oto =
+ dml_max(
+ *Tno_bw + PDEAndMetaPTEBytesFrame / prefetch_bw_oto,
+ dml_max(
+ UrgentExtraLatency
+ + UrgentLatency
+ * (PageTableLevels
+ - 1),
+ LineTime / 4.0));
+ } else
+ Tvm_oto = LineTime / 4.0;
+
+ if ((VirtualMemoryEnable == true || DCCEnable == true)) {
+ Tr0_oto = dml_max(
+ (MetaRowByte + PixelPTEBytesPerRow) / prefetch_bw_oto,
+ dml_max(UrgentLatency, dml_max(LineTime - Tvm_oto, LineTime / 4)));
+ } else
+ Tr0_oto = LineTime - Tvm_oto;
+
+ Tpre_oto = Tvm_oto + Tr0_oto + Tsw_oto;
+
+ dst_y_prefetch_oto = Tpre_oto / LineTime;
+
+ if (dst_y_prefetch_oto < dst_y_prefetch_equ)
+ *DestinationLinesForPrefetch = dst_y_prefetch_oto;
+ else
+ *DestinationLinesForPrefetch = dst_y_prefetch_equ;
+
+ *DestinationLinesForPrefetch = dml_floor(4.0 * (*DestinationLinesForPrefetch + 0.125), 1)
+ / 4;
+
+ dml_print("DML: VStartup: %d\n", VStartup);
+ dml_print("DML: TCalc: %f\n", TCalc);
+ dml_print("DML: TWait: %f\n", TWait);
+ dml_print("DML: XFCRemoteSurfaceFlipDelay: %f\n", XFCRemoteSurfaceFlipDelay);
+ dml_print("DML: LineTime: %f\n", LineTime);
+ dml_print("DML: Tsetup: %f\n", Tsetup);
+ dml_print("DML: Tdm: %f\n", Tdm);
+ dml_print("DML: DSTYAfterScaler: %f\n", *DSTYAfterScaler);
+ dml_print("DML: DSTXAfterScaler: %f\n", *DSTXAfterScaler);
+ dml_print("DML: HTotal: %d\n", HTotal);
+
+ *PrefetchBandwidth = 0;
+ *DestinationLinesToRequestVMInVBlank = 0;
+ *DestinationLinesToRequestRowInVBlank = 0;
+ *VRatioPrefetchY = 0;
+ *VRatioPrefetchC = 0;
+ *RequiredPrefetchPixDataBW = 0;
+ if (*DestinationLinesForPrefetch > 1) {
+ *PrefetchBandwidth = (PDEAndMetaPTEBytesFrame + 2 * MetaRowByte
+ + 2 * PixelPTEBytesPerRow
+ + PrefetchSourceLinesY * SwathWidthY * dml_ceil(BytePerPixelDETY, 1)
+ + PrefetchSourceLinesC * SwathWidthY / 2
+ * dml_ceil(BytePerPixelDETC, 2))
+ / (*DestinationLinesForPrefetch * LineTime - *Tno_bw);
+ if (VirtualMemoryEnable) {
+ TimeForFetchingMetaPTE =
+ dml_max(
+ *Tno_bw
+ + (double) PDEAndMetaPTEBytesFrame
+ / *PrefetchBandwidth,
+ dml_max(
+ UrgentExtraLatency
+ + UrgentLatency
+ * (PageTableLevels
+ - 1),
+ LineTime / 4));
+ } else {
+ if (NumberOfCursors > 0 || XFCEnabled)
+ TimeForFetchingMetaPTE = LineTime / 4;
+ else
+ TimeForFetchingMetaPTE = 0.0;
+ }
+
+ if ((VirtualMemoryEnable == true || DCCEnable == true)) {
+ TimeForFetchingRowInVBlank =
+ dml_max(
+ (MetaRowByte + PixelPTEBytesPerRow)
+ / *PrefetchBandwidth,
+ dml_max(
+ UrgentLatency,
+ dml_max(
+ LineTime
+ - TimeForFetchingMetaPTE,
+ LineTime
+ / 4.0)));
+ } else {
+ if (NumberOfCursors > 0 || XFCEnabled)
+ TimeForFetchingRowInVBlank = LineTime - TimeForFetchingMetaPTE;
+ else
+ TimeForFetchingRowInVBlank = 0.0;
+ }
+
+ *DestinationLinesToRequestVMInVBlank = dml_floor(
+ 4.0 * (TimeForFetchingMetaPTE / LineTime + 0.125),
+ 1) / 4.0;
+
+ *DestinationLinesToRequestRowInVBlank = dml_floor(
+ 4.0 * (TimeForFetchingRowInVBlank / LineTime + 0.125),
+ 1) / 4.0;
+
+ LinesToRequestPrefetchPixelData =
+ *DestinationLinesForPrefetch
+ - ((NumberOfCursors > 0 || VirtualMemoryEnable
+ || DCCEnable) ?
+ (*DestinationLinesToRequestVMInVBlank
+ + *DestinationLinesToRequestRowInVBlank) :
+ 0.0);
+
+ if (LinesToRequestPrefetchPixelData > 0) {
+
+ *VRatioPrefetchY = (double) PrefetchSourceLinesY
+ / LinesToRequestPrefetchPixelData;
+ *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
+ if ((SwathHeightY > 4) && (VInitPreFillY > 3)) {
+ if (LinesToRequestPrefetchPixelData > (VInitPreFillY - 3.0) / 2.0) {
+ *VRatioPrefetchY =
+ dml_max(
+ (double) PrefetchSourceLinesY
+ / LinesToRequestPrefetchPixelData,
+ (double) MaxNumSwathY
+ * SwathHeightY
+ / (LinesToRequestPrefetchPixelData
+ - (VInitPreFillY
+ - 3.0)
+ / 2.0));
+ *VRatioPrefetchY = dml_max(*VRatioPrefetchY, 1.0);
+ } else {
+ MyError = true;
+ *VRatioPrefetchY = 0;
+ }
+ }
+
+ *VRatioPrefetchC = (double) PrefetchSourceLinesC
+ / LinesToRequestPrefetchPixelData;
+ *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
+
+ if ((SwathHeightC > 4)) {
+ if (LinesToRequestPrefetchPixelData > (VInitPreFillC - 3.0) / 2.0) {
+ *VRatioPrefetchC =
+ dml_max(
+ *VRatioPrefetchC,
+ (double) MaxNumSwathC
+ * SwathHeightC
+ / (LinesToRequestPrefetchPixelData
+ - (VInitPreFillC
+ - 3.0)
+ / 2.0));
+ *VRatioPrefetchC = dml_max(*VRatioPrefetchC, 1.0);
+ } else {
+ MyError = true;
+ *VRatioPrefetchC = 0;
+ }
+ }
+
+ *RequiredPrefetchPixDataBW =
+ DPPPerPlane
+ * ((double) PrefetchSourceLinesY
+ / LinesToRequestPrefetchPixelData
+ * dml_ceil(
+ BytePerPixelDETY,
+ 1)
+ + (double) PrefetchSourceLinesC
+ / LinesToRequestPrefetchPixelData
+ * dml_ceil(
+ BytePerPixelDETC,
+ 2)
+ / 2)
+ * SwathWidthY / LineTime;
+ } else {
+ MyError = true;
+ *VRatioPrefetchY = 0;
+ *VRatioPrefetchC = 0;
+ *RequiredPrefetchPixDataBW = 0;
+ }
+
+ } else {
+ MyError = true;
+ }
+
+ if (MyError) {
+ *PrefetchBandwidth = 0;
+ TimeForFetchingMetaPTE = 0;
+ TimeForFetchingRowInVBlank = 0;
+ *DestinationLinesToRequestVMInVBlank = 0;
+ *DestinationLinesToRequestRowInVBlank = 0;
+ *DestinationLinesForPrefetch = 0;
+ LinesToRequestPrefetchPixelData = 0;
+ *VRatioPrefetchY = 0;
+ *VRatioPrefetchC = 0;
+ *RequiredPrefetchPixDataBW = 0;
+ }
+
+ return MyError;
+}
+
+static double RoundToDFSGranularityUp(double Clock, double VCOSpeed)
+{
+ return VCOSpeed * 4 / dml_floor(VCOSpeed * 4 / Clock, 1);
+}
+
+static double RoundToDFSGranularityDown(double Clock, double VCOSpeed)
+{
+ return VCOSpeed * 4 / dml_ceil(VCOSpeed * 4 / Clock, 1);
+}
+
+static double CalculatePrefetchSourceLines(
+ struct display_mode_lib *mode_lib,
+ double VRatio,
+ double vtaps,
+ bool Interlace,
+ bool ProgressiveToInterlaceUnitInOPP,
+ unsigned int SwathHeight,
+ unsigned int ViewportYStart,
+ double *VInitPreFill,
+ unsigned int *MaxNumSwath)
+{
+ unsigned int MaxPartialSwath;
+
+ if (ProgressiveToInterlaceUnitInOPP)
+ *VInitPreFill = dml_floor((VRatio + vtaps + 1) / 2.0, 1);
+ else
+ *VInitPreFill = dml_floor((VRatio + vtaps + 1 + Interlace * 0.5 * VRatio) / 2.0, 1);
+
+ if (!mode_lib->vba.IgnoreViewportPositioning) {
+
+ *MaxNumSwath = dml_ceil((*VInitPreFill - 1.0) / SwathHeight, 1) + 1.0;
+
+ if (*VInitPreFill > 1.0)
+ MaxPartialSwath = (unsigned int) (*VInitPreFill - 2) % SwathHeight;
+ else
+ MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 2)
+ % SwathHeight;
+ MaxPartialSwath = dml_max(1U, MaxPartialSwath);
+
+ } else {
+
+ if (ViewportYStart != 0)
+ dml_print(
+ "WARNING DML: using viewport y position of 0 even though actual viewport y position is non-zero in prefetch source lines calculation\n");
+
+ *MaxNumSwath = dml_ceil(*VInitPreFill / SwathHeight, 1);
+
+ if (*VInitPreFill > 1.0)
+ MaxPartialSwath = (unsigned int) (*VInitPreFill - 1) % SwathHeight;
+ else
+ MaxPartialSwath = (unsigned int) (*VInitPreFill + SwathHeight - 1)
+ % SwathHeight;
+ }
+
+ return *MaxNumSwath * SwathHeight + MaxPartialSwath;
+}
+
+static unsigned int CalculateVMAndRowBytes(
+ struct display_mode_lib *mode_lib,
+ bool DCCEnable,
+ unsigned int BlockHeight256Bytes,
+ unsigned int BlockWidth256Bytes,
+ enum source_format_class SourcePixelFormat,
+ unsigned int SurfaceTiling,
+ unsigned int BytePerPixel,
+ enum scan_direction_class ScanDirection,
+ unsigned int ViewportWidth,
+ unsigned int ViewportHeight,
+ unsigned int SwathWidth,
+ bool VirtualMemoryEnable,
+ unsigned int VMMPageSize,
+ unsigned int PTEBufferSizeInRequests,
+ unsigned int PDEProcessingBufIn64KBReqs,
+ unsigned int Pitch,
+ unsigned int DCCMetaPitch,
+ unsigned int *MacroTileWidth,
+ unsigned int *MetaRowByte,
+ unsigned int *PixelPTEBytesPerRow,
+ bool *PTEBufferSizeNotExceeded,
+ unsigned int *dpte_row_height,
+ unsigned int *meta_row_height)
+{
+ unsigned int MetaRequestHeight;
+ unsigned int MetaRequestWidth;
+ unsigned int MetaSurfWidth;
+ unsigned int MetaSurfHeight;
+ unsigned int MPDEBytesFrame;
+ unsigned int MetaPTEBytesFrame;
+ unsigned int DCCMetaSurfaceBytes;
+
+ unsigned int MacroTileSizeBytes;
+ unsigned int MacroTileHeight;
+ unsigned int DPDE0BytesFrame;
+ unsigned int ExtraDPDEBytesFrame;
+ unsigned int PDEAndMetaPTEBytesFrame;
+
+ if (DCCEnable == true) {
+ MetaRequestHeight = 8 * BlockHeight256Bytes;
+ MetaRequestWidth = 8 * BlockWidth256Bytes;
+ if (ScanDirection == dm_horz) {
+ *meta_row_height = MetaRequestHeight;
+ MetaSurfWidth = dml_ceil((double) SwathWidth - 1, MetaRequestWidth)
+ + MetaRequestWidth;
+ *MetaRowByte = MetaSurfWidth * MetaRequestHeight * BytePerPixel / 256.0;
+ } else {
+ *meta_row_height = MetaRequestWidth;
+ MetaSurfHeight = dml_ceil((double) SwathWidth - 1, MetaRequestHeight)
+ + MetaRequestHeight;
+ *MetaRowByte = MetaSurfHeight * MetaRequestWidth * BytePerPixel / 256.0;
+ }
+ if (ScanDirection == dm_horz) {
+ DCCMetaSurfaceBytes = DCCMetaPitch
+ * (dml_ceil(ViewportHeight - 1, 64 * BlockHeight256Bytes)
+ + 64 * BlockHeight256Bytes) * BytePerPixel
+ / 256;
+ } else {
+ DCCMetaSurfaceBytes = DCCMetaPitch
+ * (dml_ceil(
+ (double) ViewportHeight - 1,
+ 64 * BlockHeight256Bytes)
+ + 64 * BlockHeight256Bytes) * BytePerPixel
+ / 256;
+ }
+ if (VirtualMemoryEnable == true) {
+ MetaPTEBytesFrame = (dml_ceil(
+ (double) (DCCMetaSurfaceBytes - VMMPageSize)
+ / (8 * VMMPageSize),
+ 1) + 1) * 64;
+ MPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 1);
+ } else {
+ MetaPTEBytesFrame = 0;
+ MPDEBytesFrame = 0;
+ }
+ } else {
+ MetaPTEBytesFrame = 0;
+ MPDEBytesFrame = 0;
+ *MetaRowByte = 0;
+ }
+
+ if (SurfaceTiling == dm_sw_linear) {
+ MacroTileSizeBytes = 256;
+ MacroTileHeight = 1;
+ } else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
+ || SurfaceTiling == dm_sw_4kb_d || SurfaceTiling == dm_sw_4kb_d_x) {
+ MacroTileSizeBytes = 4096;
+ MacroTileHeight = 4 * BlockHeight256Bytes;
+ } else if (SurfaceTiling == dm_sw_64kb_s || SurfaceTiling == dm_sw_64kb_s_t
+ || SurfaceTiling == dm_sw_64kb_s_x || SurfaceTiling == dm_sw_64kb_d
+ || SurfaceTiling == dm_sw_64kb_d_t || SurfaceTiling == dm_sw_64kb_d_x
+ || SurfaceTiling == dm_sw_64kb_r_x) {
+ MacroTileSizeBytes = 65536;
+ MacroTileHeight = 16 * BlockHeight256Bytes;
+ } else {
+ MacroTileSizeBytes = 262144;
+ MacroTileHeight = 32 * BlockHeight256Bytes;
+ }
+ *MacroTileWidth = MacroTileSizeBytes / BytePerPixel / MacroTileHeight;
+
+ if (VirtualMemoryEnable == true && mode_lib->vba.MaxPageTableLevels > 1) {
+ if (ScanDirection == dm_horz) {
+ DPDE0BytesFrame =
+ 64
+ * (dml_ceil(
+ ((Pitch
+ * (dml_ceil(
+ ViewportHeight
+ - 1,
+ MacroTileHeight)
+ + MacroTileHeight)
+ * BytePerPixel)
+ - MacroTileSizeBytes)
+ / (8
+ * 2097152),
+ 1) + 1);
+ } else {
+ DPDE0BytesFrame =
+ 64
+ * (dml_ceil(
+ ((Pitch
+ * (dml_ceil(
+ (double) SwathWidth
+ - 1,
+ MacroTileHeight)
+ + MacroTileHeight)
+ * BytePerPixel)
+ - MacroTileSizeBytes)
+ / (8
+ * 2097152),
+ 1) + 1);
+ }
+ ExtraDPDEBytesFrame = 128 * (mode_lib->vba.MaxPageTableLevels - 2);
+ } else {
+ DPDE0BytesFrame = 0;
+ ExtraDPDEBytesFrame = 0;
+ }
+
+ PDEAndMetaPTEBytesFrame = MetaPTEBytesFrame + MPDEBytesFrame + DPDE0BytesFrame
+ + ExtraDPDEBytesFrame;
+
+ if (VirtualMemoryEnable == true) {
+ unsigned int PTERequestSize;
+ unsigned int PixelPTEReqHeight;
+ unsigned int PixelPTEReqWidth;
+ double FractionOfPTEReturnDrop;
+ unsigned int EffectivePDEProcessingBufIn64KBReqs;
+
+ if (SurfaceTiling == dm_sw_linear) {
+ PixelPTEReqHeight = 1;
+ PixelPTEReqWidth = 8.0 * VMMPageSize / BytePerPixel;
+ PTERequestSize = 64;
+ FractionOfPTEReturnDrop = 0;
+ } else if (MacroTileSizeBytes == 4096) {
+ PixelPTEReqHeight = MacroTileHeight;
+ PixelPTEReqWidth = 8 * *MacroTileWidth;
+ PTERequestSize = 64;
+ if (ScanDirection == dm_horz)
+ FractionOfPTEReturnDrop = 0;
+ else
+ FractionOfPTEReturnDrop = 7 / 8;
+ } else if (VMMPageSize == 4096 && MacroTileSizeBytes > 4096) {
+ PixelPTEReqHeight = 16 * BlockHeight256Bytes;
+ PixelPTEReqWidth = 16 * BlockWidth256Bytes;
+ PTERequestSize = 128;
+ FractionOfPTEReturnDrop = 0;
+ } else {
+ PixelPTEReqHeight = MacroTileHeight;
+ PixelPTEReqWidth = 8 * *MacroTileWidth;
+ PTERequestSize = 64;
+ FractionOfPTEReturnDrop = 0;
+ }
+
+ if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)
+ EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs / 2;
+ else
+ EffectivePDEProcessingBufIn64KBReqs = PDEProcessingBufIn64KBReqs;
+
+ if (SurfaceTiling == dm_sw_linear) {
+ *dpte_row_height =
+ dml_min(
+ 128,
+ 1
+ << (unsigned int) dml_floor(
+ dml_log2(
+ dml_min(
+ (double) PTEBufferSizeInRequests
+ * PixelPTEReqWidth,
+ EffectivePDEProcessingBufIn64KBReqs
+ * 65536.0
+ / BytePerPixel)
+ / Pitch),
+ 1));
+ *PixelPTEBytesPerRow = PTERequestSize
+ * (dml_ceil(
+ (double) (Pitch * *dpte_row_height - 1)
+ / PixelPTEReqWidth,
+ 1) + 1);
+ } else if (ScanDirection == dm_horz) {
+ *dpte_row_height = PixelPTEReqHeight;
+ *PixelPTEBytesPerRow = PTERequestSize
+ * (dml_ceil(((double) SwathWidth - 1) / PixelPTEReqWidth, 1)
+ + 1);
+ } else {
+ *dpte_row_height = dml_min(PixelPTEReqWidth, *MacroTileWidth);
+ *PixelPTEBytesPerRow = PTERequestSize
+ * (dml_ceil(
+ ((double) SwathWidth - 1)
+ / PixelPTEReqHeight,
+ 1) + 1);
+ }
+ if (*PixelPTEBytesPerRow * (1 - FractionOfPTEReturnDrop)
+ <= 64 * PTEBufferSizeInRequests) {
+ *PTEBufferSizeNotExceeded = true;
+ } else {
+ *PTEBufferSizeNotExceeded = false;
+ }
+ } else {
+ *PixelPTEBytesPerRow = 0;
+ *PTEBufferSizeNotExceeded = true;
+ }
+
+ return PDEAndMetaPTEBytesFrame;
+}
+
+static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
+ struct display_mode_lib *mode_lib)
+{
+ unsigned int j, k;
+
+ mode_lib->vba.WritebackDISPCLK = 0.0;
+ mode_lib->vba.DISPCLKWithRamping = 0;
+ mode_lib->vba.DISPCLKWithoutRamping = 0;
+ mode_lib->vba.GlobalDPPCLK = 0.0;
+
+ // dml_ml->vba.DISPCLK and dml_ml->vba.DPPCLK Calculation
+ //
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.WritebackEnable[k]) {
+ mode_lib->vba.WritebackDISPCLK =
+ dml_max(
+ mode_lib->vba.WritebackDISPCLK,
+ CalculateWriteBackDISPCLK(
+ mode_lib->vba.WritebackPixelFormat[k],
+ mode_lib->vba.PixelClock[k],
+ mode_lib->vba.WritebackHRatio[k],
+ mode_lib->vba.WritebackVRatio[k],
+ mode_lib->vba.WritebackLumaHTaps[k],
+ mode_lib->vba.WritebackLumaVTaps[k],
+ mode_lib->vba.WritebackChromaHTaps[k],
+ mode_lib->vba.WritebackChromaVTaps[k],
+ mode_lib->vba.WritebackDestinationWidth[k],
+ mode_lib->vba.HTotal[k],
+ mode_lib->vba.WritebackChromaLineBufferWidth));
+ }
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.HRatio[k] > 1) {
+ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput
+ * mode_lib->vba.HRatio[k]
+ / dml_ceil(
+ mode_lib->vba.htaps[k]
+ / 6.0,
+ 1));
+ } else {
+ mode_lib->vba.PSCL_THROUGHPUT_LUMA[k] = dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput);
+ }
+
+ mode_lib->vba.DPPCLKUsingSingleDPPLuma =
+ mode_lib->vba.PixelClock[k]
+ * dml_max(
+ mode_lib->vba.vtaps[k] / 6.0
+ * dml_min(
+ 1.0,
+ mode_lib->vba.HRatio[k]),
+ dml_max(
+ mode_lib->vba.HRatio[k]
+ * mode_lib->vba.VRatio[k]
+ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k],
+ 1.0));
+
+ if ((mode_lib->vba.htaps[k] > 6 || mode_lib->vba.vtaps[k] > 6)
+ && mode_lib->vba.DPPCLKUsingSingleDPPLuma
+ < 2 * mode_lib->vba.PixelClock[k]) {
+ mode_lib->vba.DPPCLKUsingSingleDPPLuma = 2 * mode_lib->vba.PixelClock[k];
+ }
+
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = 0.0;
+ mode_lib->vba.DPPCLKUsingSingleDPP[k] =
+ mode_lib->vba.DPPCLKUsingSingleDPPLuma;
+ } else {
+ if (mode_lib->vba.HRatio[k] > 1) {
+ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] =
+ dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput
+ * mode_lib->vba.HRatio[k]
+ / 2
+ / dml_ceil(
+ mode_lib->vba.HTAPsChroma[k]
+ / 6.0,
+ 1.0));
+ } else {
+ mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k] = dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput);
+ }
+ mode_lib->vba.DPPCLKUsingSingleDPPChroma =
+ mode_lib->vba.PixelClock[k]
+ * dml_max(
+ mode_lib->vba.VTAPsChroma[k]
+ / 6.0
+ * dml_min(
+ 1.0,
+ mode_lib->vba.HRatio[k]
+ / 2),
+ dml_max(
+ mode_lib->vba.HRatio[k]
+ * mode_lib->vba.VRatio[k]
+ / 4
+ / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k],
+ 1.0));
+
+ if ((mode_lib->vba.HTAPsChroma[k] > 6 || mode_lib->vba.VTAPsChroma[k] > 6)
+ && mode_lib->vba.DPPCLKUsingSingleDPPChroma
+ < 2 * mode_lib->vba.PixelClock[k]) {
+ mode_lib->vba.DPPCLKUsingSingleDPPChroma = 2
+ * mode_lib->vba.PixelClock[k];
+ }
+
+ mode_lib->vba.DPPCLKUsingSingleDPP[k] = dml_max(
+ mode_lib->vba.DPPCLKUsingSingleDPPLuma,
+ mode_lib->vba.DPPCLKUsingSingleDPPChroma);
+ }
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.BlendingAndTiming[k] != k)
+ continue;
+ if (mode_lib->vba.ODMCombineEnabled[k]) {
+ mode_lib->vba.DISPCLKWithRamping =
+ dml_max(
+ mode_lib->vba.DISPCLKWithRamping,
+ mode_lib->vba.PixelClock[k] / 2
+ * (1
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100)
+ * (1
+ + mode_lib->vba.DISPCLKRampingMargin
+ / 100));
+ mode_lib->vba.DISPCLKWithoutRamping =
+ dml_max(
+ mode_lib->vba.DISPCLKWithoutRamping,
+ mode_lib->vba.PixelClock[k] / 2
+ * (1
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100));
+ } else if (!mode_lib->vba.ODMCombineEnabled[k]) {
+ mode_lib->vba.DISPCLKWithRamping =
+ dml_max(
+ mode_lib->vba.DISPCLKWithRamping,
+ mode_lib->vba.PixelClock[k]
+ * (1
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100)
+ * (1
+ + mode_lib->vba.DISPCLKRampingMargin
+ / 100));
+ mode_lib->vba.DISPCLKWithoutRamping =
+ dml_max(
+ mode_lib->vba.DISPCLKWithoutRamping,
+ mode_lib->vba.PixelClock[k]
+ * (1
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100));
+ }
+ }
+
+ mode_lib->vba.DISPCLKWithRamping = dml_max(
+ mode_lib->vba.DISPCLKWithRamping,
+ mode_lib->vba.WritebackDISPCLK);
+ mode_lib->vba.DISPCLKWithoutRamping = dml_max(
+ mode_lib->vba.DISPCLKWithoutRamping,
+ mode_lib->vba.WritebackDISPCLK);
+
+ ASSERT(mode_lib->vba.DISPCLKDPPCLKVCOSpeed != 0);
+ mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
+ mode_lib->vba.DISPCLKWithRamping,
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+ mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity = RoundToDFSGranularityUp(
+ mode_lib->vba.DISPCLKWithoutRamping,
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+ mode_lib->vba.MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown(
+ mode_lib->vba.soc.clock_limits[NumberOfStates - 1].dispclk_mhz,
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+ if (mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity
+ > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
+ mode_lib->vba.DISPCLK_calculated =
+ mode_lib->vba.DISPCLKWithoutRampingRoundedToDFSGranularity;
+ } else if (mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity
+ > mode_lib->vba.MaxDispclkRoundedToDFSGranularity) {
+ mode_lib->vba.DISPCLK_calculated = mode_lib->vba.MaxDispclkRoundedToDFSGranularity;
+ } else {
+ mode_lib->vba.DISPCLK_calculated =
+ mode_lib->vba.DISPCLKWithRampingRoundedToDFSGranularity;
+ }
+ DTRACE(" dispclk_mhz (calculated) = %f", mode_lib->vba.DISPCLK_calculated);
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.DPPCLKUsingSingleDPP[k]
+ / mode_lib->vba.DPPPerPlane[k]
+ * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100);
+ mode_lib->vba.GlobalDPPCLK = dml_max(
+ mode_lib->vba.GlobalDPPCLK,
+ mode_lib->vba.DPPCLK_calculated[k]);
+ }
+ mode_lib->vba.GlobalDPPCLK = RoundToDFSGranularityUp(
+ mode_lib->vba.GlobalDPPCLK,
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.DPPCLK_calculated[k] = mode_lib->vba.GlobalDPPCLK / 255
+ * dml_ceil(
+ mode_lib->vba.DPPCLK_calculated[k] * 255
+ / mode_lib->vba.GlobalDPPCLK,
+ 1);
+ DTRACE(" dppclk_mhz[%i] (calculated) = %f", k, mode_lib->vba.DPPCLK_calculated[k]);
+ }
+
+ // Urgent Watermark
+ mode_lib->vba.DCCEnabledAnyPlane = false;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+ if (mode_lib->vba.DCCEnable[k])
+ mode_lib->vba.DCCEnabledAnyPlane = true;
+
+ mode_lib->vba.ReturnBandwidthToDCN = dml_min(
+ mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
+ mode_lib->vba.FabricAndDRAMBandwidth * 1000)
+ * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency / 100;
+
+ mode_lib->vba.ReturnBW = mode_lib->vba.ReturnBandwidthToDCN;
+ mode_lib->vba.ReturnBW = adjust_ReturnBW(
+ mode_lib,
+ mode_lib->vba.ReturnBW,
+ mode_lib->vba.DCCEnabledAnyPlane,
+ mode_lib->vba.ReturnBandwidthToDCN);
+
+ // Let's do this calculation again??
+ mode_lib->vba.ReturnBandwidthToDCN = dml_min(
+ mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLK,
+ mode_lib->vba.FabricAndDRAMBandwidth * 1000);
+ mode_lib->vba.ReturnBW = adjust_ReturnBW(
+ mode_lib,
+ mode_lib->vba.ReturnBW,
+ mode_lib->vba.DCCEnabledAnyPlane,
+ mode_lib->vba.ReturnBandwidthToDCN);
+
+ DTRACE(" dcfclk_mhz = %f", mode_lib->vba.DCFCLK);
+ DTRACE(" return_bw_to_dcn = %f", mode_lib->vba.ReturnBandwidthToDCN);
+ DTRACE(" return_bus_bw = %f", mode_lib->vba.ReturnBW);
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ bool MainPlaneDoesODMCombine = false;
+
+ if (mode_lib->vba.SourceScan[k] == dm_horz)
+ mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportWidth[k];
+ else
+ mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
+
+ if (mode_lib->vba.ODMCombineEnabled[k] == true)
+ MainPlaneDoesODMCombine = true;
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+ if (mode_lib->vba.BlendingAndTiming[k] == j
+ && mode_lib->vba.ODMCombineEnabled[j] == true)
+ MainPlaneDoesODMCombine = true;
+
+ if (MainPlaneDoesODMCombine == true)
+ mode_lib->vba.SwathWidthY[k] = dml_min(
+ (double) mode_lib->vba.SwathWidthSingleDPPY[k],
+ dml_round(
+ mode_lib->vba.HActive[k] / 2.0
+ * mode_lib->vba.HRatio[k]));
+ else
+ mode_lib->vba.SwathWidthY[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+ / mode_lib->vba.DPPPerPlane[k];
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+ mode_lib->vba.BytePerPixelDETY[k] = 8;
+ mode_lib->vba.BytePerPixelDETC[k] = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+ mode_lib->vba.BytePerPixelDETY[k] = 4;
+ mode_lib->vba.BytePerPixelDETC[k] = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+ mode_lib->vba.BytePerPixelDETY[k] = 2;
+ mode_lib->vba.BytePerPixelDETC[k] = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
+ mode_lib->vba.BytePerPixelDETY[k] = 1;
+ mode_lib->vba.BytePerPixelDETC[k] = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+ mode_lib->vba.BytePerPixelDETY[k] = 1;
+ mode_lib->vba.BytePerPixelDETC[k] = 2;
+ } else { // dm_420_10
+ mode_lib->vba.BytePerPixelDETY[k] = 4.0 / 3.0;
+ mode_lib->vba.BytePerPixelDETC[k] = 8.0 / 3.0;
+ }
+ }
+
+ mode_lib->vba.TotalDataReadBandwidth = 0.0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.ReadBandwidthPlaneLuma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
+ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ * mode_lib->vba.VRatio[k];
+ mode_lib->vba.ReadBandwidthPlaneChroma[k] = mode_lib->vba.SwathWidthSingleDPPY[k]
+ / 2 * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
+ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ * mode_lib->vba.VRatio[k] / 2;
+ DTRACE(
+ " read_bw[%i] = %fBps",
+ k,
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k]);
+ mode_lib->vba.TotalDataReadBandwidth += mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k];
+ }
+
+ mode_lib->vba.TotalDCCActiveDPP = 0;
+ mode_lib->vba.TotalActiveDPP = 0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.TotalActiveDPP = mode_lib->vba.TotalActiveDPP
+ + mode_lib->vba.DPPPerPlane[k];
+ if (mode_lib->vba.DCCEnable[k])
+ mode_lib->vba.TotalDCCActiveDPP = mode_lib->vba.TotalDCCActiveDPP
+ + mode_lib->vba.DPPPerPlane[k];
+ }
+
+ mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency =
+ (mode_lib->vba.RoundTripPingLatencyCycles + 32) / mode_lib->vba.DCFCLK
+ + mode_lib->vba.UrgentOutOfOrderReturnPerChannel
+ * mode_lib->vba.NumberOfChannels
+ / mode_lib->vba.ReturnBW;
+
+ mode_lib->vba.LastPixelOfLineExtraWatermark = 0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ double DataFabricLineDeliveryTimeLuma, DataFabricLineDeliveryTimeChroma;
+
+ if (mode_lib->vba.VRatio[k] <= 1.0)
+ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
+ (double) mode_lib->vba.SwathWidthY[k]
+ * mode_lib->vba.DPPPerPlane[k]
+ / mode_lib->vba.HRatio[k]
+ / mode_lib->vba.PixelClock[k];
+ else
+ mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k] =
+ (double) mode_lib->vba.SwathWidthY[k]
+ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+ / mode_lib->vba.DPPCLK[k];
+
+ DataFabricLineDeliveryTimeLuma = mode_lib->vba.SwathWidthSingleDPPY[k]
+ * mode_lib->vba.SwathHeightY[k]
+ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1)
+ / (mode_lib->vba.ReturnBW * mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ / mode_lib->vba.TotalDataReadBandwidth);
+ mode_lib->vba.LastPixelOfLineExtraWatermark = dml_max(
+ mode_lib->vba.LastPixelOfLineExtraWatermark,
+ DataFabricLineDeliveryTimeLuma
+ - mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k]);
+
+ if (mode_lib->vba.BytePerPixelDETC[k] == 0)
+ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] = 0.0;
+ else if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0)
+ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
+ mode_lib->vba.SwathWidthY[k] / 2.0
+ * mode_lib->vba.DPPPerPlane[k]
+ / (mode_lib->vba.HRatio[k] / 2.0)
+ / mode_lib->vba.PixelClock[k];
+ else
+ mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k] =
+ mode_lib->vba.SwathWidthY[k] / 2.0
+ / mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
+ / mode_lib->vba.DPPCLK[k];
+
+ DataFabricLineDeliveryTimeChroma = mode_lib->vba.SwathWidthSingleDPPY[k] / 2.0
+ * mode_lib->vba.SwathHeightC[k]
+ * dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2)
+ / (mode_lib->vba.ReturnBW
+ * mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ / mode_lib->vba.TotalDataReadBandwidth);
+ mode_lib->vba.LastPixelOfLineExtraWatermark =
+ dml_max(
+ mode_lib->vba.LastPixelOfLineExtraWatermark,
+ DataFabricLineDeliveryTimeChroma
+ - mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
+ }
+
+ mode_lib->vba.UrgentExtraLatency = mode_lib->vba.UrgentRoundTripAndOutOfOrderLatency
+ + (mode_lib->vba.TotalActiveDPP * mode_lib->vba.PixelChunkSizeInKByte
+ + mode_lib->vba.TotalDCCActiveDPP
+ * mode_lib->vba.MetaChunkSize) * 1024.0
+ / mode_lib->vba.ReturnBW;
+
+ if (mode_lib->vba.VirtualMemoryEnable)
+ mode_lib->vba.UrgentExtraLatency += mode_lib->vba.TotalActiveDPP
+ * mode_lib->vba.PTEChunkSize * 1024.0 / mode_lib->vba.ReturnBW;
+
+ mode_lib->vba.UrgentWatermark = mode_lib->vba.UrgentLatency
+ + mode_lib->vba.LastPixelOfLineExtraWatermark
+ + mode_lib->vba.UrgentExtraLatency;
+
+ DTRACE(" urgent_extra_latency = %fus", mode_lib->vba.UrgentExtraLatency);
+ DTRACE(" wm_urgent = %fus", mode_lib->vba.UrgentWatermark);
+
+ mode_lib->vba.MemoryTripWatermark = mode_lib->vba.UrgentLatency;
+
+ mode_lib->vba.TotalActiveWriteback = 0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.WritebackEnable[k])
+ mode_lib->vba.TotalActiveWriteback = mode_lib->vba.TotalActiveWriteback + 1;
+ }
+
+ if (mode_lib->vba.TotalActiveWriteback <= 1)
+ mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency;
+ else
+ mode_lib->vba.WritebackUrgentWatermark = mode_lib->vba.WritebackLatency
+ + mode_lib->vba.WritebackChunkSize * 1024.0 / 32
+ / mode_lib->vba.SOCCLK;
+
+ DTRACE(" wm_wb_urgent = %fus", mode_lib->vba.WritebackUrgentWatermark);
+
+ // NB P-State/DRAM Clock Change Watermark
+ mode_lib->vba.DRAMClockChangeWatermark = mode_lib->vba.DRAMClockChangeLatency
+ + mode_lib->vba.UrgentWatermark;
+
+ DTRACE(" wm_pstate_change = %fus", mode_lib->vba.DRAMClockChangeWatermark);
+
+ DTRACE(" calculating wb pstate watermark");
+ DTRACE(" total wb outputs %d", mode_lib->vba.TotalActiveWriteback);
+ DTRACE(" socclk frequency %f Mhz", mode_lib->vba.SOCCLK);
+
+ if (mode_lib->vba.TotalActiveWriteback <= 1)
+ mode_lib->vba.WritebackDRAMClockChangeWatermark =
+ mode_lib->vba.DRAMClockChangeLatency
+ + mode_lib->vba.WritebackLatency;
+ else
+ mode_lib->vba.WritebackDRAMClockChangeWatermark =
+ mode_lib->vba.DRAMClockChangeLatency
+ + mode_lib->vba.WritebackLatency
+ + mode_lib->vba.WritebackChunkSize * 1024.0 / 32
+ / mode_lib->vba.SOCCLK;
+
+ DTRACE(" wm_wb_pstate %fus", mode_lib->vba.WritebackDRAMClockChangeWatermark);
+
+ // Stutter Efficiency
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.LinesInDETY[k] = mode_lib->vba.DETBufferSizeY[k]
+ / mode_lib->vba.BytePerPixelDETY[k] / mode_lib->vba.SwathWidthY[k];
+ mode_lib->vba.LinesInDETYRoundedDownToSwath[k] = dml_floor(
+ mode_lib->vba.LinesInDETY[k],
+ mode_lib->vba.SwathHeightY[k]);
+ mode_lib->vba.FullDETBufferingTimeY[k] =
+ mode_lib->vba.LinesInDETYRoundedDownToSwath[k]
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ / mode_lib->vba.VRatio[k];
+ if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+ mode_lib->vba.LinesInDETC[k] = mode_lib->vba.DETBufferSizeC[k]
+ / mode_lib->vba.BytePerPixelDETC[k]
+ / (mode_lib->vba.SwathWidthY[k] / 2);
+ mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = dml_floor(
+ mode_lib->vba.LinesInDETC[k],
+ mode_lib->vba.SwathHeightC[k]);
+ mode_lib->vba.FullDETBufferingTimeC[k] =
+ mode_lib->vba.LinesInDETCRoundedDownToSwath[k]
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ / (mode_lib->vba.VRatio[k] / 2);
+ } else {
+ mode_lib->vba.LinesInDETC[k] = 0;
+ mode_lib->vba.LinesInDETCRoundedDownToSwath[k] = 0;
+ mode_lib->vba.FullDETBufferingTimeC[k] = 999999;
+ }
+ }
+
+ mode_lib->vba.MinFullDETBufferingTime = 999999.0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.FullDETBufferingTimeY[k]
+ < mode_lib->vba.MinFullDETBufferingTime) {
+ mode_lib->vba.MinFullDETBufferingTime =
+ mode_lib->vba.FullDETBufferingTimeY[k];
+ mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
+ (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k];
+ }
+ if (mode_lib->vba.FullDETBufferingTimeC[k]
+ < mode_lib->vba.MinFullDETBufferingTime) {
+ mode_lib->vba.MinFullDETBufferingTime =
+ mode_lib->vba.FullDETBufferingTimeC[k];
+ mode_lib->vba.FrameTimeForMinFullDETBufferingTime =
+ (double) mode_lib->vba.VTotal[k] * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k];
+ }
+ }
+
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond = 0.0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.DCCEnable[k]) {
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ + mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ / mode_lib->vba.DCCRate[k]
+ / 1000
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ / mode_lib->vba.DCCRate[k]
+ / 1000;
+ } else {
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ + mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ / 1000
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ / 1000;
+ }
+ if (mode_lib->vba.DCCEnable[k]) {
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ + mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ / 1000 / 256
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ / 1000 / 256;
+ }
+ if (mode_lib->vba.VirtualMemoryEnable) {
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond =
+ mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ + mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ / 1000 / 512
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ / 1000 / 512;
+ }
+ }
+
+ mode_lib->vba.PartOfBurstThatFitsInROB =
+ dml_min(
+ mode_lib->vba.MinFullDETBufferingTime
+ * mode_lib->vba.TotalDataReadBandwidth,
+ mode_lib->vba.ROBBufferSizeInKByte * 1024
+ * mode_lib->vba.TotalDataReadBandwidth
+ / (mode_lib->vba.AverageReadBandwidthGBytePerSecond
+ * 1000));
+ mode_lib->vba.StutterBurstTime = mode_lib->vba.PartOfBurstThatFitsInROB
+ * (mode_lib->vba.AverageReadBandwidthGBytePerSecond * 1000)
+ / mode_lib->vba.TotalDataReadBandwidth / mode_lib->vba.ReturnBW
+ + (mode_lib->vba.MinFullDETBufferingTime
+ * mode_lib->vba.TotalDataReadBandwidth
+ - mode_lib->vba.PartOfBurstThatFitsInROB)
+ / (mode_lib->vba.DCFCLK * 64);
+ if (mode_lib->vba.TotalActiveWriteback == 0) {
+ mode_lib->vba.StutterEfficiencyNotIncludingVBlank = (1
+ - (mode_lib->vba.SRExitTime + mode_lib->vba.StutterBurstTime)
+ / mode_lib->vba.MinFullDETBufferingTime) * 100;
+ } else {
+ mode_lib->vba.StutterEfficiencyNotIncludingVBlank = 0;
+ }
+
+ mode_lib->vba.SmallestVBlank = 999999;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
+ mode_lib->vba.VBlankTime = (double) (mode_lib->vba.VTotal[k]
+ - mode_lib->vba.VActive[k]) * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k];
+ } else {
+ mode_lib->vba.VBlankTime = 0;
+ }
+ mode_lib->vba.SmallestVBlank = dml_min(
+ mode_lib->vba.SmallestVBlank,
+ mode_lib->vba.VBlankTime);
+ }
+
+ mode_lib->vba.StutterEfficiency = (mode_lib->vba.StutterEfficiencyNotIncludingVBlank / 100
+ * (mode_lib->vba.FrameTimeForMinFullDETBufferingTime
+ - mode_lib->vba.SmallestVBlank)
+ + mode_lib->vba.SmallestVBlank)
+ / mode_lib->vba.FrameTimeForMinFullDETBufferingTime * 100;
+
+ // dml_ml->vba.DCFCLK Deep Sleep
+ mode_lib->vba.DCFClkDeepSleep = 8.0;
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++) {
+ if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+ mode_lib->vba.DCFCLKDeepSleepPerPlane =
+ dml_max(
+ 1.1 * mode_lib->vba.SwathWidthY[k]
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelDETY[k],
+ 1) / 32
+ / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k],
+ 1.1 * mode_lib->vba.SwathWidthY[k] / 2.0
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelDETC[k],
+ 2) / 32
+ / mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k]);
+ } else
+ mode_lib->vba.DCFCLKDeepSleepPerPlane = 1.1 * mode_lib->vba.SwathWidthY[k]
+ * dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1) / 64.0
+ / mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k];
+ mode_lib->vba.DCFCLKDeepSleepPerPlane = dml_max(
+ mode_lib->vba.DCFCLKDeepSleepPerPlane,
+ mode_lib->vba.PixelClock[k] / 16.0);
+ mode_lib->vba.DCFClkDeepSleep = dml_max(
+ mode_lib->vba.DCFClkDeepSleep,
+ mode_lib->vba.DCFCLKDeepSleepPerPlane);
+
+ DTRACE(
+ " dcfclk_deepsleep_per_plane[%i] = %fMHz",
+ k,
+ mode_lib->vba.DCFCLKDeepSleepPerPlane);
+ }
+
+ DTRACE(" dcfclk_deepsleep_mhz = %fMHz", mode_lib->vba.DCFClkDeepSleep);
+
+ // Stutter Watermark
+ mode_lib->vba.StutterExitWatermark = mode_lib->vba.SRExitTime
+ + mode_lib->vba.LastPixelOfLineExtraWatermark
+ + mode_lib->vba.UrgentExtraLatency + 10 / mode_lib->vba.DCFClkDeepSleep;
+ mode_lib->vba.StutterEnterPlusExitWatermark = mode_lib->vba.SREnterPlusExitTime
+ + mode_lib->vba.LastPixelOfLineExtraWatermark
+ + mode_lib->vba.UrgentExtraLatency;
+
+ DTRACE(" wm_cstate_exit = %fus", mode_lib->vba.StutterExitWatermark);
+ DTRACE(" wm_cstate_enter_exit = %fus", mode_lib->vba.StutterEnterPlusExitWatermark);
+
+ // Urgent Latency Supported
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.EffectiveDETPlusLBLinesLuma =
+ dml_floor(
+ mode_lib->vba.LinesInDETY[k]
+ + dml_min(
+ mode_lib->vba.LinesInDETY[k]
+ * mode_lib->vba.DPPCLK[k]
+ * mode_lib->vba.BytePerPixelDETY[k]
+ * mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+ / (mode_lib->vba.ReturnBW
+ / mode_lib->vba.DPPPerPlane[k]),
+ (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
+ mode_lib->vba.SwathHeightY[k]);
+
+ mode_lib->vba.UrgentLatencySupportUsLuma = mode_lib->vba.EffectiveDETPlusLBLinesLuma
+ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ / mode_lib->vba.VRatio[k]
+ - mode_lib->vba.EffectiveDETPlusLBLinesLuma
+ * mode_lib->vba.SwathWidthY[k]
+ * mode_lib->vba.BytePerPixelDETY[k]
+ / (mode_lib->vba.ReturnBW
+ / mode_lib->vba.DPPPerPlane[k]);
+
+ if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+ mode_lib->vba.EffectiveDETPlusLBLinesChroma =
+ dml_floor(
+ mode_lib->vba.LinesInDETC[k]
+ + dml_min(
+ mode_lib->vba.LinesInDETC[k]
+ * mode_lib->vba.DPPCLK[k]
+ * mode_lib->vba.BytePerPixelDETC[k]
+ * mode_lib->vba.PSCL_THROUGHPUT_CHROMA[k]
+ / (mode_lib->vba.ReturnBW
+ / mode_lib->vba.DPPPerPlane[k]),
+ (double) mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
+ mode_lib->vba.SwathHeightC[k]);
+ mode_lib->vba.UrgentLatencySupportUsChroma =
+ mode_lib->vba.EffectiveDETPlusLBLinesChroma
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ / (mode_lib->vba.VRatio[k] / 2)
+ - mode_lib->vba.EffectiveDETPlusLBLinesChroma
+ * (mode_lib->vba.SwathWidthY[k]
+ / 2)
+ * mode_lib->vba.BytePerPixelDETC[k]
+ / (mode_lib->vba.ReturnBW
+ / mode_lib->vba.DPPPerPlane[k]);
+ mode_lib->vba.UrgentLatencySupportUs[k] = dml_min(
+ mode_lib->vba.UrgentLatencySupportUsLuma,
+ mode_lib->vba.UrgentLatencySupportUsChroma);
+ } else {
+ mode_lib->vba.UrgentLatencySupportUs[k] =
+ mode_lib->vba.UrgentLatencySupportUsLuma;
+ }
+ }
+
+ mode_lib->vba.MinUrgentLatencySupportUs = 999999;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.MinUrgentLatencySupportUs = dml_min(
+ mode_lib->vba.MinUrgentLatencySupportUs,
+ mode_lib->vba.UrgentLatencySupportUs[k]);
+ }
+
+ // Non-Urgent Latency Tolerance
+ mode_lib->vba.NonUrgentLatencyTolerance = mode_lib->vba.MinUrgentLatencySupportUs
+ - mode_lib->vba.UrgentWatermark;
+
+ // DSCCLK
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if ((mode_lib->vba.BlendingAndTiming[k] != k) || !mode_lib->vba.DSCEnabled[k]) {
+ mode_lib->vba.DSCCLK_calculated[k] = 0.0;
+ } else {
+ if (mode_lib->vba.OutputFormat[k] == dm_420
+ || mode_lib->vba.OutputFormat[k] == dm_n422)
+ mode_lib->vba.DSCFormatFactor = 2;
+ else
+ mode_lib->vba.DSCFormatFactor = 1;
+ if (mode_lib->vba.ODMCombineEnabled[k])
+ mode_lib->vba.DSCCLK_calculated[k] =
+ mode_lib->vba.PixelClockBackEnd[k] / 6
+ / mode_lib->vba.DSCFormatFactor
+ / (1
+ - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100);
+ else
+ mode_lib->vba.DSCCLK_calculated[k] =
+ mode_lib->vba.PixelClockBackEnd[k] / 3
+ / mode_lib->vba.DSCFormatFactor
+ / (1
+ - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100);
+ }
+ }
+
+ // DSC Delay
+ // TODO
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ double bpp = mode_lib->vba.OutputBpp[k];
+ unsigned int slices = mode_lib->vba.NumberOfDSCSlices[k];
+
+ if (mode_lib->vba.DSCEnabled[k] && bpp != 0) {
+ if (!mode_lib->vba.ODMCombineEnabled[k]) {
+ mode_lib->vba.DSCDelay[k] =
+ dscceComputeDelay(
+ mode_lib->vba.DSCInputBitPerComponent[k],
+ bpp,
+ dml_ceil(
+ (double) mode_lib->vba.HActive[k]
+ / mode_lib->vba.NumberOfDSCSlices[k],
+ 1),
+ slices,
+ mode_lib->vba.OutputFormat[k])
+ + dscComputeDelay(
+ mode_lib->vba.OutputFormat[k]);
+ } else {
+ mode_lib->vba.DSCDelay[k] =
+ 2
+ * (dscceComputeDelay(
+ mode_lib->vba.DSCInputBitPerComponent[k],
+ bpp,
+ dml_ceil(
+ (double) mode_lib->vba.HActive[k]
+ / mode_lib->vba.NumberOfDSCSlices[k],
+ 1),
+ slices / 2.0,
+ mode_lib->vba.OutputFormat[k])
+ + dscComputeDelay(
+ mode_lib->vba.OutputFormat[k]));
+ }
+ mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[k]
+ * mode_lib->vba.PixelClock[k]
+ / mode_lib->vba.PixelClockBackEnd[k];
+ } else {
+ mode_lib->vba.DSCDelay[k] = 0;
+ }
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) // NumberOfPlanes
+ if (j != k && mode_lib->vba.BlendingAndTiming[k] == j
+ && mode_lib->vba.DSCEnabled[j])
+ mode_lib->vba.DSCDelay[k] = mode_lib->vba.DSCDelay[j];
+
+ // Prefetch
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ unsigned int PDEAndMetaPTEBytesFrameY;
+ unsigned int PixelPTEBytesPerRowY;
+ unsigned int MetaRowByteY;
+ unsigned int MetaRowByteC;
+ unsigned int PDEAndMetaPTEBytesFrameC;
+ unsigned int PixelPTEBytesPerRowC;
+
+ Calculate256BBlockSizes(
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.SurfaceTiling[k],
+ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+ dml_ceil(mode_lib->vba.BytePerPixelDETC[k], 2),
+ &mode_lib->vba.BlockHeight256BytesY[k],
+ &mode_lib->vba.BlockHeight256BytesC[k],
+ &mode_lib->vba.BlockWidth256BytesY[k],
+ &mode_lib->vba.BlockWidth256BytesC[k]);
+ PDEAndMetaPTEBytesFrameY = CalculateVMAndRowBytes(
+ mode_lib,
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.BlockHeight256BytesY[k],
+ mode_lib->vba.BlockWidth256BytesY[k],
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.SurfaceTiling[k],
+ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+ mode_lib->vba.SourceScan[k],
+ mode_lib->vba.ViewportWidth[k],
+ mode_lib->vba.ViewportHeight[k],
+ mode_lib->vba.SwathWidthY[k],
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.VMMPageSize,
+ mode_lib->vba.PTEBufferSizeInRequests,
+ mode_lib->vba.PDEProcessingBufIn64KBReqs,
+ mode_lib->vba.PitchY[k],
+ mode_lib->vba.DCCMetaPitchY[k],
+ &mode_lib->vba.MacroTileWidthY[k],
+ &MetaRowByteY,
+ &PixelPTEBytesPerRowY,
+ &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
+ &mode_lib->vba.dpte_row_height[k],
+ &mode_lib->vba.meta_row_height[k]);
+ mode_lib->vba.PrefetchSourceLinesY[k] = CalculatePrefetchSourceLines(
+ mode_lib,
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.vtaps[k],
+ mode_lib->vba.Interlace[k],
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+ mode_lib->vba.SwathHeightY[k],
+ mode_lib->vba.ViewportYStartY[k],
+ &mode_lib->vba.VInitPreFillY[k],
+ &mode_lib->vba.MaxNumSwathY[k]);
+
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_8)) {
+ PDEAndMetaPTEBytesFrameC =
+ CalculateVMAndRowBytes(
+ mode_lib,
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.BlockHeight256BytesC[k],
+ mode_lib->vba.BlockWidth256BytesC[k],
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.SurfaceTiling[k],
+ dml_ceil(
+ mode_lib->vba.BytePerPixelDETC[k],
+ 2),
+ mode_lib->vba.SourceScan[k],
+ mode_lib->vba.ViewportWidth[k] / 2,
+ mode_lib->vba.ViewportHeight[k] / 2,
+ mode_lib->vba.SwathWidthY[k] / 2,
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.VMMPageSize,
+ mode_lib->vba.PTEBufferSizeInRequests,
+ mode_lib->vba.PDEProcessingBufIn64KBReqs,
+ mode_lib->vba.PitchC[k],
+ 0,
+ &mode_lib->vba.MacroTileWidthC[k],
+ &MetaRowByteC,
+ &PixelPTEBytesPerRowC,
+ &mode_lib->vba.PTEBufferSizeNotExceeded[mode_lib->vba.VoltageLevel],
+ &mode_lib->vba.dpte_row_height_chroma[k],
+ &mode_lib->vba.meta_row_height_chroma[k]);
+ mode_lib->vba.PrefetchSourceLinesC[k] = CalculatePrefetchSourceLines(
+ mode_lib,
+ mode_lib->vba.VRatio[k] / 2,
+ mode_lib->vba.VTAPsChroma[k],
+ mode_lib->vba.Interlace[k],
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+ mode_lib->vba.SwathHeightC[k],
+ mode_lib->vba.ViewportYStartC[k],
+ &mode_lib->vba.VInitPreFillC[k],
+ &mode_lib->vba.MaxNumSwathC[k]);
+ } else {
+ PixelPTEBytesPerRowC = 0;
+ PDEAndMetaPTEBytesFrameC = 0;
+ MetaRowByteC = 0;
+ mode_lib->vba.MaxNumSwathC[k] = 0;
+ mode_lib->vba.PrefetchSourceLinesC[k] = 0;
+ }
+
+ mode_lib->vba.PixelPTEBytesPerRow[k] = PixelPTEBytesPerRowY + PixelPTEBytesPerRowC;
+ mode_lib->vba.PDEAndMetaPTEBytesFrame[k] = PDEAndMetaPTEBytesFrameY
+ + PDEAndMetaPTEBytesFrameC;
+ mode_lib->vba.MetaRowByte[k] = MetaRowByteY + MetaRowByteC;
+
+ CalculateActiveRowBandwidth(
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+ MetaRowByteY,
+ MetaRowByteC,
+ mode_lib->vba.meta_row_height[k],
+ mode_lib->vba.meta_row_height_chroma[k],
+ PixelPTEBytesPerRowY,
+ PixelPTEBytesPerRowC,
+ mode_lib->vba.dpte_row_height[k],
+ mode_lib->vba.dpte_row_height_chroma[k],
+ &mode_lib->vba.meta_row_bw[k],
+ &mode_lib->vba.dpte_row_bw[k],
+ &mode_lib->vba.qual_row_bw[k]);
+ }
+
+ mode_lib->vba.TCalc = 24.0 / mode_lib->vba.DCFClkDeepSleep;
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ if (mode_lib->vba.WritebackEnable[k] == true) {
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+ mode_lib->vba.WritebackLatency
+ + CalculateWriteBackDelay(
+ mode_lib->vba.WritebackPixelFormat[k],
+ mode_lib->vba.WritebackHRatio[k],
+ mode_lib->vba.WritebackVRatio[k],
+ mode_lib->vba.WritebackLumaHTaps[k],
+ mode_lib->vba.WritebackLumaVTaps[k],
+ mode_lib->vba.WritebackChromaHTaps[k],
+ mode_lib->vba.WritebackChromaVTaps[k],
+ mode_lib->vba.WritebackDestinationWidth[k])
+ / mode_lib->vba.DISPCLK;
+ } else
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] = 0;
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+ if (mode_lib->vba.BlendingAndTiming[j] == k
+ && mode_lib->vba.WritebackEnable[j] == true) {
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+ dml_max(
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k],
+ mode_lib->vba.WritebackLatency
+ + CalculateWriteBackDelay(
+ mode_lib->vba.WritebackPixelFormat[j],
+ mode_lib->vba.WritebackHRatio[j],
+ mode_lib->vba.WritebackVRatio[j],
+ mode_lib->vba.WritebackLumaHTaps[j],
+ mode_lib->vba.WritebackLumaVTaps[j],
+ mode_lib->vba.WritebackChromaHTaps[j],
+ mode_lib->vba.WritebackChromaVTaps[j],
+ mode_lib->vba.WritebackDestinationWidth[j])
+ / mode_lib->vba.DISPCLK);
+ }
+ }
+ }
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
+ if (mode_lib->vba.BlendingAndTiming[k] == j)
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k] =
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][j];
+
+ mode_lib->vba.VStartupLines = 13;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.MaxVStartupLines[k] =
+ mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
+ - dml_max(
+ 1.0,
+ dml_ceil(
+ mode_lib->vba.WritebackDelay[mode_lib->vba.VoltageLevel][k]
+ / (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]),
+ 1));
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k)
+ mode_lib->vba.MaximumMaxVStartupLines = dml_max(
+ mode_lib->vba.MaximumMaxVStartupLines,
+ mode_lib->vba.MaxVStartupLines[k]);
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.cursor_bw[k] = 0.0;
+ for (j = 0; j < mode_lib->vba.NumberOfCursors[k]; ++j)
+ mode_lib->vba.cursor_bw[k] += mode_lib->vba.CursorWidth[k][j]
+ * mode_lib->vba.CursorBPP[k][j] / 8.0
+ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ * mode_lib->vba.VRatio[k];
+ }
+
+ do {
+ double MaxTotalRDBandwidth = 0;
+ bool DestinationLineTimesForPrefetchLessThan2 = false;
+ bool VRatioPrefetchMoreThan4 = false;
+ bool prefetch_vm_bw_valid = true;
+ bool prefetch_row_bw_valid = true;
+ double TWait = CalculateTWait(
+ mode_lib->vba.PrefetchMode,
+ mode_lib->vba.DRAMClockChangeLatency,
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.SREnterPlusExitTime);
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.XFCEnabled[k] == true) {
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay =
+ CalculateRemoteSurfaceFlipDelay(
+ mode_lib,
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.SwathWidthY[k],
+ dml_ceil(
+ mode_lib->vba.BytePerPixelDETY[k],
+ 1),
+ mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k],
+ mode_lib->vba.XFCTSlvVupdateOffset,
+ mode_lib->vba.XFCTSlvVupdateWidth,
+ mode_lib->vba.XFCTSlvVreadyOffset,
+ mode_lib->vba.XFCXBUFLatencyTolerance,
+ mode_lib->vba.XFCFillBWOverhead,
+ mode_lib->vba.XFCSlvChunkSize,
+ mode_lib->vba.XFCBusTransportTime,
+ mode_lib->vba.TCalc,
+ TWait,
+ &mode_lib->vba.SrcActiveDrainRate,
+ &mode_lib->vba.TInitXFill,
+ &mode_lib->vba.TslvChk);
+ } else {
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0;
+ }
+ mode_lib->vba.ErrorResult[k] =
+ CalculatePrefetchSchedule(
+ mode_lib,
+ mode_lib->vba.DPPCLK[k],
+ mode_lib->vba.DISPCLK,
+ mode_lib->vba.PixelClock[k],
+ mode_lib->vba.DCFClkDeepSleep,
+ mode_lib->vba.DSCDelay[k],
+ mode_lib->vba.DPPPerPlane[k],
+ mode_lib->vba.ScalerEnabled[k],
+ mode_lib->vba.NumberOfCursors[k],
+ mode_lib->vba.DPPCLKDelaySubtotal,
+ mode_lib->vba.DPPCLKDelaySCL,
+ mode_lib->vba.DPPCLKDelaySCLLBOnly,
+ mode_lib->vba.DPPCLKDelayCNVCFormater,
+ mode_lib->vba.DPPCLKDelayCNVCCursor,
+ mode_lib->vba.DISPCLKDelaySubtotal,
+ (unsigned int) (mode_lib->vba.SwathWidthY[k]
+ / mode_lib->vba.HRatio[k]),
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.VTotal[k]
+ - mode_lib->vba.VActive[k],
+ mode_lib->vba.HTotal[k],
+ mode_lib->vba.MaxInterDCNTileRepeaters,
+ dml_min(
+ mode_lib->vba.VStartupLines,
+ mode_lib->vba.MaxVStartupLines[k]),
+ mode_lib->vba.MaxPageTableLevels,
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.DynamicMetadataEnable[k],
+ mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
+ mode_lib->vba.DynamicMetadataTransmittedBytes[k],
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.UrgentExtraLatency,
+ mode_lib->vba.TCalc,
+ mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
+ mode_lib->vba.MetaRowByte[k],
+ mode_lib->vba.PixelPTEBytesPerRow[k],
+ mode_lib->vba.PrefetchSourceLinesY[k],
+ mode_lib->vba.SwathWidthY[k],
+ mode_lib->vba.BytePerPixelDETY[k],
+ mode_lib->vba.VInitPreFillY[k],
+ mode_lib->vba.MaxNumSwathY[k],
+ mode_lib->vba.PrefetchSourceLinesC[k],
+ mode_lib->vba.BytePerPixelDETC[k],
+ mode_lib->vba.VInitPreFillC[k],
+ mode_lib->vba.MaxNumSwathC[k],
+ mode_lib->vba.SwathHeightY[k],
+ mode_lib->vba.SwathHeightC[k],
+ TWait,
+ mode_lib->vba.XFCEnabled[k],
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay,
+ mode_lib->vba.Interlace[k],
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+ &mode_lib->vba.DSTXAfterScaler[k],
+ &mode_lib->vba.DSTYAfterScaler[k],
+ &mode_lib->vba.DestinationLinesForPrefetch[k],
+ &mode_lib->vba.PrefetchBandwidth[k],
+ &mode_lib->vba.DestinationLinesToRequestVMInVBlank[k],
+ &mode_lib->vba.DestinationLinesToRequestRowInVBlank[k],
+ &mode_lib->vba.VRatioPrefetchY[k],
+ &mode_lib->vba.VRatioPrefetchC[k],
+ &mode_lib->vba.RequiredPrefetchPixDataBW[k],
+ &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+ &mode_lib->vba.Tno_bw[k],
+ &mode_lib->vba.VUpdateOffsetPix[k],
+ &mode_lib->vba.VUpdateWidthPix[k],
+ &mode_lib->vba.VReadyOffsetPix[k]);
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ mode_lib->vba.VStartup[k] = dml_min(
+ mode_lib->vba.VStartupLines,
+ mode_lib->vba.MaxVStartupLines[k]);
+ if (mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata
+ != 0) {
+ mode_lib->vba.VStartup[k] =
+ mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
+ }
+ } else {
+ mode_lib->vba.VStartup[k] =
+ dml_min(
+ mode_lib->vba.VStartupLines,
+ mode_lib->vba.MaxVStartupLines[mode_lib->vba.BlendingAndTiming[k]]);
+ }
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+
+ if (mode_lib->vba.PDEAndMetaPTEBytesFrame[k] == 0)
+ mode_lib->vba.prefetch_vm_bw[k] = 0;
+ else if (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k] > 0) {
+ mode_lib->vba.prefetch_vm_bw[k] =
+ (double) mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+ / (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ } else {
+ mode_lib->vba.prefetch_vm_bw[k] = 0;
+ prefetch_vm_bw_valid = false;
+ }
+ if (mode_lib->vba.MetaRowByte[k] + mode_lib->vba.PixelPTEBytesPerRow[k]
+ == 0)
+ mode_lib->vba.prefetch_row_bw[k] = 0;
+ else if (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k] > 0) {
+ mode_lib->vba.prefetch_row_bw[k] =
+ (double) (mode_lib->vba.MetaRowByte[k]
+ + mode_lib->vba.PixelPTEBytesPerRow[k])
+ / (mode_lib->vba.DestinationLinesToRequestRowInVBlank[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ } else {
+ mode_lib->vba.prefetch_row_bw[k] = 0;
+ prefetch_row_bw_valid = false;
+ }
+
+ MaxTotalRDBandwidth =
+ MaxTotalRDBandwidth + mode_lib->vba.cursor_bw[k]
+ + dml_max(
+ mode_lib->vba.prefetch_vm_bw[k],
+ dml_max(
+ mode_lib->vba.prefetch_row_bw[k],
+ dml_max(
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k],
+ mode_lib->vba.RequiredPrefetchPixDataBW[k])
+ + mode_lib->vba.meta_row_bw[k]
+ + mode_lib->vba.dpte_row_bw[k]));
+
+ if (mode_lib->vba.DestinationLinesForPrefetch[k] < 2)
+ DestinationLineTimesForPrefetchLessThan2 = true;
+ if (mode_lib->vba.VRatioPrefetchY[k] > 4
+ || mode_lib->vba.VRatioPrefetchC[k] > 4)
+ VRatioPrefetchMoreThan4 = true;
+ }
+
+ if (MaxTotalRDBandwidth <= mode_lib->vba.ReturnBW && prefetch_vm_bw_valid
+ && prefetch_row_bw_valid && !VRatioPrefetchMoreThan4
+ && !DestinationLineTimesForPrefetchLessThan2)
+ mode_lib->vba.PrefetchModeSupported = true;
+ else {
+ mode_lib->vba.PrefetchModeSupported = false;
+ dml_print(
+ "DML: CalculatePrefetchSchedule ***failed***. Bandwidth violation. Results are NOT valid\n");
+ }
+
+ if (mode_lib->vba.PrefetchModeSupported == true) {
+ double final_flip_bw[DC__NUM_DPP__MAX];
+ unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
+ double total_dcn_read_bw_with_flip = 0;
+
+ mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.ReturnBW;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.BandwidthAvailableForImmediateFlip =
+ mode_lib->vba.BandwidthAvailableForImmediateFlip
+ - mode_lib->vba.cursor_bw[k]
+ - dml_max(
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k]
+ + mode_lib->vba.qual_row_bw[k],
+ mode_lib->vba.PrefetchBandwidth[k]);
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ ImmediateFlipBytes[k] = 0;
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+ ImmediateFlipBytes[k] =
+ mode_lib->vba.PDEAndMetaPTEBytesFrame[k]
+ + mode_lib->vba.MetaRowByte[k]
+ + mode_lib->vba.PixelPTEBytesPerRow[k];
+ }
+ }
+ mode_lib->vba.TotImmediateFlipBytes = 0;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+ mode_lib->vba.TotImmediateFlipBytes =
+ mode_lib->vba.TotImmediateFlipBytes
+ + ImmediateFlipBytes[k];
+ }
+ }
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ CalculateFlipSchedule(
+ mode_lib,
+ mode_lib->vba.UrgentExtraLatency,
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.MaxPageTableLevels,
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.BandwidthAvailableForImmediateFlip,
+ mode_lib->vba.TotImmediateFlipBytes,
+ mode_lib->vba.SourcePixelFormat[k],
+ ImmediateFlipBytes[k],
+ mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k],
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.Tno_bw[k],
+ mode_lib->vba.PDEAndMetaPTEBytesFrame[k],
+ mode_lib->vba.MetaRowByte[k],
+ mode_lib->vba.PixelPTEBytesPerRow[k],
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.dpte_row_height[k],
+ mode_lib->vba.meta_row_height[k],
+ mode_lib->vba.qual_row_bw[k],
+ &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
+ &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
+ &final_flip_bw[k],
+ &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
+ }
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ total_dcn_read_bw_with_flip =
+ total_dcn_read_bw_with_flip
+ + mode_lib->vba.cursor_bw[k]
+ + dml_max(
+ mode_lib->vba.prefetch_vm_bw[k],
+ dml_max(
+ mode_lib->vba.prefetch_row_bw[k],
+ final_flip_bw[k]
+ + dml_max(
+ mode_lib->vba.ReadBandwidthPlaneLuma[k]
+ + mode_lib->vba.ReadBandwidthPlaneChroma[k],
+ mode_lib->vba.RequiredPrefetchPixDataBW[k])));
+ }
+ mode_lib->vba.ImmediateFlipSupported = true;
+ if (total_dcn_read_bw_with_flip > mode_lib->vba.ReturnBW) {
+ mode_lib->vba.ImmediateFlipSupported = false;
+ }
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
+ mode_lib->vba.ImmediateFlipSupported = false;
+ }
+ }
+ } else {
+ mode_lib->vba.ImmediateFlipSupported = false;
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.ErrorResult[k]) {
+ mode_lib->vba.PrefetchModeSupported = false;
+ dml_print(
+ "DML: CalculatePrefetchSchedule ***failed***. Prefetch schedule violation. Results are NOT valid\n");
+ }
+ }
+
+ mode_lib->vba.VStartupLines = mode_lib->vba.VStartupLines + 1;
+ } while (!((mode_lib->vba.PrefetchModeSupported
+ && (!mode_lib->vba.ImmediateFlipSupport
+ || mode_lib->vba.ImmediateFlipSupported))
+ || mode_lib->vba.MaximumMaxVStartupLines < mode_lib->vba.VStartupLines));
+
+ //Display Pipeline Delivery Time in Prefetch
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.VRatioPrefetchY[k] <= 1) {
+ mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
+ mode_lib->vba.SwathWidthY[k] * mode_lib->vba.DPPPerPlane[k]
+ / mode_lib->vba.HRatio[k]
+ / mode_lib->vba.PixelClock[k];
+ } else {
+ mode_lib->vba.DisplayPipeLineDeliveryTimeLumaPrefetch[k] =
+ mode_lib->vba.SwathWidthY[k]
+ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+ / mode_lib->vba.DPPCLK[k];
+ }
+ if (mode_lib->vba.BytePerPixelDETC[k] == 0) {
+ mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] = 0;
+ } else {
+ if (mode_lib->vba.VRatioPrefetchC[k] <= 1) {
+ mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
+ mode_lib->vba.SwathWidthY[k]
+ * mode_lib->vba.DPPPerPlane[k]
+ / mode_lib->vba.HRatio[k]
+ / mode_lib->vba.PixelClock[k];
+ } else {
+ mode_lib->vba.DisplayPipeLineDeliveryTimeChromaPrefetch[k] =
+ mode_lib->vba.SwathWidthY[k]
+ / mode_lib->vba.PSCL_THROUGHPUT_LUMA[k]
+ / mode_lib->vba.DPPCLK[k];
+ }
+ }
+ }
+
+ // Min TTUVBlank
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.PrefetchMode == 0) {
+ mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = true;
+ mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
+ mode_lib->vba.MinTTUVBlank[k] = dml_max(
+ mode_lib->vba.DRAMClockChangeWatermark,
+ dml_max(
+ mode_lib->vba.StutterEnterPlusExitWatermark,
+ mode_lib->vba.UrgentWatermark));
+ } else if (mode_lib->vba.PrefetchMode == 1) {
+ mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
+ mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = true;
+ mode_lib->vba.MinTTUVBlank[k] = dml_max(
+ mode_lib->vba.StutterEnterPlusExitWatermark,
+ mode_lib->vba.UrgentWatermark);
+ } else {
+ mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k] = false;
+ mode_lib->vba.AllowDRAMSelfRefreshDuringVBlank[k] = false;
+ mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.UrgentWatermark;
+ }
+ if (!mode_lib->vba.DynamicMetadataEnable[k])
+ mode_lib->vba.MinTTUVBlank[k] = mode_lib->vba.TCalc
+ + mode_lib->vba.MinTTUVBlank[k];
+ }
+
+ // DCC Configuration
+ mode_lib->vba.ActiveDPPs = 0;
+ // NB P-State/DRAM Clock Change Support
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.ActiveDPPs = mode_lib->vba.ActiveDPPs + mode_lib->vba.DPPPerPlane[k];
+ }
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ double EffectiveLBLatencyHidingY;
+ double EffectiveLBLatencyHidingC;
+ double DPPOutputBufferLinesY;
+ double DPPOutputBufferLinesC;
+ double DPPOPPBufferingY;
+ double MaxDETBufferingTimeY;
+ double ActiveDRAMClockChangeLatencyMarginY;
+
+ mode_lib->vba.LBLatencyHidingSourceLinesY =
+ dml_min(
+ mode_lib->vba.MaxLineBufferLines,
+ (unsigned int) dml_floor(
+ (double) mode_lib->vba.LineBufferSize
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.SwathWidthY[k]
+ / dml_max(
+ mode_lib->vba.HRatio[k],
+ 1.0)),
+ 1)) - (mode_lib->vba.vtaps[k] - 1);
+
+ mode_lib->vba.LBLatencyHidingSourceLinesC =
+ dml_min(
+ mode_lib->vba.MaxLineBufferLines,
+ (unsigned int) dml_floor(
+ (double) mode_lib->vba.LineBufferSize
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.SwathWidthY[k]
+ / 2.0
+ / dml_max(
+ mode_lib->vba.HRatio[k]
+ / 2,
+ 1.0)),
+ 1))
+ - (mode_lib->vba.VTAPsChroma[k] - 1);
+
+ EffectiveLBLatencyHidingY = mode_lib->vba.LBLatencyHidingSourceLinesY
+ / mode_lib->vba.VRatio[k]
+ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+
+ EffectiveLBLatencyHidingC = mode_lib->vba.LBLatencyHidingSourceLinesC
+ / (mode_lib->vba.VRatio[k] / 2)
+ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+
+ if (mode_lib->vba.SwathWidthY[k] > 2 * mode_lib->vba.DPPOutputBufferPixels) {
+ DPPOutputBufferLinesY = mode_lib->vba.DPPOutputBufferPixels
+ / mode_lib->vba.SwathWidthY[k];
+ } else if (mode_lib->vba.SwathWidthY[k] > mode_lib->vba.DPPOutputBufferPixels) {
+ DPPOutputBufferLinesY = 0.5;
+ } else {
+ DPPOutputBufferLinesY = 1;
+ }
+
+ if (mode_lib->vba.SwathWidthY[k] / 2 > 2 * mode_lib->vba.DPPOutputBufferPixels) {
+ DPPOutputBufferLinesC = mode_lib->vba.DPPOutputBufferPixels
+ / (mode_lib->vba.SwathWidthY[k] / 2);
+ } else if (mode_lib->vba.SwathWidthY[k] / 2 > mode_lib->vba.DPPOutputBufferPixels) {
+ DPPOutputBufferLinesC = 0.5;
+ } else {
+ DPPOutputBufferLinesC = 1;
+ }
+
+ DPPOPPBufferingY = (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ * (DPPOutputBufferLinesY + mode_lib->vba.OPPOutputBufferLines);
+ MaxDETBufferingTimeY = mode_lib->vba.FullDETBufferingTimeY[k]
+ + (mode_lib->vba.LinesInDETY[k]
+ - mode_lib->vba.LinesInDETYRoundedDownToSwath[k])
+ / mode_lib->vba.SwathHeightY[k]
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+
+ ActiveDRAMClockChangeLatencyMarginY = DPPOPPBufferingY + EffectiveLBLatencyHidingY
+ + MaxDETBufferingTimeY - mode_lib->vba.DRAMClockChangeWatermark;
+
+ if (mode_lib->vba.ActiveDPPs > 1) {
+ ActiveDRAMClockChangeLatencyMarginY =
+ ActiveDRAMClockChangeLatencyMarginY
+ - (1 - 1 / (mode_lib->vba.ActiveDPPs - 1))
+ * mode_lib->vba.SwathHeightY[k]
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ }
+
+ if (mode_lib->vba.BytePerPixelDETC[k] > 0) {
+ double DPPOPPBufferingC = (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ * (DPPOutputBufferLinesC
+ + mode_lib->vba.OPPOutputBufferLines);
+ double MaxDETBufferingTimeC =
+ mode_lib->vba.FullDETBufferingTimeC[k]
+ + (mode_lib->vba.LinesInDETC[k]
+ - mode_lib->vba.LinesInDETCRoundedDownToSwath[k])
+ / mode_lib->vba.SwathHeightC[k]
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ double ActiveDRAMClockChangeLatencyMarginC = DPPOPPBufferingC
+ + EffectiveLBLatencyHidingC + MaxDETBufferingTimeC
+ - mode_lib->vba.DRAMClockChangeWatermark;
+
+ if (mode_lib->vba.ActiveDPPs > 1) {
+ ActiveDRAMClockChangeLatencyMarginC =
+ ActiveDRAMClockChangeLatencyMarginC
+ - (1
+ - 1
+ / (mode_lib->vba.ActiveDPPs
+ - 1))
+ * mode_lib->vba.SwathHeightC[k]
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ }
+ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
+ ActiveDRAMClockChangeLatencyMarginY,
+ ActiveDRAMClockChangeLatencyMarginC);
+ } else {
+ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] =
+ ActiveDRAMClockChangeLatencyMarginY;
+ }
+
+ if (mode_lib->vba.WritebackEnable[k]) {
+ double WritebackDRAMClockChangeLatencyMargin;
+
+ if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+ WritebackDRAMClockChangeLatencyMargin =
+ (double) (mode_lib->vba.WritebackInterfaceLumaBufferSize
+ + mode_lib->vba.WritebackInterfaceChromaBufferSize)
+ / (mode_lib->vba.WritebackDestinationWidth[k]
+ * mode_lib->vba.WritebackDestinationHeight[k]
+ / (mode_lib->vba.WritebackSourceHeight[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ * 4)
+ - mode_lib->vba.WritebackDRAMClockChangeWatermark;
+ } else if (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+ WritebackDRAMClockChangeLatencyMargin =
+ dml_min(
+ (double) mode_lib->vba.WritebackInterfaceLumaBufferSize
+ * 8.0 / 10,
+ 2.0
+ * mode_lib->vba.WritebackInterfaceChromaBufferSize
+ * 8 / 10)
+ / (mode_lib->vba.WritebackDestinationWidth[k]
+ * mode_lib->vba.WritebackDestinationHeight[k]
+ / (mode_lib->vba.WritebackSourceHeight[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]))
+ - mode_lib->vba.WritebackDRAMClockChangeWatermark;
+ } else {
+ WritebackDRAMClockChangeLatencyMargin =
+ dml_min(
+ (double) mode_lib->vba.WritebackInterfaceLumaBufferSize,
+ 2.0
+ * mode_lib->vba.WritebackInterfaceChromaBufferSize)
+ / (mode_lib->vba.WritebackDestinationWidth[k]
+ * mode_lib->vba.WritebackDestinationHeight[k]
+ / (mode_lib->vba.WritebackSourceHeight[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]))
+ - mode_lib->vba.WritebackDRAMClockChangeWatermark;
+ }
+ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k] = dml_min(
+ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k],
+ WritebackDRAMClockChangeLatencyMargin);
+ }
+ }
+
+ mode_lib->vba.MinActiveDRAMClockChangeMargin = 999999;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k]
+ < mode_lib->vba.MinActiveDRAMClockChangeMargin) {
+ mode_lib->vba.MinActiveDRAMClockChangeMargin =
+ mode_lib->vba.ActiveDRAMClockChangeLatencyMargin[k];
+ }
+ }
+
+ mode_lib->vba.MinActiveDRAMClockChangeLatencySupported =
+ mode_lib->vba.MinActiveDRAMClockChangeMargin
+ + mode_lib->vba.DRAMClockChangeLatency;
+
+ if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) {
+ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vactive;
+ } else {
+ if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) {
+ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_vblank;
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (!mode_lib->vba.AllowDRAMClockChangeDuringVBlank[k]) {
+ mode_lib->vba.DRAMClockChangeSupport =
+ dm_dram_clock_change_unsupported;
+ }
+ }
+ } else {
+ mode_lib->vba.DRAMClockChangeSupport = dm_dram_clock_change_unsupported;
+ }
+ }
+
+ //XFC Parameters:
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ if (mode_lib->vba.XFCEnabled[k] == true) {
+ double TWait;
+
+ mode_lib->vba.XFCSlaveVUpdateOffset[k] = mode_lib->vba.XFCTSlvVupdateOffset;
+ mode_lib->vba.XFCSlaveVupdateWidth[k] = mode_lib->vba.XFCTSlvVupdateWidth;
+ mode_lib->vba.XFCSlaveVReadyOffset[k] = mode_lib->vba.XFCTSlvVreadyOffset;
+ TWait = CalculateTWait(
+ mode_lib->vba.PrefetchMode,
+ mode_lib->vba.DRAMClockChangeLatency,
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.SREnterPlusExitTime);
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay = CalculateRemoteSurfaceFlipDelay(
+ mode_lib,
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.SwathWidthY[k],
+ dml_ceil(mode_lib->vba.BytePerPixelDETY[k], 1),
+ mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k],
+ mode_lib->vba.XFCTSlvVupdateOffset,
+ mode_lib->vba.XFCTSlvVupdateWidth,
+ mode_lib->vba.XFCTSlvVreadyOffset,
+ mode_lib->vba.XFCXBUFLatencyTolerance,
+ mode_lib->vba.XFCFillBWOverhead,
+ mode_lib->vba.XFCSlvChunkSize,
+ mode_lib->vba.XFCBusTransportTime,
+ mode_lib->vba.TCalc,
+ TWait,
+ &mode_lib->vba.SrcActiveDrainRate,
+ &mode_lib->vba.TInitXFill,
+ &mode_lib->vba.TslvChk);
+ mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] =
+ dml_floor(
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay
+ / (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]),
+ 1);
+ mode_lib->vba.XFCTransferDelay[k] =
+ dml_ceil(
+ mode_lib->vba.XFCBusTransportTime
+ / (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]),
+ 1);
+ mode_lib->vba.XFCPrechargeDelay[k] =
+ dml_ceil(
+ (mode_lib->vba.XFCBusTransportTime
+ + mode_lib->vba.TInitXFill
+ + mode_lib->vba.TslvChk)
+ / (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]),
+ 1);
+ mode_lib->vba.InitFillLevel = mode_lib->vba.XFCXBUFLatencyTolerance
+ * mode_lib->vba.SrcActiveDrainRate;
+ mode_lib->vba.FinalFillMargin =
+ (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+ + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]
+ * mode_lib->vba.SrcActiveDrainRate
+ + mode_lib->vba.XFCFillConstant;
+ mode_lib->vba.FinalFillLevel = mode_lib->vba.XFCRemoteSurfaceFlipDelay
+ * mode_lib->vba.SrcActiveDrainRate
+ + mode_lib->vba.FinalFillMargin;
+ mode_lib->vba.RemainingFillLevel = dml_max(
+ 0.0,
+ mode_lib->vba.FinalFillLevel - mode_lib->vba.InitFillLevel);
+ mode_lib->vba.TFinalxFill = mode_lib->vba.RemainingFillLevel
+ / (mode_lib->vba.SrcActiveDrainRate
+ * mode_lib->vba.XFCFillBWOverhead / 100);
+ mode_lib->vba.XFCPrefetchMargin[k] =
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay
+ + mode_lib->vba.TFinalxFill
+ + (mode_lib->vba.DestinationLinesToRequestVMInVBlank[k]
+ + mode_lib->vba.DestinationLinesToRequestRowInVBlank[k])
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k];
+ } else {
+ mode_lib->vba.XFCSlaveVUpdateOffset[k] = 0;
+ mode_lib->vba.XFCSlaveVupdateWidth[k] = 0;
+ mode_lib->vba.XFCSlaveVReadyOffset[k] = 0;
+ mode_lib->vba.XFCRemoteSurfaceFlipLatency[k] = 0;
+ mode_lib->vba.XFCPrechargeDelay[k] = 0;
+ mode_lib->vba.XFCTransferDelay[k] = 0;
+ mode_lib->vba.XFCPrefetchMargin[k] = 0;
+ }
+ }
+}
+
+static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
+{
+ double BytePerPixDETY;
+ double BytePerPixDETC;
+ double Read256BytesBlockHeightY;
+ double Read256BytesBlockHeightC;
+ double Read256BytesBlockWidthY;
+ double Read256BytesBlockWidthC;
+ double MaximumSwathHeightY;
+ double MaximumSwathHeightC;
+ double MinimumSwathHeightY;
+ double MinimumSwathHeightC;
+ double SwathWidth;
+ double SwathWidthGranularityY;
+ double SwathWidthGranularityC;
+ double RoundedUpMaxSwathSizeBytesY;
+ double RoundedUpMaxSwathSizeBytesC;
+ unsigned int j, k;
+
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ bool MainPlaneDoesODMCombine = false;
+
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+ BytePerPixDETY = 8;
+ BytePerPixDETC = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+ BytePerPixDETY = 4;
+ BytePerPixDETC = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+ BytePerPixDETY = 2;
+ BytePerPixDETC = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8) {
+ BytePerPixDETY = 1;
+ BytePerPixDETC = 0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+ BytePerPixDETY = 1;
+ BytePerPixDETC = 2;
+ } else {
+ BytePerPixDETY = 4.0 / 3.0;
+ BytePerPixDETC = 8.0 / 3.0;
+ }
+
+ if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+ Read256BytesBlockHeightY = 1;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+ Read256BytesBlockHeightY = 4;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16) {
+ Read256BytesBlockHeightY = 8;
+ } else {
+ Read256BytesBlockHeightY = 16;
+ }
+ Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
+ / Read256BytesBlockHeightY;
+ Read256BytesBlockHeightC = 0;
+ Read256BytesBlockWidthC = 0;
+ } else {
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+ Read256BytesBlockHeightY = 1;
+ Read256BytesBlockHeightC = 1;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+ Read256BytesBlockHeightY = 16;
+ Read256BytesBlockHeightC = 8;
+ } else {
+ Read256BytesBlockHeightY = 8;
+ Read256BytesBlockHeightC = 8;
+ }
+ Read256BytesBlockWidthY = 256 / dml_ceil(BytePerPixDETY, 1)
+ / Read256BytesBlockHeightY;
+ Read256BytesBlockWidthC = 256 / dml_ceil(BytePerPixDETC, 2)
+ / Read256BytesBlockHeightC;
+ }
+
+ if (mode_lib->vba.SourceScan[k] == dm_horz) {
+ MaximumSwathHeightY = Read256BytesBlockHeightY;
+ MaximumSwathHeightC = Read256BytesBlockHeightC;
+ } else {
+ MaximumSwathHeightY = Read256BytesBlockWidthY;
+ MaximumSwathHeightC = Read256BytesBlockWidthC;
+ }
+
+ if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_8)) {
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+ || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+ && (mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_4kb_s
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_4kb_s_x
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_64kb_s
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_64kb_s_t
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_64kb_s_x
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_var_s
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_var_s_x)
+ && mode_lib->vba.SourceScan[k] == dm_horz)) {
+ MinimumSwathHeightY = MaximumSwathHeightY;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_8
+ && mode_lib->vba.SourceScan[k] != dm_horz) {
+ MinimumSwathHeightY = MaximumSwathHeightY;
+ } else {
+ MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
+ }
+ MinimumSwathHeightC = MaximumSwathHeightC;
+ } else {
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+ MinimumSwathHeightY = MaximumSwathHeightY;
+ MinimumSwathHeightC = MaximumSwathHeightC;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
+ && mode_lib->vba.SourceScan[k] == dm_horz) {
+ MinimumSwathHeightY = MaximumSwathHeightY / 2.0;
+ MinimumSwathHeightC = MaximumSwathHeightC;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
+ && mode_lib->vba.SourceScan[k] == dm_horz) {
+ MinimumSwathHeightC = MaximumSwathHeightC / 2.0;
+ MinimumSwathHeightY = MaximumSwathHeightY;
+ } else {
+ MinimumSwathHeightY = MaximumSwathHeightY;
+ MinimumSwathHeightC = MaximumSwathHeightC;
+ }
+ }
+
+ if (mode_lib->vba.SourceScan[k] == dm_horz) {
+ SwathWidth = mode_lib->vba.ViewportWidth[k];
+ } else {
+ SwathWidth = mode_lib->vba.ViewportHeight[k];
+ }
+
+ if (mode_lib->vba.ODMCombineEnabled[k] == true) {
+ MainPlaneDoesODMCombine = true;
+ }
+ for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
+ if (mode_lib->vba.BlendingAndTiming[k] == j
+ && mode_lib->vba.ODMCombineEnabled[j] == true) {
+ MainPlaneDoesODMCombine = true;
+ }
+ }
+
+ if (MainPlaneDoesODMCombine == true) {
+ SwathWidth = dml_min(
+ SwathWidth,
+ mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]);
+ } else {
+ SwathWidth = SwathWidth / mode_lib->vba.DPPPerPlane[k];
+ }
+
+ SwathWidthGranularityY = 256 / dml_ceil(BytePerPixDETY, 1) / MaximumSwathHeightY;
+ RoundedUpMaxSwathSizeBytesY = (dml_ceil(
+ (double) (SwathWidth - 1),
+ SwathWidthGranularityY) + SwathWidthGranularityY) * BytePerPixDETY
+ * MaximumSwathHeightY;
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+ RoundedUpMaxSwathSizeBytesY = dml_ceil(RoundedUpMaxSwathSizeBytesY, 256)
+ + 256;
+ }
+ if (MaximumSwathHeightC > 0) {
+ SwathWidthGranularityC = 256.0 / dml_ceil(BytePerPixDETC, 2)
+ / MaximumSwathHeightC;
+ RoundedUpMaxSwathSizeBytesC = (dml_ceil(
+ (double) (SwathWidth / 2.0 - 1),
+ SwathWidthGranularityC) + SwathWidthGranularityC)
+ * BytePerPixDETC * MaximumSwathHeightC;
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+ RoundedUpMaxSwathSizeBytesC = dml_ceil(
+ RoundedUpMaxSwathSizeBytesC,
+ 256) + 256;
+ }
+ } else
+ RoundedUpMaxSwathSizeBytesC = 0.0;
+
+ if (RoundedUpMaxSwathSizeBytesY + RoundedUpMaxSwathSizeBytesC
+ <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
+ mode_lib->vba.SwathHeightY[k] = MaximumSwathHeightY;
+ mode_lib->vba.SwathHeightC[k] = MaximumSwathHeightC;
+ } else {
+ mode_lib->vba.SwathHeightY[k] = MinimumSwathHeightY;
+ mode_lib->vba.SwathHeightC[k] = MinimumSwathHeightC;
+ }
+
+ if (mode_lib->vba.SwathHeightC[k] == 0) {
+ mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte * 1024;
+ mode_lib->vba.DETBufferSizeC[k] = 0;
+ } else if (mode_lib->vba.SwathHeightY[k] <= mode_lib->vba.SwathHeightC[k]) {
+ mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / 2;
+ mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / 2;
+ } else {
+ mode_lib->vba.DETBufferSizeY[k] = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 * 2 / 3;
+ mode_lib->vba.DETBufferSizeC[k] = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / 3;
+ }
+ }
+}
+
+bool Calculate256BBlockSizes(
+ enum source_format_class SourcePixelFormat,
+ enum dm_swizzle_mode SurfaceTiling,
+ unsigned int BytePerPixelY,
+ unsigned int BytePerPixelC,
+ unsigned int *BlockHeight256BytesY,
+ unsigned int *BlockHeight256BytesC,
+ unsigned int *BlockWidth256BytesY,
+ unsigned int *BlockWidth256BytesC)
+{
+ if ((SourcePixelFormat == dm_444_64 || SourcePixelFormat == dm_444_32
+ || SourcePixelFormat == dm_444_16
+ || SourcePixelFormat == dm_444_8)) {
+ if (SurfaceTiling == dm_sw_linear) {
+ *BlockHeight256BytesY = 1;
+ } else if (SourcePixelFormat == dm_444_64) {
+ *BlockHeight256BytesY = 4;
+ } else if (SourcePixelFormat == dm_444_8) {
+ *BlockHeight256BytesY = 16;
+ } else {
+ *BlockHeight256BytesY = 8;
+ }
+ *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
+ *BlockHeight256BytesC = 0;
+ *BlockWidth256BytesC = 0;
+ } else {
+ if (SurfaceTiling == dm_sw_linear) {
+ *BlockHeight256BytesY = 1;
+ *BlockHeight256BytesC = 1;
+ } else if (SourcePixelFormat == dm_420_8) {
+ *BlockHeight256BytesY = 16;
+ *BlockHeight256BytesC = 8;
+ } else {
+ *BlockHeight256BytesY = 8;
+ *BlockHeight256BytesC = 8;
+ }
+ *BlockWidth256BytesY = 256 / BytePerPixelY / *BlockHeight256BytesY;
+ *BlockWidth256BytesC = 256 / BytePerPixelC / *BlockHeight256BytesC;
+ }
+ return true;
+}
+
+static double CalculateTWait(
+ unsigned int PrefetchMode,
+ double DRAMClockChangeLatency,
+ double UrgentLatency,
+ double SREnterPlusExitTime)
+{
+ if (PrefetchMode == 0) {
+ return dml_max(
+ DRAMClockChangeLatency + UrgentLatency,
+ dml_max(SREnterPlusExitTime, UrgentLatency));
+ } else if (PrefetchMode == 1) {
+ return dml_max(SREnterPlusExitTime, UrgentLatency);
+ } else {
+ return UrgentLatency;
+ }
+}
+
+static double CalculateRemoteSurfaceFlipDelay(
+ struct display_mode_lib *mode_lib,
+ double VRatio,
+ double SwathWidth,
+ double Bpp,
+ double LineTime,
+ double XFCTSlvVupdateOffset,
+ double XFCTSlvVupdateWidth,
+ double XFCTSlvVreadyOffset,
+ double XFCXBUFLatencyTolerance,
+ double XFCFillBWOverhead,
+ double XFCSlvChunkSize,
+ double XFCBusTransportTime,
+ double TCalc,
+ double TWait,
+ double *SrcActiveDrainRate,
+ double *TInitXFill,
+ double *TslvChk)
+{
+ double TSlvSetup, AvgfillRate, result;
+
+ *SrcActiveDrainRate = VRatio * SwathWidth * Bpp / LineTime;
+ TSlvSetup = XFCTSlvVupdateOffset + XFCTSlvVupdateWidth + XFCTSlvVreadyOffset;
+ *TInitXFill = XFCXBUFLatencyTolerance / (1 + XFCFillBWOverhead / 100);
+ AvgfillRate = *SrcActiveDrainRate * (1 + XFCFillBWOverhead / 100);
+ *TslvChk = XFCSlvChunkSize / AvgfillRate;
+ dml_print(
+ "DML::CalculateRemoteSurfaceFlipDelay: SrcActiveDrainRate: %f\n",
+ *SrcActiveDrainRate);
+ dml_print("DML::CalculateRemoteSurfaceFlipDelay: TSlvSetup: %f\n", TSlvSetup);
+ dml_print("DML::CalculateRemoteSurfaceFlipDelay: TInitXFill: %f\n", *TInitXFill);
+ dml_print("DML::CalculateRemoteSurfaceFlipDelay: AvgfillRate: %f\n", AvgfillRate);
+ dml_print("DML::CalculateRemoteSurfaceFlipDelay: TslvChk: %f\n", *TslvChk);
+ result = 2 * XFCBusTransportTime + TSlvSetup + TCalc + TWait + *TslvChk + *TInitXFill; // TODO: This doesn't seem to match programming guide
+ dml_print("DML::CalculateRemoteSurfaceFlipDelay: RemoteSurfaceFlipDelay: %f\n", result);
+ return result;
+}
+
+static double CalculateWriteBackDISPCLK(
+ enum source_format_class WritebackPixelFormat,
+ double PixelClock,
+ double WritebackHRatio,
+ double WritebackVRatio,
+ unsigned int WritebackLumaHTaps,
+ unsigned int WritebackLumaVTaps,
+ unsigned int WritebackChromaHTaps,
+ unsigned int WritebackChromaVTaps,
+ double WritebackDestinationWidth,
+ unsigned int HTotal,
+ unsigned int WritebackChromaLineBufferWidth)
+{
+ double CalculateWriteBackDISPCLK =
+ 1.01 * PixelClock
+ * dml_max(
+ dml_ceil(WritebackLumaHTaps / 4.0, 1)
+ / WritebackHRatio,
+ dml_max(
+ (WritebackLumaVTaps
+ * dml_ceil(
+ 1.0
+ / WritebackVRatio,
+ 1)
+ * dml_ceil(
+ WritebackDestinationWidth
+ / 4.0,
+ 1)
+ + dml_ceil(
+ WritebackDestinationWidth
+ / 4.0,
+ 1))
+ / (double) HTotal
+ + dml_ceil(
+ 1.0
+ / WritebackVRatio,
+ 1)
+ * (dml_ceil(
+ WritebackLumaVTaps
+ / 4.0,
+ 1)
+ + 4.0)
+ / (double) HTotal,
+ dml_ceil(
+ 1.0
+ / WritebackVRatio,
+ 1)
+ * WritebackDestinationWidth
+ / (double) HTotal));
+ if (WritebackPixelFormat != dm_444_32) {
+ CalculateWriteBackDISPCLK =
+ dml_max(
+ CalculateWriteBackDISPCLK,
+ 1.01 * PixelClock
+ * dml_max(
+ dml_ceil(
+ WritebackChromaHTaps
+ / 2.0,
+ 1)
+ / (2
+ * WritebackHRatio),
+ dml_max(
+ (WritebackChromaVTaps
+ * dml_ceil(
+ 1
+ / (2
+ * WritebackVRatio),
+ 1)
+ * dml_ceil(
+ WritebackDestinationWidth
+ / 2.0
+ / 2.0,
+ 1)
+ + dml_ceil(
+ WritebackDestinationWidth
+ / 2.0
+ / WritebackChromaLineBufferWidth,
+ 1))
+ / HTotal
+ + dml_ceil(
+ 1
+ / (2
+ * WritebackVRatio),
+ 1)
+ * (dml_ceil(
+ WritebackChromaVTaps
+ / 4.0,
+ 1)
+ + 4)
+ / HTotal,
+ dml_ceil(
+ 1.0
+ / (2
+ * WritebackVRatio),
+ 1)
+ * WritebackDestinationWidth
+ / 2.0
+ / HTotal)));
+ }
+ return CalculateWriteBackDISPCLK;
+}
+
+static double CalculateWriteBackDelay(
+ enum source_format_class WritebackPixelFormat,
+ double WritebackHRatio,
+ double WritebackVRatio,
+ unsigned int WritebackLumaHTaps,
+ unsigned int WritebackLumaVTaps,
+ unsigned int WritebackChromaHTaps,
+ unsigned int WritebackChromaVTaps,
+ unsigned int WritebackDestinationWidth)
+{
+ double CalculateWriteBackDelay =
+ dml_max(
+ dml_ceil(WritebackLumaHTaps / 4.0, 1) / WritebackHRatio,
+ WritebackLumaVTaps * dml_ceil(1.0 / WritebackVRatio, 1)
+ * dml_ceil(
+ WritebackDestinationWidth
+ / 4.0,
+ 1)
+ + dml_ceil(1.0 / WritebackVRatio, 1)
+ * (dml_ceil(
+ WritebackLumaVTaps
+ / 4.0,
+ 1) + 4));
+
+ if (WritebackPixelFormat != dm_444_32) {
+ CalculateWriteBackDelay =
+ dml_max(
+ CalculateWriteBackDelay,
+ dml_max(
+ dml_ceil(
+ WritebackChromaHTaps
+ / 2.0,
+ 1)
+ / (2
+ * WritebackHRatio),
+ WritebackChromaVTaps
+ * dml_ceil(
+ 1
+ / (2
+ * WritebackVRatio),
+ 1)
+ * dml_ceil(
+ WritebackDestinationWidth
+ / 2.0
+ / 2.0,
+ 1)
+ + dml_ceil(
+ 1
+ / (2
+ * WritebackVRatio),
+ 1)
+ * (dml_ceil(
+ WritebackChromaVTaps
+ / 4.0,
+ 1)
+ + 4)));
+ }
+ return CalculateWriteBackDelay;
+}
+
+static void CalculateActiveRowBandwidth(
+ bool VirtualMemoryEnable,
+ enum source_format_class SourcePixelFormat,
+ double VRatio,
+ bool DCCEnable,
+ double LineTime,
+ unsigned int MetaRowByteLuma,
+ unsigned int MetaRowByteChroma,
+ unsigned int meta_row_height_luma,
+ unsigned int meta_row_height_chroma,
+ unsigned int PixelPTEBytesPerRowLuma,
+ unsigned int PixelPTEBytesPerRowChroma,
+ unsigned int dpte_row_height_luma,
+ unsigned int dpte_row_height_chroma,
+ double *meta_row_bw,
+ double *dpte_row_bw,
+ double *qual_row_bw)
+{
+ if (DCCEnable != true) {
+ *meta_row_bw = 0;
+ } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+ *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime)
+ + VRatio / 2 * MetaRowByteChroma
+ / (meta_row_height_chroma * LineTime);
+ } else {
+ *meta_row_bw = VRatio * MetaRowByteLuma / (meta_row_height_luma * LineTime);
+ }
+
+ if (VirtualMemoryEnable != true) {
+ *dpte_row_bw = 0;
+ } else if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+ *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime)
+ + VRatio / 2 * PixelPTEBytesPerRowChroma
+ / (dpte_row_height_chroma * LineTime);
+ } else {
+ *dpte_row_bw = VRatio * PixelPTEBytesPerRowLuma / (dpte_row_height_luma * LineTime);
+ }
+
+ if ((SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10)) {
+ *qual_row_bw = *meta_row_bw + *dpte_row_bw;
+ } else {
+ *qual_row_bw = 0;
+ }
+}
+
+static void CalculateFlipSchedule(
+ struct display_mode_lib *mode_lib,
+ double UrgentExtraLatency,
+ double UrgentLatency,
+ unsigned int MaxPageTableLevels,
+ bool VirtualMemoryEnable,
+ double BandwidthAvailableForImmediateFlip,
+ unsigned int TotImmediateFlipBytes,
+ enum source_format_class SourcePixelFormat,
+ unsigned int ImmediateFlipBytes,
+ double LineTime,
+ double Tno_bw,
+ double VRatio,
+ double PDEAndMetaPTEBytesFrame,
+ unsigned int MetaRowByte,
+ unsigned int PixelPTEBytesPerRow,
+ bool DCCEnable,
+ unsigned int dpte_row_height,
+ unsigned int meta_row_height,
+ double qual_row_bw,
+ double *DestinationLinesToRequestVMInImmediateFlip,
+ double *DestinationLinesToRequestRowInImmediateFlip,
+ double *final_flip_bw,
+ bool *ImmediateFlipSupportedForPipe)
+{
+ double min_row_time = 0.0;
+
+ if (SourcePixelFormat == dm_420_8 || SourcePixelFormat == dm_420_10) {
+ *DestinationLinesToRequestVMInImmediateFlip = 0.0;
+ *DestinationLinesToRequestRowInImmediateFlip = 0.0;
+ *final_flip_bw = qual_row_bw;
+ *ImmediateFlipSupportedForPipe = true;
+ } else {
+ double TimeForFetchingMetaPTEImmediateFlip;
+ double TimeForFetchingRowInVBlankImmediateFlip;
+
+ if (VirtualMemoryEnable == true) {
+ mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
+ * ImmediateFlipBytes / TotImmediateFlipBytes;
+ TimeForFetchingMetaPTEImmediateFlip =
+ dml_max(
+ Tno_bw
+ + PDEAndMetaPTEBytesFrame
+ / mode_lib->vba.ImmediateFlipBW,
+ dml_max(
+ UrgentExtraLatency
+ + UrgentLatency
+ * (MaxPageTableLevels
+ - 1),
+ LineTime / 4.0));
+ } else {
+ TimeForFetchingMetaPTEImmediateFlip = 0;
+ }
+
+ *DestinationLinesToRequestVMInImmediateFlip = dml_floor(
+ 4.0 * (TimeForFetchingMetaPTEImmediateFlip / LineTime + 0.125),
+ 1) / 4.0;
+
+ if ((VirtualMemoryEnable == true || DCCEnable == true)) {
+ mode_lib->vba.ImmediateFlipBW = BandwidthAvailableForImmediateFlip
+ * ImmediateFlipBytes / TotImmediateFlipBytes;
+ TimeForFetchingRowInVBlankImmediateFlip = dml_max(
+ (MetaRowByte + PixelPTEBytesPerRow)
+ / mode_lib->vba.ImmediateFlipBW,
+ dml_max(UrgentLatency, LineTime / 4.0));
+ } else {
+ TimeForFetchingRowInVBlankImmediateFlip = 0;
+ }
+
+ *DestinationLinesToRequestRowInImmediateFlip = dml_floor(
+ 4.0 * (TimeForFetchingRowInVBlankImmediateFlip / LineTime + 0.125),
+ 1) / 4.0;
+
+ if (VirtualMemoryEnable == true) {
+ *final_flip_bw =
+ dml_max(
+ PDEAndMetaPTEBytesFrame
+ / (*DestinationLinesToRequestVMInImmediateFlip
+ * LineTime),
+ (MetaRowByte + PixelPTEBytesPerRow)
+ / (TimeForFetchingRowInVBlankImmediateFlip
+ * LineTime));
+ } else if (MetaRowByte + PixelPTEBytesPerRow > 0) {
+ *final_flip_bw = (MetaRowByte + PixelPTEBytesPerRow)
+ / (TimeForFetchingRowInVBlankImmediateFlip * LineTime);
+ } else {
+ *final_flip_bw = 0;
+ }
+
+ if (VirtualMemoryEnable && !DCCEnable)
+ min_row_time = dpte_row_height * LineTime / VRatio;
+ else if (!VirtualMemoryEnable && DCCEnable)
+ min_row_time = meta_row_height * LineTime / VRatio;
+ else
+ min_row_time = dml_min(dpte_row_height, meta_row_height) * LineTime
+ / VRatio;
+
+ if (*DestinationLinesToRequestVMInImmediateFlip >= 8
+ || *DestinationLinesToRequestRowInImmediateFlip >= 16
+ || TimeForFetchingMetaPTEImmediateFlip
+ + 2 * TimeForFetchingRowInVBlankImmediateFlip
+ > min_row_time)
+ *ImmediateFlipSupportedForPipe = false;
+ else
+ *ImmediateFlipSupportedForPipe = true;
+ }
+}
+
+static void PixelClockAdjustmentForProgressiveToInterlaceUnit(struct display_mode_lib *mode_lib)
+{
+ unsigned int k;
+
+ //Progressive To dml_ml->vba.Interlace Unit Effect
+ for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
+ mode_lib->vba.PixelClockBackEnd[k] = mode_lib->vba.PixelClock[k];
+ if (mode_lib->vba.Interlace[k] == 1
+ && mode_lib->vba.ProgressiveToInterlaceUnitInOPP == true) {
+ mode_lib->vba.PixelClock[k] = 2 * mode_lib->vba.PixelClock[k];
+ }
+ }
+}
+
+static unsigned int CursorBppEnumToBits(enum cursor_bpp ebpp)
+{
+ switch (ebpp) {
+ case dm_cur_2bit:
+ return 2;
+ case dm_cur_32bit:
+ return 32;
+ case dm_cur_64bit:
+ return 64;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int TruncToValidBPP(
+ double DecimalBPP,
+ bool DSCEnabled,
+ enum output_encoder_class Output,
+ enum output_format_class Format,
+ unsigned int DSCInputBitPerComponent)
+{
+ if (Output == dm_hdmi) {
+ if (Format == dm_420) {
+ if (DecimalBPP >= 18)
+ return 18;
+ else if (DecimalBPP >= 15)
+ return 15;
+ else if (DecimalBPP >= 12)
+ return 12;
+ else
+ return 0;
+ } else if (Format == dm_444) {
+ if (DecimalBPP >= 36)
+ return 36;
+ else if (DecimalBPP >= 30)
+ return 30;
+ else if (DecimalBPP >= 24)
+ return 24;
+ else
+ return 0;
+ } else {
+ if (DecimalBPP / 1.5 >= 24)
+ return 24;
+ else if (DecimalBPP / 1.5 >= 20)
+ return 20;
+ else if (DecimalBPP / 1.5 >= 16)
+ return 16;
+ else
+ return 0;
+ }
+ } else {
+ if (DSCEnabled) {
+ if (Format == dm_420) {
+ if (DecimalBPP < 6)
+ return 0;
+ else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
+ return 1.5 * DSCInputBitPerComponent - 1 / 16;
+ else
+ return dml_floor(16 * DecimalBPP, 1) / 16;
+ } else if (Format == dm_n422) {
+ if (DecimalBPP < 7)
+ return 0;
+ else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
+ return 2 * DSCInputBitPerComponent - 1 / 16;
+ else
+ return dml_floor(16 * DecimalBPP, 1) / 16;
+ } else {
+ if (DecimalBPP < 8)
+ return 0;
+ else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
+ return 3 * DSCInputBitPerComponent - 1 / 16;
+ else
+ return dml_floor(16 * DecimalBPP, 1) / 16;
+ }
+ } else if (Format == dm_420) {
+ if (DecimalBPP >= 18)
+ return 18;
+ else if (DecimalBPP >= 15)
+ return 15;
+ else if (DecimalBPP >= 12)
+ return 12;
+ else
+ return 0;
+ } else if (Format == dm_s422 || Format == dm_n422) {
+ if (DecimalBPP >= 24)
+ return 24;
+ else if (DecimalBPP >= 20)
+ return 20;
+ else if (DecimalBPP >= 16)
+ return 16;
+ else
+ return 0;
+ } else {
+ if (DecimalBPP >= 36)
+ return 36;
+ else if (DecimalBPP >= 30)
+ return 30;
+ else if (DecimalBPP >= 24)
+ return 24;
+ else
+ return 0;
+ }
+ }
+}
+
+static void ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib)
+{
+ int i;
+ unsigned int j, k;
+ /*MODE SUPPORT, VOLTAGE STATE AND SOC CONFIGURATION*/
+
+ /*Scale Ratio, taps Support Check*/
+
+ mode_lib->vba.ScaleRatioAndTapsSupport = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.ScalerEnabled[k] == false
+ && ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)
+ || mode_lib->vba.HRatio[k] != 1.0
+ || mode_lib->vba.htaps[k] != 1.0
+ || mode_lib->vba.VRatio[k] != 1.0
+ || mode_lib->vba.vtaps[k] != 1.0)) {
+ mode_lib->vba.ScaleRatioAndTapsSupport = false;
+ } else if (mode_lib->vba.vtaps[k] < 1.0 || mode_lib->vba.vtaps[k] > 8.0
+ || mode_lib->vba.htaps[k] < 1.0 || mode_lib->vba.htaps[k] > 8.0
+ || (mode_lib->vba.htaps[k] > 1.0
+ && (mode_lib->vba.htaps[k] % 2) == 1)
+ || mode_lib->vba.HRatio[k] > mode_lib->vba.MaxHSCLRatio
+ || mode_lib->vba.VRatio[k] > mode_lib->vba.MaxVSCLRatio
+ || mode_lib->vba.HRatio[k] > mode_lib->vba.htaps[k]
+ || mode_lib->vba.VRatio[k] > mode_lib->vba.vtaps[k]
+ || (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8
+ && (mode_lib->vba.HRatio[k] / 2.0
+ > mode_lib->vba.HTAPsChroma[k]
+ || mode_lib->vba.VRatio[k] / 2.0
+ > mode_lib->vba.VTAPsChroma[k]))) {
+ mode_lib->vba.ScaleRatioAndTapsSupport = false;
+ }
+ }
+ /*Source Format, Pixel Format and Scan Support Check*/
+
+ mode_lib->vba.SourceFormatPixelAndScanSupport = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if ((mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+ && mode_lib->vba.SourceScan[k] != dm_horz)
+ || ((mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_var_d_x)
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_64)
+ || (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x
+ && (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8
+ || mode_lib->vba.SourcePixelFormat[k]
+ == dm_420_8
+ || mode_lib->vba.SourcePixelFormat[k]
+ == dm_420_10))
+ || (((mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_gfx7_2d_thin_gl
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_gfx7_2d_thin_lvp)
+ && !((mode_lib->vba.SourcePixelFormat[k]
+ == dm_444_64
+ || mode_lib->vba.SourcePixelFormat[k]
+ == dm_444_32)
+ && mode_lib->vba.SourceScan[k]
+ == dm_horz
+ && mode_lib->vba.SupportGFX7CompatibleTilingIn32bppAnd64bpp
+ == true
+ && mode_lib->vba.DCCEnable[k]
+ == false))
+ || (mode_lib->vba.DCCEnable[k] == true
+ && (mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_linear
+ || mode_lib->vba.SourcePixelFormat[k]
+ == dm_420_8
+ || mode_lib->vba.SourcePixelFormat[k]
+ == dm_420_10)))) {
+ mode_lib->vba.SourceFormatPixelAndScanSupport = false;
+ }
+ }
+ /*Bandwidth Support Check*/
+
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.SourceScan[k] == dm_horz) {
+ mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportWidth[k];
+ } else {
+ mode_lib->vba.SwathWidthYSingleDPP[k] = mode_lib->vba.ViewportHeight[k];
+ }
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_444_64) {
+ mode_lib->vba.BytePerPixelInDETY[k] = 8.0;
+ mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_32) {
+ mode_lib->vba.BytePerPixelInDETY[k] = 4.0;
+ mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+ || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16) {
+ mode_lib->vba.BytePerPixelInDETY[k] = 2.0;
+ mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_mono_8) {
+ mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
+ mode_lib->vba.BytePerPixelInDETC[k] = 0.0;
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8) {
+ mode_lib->vba.BytePerPixelInDETY[k] = 1.0;
+ mode_lib->vba.BytePerPixelInDETC[k] = 2.0;
+ } else {
+ mode_lib->vba.BytePerPixelInDETY[k] = 4.0 / 3;
+ mode_lib->vba.BytePerPixelInDETC[k] = 8.0 / 3;
+ }
+ }
+ mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.SwathWidthYSingleDPP[k]
+ * (dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
+ * mode_lib->vba.VRatio[k]
+ + dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
+ / 2.0 * mode_lib->vba.VRatio[k] / 2)
+ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]);
+ if (mode_lib->vba.DCCEnable[k] == true) {
+ mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+ * (1 + 1 / 256);
+ }
+ if (mode_lib->vba.VirtualMemoryEnable == true
+ && mode_lib->vba.SourceScan[k] != dm_horz
+ && (mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_s_x
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_4kb_d_x)) {
+ mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+ * (1 + 1 / 64);
+ } else if (mode_lib->vba.VirtualMemoryEnable == true
+ && mode_lib->vba.SourceScan[k] == dm_horz
+ && (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_32)
+ && (mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_t
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_s_x
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_t
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_d_x
+ || mode_lib->vba.SurfaceTiling[k] == dm_sw_64kb_r_x)) {
+ mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+ * (1 + 1 / 256);
+ } else if (mode_lib->vba.VirtualMemoryEnable == true) {
+ mode_lib->vba.ReadBandwidth[k] = mode_lib->vba.ReadBandwidth[k]
+ * (1 + 1 / 512);
+ }
+ mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond =
+ mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
+ + mode_lib->vba.ReadBandwidth[k] / 1000.0;
+ }
+ mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.WritebackEnable[k] == true
+ && mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+ mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+ * mode_lib->vba.WritebackDestinationHeight[k]
+ / (mode_lib->vba.WritebackSourceHeight[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]) * 4.0;
+ } else if (mode_lib->vba.WritebackEnable[k] == true
+ && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+ mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+ * mode_lib->vba.WritebackDestinationHeight[k]
+ / (mode_lib->vba.WritebackSourceHeight[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]) * 3.0;
+ } else if (mode_lib->vba.WritebackEnable[k] == true) {
+ mode_lib->vba.WriteBandwidth[k] = mode_lib->vba.WritebackDestinationWidth[k]
+ * mode_lib->vba.WritebackDestinationHeight[k]
+ / (mode_lib->vba.WritebackSourceHeight[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]) * 1.5;
+ } else {
+ mode_lib->vba.WriteBandwidth[k] = 0.0;
+ }
+ mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond =
+ mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond
+ + mode_lib->vba.WriteBandwidth[k] / 1000.0;
+ }
+ mode_lib->vba.TotalBandwidthConsumedGBytePerSecond =
+ mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond
+ + mode_lib->vba.TotalWriteBandwidthConsumedGBytePerSecond;
+ mode_lib->vba.DCCEnabledInAnyPlane = false;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.DCCEnable[k] == true) {
+ mode_lib->vba.DCCEnabledInAnyPlane = true;
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.FabricAndDRAMBandwidthPerState[i] = dml_min(
+ mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
+ * mode_lib->vba.DRAMChannelWidth,
+ mode_lib->vba.FabricClockPerState[i]
+ * mode_lib->vba.FabricDatapathToDCNDataReturn)
+ / 1000;
+ mode_lib->vba.ReturnBWToDCNPerState = dml_min(
+ mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
+ mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0)
+ * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
+ / 100;
+ mode_lib->vba.ReturnBWPerState[i] = mode_lib->vba.ReturnBWToDCNPerState;
+ if (mode_lib->vba.DCCEnabledInAnyPlane == true
+ && mode_lib->vba.ReturnBWToDCNPerState
+ > mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.ReturnBusWidth
+ / 4.0) {
+ mode_lib->vba.ReturnBWPerState[i] =
+ dml_min(
+ mode_lib->vba.ReturnBWPerState[i],
+ mode_lib->vba.ReturnBWToDCNPerState * 4.0
+ * (1.0
+ - mode_lib->vba.UrgentLatency
+ / ((mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0
+ / (mode_lib->vba.ReturnBWToDCNPerState
+ - mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.ReturnBusWidth
+ / 4.0)
+ + mode_lib->vba.UrgentLatency)));
+ }
+ mode_lib->vba.CriticalPoint =
+ 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.UrgentLatency
+ / (mode_lib->vba.ReturnBWToDCNPerState
+ * mode_lib->vba.UrgentLatency
+ + (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0);
+ if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
+ && mode_lib->vba.CriticalPoint < 4.0) {
+ mode_lib->vba.ReturnBWPerState[i] =
+ dml_min(
+ mode_lib->vba.ReturnBWPerState[i],
+ dml_pow(
+ 4.0
+ * mode_lib->vba.ReturnBWToDCNPerState
+ * (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0
+ * mode_lib->vba.ReturnBusWidth
+ * mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.UrgentLatency
+ / (mode_lib->vba.ReturnBWToDCNPerState
+ * mode_lib->vba.UrgentLatency
+ + (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0),
+ 2));
+ }
+ mode_lib->vba.ReturnBWToDCNPerState = dml_min(
+ mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
+ mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000.0);
+ if (mode_lib->vba.DCCEnabledInAnyPlane == true
+ && mode_lib->vba.ReturnBWToDCNPerState
+ > mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.ReturnBusWidth
+ / 4.0) {
+ mode_lib->vba.ReturnBWPerState[i] =
+ dml_min(
+ mode_lib->vba.ReturnBWPerState[i],
+ mode_lib->vba.ReturnBWToDCNPerState * 4.0
+ * (1.0
+ - mode_lib->vba.UrgentLatency
+ / ((mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0
+ / (mode_lib->vba.ReturnBWToDCNPerState
+ - mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.ReturnBusWidth
+ / 4.0)
+ + mode_lib->vba.UrgentLatency)));
+ }
+ mode_lib->vba.CriticalPoint =
+ 2.0 * mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.UrgentLatency
+ / (mode_lib->vba.ReturnBWToDCNPerState
+ * mode_lib->vba.UrgentLatency
+ + (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0);
+ if (mode_lib->vba.DCCEnabledInAnyPlane == true && mode_lib->vba.CriticalPoint > 1.0
+ && mode_lib->vba.CriticalPoint < 4.0) {
+ mode_lib->vba.ReturnBWPerState[i] =
+ dml_min(
+ mode_lib->vba.ReturnBWPerState[i],
+ dml_pow(
+ 4.0
+ * mode_lib->vba.ReturnBWToDCNPerState
+ * (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0
+ * mode_lib->vba.ReturnBusWidth
+ * mode_lib->vba.DCFCLKPerState[i]
+ * mode_lib->vba.UrgentLatency
+ / (mode_lib->vba.ReturnBWToDCNPerState
+ * mode_lib->vba.UrgentLatency
+ + (mode_lib->vba.ROBBufferSizeInKByte
+ - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0),
+ 2));
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ if ((mode_lib->vba.TotalReadBandwidthConsumedGBytePerSecond * 1000.0
+ <= mode_lib->vba.ReturnBWPerState[i])
+ && (mode_lib->vba.TotalBandwidthConsumedGBytePerSecond * 1000.0
+ <= mode_lib->vba.FabricAndDRAMBandwidthPerState[i]
+ * 1000.0
+ * mode_lib->vba.PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency
+ / 100.0)) {
+ mode_lib->vba.BandwidthSupport[i] = true;
+ } else {
+ mode_lib->vba.BandwidthSupport[i] = false;
+ }
+ }
+ /*Writeback Latency support check*/
+
+ mode_lib->vba.WritebackLatencySupport = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.WritebackEnable[k] == true) {
+ if (mode_lib->vba.WritebackPixelFormat[k] == dm_444_32) {
+ if (mode_lib->vba.WriteBandwidth[k]
+ > (mode_lib->vba.WritebackInterfaceLumaBufferSize
+ + mode_lib->vba.WritebackInterfaceChromaBufferSize)
+ / mode_lib->vba.WritebackLatency) {
+ mode_lib->vba.WritebackLatencySupport = false;
+ }
+ } else {
+ if (mode_lib->vba.WriteBandwidth[k]
+ > 1.5
+ * dml_min(
+ mode_lib->vba.WritebackInterfaceLumaBufferSize,
+ 2.0
+ * mode_lib->vba.WritebackInterfaceChromaBufferSize)
+ / mode_lib->vba.WritebackLatency) {
+ mode_lib->vba.WritebackLatencySupport = false;
+ }
+ }
+ }
+ }
+ /*Re-ordering Buffer Support Check*/
+
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
+ (mode_lib->vba.RoundTripPingLatencyCycles + 32.0)
+ / mode_lib->vba.DCFCLKPerState[i]
+ + mode_lib->vba.UrgentOutOfOrderReturnPerChannel
+ * mode_lib->vba.NumberOfChannels
+ / mode_lib->vba.ReturnBWPerState[i];
+ if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte)
+ * 1024.0 / mode_lib->vba.ReturnBWPerState[i]
+ > mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
+ mode_lib->vba.ROBSupport[i] = true;
+ } else {
+ mode_lib->vba.ROBSupport[i] = false;
+ }
+ }
+ /*Writeback Mode Support Check*/
+
+ mode_lib->vba.TotalNumberOfActiveWriteback = 0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.WritebackEnable[k] == true) {
+ mode_lib->vba.TotalNumberOfActiveWriteback =
+ mode_lib->vba.TotalNumberOfActiveWriteback + 1;
+ }
+ }
+ mode_lib->vba.WritebackModeSupport = true;
+ if (mode_lib->vba.TotalNumberOfActiveWriteback > mode_lib->vba.MaxNumWriteback) {
+ mode_lib->vba.WritebackModeSupport = false;
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.WritebackEnable[k] == true
+ && mode_lib->vba.Writeback10bpc420Supported != true
+ && mode_lib->vba.WritebackPixelFormat[k] == dm_420_10) {
+ mode_lib->vba.WritebackModeSupport = false;
+ }
+ }
+ /*Writeback Scale Ratio and Taps Support Check*/
+
+ mode_lib->vba.WritebackScaleRatioAndTapsSupport = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.WritebackEnable[k] == true) {
+ if (mode_lib->vba.WritebackLumaAndChromaScalingSupported == false
+ && (mode_lib->vba.WritebackHRatio[k] != 1.0
+ || mode_lib->vba.WritebackVRatio[k] != 1.0)) {
+ mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+ }
+ if (mode_lib->vba.WritebackHRatio[k] > mode_lib->vba.WritebackMaxHSCLRatio
+ || mode_lib->vba.WritebackVRatio[k]
+ > mode_lib->vba.WritebackMaxVSCLRatio
+ || mode_lib->vba.WritebackHRatio[k]
+ < mode_lib->vba.WritebackMinHSCLRatio
+ || mode_lib->vba.WritebackVRatio[k]
+ < mode_lib->vba.WritebackMinVSCLRatio
+ || mode_lib->vba.WritebackLumaHTaps[k]
+ > mode_lib->vba.WritebackMaxHSCLTaps
+ || mode_lib->vba.WritebackLumaVTaps[k]
+ > mode_lib->vba.WritebackMaxVSCLTaps
+ || mode_lib->vba.WritebackHRatio[k]
+ > mode_lib->vba.WritebackLumaHTaps[k]
+ || mode_lib->vba.WritebackVRatio[k]
+ > mode_lib->vba.WritebackLumaVTaps[k]
+ || (mode_lib->vba.WritebackLumaHTaps[k] > 2.0
+ && ((mode_lib->vba.WritebackLumaHTaps[k] % 2)
+ == 1))
+ || (mode_lib->vba.WritebackPixelFormat[k] != dm_444_32
+ && (mode_lib->vba.WritebackChromaHTaps[k]
+ > mode_lib->vba.WritebackMaxHSCLTaps
+ || mode_lib->vba.WritebackChromaVTaps[k]
+ > mode_lib->vba.WritebackMaxVSCLTaps
+ || 2.0
+ * mode_lib->vba.WritebackHRatio[k]
+ > mode_lib->vba.WritebackChromaHTaps[k]
+ || 2.0
+ * mode_lib->vba.WritebackVRatio[k]
+ > mode_lib->vba.WritebackChromaVTaps[k]
+ || (mode_lib->vba.WritebackChromaHTaps[k] > 2.0
+ && ((mode_lib->vba.WritebackChromaHTaps[k] % 2) == 1))))) {
+ mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+ }
+ if (mode_lib->vba.WritebackVRatio[k] < 1.0) {
+ mode_lib->vba.WritebackLumaVExtra =
+ dml_max(1.0 - 2.0 / dml_ceil(1.0 / mode_lib->vba.WritebackVRatio[k], 1.0), 0.0);
+ } else {
+ mode_lib->vba.WritebackLumaVExtra = -1;
+ }
+ if ((mode_lib->vba.WritebackPixelFormat[k] == dm_444_32
+ && mode_lib->vba.WritebackLumaVTaps[k]
+ > (mode_lib->vba.WritebackLineBufferLumaBufferSize
+ + mode_lib->vba.WritebackLineBufferChromaBufferSize)
+ / 3.0
+ / mode_lib->vba.WritebackDestinationWidth[k]
+ - mode_lib->vba.WritebackLumaVExtra)
+ || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
+ && mode_lib->vba.WritebackLumaVTaps[k]
+ > mode_lib->vba.WritebackLineBufferLumaBufferSize
+ / mode_lib->vba.WritebackDestinationWidth[k]
+ - mode_lib->vba.WritebackLumaVExtra)
+ || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
+ && mode_lib->vba.WritebackLumaVTaps[k]
+ > mode_lib->vba.WritebackLineBufferLumaBufferSize
+ * 8.0 / 10.0
+ / mode_lib->vba.WritebackDestinationWidth[k]
+ - mode_lib->vba.WritebackLumaVExtra)) {
+ mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+ }
+ if (2.0 * mode_lib->vba.WritebackVRatio[k] < 1) {
+ mode_lib->vba.WritebackChromaVExtra = 0.0;
+ } else {
+ mode_lib->vba.WritebackChromaVExtra = -1;
+ }
+ if ((mode_lib->vba.WritebackPixelFormat[k] == dm_420_8
+ && mode_lib->vba.WritebackChromaVTaps[k]
+ > mode_lib->vba.WritebackLineBufferChromaBufferSize
+ / mode_lib->vba.WritebackDestinationWidth[k]
+ - mode_lib->vba.WritebackChromaVExtra)
+ || (mode_lib->vba.WritebackPixelFormat[k] == dm_420_10
+ && mode_lib->vba.WritebackChromaVTaps[k]
+ > mode_lib->vba.WritebackLineBufferChromaBufferSize
+ * 8.0 / 10.0
+ / mode_lib->vba.WritebackDestinationWidth[k]
+ - mode_lib->vba.WritebackChromaVExtra)) {
+ mode_lib->vba.WritebackScaleRatioAndTapsSupport = false;
+ }
+ }
+ }
+ /*Maximum DISPCLK/DPPCLK Support check*/
+
+ mode_lib->vba.WritebackRequiredDISPCLK = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.WritebackEnable[k] == true) {
+ mode_lib->vba.WritebackRequiredDISPCLK =
+ dml_max(
+ mode_lib->vba.WritebackRequiredDISPCLK,
+ CalculateWriteBackDISPCLK(
+ mode_lib->vba.WritebackPixelFormat[k],
+ mode_lib->vba.PixelClock[k],
+ mode_lib->vba.WritebackHRatio[k],
+ mode_lib->vba.WritebackVRatio[k],
+ mode_lib->vba.WritebackLumaHTaps[k],
+ mode_lib->vba.WritebackLumaVTaps[k],
+ mode_lib->vba.WritebackChromaHTaps[k],
+ mode_lib->vba.WritebackChromaVTaps[k],
+ mode_lib->vba.WritebackDestinationWidth[k],
+ mode_lib->vba.HTotal[k],
+ mode_lib->vba.WritebackChromaLineBufferWidth));
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.HRatio[k] > 1.0) {
+ mode_lib->vba.PSCL_FACTOR[k] = dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput
+ * mode_lib->vba.HRatio[k]
+ / dml_ceil(
+ mode_lib->vba.htaps[k]
+ / 6.0,
+ 1.0));
+ } else {
+ mode_lib->vba.PSCL_FACTOR[k] = dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput);
+ }
+ if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+ mode_lib->vba.PSCL_FACTOR_CHROMA[k] = 0.0;
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
+ mode_lib->vba.PixelClock[k]
+ * dml_max3(
+ mode_lib->vba.vtaps[k] / 6.0
+ * dml_min(
+ 1.0,
+ mode_lib->vba.HRatio[k]),
+ mode_lib->vba.HRatio[k]
+ * mode_lib->vba.VRatio[k]
+ / mode_lib->vba.PSCL_FACTOR[k],
+ 1.0);
+ if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0)
+ && mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ < 2.0 * mode_lib->vba.PixelClock[k]) {
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
+ * mode_lib->vba.PixelClock[k];
+ }
+ } else {
+ if (mode_lib->vba.HRatio[k] / 2.0 > 1.0) {
+ mode_lib->vba.PSCL_FACTOR_CHROMA[k] =
+ dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput
+ * mode_lib->vba.HRatio[k]
+ / 2.0
+ / dml_ceil(
+ mode_lib->vba.HTAPsChroma[k]
+ / 6.0,
+ 1.0));
+ } else {
+ mode_lib->vba.PSCL_FACTOR_CHROMA[k] = dml_min(
+ mode_lib->vba.MaxDCHUBToPSCLThroughput,
+ mode_lib->vba.MaxPSCLToLBThroughput);
+ }
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k] =
+ mode_lib->vba.PixelClock[k]
+ * dml_max5(
+ mode_lib->vba.vtaps[k] / 6.0
+ * dml_min(
+ 1.0,
+ mode_lib->vba.HRatio[k]),
+ mode_lib->vba.HRatio[k]
+ * mode_lib->vba.VRatio[k]
+ / mode_lib->vba.PSCL_FACTOR[k],
+ mode_lib->vba.VTAPsChroma[k]
+ / 6.0
+ * dml_min(
+ 1.0,
+ mode_lib->vba.HRatio[k]
+ / 2.0),
+ mode_lib->vba.HRatio[k]
+ * mode_lib->vba.VRatio[k]
+ / 4.0
+ / mode_lib->vba.PSCL_FACTOR_CHROMA[k],
+ 1.0);
+ if ((mode_lib->vba.htaps[k] > 6.0 || mode_lib->vba.vtaps[k] > 6.0
+ || mode_lib->vba.HTAPsChroma[k] > 6.0
+ || mode_lib->vba.VTAPsChroma[k] > 6.0)
+ && mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ < 2.0 * mode_lib->vba.PixelClock[k]) {
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k] = 2.0
+ * mode_lib->vba.PixelClock[k];
+ }
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ Calculate256BBlockSizes(
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.SurfaceTiling[k],
+ dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
+ dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
+ &mode_lib->vba.Read256BlockHeightY[k],
+ &mode_lib->vba.Read256BlockHeightC[k],
+ &mode_lib->vba.Read256BlockWidthY[k],
+ &mode_lib->vba.Read256BlockWidthC[k]);
+ if (mode_lib->vba.SourceScan[k] == dm_horz) {
+ mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockHeightY[k];
+ mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockHeightC[k];
+ } else {
+ mode_lib->vba.MaxSwathHeightY[k] = mode_lib->vba.Read256BlockWidthY[k];
+ mode_lib->vba.MaxSwathHeightC[k] = mode_lib->vba.Read256BlockWidthC[k];
+ }
+ if ((mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_32
+ || mode_lib->vba.SourcePixelFormat[k] == dm_444_16
+ || mode_lib->vba.SourcePixelFormat[k] == dm_mono_16
+ || mode_lib->vba.SourcePixelFormat[k] == dm_mono_8)) {
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear
+ || (mode_lib->vba.SourcePixelFormat[k] == dm_444_64
+ && (mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_4kb_s
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_4kb_s_x
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_64kb_s
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_64kb_s_t
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_64kb_s_x
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_var_s
+ || mode_lib->vba.SurfaceTiling[k]
+ == dm_sw_var_s_x)
+ && mode_lib->vba.SourceScan[k] == dm_horz)) {
+ mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+ } else {
+ mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
+ / 2.0;
+ }
+ mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+ } else {
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+ mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+ mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_8
+ && mode_lib->vba.SourceScan[k] == dm_horz) {
+ mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k]
+ / 2.0;
+ mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+ } else if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10
+ && mode_lib->vba.SourceScan[k] == dm_horz) {
+ mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k]
+ / 2.0;
+ mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+ } else {
+ mode_lib->vba.MinSwathHeightY[k] = mode_lib->vba.MaxSwathHeightY[k];
+ mode_lib->vba.MinSwathHeightC[k] = mode_lib->vba.MaxSwathHeightC[k];
+ }
+ }
+ if (mode_lib->vba.SurfaceTiling[k] == dm_sw_linear) {
+ mode_lib->vba.MaximumSwathWidthSupport = 8192.0;
+ } else {
+ mode_lib->vba.MaximumSwathWidthSupport = 5120.0;
+ }
+ mode_lib->vba.MaximumSwathWidthInDETBuffer =
+ dml_min(
+ mode_lib->vba.MaximumSwathWidthSupport,
+ mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0
+ / (mode_lib->vba.BytePerPixelInDETY[k]
+ * mode_lib->vba.MinSwathHeightY[k]
+ + mode_lib->vba.BytePerPixelInDETC[k]
+ / 2.0
+ * mode_lib->vba.MinSwathHeightC[k]));
+ if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+ mode_lib->vba.MaximumSwathWidthInLineBuffer =
+ mode_lib->vba.LineBufferSize
+ * dml_max(mode_lib->vba.HRatio[k], 1.0)
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.vtaps[k]
+ + dml_max(
+ dml_ceil(
+ mode_lib->vba.VRatio[k],
+ 1.0)
+ - 2,
+ 0.0));
+ } else {
+ mode_lib->vba.MaximumSwathWidthInLineBuffer =
+ dml_min(
+ mode_lib->vba.LineBufferSize
+ * dml_max(
+ mode_lib->vba.HRatio[k],
+ 1.0)
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.vtaps[k]
+ + dml_max(
+ dml_ceil(
+ mode_lib->vba.VRatio[k],
+ 1.0)
+ - 2,
+ 0.0)),
+ 2.0 * mode_lib->vba.LineBufferSize
+ * dml_max(
+ mode_lib->vba.HRatio[k]
+ / 2.0,
+ 1.0)
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.VTAPsChroma[k]
+ + dml_max(
+ dml_ceil(
+ mode_lib->vba.VRatio[k]
+ / 2.0,
+ 1.0)
+ - 2,
+ 0.0)));
+ }
+ mode_lib->vba.MaximumSwathWidth[k] = dml_min(
+ mode_lib->vba.MaximumSwathWidthInDETBuffer,
+ mode_lib->vba.MaximumSwathWidthInLineBuffer);
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
+ mode_lib->vba.MaxDispclk[i],
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+ mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity = RoundToDFSGranularityDown(
+ mode_lib->vba.MaxDppclk[i],
+ mode_lib->vba.DISPCLKDPPCLKVCOSpeed);
+ mode_lib->vba.RequiredDISPCLK[i] = 0.0;
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
+ mode_lib->vba.PixelClock[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ * (1.0
+ + mode_lib->vba.DISPCLKRampingMargin
+ / 100.0);
+ if (mode_lib->vba.ODMCapability == true
+ && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+ > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+ mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
+ mode_lib->vba.PlaneRequiredDISPCLK =
+ mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+ / 2.0;
+ } else {
+ mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
+ mode_lib->vba.PlaneRequiredDISPCLK =
+ mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+ }
+ if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
+ && mode_lib->vba.SwathWidthYSingleDPP[k]
+ <= mode_lib->vba.MaximumSwathWidth[k]
+ && mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
+ mode_lib->vba.NoOfDPP[i][k] = 1;
+ mode_lib->vba.RequiredDPPCLK[i][k] =
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0);
+ } else {
+ mode_lib->vba.NoOfDPP[i][k] = 2;
+ mode_lib->vba.RequiredDPPCLK[i][k] =
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ / 2.0;
+ }
+ mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+ mode_lib->vba.RequiredDISPCLK[i],
+ mode_lib->vba.PlaneRequiredDISPCLK);
+ if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k] / mode_lib->vba.NoOfDPP[i][k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+ || (mode_lib->vba.PlaneRequiredDISPCLK
+ > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+ }
+ }
+ mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.TotalNumberOfActiveDPP[i] =
+ mode_lib->vba.TotalNumberOfActiveDPP[i]
+ + mode_lib->vba.NoOfDPP[i][k];
+ }
+ if ((mode_lib->vba.MaxDispclk[i] == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
+ && mode_lib->vba.MaxDppclk[i]
+ == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])
+ && (mode_lib->vba.TotalNumberOfActiveDPP[i]
+ > mode_lib->vba.MaxNumDPP
+ || mode_lib->vba.DISPCLK_DPPCLK_Support[i] == false)) {
+ mode_lib->vba.RequiredDISPCLK[i] = 0.0;
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine =
+ mode_lib->vba.PixelClock[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0);
+ if (mode_lib->vba.ODMCapability == true
+ && mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+ > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+ mode_lib->vba.ODMCombineEnablePerState[i][k] = true;
+ mode_lib->vba.PlaneRequiredDISPCLK =
+ mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine
+ / 2.0;
+ } else {
+ mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
+ mode_lib->vba.PlaneRequiredDISPCLK =
+ mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+ }
+ if (mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
+ && mode_lib->vba.SwathWidthYSingleDPP[k]
+ <= mode_lib->vba.MaximumSwathWidth[k]
+ && mode_lib->vba.ODMCombineEnablePerState[i][k]
+ == false) {
+ mode_lib->vba.NoOfDPP[i][k] = 1;
+ mode_lib->vba.RequiredDPPCLK[i][k] =
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0);
+ } else {
+ mode_lib->vba.NoOfDPP[i][k] = 2;
+ mode_lib->vba.RequiredDPPCLK[i][k] =
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ / 2.0;
+ }
+ mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+ mode_lib->vba.RequiredDISPCLK[i],
+ mode_lib->vba.PlaneRequiredDISPCLK);
+ if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ / mode_lib->vba.NoOfDPP[i][k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+ || (mode_lib->vba.PlaneRequiredDISPCLK
+ > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+ }
+ }
+ mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.TotalNumberOfActiveDPP[i] =
+ mode_lib->vba.TotalNumberOfActiveDPP[i]
+ + mode_lib->vba.NoOfDPP[i][k];
+ }
+ }
+ if (mode_lib->vba.TotalNumberOfActiveDPP[i] > mode_lib->vba.MaxNumDPP) {
+ mode_lib->vba.RequiredDISPCLK[i] = 0.0;
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.ODMCombineEnablePerState[i][k] = false;
+ if (mode_lib->vba.SwathWidthYSingleDPP[k]
+ <= mode_lib->vba.MaximumSwathWidth[k]) {
+ mode_lib->vba.NoOfDPP[i][k] = 1;
+ mode_lib->vba.RequiredDPPCLK[i][k] =
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0);
+ } else {
+ mode_lib->vba.NoOfDPP[i][k] = 2;
+ mode_lib->vba.RequiredDPPCLK[i][k] =
+ mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ / 2.0;
+ }
+ if (!(mode_lib->vba.MaxDispclk[i]
+ == mode_lib->vba.MaxDispclk[DC__VOLTAGE_STATES]
+ && mode_lib->vba.MaxDppclk[i]
+ == mode_lib->vba.MaxDppclk[DC__VOLTAGE_STATES])) {
+ mode_lib->vba.PlaneRequiredDISPCLK =
+ mode_lib->vba.PixelClock[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ * (1.0
+ + mode_lib->vba.DISPCLKRampingMargin
+ / 100.0);
+ } else {
+ mode_lib->vba.PlaneRequiredDISPCLK =
+ mode_lib->vba.PixelClock[k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0);
+ }
+ mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+ mode_lib->vba.RequiredDISPCLK[i],
+ mode_lib->vba.PlaneRequiredDISPCLK);
+ if ((mode_lib->vba.MinDPPCLKUsingSingleDPP[k]
+ / mode_lib->vba.NoOfDPP[i][k]
+ * (1.0
+ + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ > mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity)
+ || (mode_lib->vba.PlaneRequiredDISPCLK
+ > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity)) {
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+ }
+ }
+ mode_lib->vba.TotalNumberOfActiveDPP[i] = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.TotalNumberOfActiveDPP[i] =
+ mode_lib->vba.TotalNumberOfActiveDPP[i]
+ + mode_lib->vba.NoOfDPP[i][k];
+ }
+ }
+ mode_lib->vba.RequiredDISPCLK[i] = dml_max(
+ mode_lib->vba.RequiredDISPCLK[i],
+ mode_lib->vba.WritebackRequiredDISPCLK);
+ if (mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity
+ < mode_lib->vba.WritebackRequiredDISPCLK) {
+ mode_lib->vba.DISPCLK_DPPCLK_Support[i] = false;
+ }
+ }
+ /*Viewport Size Check*/
+
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.ViewportSizeSupport[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
+ if (dml_min(
+ mode_lib->vba.SwathWidthYSingleDPP[k],
+ dml_round(
+ mode_lib->vba.HActive[k] / 2.0
+ * mode_lib->vba.HRatio[k]))
+ > mode_lib->vba.MaximumSwathWidth[k]) {
+ mode_lib->vba.ViewportSizeSupport[i] = false;
+ }
+ } else {
+ if (mode_lib->vba.SwathWidthYSingleDPP[k] / 2.0
+ > mode_lib->vba.MaximumSwathWidth[k]) {
+ mode_lib->vba.ViewportSizeSupport[i] = false;
+ }
+ }
+ }
+ }
+ /*Total Available Pipes Support Check*/
+
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ if (mode_lib->vba.TotalNumberOfActiveDPP[i] <= mode_lib->vba.MaxNumDPP) {
+ mode_lib->vba.TotalAvailablePipesSupport[i] = true;
+ } else {
+ mode_lib->vba.TotalAvailablePipesSupport[i] = false;
+ }
+ }
+ /*Total Available OTG Support Check*/
+
+ mode_lib->vba.TotalNumberOfActiveOTG = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ mode_lib->vba.TotalNumberOfActiveOTG = mode_lib->vba.TotalNumberOfActiveOTG
+ + 1.0;
+ }
+ }
+ if (mode_lib->vba.TotalNumberOfActiveOTG <= mode_lib->vba.MaxNumOTG) {
+ mode_lib->vba.NumberOfOTGSupport = true;
+ } else {
+ mode_lib->vba.NumberOfOTGSupport = false;
+ }
+ /*Display IO and DSC Support Check*/
+
+ mode_lib->vba.NonsupportedDSCInputBPC = false;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (!(mode_lib->vba.DSCInputBitPerComponent[k] == 12.0
+ || mode_lib->vba.DSCInputBitPerComponent[k] == 10.0
+ || mode_lib->vba.DSCInputBitPerComponent[k] == 8.0)) {
+ mode_lib->vba.NonsupportedDSCInputBPC = true;
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.RequiresDSC[i][k] = 0;
+ mode_lib->vba.RequiresFEC[i][k] = 0;
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ if (mode_lib->vba.Output[k] == dm_hdmi) {
+ mode_lib->vba.RequiresDSC[i][k] = 0;
+ mode_lib->vba.RequiresFEC[i][k] = 0;
+ mode_lib->vba.OutputBppPerState[i][k] =
+ TruncToValidBPP(
+ dml_min(
+ 600.0,
+ mode_lib->vba.PHYCLKPerState[i])
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 24,
+ false,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ } else if (mode_lib->vba.Output[k] == dm_dp
+ || mode_lib->vba.Output[k] == dm_edp) {
+ if (mode_lib->vba.Output[k] == dm_edp) {
+ mode_lib->vba.EffectiveFECOverhead = 0.0;
+ } else {
+ mode_lib->vba.EffectiveFECOverhead =
+ mode_lib->vba.FECOverhead;
+ }
+ if (mode_lib->vba.PHYCLKPerState[i] >= 270.0) {
+ mode_lib->vba.Outbpp =
+ TruncToValidBPP(
+ (1.0
+ - mode_lib->vba.Downspreading
+ / 100.0)
+ * 270.0
+ * mode_lib->vba.OutputLinkDPLanes[k]
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 8.0,
+ false,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ mode_lib->vba.OutbppDSC =
+ TruncToValidBPP(
+ (1.0
+ - mode_lib->vba.Downspreading
+ / 100.0)
+ * (1.0
+ - mode_lib->vba.EffectiveFECOverhead
+ / 100.0)
+ * 270.0
+ * mode_lib->vba.OutputLinkDPLanes[k]
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 8.0,
+ true,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ if (mode_lib->vba.DSCEnabled[k] == true) {
+ mode_lib->vba.RequiresDSC[i][k] = true;
+ if (mode_lib->vba.Output[k] == dm_dp) {
+ mode_lib->vba.RequiresFEC[i][k] =
+ true;
+ } else {
+ mode_lib->vba.RequiresFEC[i][k] =
+ false;
+ }
+ mode_lib->vba.Outbpp =
+ mode_lib->vba.OutbppDSC;
+ } else {
+ mode_lib->vba.RequiresDSC[i][k] = false;
+ mode_lib->vba.RequiresFEC[i][k] = false;
+ }
+ mode_lib->vba.OutputBppPerState[i][k] =
+ mode_lib->vba.Outbpp;
+ }
+ if (mode_lib->vba.Outbpp == 0) {
+ mode_lib->vba.Outbpp =
+ TruncToValidBPP(
+ (1.0
+ - mode_lib->vba.Downspreading
+ / 100.0)
+ * 540.0
+ * mode_lib->vba.OutputLinkDPLanes[k]
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 8.0,
+ false,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ mode_lib->vba.OutbppDSC =
+ TruncToValidBPP(
+ (1.0
+ - mode_lib->vba.Downspreading
+ / 100.0)
+ * (1.0
+ - mode_lib->vba.EffectiveFECOverhead
+ / 100.0)
+ * 540.0
+ * mode_lib->vba.OutputLinkDPLanes[k]
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 8.0,
+ true,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ if (mode_lib->vba.DSCEnabled[k] == true) {
+ mode_lib->vba.RequiresDSC[i][k] = true;
+ if (mode_lib->vba.Output[k] == dm_dp) {
+ mode_lib->vba.RequiresFEC[i][k] =
+ true;
+ } else {
+ mode_lib->vba.RequiresFEC[i][k] =
+ false;
+ }
+ mode_lib->vba.Outbpp =
+ mode_lib->vba.OutbppDSC;
+ } else {
+ mode_lib->vba.RequiresDSC[i][k] = false;
+ mode_lib->vba.RequiresFEC[i][k] = false;
+ }
+ mode_lib->vba.OutputBppPerState[i][k] =
+ mode_lib->vba.Outbpp;
+ }
+ if (mode_lib->vba.Outbpp == 0
+ && mode_lib->vba.PHYCLKPerState[i]
+ >= 810.0) {
+ mode_lib->vba.Outbpp =
+ TruncToValidBPP(
+ (1.0
+ - mode_lib->vba.Downspreading
+ / 100.0)
+ * 810.0
+ * mode_lib->vba.OutputLinkDPLanes[k]
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 8.0,
+ false,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ mode_lib->vba.OutbppDSC =
+ TruncToValidBPP(
+ (1.0
+ - mode_lib->vba.Downspreading
+ / 100.0)
+ * (1.0
+ - mode_lib->vba.EffectiveFECOverhead
+ / 100.0)
+ * 810.0
+ * mode_lib->vba.OutputLinkDPLanes[k]
+ / mode_lib->vba.PixelClockBackEnd[k]
+ * 8.0,
+ true,
+ mode_lib->vba.Output[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.DSCInputBitPerComponent[k]);
+ if (mode_lib->vba.DSCEnabled[k] == true
+ || mode_lib->vba.Outbpp == 0) {
+ mode_lib->vba.RequiresDSC[i][k] = true;
+ if (mode_lib->vba.Output[k] == dm_dp) {
+ mode_lib->vba.RequiresFEC[i][k] =
+ true;
+ } else {
+ mode_lib->vba.RequiresFEC[i][k] =
+ false;
+ }
+ mode_lib->vba.Outbpp =
+ mode_lib->vba.OutbppDSC;
+ } else {
+ mode_lib->vba.RequiresDSC[i][k] = false;
+ mode_lib->vba.RequiresFEC[i][k] = false;
+ }
+ mode_lib->vba.OutputBppPerState[i][k] =
+ mode_lib->vba.Outbpp;
+ }
+ }
+ } else {
+ mode_lib->vba.OutputBppPerState[i][k] = 0;
+ }
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.DIOSupport[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.OutputBppPerState[i][k] == 0
+ || (mode_lib->vba.OutputFormat[k] == dm_420
+ && mode_lib->vba.ProgressiveToInterlaceUnitInOPP
+ == true)) {
+ mode_lib->vba.DIOSupport[i] = false;
+ }
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] = false;
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ if ((mode_lib->vba.Output[k] == dm_dp
+ || mode_lib->vba.Output[k] == dm_edp)) {
+ if (mode_lib->vba.OutputFormat[k] == dm_420
+ || mode_lib->vba.OutputFormat[k]
+ == dm_n422) {
+ mode_lib->vba.DSCFormatFactor = 2;
+ } else {
+ mode_lib->vba.DSCFormatFactor = 1;
+ }
+ if (mode_lib->vba.RequiresDSC[i][k] == true) {
+ if (mode_lib->vba.ODMCombineEnablePerState[i][k]
+ == true) {
+ if (mode_lib->vba.PixelClockBackEnd[k] / 6.0
+ / mode_lib->vba.DSCFormatFactor
+ > (1.0
+ - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ * mode_lib->vba.MaxDSCCLK[i]) {
+ mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
+ true;
+ }
+ } else {
+ if (mode_lib->vba.PixelClockBackEnd[k] / 3.0
+ / mode_lib->vba.DSCFormatFactor
+ > (1.0
+ - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading
+ / 100.0)
+ * mode_lib->vba.MaxDSCCLK[i]) {
+ mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] =
+ true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.NotEnoughDSCUnits[i] = false;
+ mode_lib->vba.TotalDSCUnitsRequired = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.RequiresDSC[i][k] == true) {
+ if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
+ mode_lib->vba.TotalDSCUnitsRequired =
+ mode_lib->vba.TotalDSCUnitsRequired + 2.0;
+ } else {
+ mode_lib->vba.TotalDSCUnitsRequired =
+ mode_lib->vba.TotalDSCUnitsRequired + 1.0;
+ }
+ }
+ }
+ if (mode_lib->vba.TotalDSCUnitsRequired > mode_lib->vba.NumberOfDSC) {
+ mode_lib->vba.NotEnoughDSCUnits[i] = true;
+ }
+ }
+ /*DSC Delay per state*/
+
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.BlendingAndTiming[k] != k) {
+ mode_lib->vba.slices = 0;
+ } else if (mode_lib->vba.RequiresDSC[i][k] == 0
+ || mode_lib->vba.RequiresDSC[i][k] == false) {
+ mode_lib->vba.slices = 0;
+ } else if (mode_lib->vba.PixelClockBackEnd[k] > 3200.0) {
+ mode_lib->vba.slices = dml_ceil(
+ mode_lib->vba.PixelClockBackEnd[k] / 400.0,
+ 4.0);
+ } else if (mode_lib->vba.PixelClockBackEnd[k] > 1360.0) {
+ mode_lib->vba.slices = 8.0;
+ } else if (mode_lib->vba.PixelClockBackEnd[k] > 680.0) {
+ mode_lib->vba.slices = 4.0;
+ } else if (mode_lib->vba.PixelClockBackEnd[k] > 340.0) {
+ mode_lib->vba.slices = 2.0;
+ } else {
+ mode_lib->vba.slices = 1.0;
+ }
+ if (mode_lib->vba.OutputBppPerState[i][k] == 0
+ || mode_lib->vba.OutputBppPerState[i][k] == 0) {
+ mode_lib->vba.bpp = 0.0;
+ } else {
+ mode_lib->vba.bpp = mode_lib->vba.OutputBppPerState[i][k];
+ }
+ if (mode_lib->vba.RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
+ if (mode_lib->vba.ODMCombineEnablePerState[i][k] == false) {
+ mode_lib->vba.DSCDelayPerState[i][k] =
+ dscceComputeDelay(
+ mode_lib->vba.DSCInputBitPerComponent[k],
+ mode_lib->vba.bpp,
+ dml_ceil(
+ mode_lib->vba.HActive[k]
+ / mode_lib->vba.slices,
+ 1.0),
+ mode_lib->vba.slices,
+ mode_lib->vba.OutputFormat[k])
+ + dscComputeDelay(
+ mode_lib->vba.OutputFormat[k]);
+ } else {
+ mode_lib->vba.DSCDelayPerState[i][k] =
+ 2.0
+ * (dscceComputeDelay(
+ mode_lib->vba.DSCInputBitPerComponent[k],
+ mode_lib->vba.bpp,
+ dml_ceil(
+ mode_lib->vba.HActive[k]
+ / mode_lib->vba.slices,
+ 1.0),
+ mode_lib->vba.slices
+ / 2,
+ mode_lib->vba.OutputFormat[k])
+ + dscComputeDelay(
+ mode_lib->vba.OutputFormat[k]));
+ }
+ mode_lib->vba.DSCDelayPerState[i][k] =
+ mode_lib->vba.DSCDelayPerState[i][k]
+ * mode_lib->vba.PixelClock[k]
+ / mode_lib->vba.PixelClockBackEnd[k];
+ } else {
+ mode_lib->vba.DSCDelayPerState[i][k] = 0.0;
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+ if (mode_lib->vba.BlendingAndTiming[k] == j
+ && mode_lib->vba.RequiresDSC[i][j] == true) {
+ mode_lib->vba.DSCDelayPerState[i][k] =
+ mode_lib->vba.DSCDelayPerState[i][j];
+ }
+ }
+ }
+ }
+ /*Urgent Latency Support Check*/
+
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ if (mode_lib->vba.ODMCombineEnablePerState[i][k] == true) {
+ mode_lib->vba.SwathWidthYPerState[i][k] =
+ dml_min(
+ mode_lib->vba.SwathWidthYSingleDPP[k],
+ dml_round(
+ mode_lib->vba.HActive[k]
+ / 2.0
+ * mode_lib->vba.HRatio[k]));
+ } else {
+ mode_lib->vba.SwathWidthYPerState[i][k] =
+ mode_lib->vba.SwathWidthYSingleDPP[k]
+ / mode_lib->vba.NoOfDPP[i][k];
+ }
+ mode_lib->vba.SwathWidthGranularityY = 256.0
+ / dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0)
+ / mode_lib->vba.MaxSwathHeightY[k];
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesY = (dml_ceil(
+ mode_lib->vba.SwathWidthYPerState[i][k] - 1.0,
+ mode_lib->vba.SwathWidthGranularityY)
+ + mode_lib->vba.SwathWidthGranularityY)
+ * mode_lib->vba.BytePerPixelInDETY[k]
+ * mode_lib->vba.MaxSwathHeightY[k];
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesY = dml_ceil(
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesY,
+ 256.0) + 256;
+ }
+ if (mode_lib->vba.MaxSwathHeightC[k] > 0.0) {
+ mode_lib->vba.SwathWidthGranularityC = 256.0
+ / dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0)
+ / mode_lib->vba.MaxSwathHeightC[k];
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesC = (dml_ceil(
+ mode_lib->vba.SwathWidthYPerState[i][k] / 2.0 - 1.0,
+ mode_lib->vba.SwathWidthGranularityC)
+ + mode_lib->vba.SwathWidthGranularityC)
+ * mode_lib->vba.BytePerPixelInDETC[k]
+ * mode_lib->vba.MaxSwathHeightC[k];
+ if (mode_lib->vba.SourcePixelFormat[k] == dm_420_10) {
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesC = dml_ceil(
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesC,
+ 256.0) + 256;
+ }
+ } else {
+ mode_lib->vba.RoundedUpMaxSwathSizeBytesC = 0.0;
+ }
+ if (mode_lib->vba.RoundedUpMaxSwathSizeBytesY
+ + mode_lib->vba.RoundedUpMaxSwathSizeBytesC
+ <= mode_lib->vba.DETBufferSizeInKByte * 1024.0 / 2.0) {
+ mode_lib->vba.SwathHeightYPerState[i][k] =
+ mode_lib->vba.MaxSwathHeightY[k];
+ mode_lib->vba.SwathHeightCPerState[i][k] =
+ mode_lib->vba.MaxSwathHeightC[k];
+ } else {
+ mode_lib->vba.SwathHeightYPerState[i][k] =
+ mode_lib->vba.MinSwathHeightY[k];
+ mode_lib->vba.SwathHeightCPerState[i][k] =
+ mode_lib->vba.MinSwathHeightC[k];
+ }
+ if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+ mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / mode_lib->vba.BytePerPixelInDETY[k]
+ / mode_lib->vba.SwathWidthYPerState[i][k];
+ mode_lib->vba.LinesInDETChroma = 0.0;
+ } else if (mode_lib->vba.SwathHeightYPerState[i][k]
+ <= mode_lib->vba.SwathHeightCPerState[i][k]) {
+ mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETY[k]
+ / mode_lib->vba.SwathWidthYPerState[i][k];
+ mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / 2.0 / mode_lib->vba.BytePerPixelInDETC[k]
+ / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
+ } else {
+ mode_lib->vba.LinesInDETLuma = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 * 2.0 / 3.0
+ / mode_lib->vba.BytePerPixelInDETY[k]
+ / mode_lib->vba.SwathWidthYPerState[i][k];
+ mode_lib->vba.LinesInDETChroma = mode_lib->vba.DETBufferSizeInKByte
+ * 1024.0 / 3.0 / mode_lib->vba.BytePerPixelInDETY[k]
+ / (mode_lib->vba.SwathWidthYPerState[i][k] / 2.0);
+ }
+ mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma =
+ dml_min(
+ mode_lib->vba.MaxLineBufferLines,
+ dml_floor(
+ mode_lib->vba.LineBufferSize
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.SwathWidthYPerState[i][k]
+ / dml_max(
+ mode_lib->vba.HRatio[k],
+ 1.0)),
+ 1.0))
+ - (mode_lib->vba.vtaps[k] - 1.0);
+ mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma =
+ dml_min(
+ mode_lib->vba.MaxLineBufferLines,
+ dml_floor(
+ mode_lib->vba.LineBufferSize
+ / mode_lib->vba.LBBitPerPixel[k]
+ / (mode_lib->vba.SwathWidthYPerState[i][k]
+ / 2.0
+ / dml_max(
+ mode_lib->vba.HRatio[k]
+ / 2.0,
+ 1.0)),
+ 1.0))
+ - (mode_lib->vba.VTAPsChroma[k] - 1.0);
+ mode_lib->vba.EffectiveDETLBLinesLuma =
+ dml_floor(
+ mode_lib->vba.LinesInDETLuma
+ + dml_min(
+ mode_lib->vba.LinesInDETLuma
+ * mode_lib->vba.RequiredDISPCLK[i]
+ * mode_lib->vba.BytePerPixelInDETY[k]
+ * mode_lib->vba.PSCL_FACTOR[k]
+ / mode_lib->vba.ReturnBWPerState[i],
+ mode_lib->vba.EffectiveLBLatencyHidingSourceLinesLuma),
+ mode_lib->vba.SwathHeightYPerState[i][k]);
+ mode_lib->vba.EffectiveDETLBLinesChroma =
+ dml_floor(
+ mode_lib->vba.LinesInDETChroma
+ + dml_min(
+ mode_lib->vba.LinesInDETChroma
+ * mode_lib->vba.RequiredDISPCLK[i]
+ * mode_lib->vba.BytePerPixelInDETC[k]
+ * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
+ / mode_lib->vba.ReturnBWPerState[i],
+ mode_lib->vba.EffectiveLBLatencyHidingSourceLinesChroma),
+ mode_lib->vba.SwathHeightCPerState[i][k]);
+ if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+ mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
+ mode_lib->vba.EffectiveDETLBLinesLuma
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ / mode_lib->vba.VRatio[k]
+ - mode_lib->vba.EffectiveDETLBLinesLuma
+ * mode_lib->vba.SwathWidthYPerState[i][k]
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0)
+ / (mode_lib->vba.ReturnBWPerState[i]
+ / mode_lib->vba.NoOfDPP[i][k]);
+ } else {
+ mode_lib->vba.UrgentLatencySupportUsPerState[i][k] =
+ dml_min(
+ mode_lib->vba.EffectiveDETLBLinesLuma
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ / mode_lib->vba.VRatio[k]
+ - mode_lib->vba.EffectiveDETLBLinesLuma
+ * mode_lib->vba.SwathWidthYPerState[i][k]
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0)
+ / (mode_lib->vba.ReturnBWPerState[i]
+ / mode_lib->vba.NoOfDPP[i][k]),
+ mode_lib->vba.EffectiveDETLBLinesChroma
+ * (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k])
+ / (mode_lib->vba.VRatio[k]
+ / 2.0)
+ - mode_lib->vba.EffectiveDETLBLinesChroma
+ * mode_lib->vba.SwathWidthYPerState[i][k]
+ / 2.0
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETC[k],
+ 2.0)
+ / (mode_lib->vba.ReturnBWPerState[i]
+ / mode_lib->vba.NoOfDPP[i][k]));
+ }
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.UrgentLatencySupport[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.UrgentLatencySupportUsPerState[i][k]
+ < mode_lib->vba.UrgentLatency / 1.0) {
+ mode_lib->vba.UrgentLatencySupport[i] = false;
+ }
+ }
+ }
+ /*Prefetch Check*/
+
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i] = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.DCCEnable[k] == true) {
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i] =
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
+ + mode_lib->vba.NoOfDPP[i][k];
+ }
+ }
+ }
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep = 8.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ mode_lib->vba.PixelClock[k] / 16.0);
+ if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
+ if (mode_lib->vba.VRatio[k] <= 1.0) {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep =
+ dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ 1.1
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0)
+ / 64.0
+ * mode_lib->vba.HRatio[k]
+ * mode_lib->vba.PixelClock[k]
+ / mode_lib->vba.NoOfDPP[i][k]);
+ } else {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep =
+ dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ 1.1
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0)
+ / 64.0
+ * mode_lib->vba.PSCL_FACTOR[k]
+ * mode_lib->vba.RequiredDPPCLK[i][k]);
+ }
+ } else {
+ if (mode_lib->vba.VRatio[k] <= 1.0) {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep =
+ dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ 1.1
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0)
+ / 32.0
+ * mode_lib->vba.HRatio[k]
+ * mode_lib->vba.PixelClock[k]
+ / mode_lib->vba.NoOfDPP[i][k]);
+ } else {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep =
+ dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ 1.1
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0)
+ / 32.0
+ * mode_lib->vba.PSCL_FACTOR[k]
+ * mode_lib->vba.RequiredDPPCLK[i][k]);
+ }
+ if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep =
+ dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ 1.1
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETC[k],
+ 2.0)
+ / 32.0
+ * mode_lib->vba.HRatio[k]
+ / 2.0
+ * mode_lib->vba.PixelClock[k]
+ / mode_lib->vba.NoOfDPP[i][k]);
+ } else {
+ mode_lib->vba.ProjectedDCFCLKDeepSleep =
+ dml_max(
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ 1.1
+ * dml_ceil(
+ mode_lib->vba.BytePerPixelInDETC[k],
+ 2.0)
+ / 32.0
+ * mode_lib->vba.PSCL_FACTOR_CHROMA[k]
+ * mode_lib->vba.RequiredDPPCLK[i][k]);
+ }
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrameY = CalculateVMAndRowBytes(
+ mode_lib,
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.Read256BlockHeightY[k],
+ mode_lib->vba.Read256BlockWidthY[k],
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.SurfaceTiling[k],
+ dml_ceil(mode_lib->vba.BytePerPixelInDETY[k], 1.0),
+ mode_lib->vba.SourceScan[k],
+ mode_lib->vba.ViewportWidth[k],
+ mode_lib->vba.ViewportHeight[k],
+ mode_lib->vba.SwathWidthYPerState[i][k],
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.VMMPageSize,
+ mode_lib->vba.PTEBufferSizeInRequests,
+ mode_lib->vba.PDEProcessingBufIn64KBReqs,
+ mode_lib->vba.PitchY[k],
+ mode_lib->vba.DCCMetaPitchY[k],
+ &mode_lib->vba.MacroTileWidthY[k],
+ &mode_lib->vba.MetaRowBytesY,
+ &mode_lib->vba.DPTEBytesPerRowY,
+ &mode_lib->vba.PTEBufferSizeNotExceededY[i][k],
+ &mode_lib->vba.dpte_row_height[k],
+ &mode_lib->vba.meta_row_height[k]);
+ mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
+ mode_lib,
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.vtaps[k],
+ mode_lib->vba.Interlace[k],
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+ mode_lib->vba.SwathHeightYPerState[i][k],
+ mode_lib->vba.ViewportYStartY[k],
+ &mode_lib->vba.PrefillY[k],
+ &mode_lib->vba.MaxNumSwY[k]);
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8)) {
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = CalculateVMAndRowBytes(
+ mode_lib,
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.Read256BlockHeightY[k],
+ mode_lib->vba.Read256BlockWidthY[k],
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.SurfaceTiling[k],
+ dml_ceil(mode_lib->vba.BytePerPixelInDETC[k], 2.0),
+ mode_lib->vba.SourceScan[k],
+ mode_lib->vba.ViewportWidth[k] / 2.0,
+ mode_lib->vba.ViewportHeight[k] / 2.0,
+ mode_lib->vba.SwathWidthYPerState[i][k] / 2.0,
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.VMMPageSize,
+ mode_lib->vba.PTEBufferSizeInRequests,
+ mode_lib->vba.PDEProcessingBufIn64KBReqs,
+ mode_lib->vba.PitchC[k],
+ 0.0,
+ &mode_lib->vba.MacroTileWidthC[k],
+ &mode_lib->vba.MetaRowBytesC,
+ &mode_lib->vba.DPTEBytesPerRowC,
+ &mode_lib->vba.PTEBufferSizeNotExceededC[i][k],
+ &mode_lib->vba.dpte_row_height_chroma[k],
+ &mode_lib->vba.meta_row_height_chroma[k]);
+ mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
+ mode_lib,
+ mode_lib->vba.VRatio[k] / 2.0,
+ mode_lib->vba.VTAPsChroma[k],
+ mode_lib->vba.Interlace[k],
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+ mode_lib->vba.SwathHeightCPerState[i][k],
+ mode_lib->vba.ViewportYStartC[k],
+ &mode_lib->vba.PrefillC[k],
+ &mode_lib->vba.MaxNumSwC[k]);
+ } else {
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
+ mode_lib->vba.MetaRowBytesC = 0.0;
+ mode_lib->vba.DPTEBytesPerRowC = 0.0;
+ mode_lib->vba.PrefetchLinesC[k] = 0.0;
+ mode_lib->vba.PTEBufferSizeNotExceededC[i][k] = true;
+ }
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] =
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrameY
+ + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
+ mode_lib->vba.MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY
+ + mode_lib->vba.MetaRowBytesC;
+ mode_lib->vba.DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY
+ + mode_lib->vba.DPTEBytesPerRowC;
+ }
+ mode_lib->vba.ExtraLatency =
+ mode_lib->vba.UrgentRoundTripAndOutOfOrderLatencyPerState[i]
+ + (mode_lib->vba.TotalNumberOfActiveDPP[i]
+ * mode_lib->vba.PixelChunkSizeInKByte
+ + mode_lib->vba.TotalNumberOfDCCActiveDPP[i]
+ * mode_lib->vba.MetaChunkSize)
+ * 1024.0
+ / mode_lib->vba.ReturnBWPerState[i];
+ if (mode_lib->vba.VirtualMemoryEnable == true) {
+ mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
+ + mode_lib->vba.TotalNumberOfActiveDPP[i]
+ * mode_lib->vba.PTEChunkSize * 1024.0
+ / mode_lib->vba.ReturnBWPerState[i];
+ }
+ mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ if (mode_lib->vba.WritebackEnable[k] == true) {
+ mode_lib->vba.WritebackDelay[i][k] =
+ mode_lib->vba.WritebackLatency
+ + CalculateWriteBackDelay(
+ mode_lib->vba.WritebackPixelFormat[k],
+ mode_lib->vba.WritebackHRatio[k],
+ mode_lib->vba.WritebackVRatio[k],
+ mode_lib->vba.WritebackLumaHTaps[k],
+ mode_lib->vba.WritebackLumaVTaps[k],
+ mode_lib->vba.WritebackChromaHTaps[k],
+ mode_lib->vba.WritebackChromaVTaps[k],
+ mode_lib->vba.WritebackDestinationWidth[k])
+ / mode_lib->vba.RequiredDISPCLK[i];
+ } else {
+ mode_lib->vba.WritebackDelay[i][k] = 0.0;
+ }
+ for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+ if (mode_lib->vba.BlendingAndTiming[j] == k
+ && mode_lib->vba.WritebackEnable[j]
+ == true) {
+ mode_lib->vba.WritebackDelay[i][k] =
+ dml_max(
+ mode_lib->vba.WritebackDelay[i][k],
+ mode_lib->vba.WritebackLatency
+ + CalculateWriteBackDelay(
+ mode_lib->vba.WritebackPixelFormat[j],
+ mode_lib->vba.WritebackHRatio[j],
+ mode_lib->vba.WritebackVRatio[j],
+ mode_lib->vba.WritebackLumaHTaps[j],
+ mode_lib->vba.WritebackLumaVTaps[j],
+ mode_lib->vba.WritebackChromaHTaps[j],
+ mode_lib->vba.WritebackChromaVTaps[j],
+ mode_lib->vba.WritebackDestinationWidth[j])
+ / mode_lib->vba.RequiredDISPCLK[i]);
+ }
+ }
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ for (j = 0; j <= mode_lib->vba.NumberOfActivePlanes - 1; j++) {
+ if (mode_lib->vba.BlendingAndTiming[k] == j) {
+ mode_lib->vba.WritebackDelay[i][k] =
+ mode_lib->vba.WritebackDelay[i][j];
+ }
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.MaximumVStartup[k] =
+ mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
+ - dml_max(
+ 1.0,
+ dml_ceil(
+ mode_lib->vba.WritebackDelay[i][k]
+ / (mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]),
+ 1.0));
+ }
+ mode_lib->vba.TWait = CalculateTWait(
+ mode_lib->vba.PrefetchMode,
+ mode_lib->vba.DRAMClockChangeLatency,
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.SREnterPlusExitTime);
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.XFCEnabled[k] == true) {
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay =
+ CalculateRemoteSurfaceFlipDelay(
+ mode_lib,
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.SwathWidthYPerState[i][k],
+ dml_ceil(
+ mode_lib->vba.BytePerPixelInDETY[k],
+ 1.0),
+ mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k],
+ mode_lib->vba.XFCTSlvVupdateOffset,
+ mode_lib->vba.XFCTSlvVupdateWidth,
+ mode_lib->vba.XFCTSlvVreadyOffset,
+ mode_lib->vba.XFCXBUFLatencyTolerance,
+ mode_lib->vba.XFCFillBWOverhead,
+ mode_lib->vba.XFCSlvChunkSize,
+ mode_lib->vba.XFCBusTransportTime,
+ mode_lib->vba.TimeCalc,
+ mode_lib->vba.TWait,
+ &mode_lib->vba.SrcActiveDrainRate,
+ &mode_lib->vba.TInitXFill,
+ &mode_lib->vba.TslvChk);
+ } else {
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
+ }
+ mode_lib->vba.IsErrorResult[i][k] =
+ CalculatePrefetchSchedule(
+ mode_lib,
+ mode_lib->vba.RequiredDPPCLK[i][k],
+ mode_lib->vba.RequiredDISPCLK[i],
+ mode_lib->vba.PixelClock[k],
+ mode_lib->vba.ProjectedDCFCLKDeepSleep,
+ mode_lib->vba.DSCDelayPerState[i][k],
+ mode_lib->vba.NoOfDPP[i][k],
+ mode_lib->vba.ScalerEnabled[k],
+ mode_lib->vba.NumberOfCursors[k],
+ mode_lib->vba.DPPCLKDelaySubtotal,
+ mode_lib->vba.DPPCLKDelaySCL,
+ mode_lib->vba.DPPCLKDelaySCLLBOnly,
+ mode_lib->vba.DPPCLKDelayCNVCFormater,
+ mode_lib->vba.DPPCLKDelayCNVCCursor,
+ mode_lib->vba.DISPCLKDelaySubtotal,
+ mode_lib->vba.SwathWidthYPerState[i][k]
+ / mode_lib->vba.HRatio[k],
+ mode_lib->vba.OutputFormat[k],
+ mode_lib->vba.VTotal[k]
+ - mode_lib->vba.VActive[k],
+ mode_lib->vba.HTotal[k],
+ mode_lib->vba.MaxInterDCNTileRepeaters,
+ mode_lib->vba.MaximumVStartup[k],
+ mode_lib->vba.MaxPageTableLevels,
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.DynamicMetadataEnable[k],
+ mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k],
+ mode_lib->vba.DynamicMetadataTransmittedBytes[k],
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.ExtraLatency,
+ mode_lib->vba.TimeCalc,
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
+ mode_lib->vba.MetaRowBytes[k],
+ mode_lib->vba.DPTEBytesPerRow[k],
+ mode_lib->vba.PrefetchLinesY[k],
+ mode_lib->vba.SwathWidthYPerState[i][k],
+ mode_lib->vba.BytePerPixelInDETY[k],
+ mode_lib->vba.PrefillY[k],
+ mode_lib->vba.MaxNumSwY[k],
+ mode_lib->vba.PrefetchLinesC[k],
+ mode_lib->vba.BytePerPixelInDETC[k],
+ mode_lib->vba.PrefillC[k],
+ mode_lib->vba.MaxNumSwC[k],
+ mode_lib->vba.SwathHeightYPerState[i][k],
+ mode_lib->vba.SwathHeightCPerState[i][k],
+ mode_lib->vba.TWait,
+ mode_lib->vba.XFCEnabled[k],
+ mode_lib->vba.XFCRemoteSurfaceFlipDelay,
+ mode_lib->vba.Interlace[k],
+ mode_lib->vba.ProgressiveToInterlaceUnitInOPP,
+ mode_lib->vba.DSTXAfterScaler,
+ mode_lib->vba.DSTYAfterScaler,
+ &mode_lib->vba.LineTimesForPrefetch[k],
+ &mode_lib->vba.PrefetchBW[k],
+ &mode_lib->vba.LinesForMetaPTE[k],
+ &mode_lib->vba.LinesForMetaAndDPTERow[k],
+ &mode_lib->vba.VRatioPreY[i][k],
+ &mode_lib->vba.VRatioPreC[i][k],
+ &mode_lib->vba.RequiredPrefetchPixelDataBW[i][k],
+ &mode_lib->vba.VStartupRequiredWhenNotEnoughTimeForDynamicMetadata,
+ &mode_lib->vba.Tno_bw[k],
+ &mode_lib->vba.VUpdateOffsetPix[k],
+ &mode_lib->vba.VUpdateWidthPix[k],
+ &mode_lib->vba.VReadyOffsetPix[k]);
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.cursor_bw[k] = mode_lib->vba.NumberOfCursors[k]
+ * mode_lib->vba.CursorWidth[k][0]
+ * mode_lib->vba.CursorBPP[k][0] / 8.0
+ / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ * mode_lib->vba.VRatio[k];
+ }
+ mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0;
+ mode_lib->vba.prefetch_vm_bw_valid = true;
+ mode_lib->vba.prefetch_row_bw_valid = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k] == 0.0) {
+ mode_lib->vba.prefetch_vm_bw[k] = 0.0;
+ } else if (mode_lib->vba.LinesForMetaPTE[k] > 0.0) {
+ mode_lib->vba.prefetch_vm_bw[k] =
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
+ / (mode_lib->vba.LinesForMetaPTE[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ } else {
+ mode_lib->vba.prefetch_vm_bw[k] = 0.0;
+ mode_lib->vba.prefetch_vm_bw_valid = false;
+ }
+ if (mode_lib->vba.MetaRowBytes[k] + mode_lib->vba.DPTEBytesPerRow[k]
+ == 0.0) {
+ mode_lib->vba.prefetch_row_bw[k] = 0.0;
+ } else if (mode_lib->vba.LinesForMetaAndDPTERow[k] > 0.0) {
+ mode_lib->vba.prefetch_row_bw[k] = (mode_lib->vba.MetaRowBytes[k]
+ + mode_lib->vba.DPTEBytesPerRow[k])
+ / (mode_lib->vba.LinesForMetaAndDPTERow[k]
+ * mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k]);
+ } else {
+ mode_lib->vba.prefetch_row_bw[k] = 0.0;
+ mode_lib->vba.prefetch_row_bw_valid = false;
+ }
+ mode_lib->vba.MaximumReadBandwidthWithPrefetch =
+ mode_lib->vba.MaximumReadBandwidthWithPrefetch
+ + mode_lib->vba.cursor_bw[k]
+ + dml_max4(
+ mode_lib->vba.prefetch_vm_bw[k],
+ mode_lib->vba.prefetch_row_bw[k],
+ mode_lib->vba.ReadBandwidth[k],
+ mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]);
+ }
+ mode_lib->vba.PrefetchSupported[i] = true;
+ if (mode_lib->vba.MaximumReadBandwidthWithPrefetch
+ > mode_lib->vba.ReturnBWPerState[i]
+ || mode_lib->vba.prefetch_vm_bw_valid == false
+ || mode_lib->vba.prefetch_row_bw_valid == false) {
+ mode_lib->vba.PrefetchSupported[i] = false;
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.LineTimesForPrefetch[k] < 2.0
+ || mode_lib->vba.LinesForMetaPTE[k] >= 8.0
+ || mode_lib->vba.LinesForMetaAndDPTERow[k] >= 16.0
+ || mode_lib->vba.IsErrorResult[i][k] == true) {
+ mode_lib->vba.PrefetchSupported[i] = false;
+ }
+ }
+ mode_lib->vba.VRatioInPrefetchSupported[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.VRatioPreY[i][k] > 4.0
+ || mode_lib->vba.VRatioPreC[i][k] > 4.0
+ || mode_lib->vba.IsErrorResult[i][k] == true) {
+ mode_lib->vba.VRatioInPrefetchSupported[i] = false;
+ }
+ }
+ if (mode_lib->vba.PrefetchSupported[i] == true
+ && mode_lib->vba.VRatioInPrefetchSupported[i] == true) {
+ mode_lib->vba.BandwidthAvailableForImmediateFlip =
+ mode_lib->vba.ReturnBWPerState[i];
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.BandwidthAvailableForImmediateFlip =
+ mode_lib->vba.BandwidthAvailableForImmediateFlip
+ - mode_lib->vba.cursor_bw[k]
+ - dml_max(
+ mode_lib->vba.ReadBandwidth[k],
+ mode_lib->vba.PrefetchBW[k]);
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.ImmediateFlipBytes[k] = 0.0;
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+ mode_lib->vba.ImmediateFlipBytes[k] =
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
+ + mode_lib->vba.MetaRowBytes[k]
+ + mode_lib->vba.DPTEBytesPerRow[k];
+ }
+ }
+ mode_lib->vba.TotImmediateFlipBytes = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
+ && mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
+ mode_lib->vba.TotImmediateFlipBytes =
+ mode_lib->vba.TotImmediateFlipBytes
+ + mode_lib->vba.ImmediateFlipBytes[k];
+ }
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ CalculateFlipSchedule(
+ mode_lib,
+ mode_lib->vba.ExtraLatency,
+ mode_lib->vba.UrgentLatency,
+ mode_lib->vba.MaxPageTableLevels,
+ mode_lib->vba.VirtualMemoryEnable,
+ mode_lib->vba.BandwidthAvailableForImmediateFlip,
+ mode_lib->vba.TotImmediateFlipBytes,
+ mode_lib->vba.SourcePixelFormat[k],
+ mode_lib->vba.ImmediateFlipBytes[k],
+ mode_lib->vba.HTotal[k]
+ / mode_lib->vba.PixelClock[k],
+ mode_lib->vba.VRatio[k],
+ mode_lib->vba.Tno_bw[k],
+ mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
+ mode_lib->vba.MetaRowBytes[k],
+ mode_lib->vba.DPTEBytesPerRow[k],
+ mode_lib->vba.DCCEnable[k],
+ mode_lib->vba.dpte_row_height[k],
+ mode_lib->vba.meta_row_height[k],
+ mode_lib->vba.qual_row_bw[k],
+ &mode_lib->vba.DestinationLinesToRequestVMInImmediateFlip[k],
+ &mode_lib->vba.DestinationLinesToRequestRowInImmediateFlip[k],
+ &mode_lib->vba.final_flip_bw[k],
+ &mode_lib->vba.ImmediateFlipSupportedForPipe[k]);
+ }
+ mode_lib->vba.total_dcn_read_bw_with_flip = 0.0;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.total_dcn_read_bw_with_flip =
+ mode_lib->vba.total_dcn_read_bw_with_flip
+ + mode_lib->vba.cursor_bw[k]
+ + dml_max3(
+ mode_lib->vba.prefetch_vm_bw[k],
+ mode_lib->vba.prefetch_row_bw[k],
+ mode_lib->vba.final_flip_bw[k]
+ + dml_max(
+ mode_lib->vba.ReadBandwidth[k],
+ mode_lib->vba.RequiredPrefetchPixelDataBW[i][k]));
+ }
+ mode_lib->vba.ImmediateFlipSupportedForState[i] = true;
+ if (mode_lib->vba.total_dcn_read_bw_with_flip
+ > mode_lib->vba.ReturnBWPerState[i]) {
+ mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.ImmediateFlipSupportedForPipe[k] == false) {
+ mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
+ }
+ }
+ } else {
+ mode_lib->vba.ImmediateFlipSupportedForState[i] = false;
+ }
+ }
+ /*PTE Buffer Size Check*/
+
+ for (i = 0; i <= DC__VOLTAGE_STATES; i++) {
+ mode_lib->vba.PTEBufferSizeNotExceeded[i] = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.PTEBufferSizeNotExceededY[i][k] == false
+ || mode_lib->vba.PTEBufferSizeNotExceededC[i][k] == false) {
+ mode_lib->vba.PTEBufferSizeNotExceeded[i] = false;
+ }
+ }
+ }
+ /*Cursor Support Check*/
+
+ mode_lib->vba.CursorSupport = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.CursorWidth[k][0] > 0.0) {
+ if (dml_floor(
+ dml_floor(
+ mode_lib->vba.CursorBufferSize
+ - mode_lib->vba.CursorChunkSize,
+ mode_lib->vba.CursorChunkSize) * 1024.0
+ / (mode_lib->vba.CursorWidth[k][0]
+ * mode_lib->vba.CursorBPP[k][0]
+ / 8.0),
+ 1.0)
+ * (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k])
+ / mode_lib->vba.VRatio[k] < mode_lib->vba.UrgentLatency
+ || (mode_lib->vba.CursorBPP[k][0] == 64.0
+ && mode_lib->vba.Cursor64BppSupport == false)) {
+ mode_lib->vba.CursorSupport = false;
+ }
+ }
+ }
+ /*Valid Pitch Check*/
+
+ mode_lib->vba.PitchSupport = true;
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.AlignedYPitch[k] = dml_ceil(
+ dml_max(mode_lib->vba.PitchY[k], mode_lib->vba.ViewportWidth[k]),
+ mode_lib->vba.MacroTileWidthY[k]);
+ if (mode_lib->vba.AlignedYPitch[k] > mode_lib->vba.PitchY[k]) {
+ mode_lib->vba.PitchSupport = false;
+ }
+ if (mode_lib->vba.DCCEnable[k] == true) {
+ mode_lib->vba.AlignedDCCMetaPitch[k] = dml_ceil(
+ dml_max(
+ mode_lib->vba.DCCMetaPitchY[k],
+ mode_lib->vba.ViewportWidth[k]),
+ 64.0 * mode_lib->vba.Read256BlockWidthY[k]);
+ } else {
+ mode_lib->vba.AlignedDCCMetaPitch[k] = mode_lib->vba.DCCMetaPitchY[k];
+ }
+ if (mode_lib->vba.AlignedDCCMetaPitch[k] > mode_lib->vba.DCCMetaPitchY[k]) {
+ mode_lib->vba.PitchSupport = false;
+ }
+ if (mode_lib->vba.SourcePixelFormat[k] != dm_444_64
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_32
+ && mode_lib->vba.SourcePixelFormat[k] != dm_444_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_16
+ && mode_lib->vba.SourcePixelFormat[k] != dm_mono_8) {
+ mode_lib->vba.AlignedCPitch[k] = dml_ceil(
+ dml_max(
+ mode_lib->vba.PitchC[k],
+ mode_lib->vba.ViewportWidth[k] / 2.0),
+ mode_lib->vba.MacroTileWidthC[k]);
+ } else {
+ mode_lib->vba.AlignedCPitch[k] = mode_lib->vba.PitchC[k];
+ }
+ if (mode_lib->vba.AlignedCPitch[k] > mode_lib->vba.PitchC[k]) {
+ mode_lib->vba.PitchSupport = false;
+ }
+ }
+ /*Mode Support, Voltage State and SOC Configuration*/
+
+ for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
+ if (mode_lib->vba.ScaleRatioAndTapsSupport == true
+ && mode_lib->vba.SourceFormatPixelAndScanSupport == true
+ && mode_lib->vba.ViewportSizeSupport[i] == true
+ && mode_lib->vba.BandwidthSupport[i] == true
+ && mode_lib->vba.DIOSupport[i] == true
+ && mode_lib->vba.NotEnoughDSCUnits[i] == false
+ && mode_lib->vba.DSCCLKRequiredMoreThanSupported[i] == false
+ && mode_lib->vba.UrgentLatencySupport[i] == true
+ && mode_lib->vba.ROBSupport[i] == true
+ && mode_lib->vba.DISPCLK_DPPCLK_Support[i] == true
+ && mode_lib->vba.TotalAvailablePipesSupport[i] == true
+ && mode_lib->vba.NumberOfOTGSupport == true
+ && mode_lib->vba.WritebackModeSupport == true
+ && mode_lib->vba.WritebackLatencySupport == true
+ && mode_lib->vba.WritebackScaleRatioAndTapsSupport == true
+ && mode_lib->vba.CursorSupport == true
+ && mode_lib->vba.PitchSupport == true
+ && mode_lib->vba.PrefetchSupported[i] == true
+ && mode_lib->vba.VRatioInPrefetchSupported[i] == true
+ && mode_lib->vba.PTEBufferSizeNotExceeded[i] == true
+ && mode_lib->vba.NonsupportedDSCInputBPC == false) {
+ mode_lib->vba.ModeSupport[i] = true;
+ } else {
+ mode_lib->vba.ModeSupport[i] = false;
+ }
+ }
+ for (i = DC__VOLTAGE_STATES; i >= 0; i--) {
+ if (i == DC__VOLTAGE_STATES || mode_lib->vba.ModeSupport[i] == true) {
+ mode_lib->vba.VoltageLevel = i;
+ }
+ }
+ mode_lib->vba.DCFCLK = mode_lib->vba.DCFCLKPerState[mode_lib->vba.VoltageLevel];
+ mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
+ mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
+ mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
+ mode_lib->vba.FabricAndDRAMBandwidth =
+ mode_lib->vba.FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
+ mode_lib->vba.ImmediateFlipSupport =
+ mode_lib->vba.ImmediateFlipSupportedForState[mode_lib->vba.VoltageLevel];
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ mode_lib->vba.DPPPerPlane[k] = mode_lib->vba.NoOfDPP[mode_lib->vba.VoltageLevel][k];
+ }
+ for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
+ if (mode_lib->vba.BlendingAndTiming[k] == k) {
+ mode_lib->vba.ODMCombineEnabled[k] =
+ mode_lib->vba.ODMCombineEnablePerState[mode_lib->vba.VoltageLevel][k];
+ } else {
+ mode_lib->vba.ODMCombineEnabled[k] = 0;
+ }
+ mode_lib->vba.DSCEnabled[k] =
+ mode_lib->vba.RequiresDSC[mode_lib->vba.VoltageLevel][k];
+ mode_lib->vba.OutputBpp[k] =
+ mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k];
+ }
+}
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 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DML2_DISPLAY_MODE_VBA_H__
+#define __DML2_DISPLAY_MODE_VBA_H__
+
+#include "dml_common_defs.h"
+
+struct display_mode_lib;
+
+void set_prefetch_mode(struct display_mode_lib *mode_lib,
+ bool cstate_en,
+ bool pstate_en,
+ bool ignore_viewport_pos,
+ bool immediate_flip_support);
+
+#define dml_get_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes)
+
+dml_get_attr_decl(clk_dcf_deepsleep);
+dml_get_attr_decl(wm_urgent);
+dml_get_attr_decl(wm_memory_trip);
+dml_get_attr_decl(wm_writeback_urgent);
+dml_get_attr_decl(wm_stutter_exit);
+dml_get_attr_decl(wm_stutter_enter_exit);
+dml_get_attr_decl(wm_dram_clock_change);
+dml_get_attr_decl(wm_writeback_dram_clock_change);
+dml_get_attr_decl(wm_xfc_underflow);
+dml_get_attr_decl(stutter_efficiency_no_vblank);
+dml_get_attr_decl(stutter_efficiency);
+dml_get_attr_decl(urgent_latency);
+dml_get_attr_decl(urgent_extra_latency);
+dml_get_attr_decl(nonurgent_latency);
+dml_get_attr_decl(dram_clock_change_latency);
+dml_get_attr_decl(dispclk_calculated);
+dml_get_attr_decl(total_data_read_bw);
+dml_get_attr_decl(return_bw);
+dml_get_attr_decl(tcalc);
+
+#define dml_get_pipe_attr_decl(attr) double get_##attr(struct display_mode_lib *mode_lib, const display_e2e_pipe_params_st *pipes, unsigned int num_pipes, unsigned int which_pipe)
+
+dml_get_pipe_attr_decl(dsc_delay);
+dml_get_pipe_attr_decl(dppclk_calculated);
+dml_get_pipe_attr_decl(dscclk_calculated);
+dml_get_pipe_attr_decl(min_ttu_vblank);
+dml_get_pipe_attr_decl(vratio_prefetch_l);
+dml_get_pipe_attr_decl(vratio_prefetch_c);
+dml_get_pipe_attr_decl(dst_x_after_scaler);
+dml_get_pipe_attr_decl(dst_y_after_scaler);
+dml_get_pipe_attr_decl(dst_y_per_vm_vblank);
+dml_get_pipe_attr_decl(dst_y_per_row_vblank);
+dml_get_pipe_attr_decl(dst_y_prefetch);
+dml_get_pipe_attr_decl(dst_y_per_vm_flip);
+dml_get_pipe_attr_decl(dst_y_per_row_flip);
+dml_get_pipe_attr_decl(xfc_transfer_delay);
+dml_get_pipe_attr_decl(xfc_precharge_delay);
+dml_get_pipe_attr_decl(xfc_remote_surface_flip_latency);
+dml_get_pipe_attr_decl(xfc_prefetch_margin);
+
+unsigned int get_vstartup_calculated(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes,
+ unsigned int which_pipe);
+
+double get_total_immediate_flip_bytes(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes);
+double get_total_immediate_flip_bw(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes);
+double get_total_prefetch_bw(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes);
+
+unsigned int dml_get_voltage_level(
+ struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *pipes,
+ unsigned int num_pipes);
+
+bool Calculate256BBlockSizes(
+ enum source_format_class SourcePixelFormat,
+ enum dm_swizzle_mode SurfaceTiling,
+ unsigned int BytePerPixelY,
+ unsigned int BytePerPixelC,
+ unsigned int *BlockHeight256BytesY,
+ unsigned int *BlockHeight256BytesC,
+ unsigned int *BlockWidth256BytesY,
+ unsigned int *BlockWidth256BytesC);
+
+
+struct vba_vars_st {
+ ip_params_st ip;
+ soc_bounding_box_st soc;
+
+ unsigned int MaximumMaxVStartupLines;
+ double cursor_bw[DC__NUM_DPP__MAX];
+ double meta_row_bw[DC__NUM_DPP__MAX];
+ double dpte_row_bw[DC__NUM_DPP__MAX];
+ double qual_row_bw[DC__NUM_DPP__MAX];
+ double WritebackDISPCLK;
+ double PSCL_THROUGHPUT_LUMA[DC__NUM_DPP__MAX];
+ double PSCL_THROUGHPUT_CHROMA[DC__NUM_DPP__MAX];
+ double DPPCLKUsingSingleDPPLuma;
+ double DPPCLKUsingSingleDPPChroma;
+ double DPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
+ double DISPCLKWithRamping;
+ double DISPCLKWithoutRamping;
+ double GlobalDPPCLK;
+ double DISPCLKWithRampingRoundedToDFSGranularity;
+ double DISPCLKWithoutRampingRoundedToDFSGranularity;
+ double MaxDispclkRoundedToDFSGranularity;
+ bool DCCEnabledAnyPlane;
+ double ReturnBandwidthToDCN;
+ unsigned int SwathWidthY[DC__NUM_DPP__MAX];
+ unsigned int SwathWidthSingleDPPY[DC__NUM_DPP__MAX];
+ double BytePerPixelDETY[DC__NUM_DPP__MAX];
+ double BytePerPixelDETC[DC__NUM_DPP__MAX];
+ double ReadBandwidthPlaneLuma[DC__NUM_DPP__MAX];
+ double ReadBandwidthPlaneChroma[DC__NUM_DPP__MAX];
+ unsigned int TotalActiveDPP;
+ unsigned int TotalDCCActiveDPP;
+ double UrgentRoundTripAndOutOfOrderLatency;
+ double DisplayPipeLineDeliveryTimeLuma[DC__NUM_DPP__MAX]; // WM
+ double DisplayPipeLineDeliveryTimeChroma[DC__NUM_DPP__MAX]; // WM
+ double LinesInDETY[DC__NUM_DPP__MAX]; // WM
+ double LinesInDETC[DC__NUM_DPP__MAX]; // WM
+ unsigned int LinesInDETYRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM
+ unsigned int LinesInDETCRoundedDownToSwath[DC__NUM_DPP__MAX]; // WM
+ double FullDETBufferingTimeY[DC__NUM_DPP__MAX]; // WM
+ double FullDETBufferingTimeC[DC__NUM_DPP__MAX]; // WM
+ double MinFullDETBufferingTime;
+ double FrameTimeForMinFullDETBufferingTime;
+ double AverageReadBandwidthGBytePerSecond;
+ double PartOfBurstThatFitsInROB;
+ double StutterBurstTime;
+ //unsigned int NextPrefetchMode;
+ double VBlankTime;
+ double SmallestVBlank;
+ double DCFCLKDeepSleepPerPlane;
+ double EffectiveDETPlusLBLinesLuma;
+ double EffectiveDETPlusLBLinesChroma;
+ double UrgentLatencySupportUsLuma;
+ double UrgentLatencySupportUsChroma;
+ double UrgentLatencySupportUs[DC__NUM_DPP__MAX];
+ unsigned int DSCFormatFactor;
+ unsigned int BlockHeight256BytesY[DC__NUM_DPP__MAX];
+ unsigned int BlockHeight256BytesC[DC__NUM_DPP__MAX];
+ unsigned int BlockWidth256BytesY[DC__NUM_DPP__MAX];
+ unsigned int BlockWidth256BytesC[DC__NUM_DPP__MAX];
+ double VInitPreFillY[DC__NUM_DPP__MAX];
+ double VInitPreFillC[DC__NUM_DPP__MAX];
+ unsigned int MaxNumSwathY[DC__NUM_DPP__MAX];
+ unsigned int MaxNumSwathC[DC__NUM_DPP__MAX];
+ double PrefetchSourceLinesY[DC__NUM_DPP__MAX];
+ double PrefetchSourceLinesC[DC__NUM_DPP__MAX];
+ double PixelPTEBytesPerRow[DC__NUM_DPP__MAX];
+ double MetaRowByte[DC__NUM_DPP__MAX];
+ unsigned int dpte_row_height[DC__NUM_DPP__MAX];
+ unsigned int dpte_row_height_chroma[DC__NUM_DPP__MAX];
+ unsigned int meta_row_height[DC__NUM_DPP__MAX];
+ unsigned int meta_row_height_chroma[DC__NUM_DPP__MAX];
+
+ unsigned int MacroTileWidthY[DC__NUM_DPP__MAX];
+ unsigned int MacroTileWidthC[DC__NUM_DPP__MAX];
+ unsigned int MaxVStartupLines[DC__NUM_DPP__MAX];
+ double WritebackDelay[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ bool PrefetchModeSupported;
+ bool AllowDRAMClockChangeDuringVBlank[DC__NUM_DPP__MAX];
+ bool AllowDRAMSelfRefreshDuringVBlank[DC__NUM_DPP__MAX];
+ double RequiredPrefetchPixDataBW[DC__NUM_DPP__MAX];
+ double XFCRemoteSurfaceFlipDelay;
+ double TInitXFill;
+ double TslvChk;
+ double SrcActiveDrainRate;
+ double Tno_bw[DC__NUM_DPP__MAX];
+ bool ImmediateFlipSupported;
+
+ double prefetch_vm_bw[DC__NUM_DPP__MAX];
+ double prefetch_row_bw[DC__NUM_DPP__MAX];
+ bool ImmediateFlipSupportedForPipe[DC__NUM_DPP__MAX];
+ unsigned int VStartupLines;
+ double DisplayPipeLineDeliveryTimeLumaPrefetch[DC__NUM_DPP__MAX];
+ double DisplayPipeLineDeliveryTimeChromaPrefetch[DC__NUM_DPP__MAX];
+ unsigned int ActiveDPPs;
+ unsigned int LBLatencyHidingSourceLinesY;
+ unsigned int LBLatencyHidingSourceLinesC;
+ double ActiveDRAMClockChangeLatencyMargin[DC__NUM_DPP__MAX];
+ double MinActiveDRAMClockChangeMargin;
+ double XFCSlaveVUpdateOffset[DC__NUM_DPP__MAX];
+ double XFCSlaveVupdateWidth[DC__NUM_DPP__MAX];
+ double XFCSlaveVReadyOffset[DC__NUM_DPP__MAX];
+ double InitFillLevel;
+ double FinalFillMargin;
+ double FinalFillLevel;
+ double RemainingFillLevel;
+ double TFinalxFill;
+
+
+ //
+ // SOC Bounding Box Parameters
+ //
+ double SRExitTime;
+ double SREnterPlusExitTime;
+ double UrgentLatency;
+ double WritebackLatency;
+ double PercentOfIdealDRAMAndFabricBWReceivedAfterUrgLatency;
+ double NumberOfChannels;
+ double DRAMChannelWidth;
+ double FabricDatapathToDCNDataReturn;
+ double ReturnBusWidth;
+ double Downspreading;
+ double DISPCLKDPPCLKDSCCLKDownSpreading;
+ double DISPCLKDPPCLKVCOSpeed;
+ double RoundTripPingLatencyCycles;
+ double UrgentOutOfOrderReturnPerChannel;
+ unsigned int VMMPageSize;
+ double DRAMClockChangeLatency;
+ double XFCBusTransportTime;
+ double XFCXBUFLatencyTolerance;
+
+ //
+ // IP Parameters
+ //
+ unsigned int ROBBufferSizeInKByte;
+ double DETBufferSizeInKByte;
+ unsigned int DPPOutputBufferPixels;
+ unsigned int OPPOutputBufferLines;
+ unsigned int PixelChunkSizeInKByte;
+ double ReturnBW;
+ bool VirtualMemoryEnable;
+ unsigned int MaxPageTableLevels;
+ unsigned int OverridePageTableLevels;
+ unsigned int PTEChunkSize;
+ unsigned int MetaChunkSize;
+ unsigned int WritebackChunkSize;
+ bool ODMCapability;
+ unsigned int NumberOfDSC;
+ unsigned int LineBufferSize;
+ unsigned int MaxLineBufferLines;
+ unsigned int WritebackInterfaceLumaBufferSize;
+ unsigned int WritebackInterfaceChromaBufferSize;
+ unsigned int WritebackChromaLineBufferWidth;
+ double MaxDCHUBToPSCLThroughput;
+ double MaxPSCLToLBThroughput;
+ unsigned int PTEBufferSizeInRequests;
+ double DISPCLKRampingMargin;
+ unsigned int MaxInterDCNTileRepeaters;
+ bool XFCSupported;
+ double XFCSlvChunkSize;
+ double XFCFillBWOverhead;
+ double XFCFillConstant;
+ double XFCTSlvVupdateOffset;
+ double XFCTSlvVupdateWidth;
+ double XFCTSlvVreadyOffset;
+ double DPPCLKDelaySubtotal;
+ double DPPCLKDelaySCL;
+ double DPPCLKDelaySCLLBOnly;
+ double DPPCLKDelayCNVCFormater;
+ double DPPCLKDelayCNVCCursor;
+ double DISPCLKDelaySubtotal;
+ bool ProgressiveToInterlaceUnitInOPP;
+ unsigned int PDEProcessingBufIn64KBReqs;
+
+ // Pipe/Plane Parameters
+ int VoltageLevel;
+ double FabricAndDRAMBandwidth;
+ double FabricClock;
+ double DRAMSpeed;
+ double DISPCLK;
+ double SOCCLK;
+ double DCFCLK;
+
+ unsigned int NumberOfActivePlanes;
+ unsigned int ViewportWidth[DC__NUM_DPP__MAX];
+ unsigned int ViewportHeight[DC__NUM_DPP__MAX];
+ unsigned int ViewportYStartY[DC__NUM_DPP__MAX];
+ unsigned int ViewportYStartC[DC__NUM_DPP__MAX];
+ unsigned int PitchY[DC__NUM_DPP__MAX];
+ unsigned int PitchC[DC__NUM_DPP__MAX];
+ double HRatio[DC__NUM_DPP__MAX];
+ double VRatio[DC__NUM_DPP__MAX];
+ unsigned int htaps[DC__NUM_DPP__MAX];
+ unsigned int vtaps[DC__NUM_DPP__MAX];
+ unsigned int HTAPsChroma[DC__NUM_DPP__MAX];
+ unsigned int VTAPsChroma[DC__NUM_DPP__MAX];
+ unsigned int HTotal[DC__NUM_DPP__MAX];
+ unsigned int VTotal[DC__NUM_DPP__MAX];
+ unsigned int DPPPerPlane[DC__NUM_DPP__MAX];
+ double PixelClock[DC__NUM_DPP__MAX];
+ double PixelClockBackEnd[DC__NUM_DPP__MAX];
+ double DPPCLK[DC__NUM_DPP__MAX];
+ bool DCCEnable[DC__NUM_DPP__MAX];
+ unsigned int DCCMetaPitchY[DC__NUM_DPP__MAX];
+ enum scan_direction_class SourceScan[DC__NUM_DPP__MAX];
+ enum source_format_class SourcePixelFormat[DC__NUM_DPP__MAX];
+ bool WritebackEnable[DC__NUM_DPP__MAX];
+ double WritebackDestinationWidth[DC__NUM_DPP__MAX];
+ double WritebackDestinationHeight[DC__NUM_DPP__MAX];
+ double WritebackSourceHeight[DC__NUM_DPP__MAX];
+ enum source_format_class WritebackPixelFormat[DC__NUM_DPP__MAX];
+ unsigned int WritebackLumaHTaps[DC__NUM_DPP__MAX];
+ unsigned int WritebackLumaVTaps[DC__NUM_DPP__MAX];
+ unsigned int WritebackChromaHTaps[DC__NUM_DPP__MAX];
+ unsigned int WritebackChromaVTaps[DC__NUM_DPP__MAX];
+ double WritebackHRatio[DC__NUM_DPP__MAX];
+ double WritebackVRatio[DC__NUM_DPP__MAX];
+ unsigned int HActive[DC__NUM_DPP__MAX];
+ unsigned int VActive[DC__NUM_DPP__MAX];
+ bool Interlace[DC__NUM_DPP__MAX];
+ enum dm_swizzle_mode SurfaceTiling[DC__NUM_DPP__MAX];
+ unsigned int ScalerRecoutWidth[DC__NUM_DPP__MAX];
+ bool DynamicMetadataEnable[DC__NUM_DPP__MAX];
+ unsigned int DynamicMetadataLinesBeforeActiveRequired[DC__NUM_DPP__MAX];
+ unsigned int DynamicMetadataTransmittedBytes[DC__NUM_DPP__MAX];
+ double DCCRate[DC__NUM_DPP__MAX];
+ bool ODMCombineEnabled[DC__NUM_DPP__MAX];
+ double OutputBpp[DC__NUM_DPP__MAX];
+ unsigned int NumberOfDSCSlices[DC__NUM_DPP__MAX];
+ bool DSCEnabled[DC__NUM_DPP__MAX];
+ unsigned int DSCDelay[DC__NUM_DPP__MAX];
+ unsigned int DSCInputBitPerComponent[DC__NUM_DPP__MAX];
+ enum output_format_class OutputFormat[DC__NUM_DPP__MAX];
+ enum output_encoder_class Output[DC__NUM_DPP__MAX];
+ unsigned int BlendingAndTiming[DC__NUM_DPP__MAX];
+ bool SynchronizedVBlank;
+ unsigned int NumberOfCursors[DC__NUM_DPP__MAX];
+ unsigned int CursorWidth[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
+ unsigned int CursorBPP[DC__NUM_DPP__MAX][DC__NUM_CURSOR__MAX];
+ bool XFCEnabled[DC__NUM_DPP__MAX];
+ bool ScalerEnabled[DC__NUM_DPP__MAX];
+
+ // Intermediates/Informational
+ bool ImmediateFlipSupport;
+ unsigned int SwathHeightY[DC__NUM_DPP__MAX];
+ unsigned int SwathHeightC[DC__NUM_DPP__MAX];
+ unsigned int DETBufferSizeY[DC__NUM_DPP__MAX];
+ unsigned int DETBufferSizeC[DC__NUM_DPP__MAX];
+ unsigned int LBBitPerPixel[DC__NUM_DPP__MAX];
+ double LastPixelOfLineExtraWatermark;
+ double TotalDataReadBandwidth;
+ unsigned int TotalActiveWriteback;
+ unsigned int EffectiveLBLatencyHidingSourceLinesLuma;
+ unsigned int EffectiveLBLatencyHidingSourceLinesChroma;
+ double BandwidthAvailableForImmediateFlip;
+ unsigned int PrefetchMode;
+ bool IgnoreViewportPositioning;
+ double PrefetchBandwidth[DC__NUM_DPP__MAX];
+ bool ErrorResult[DC__NUM_DPP__MAX];
+ double PDEAndMetaPTEBytesFrame[DC__NUM_DPP__MAX];
+
+ //
+ // Calculated dml_ml->vba.Outputs
+ //
+ double DCFClkDeepSleep;
+ double UrgentWatermark;
+ double UrgentExtraLatency;
+ double MemoryTripWatermark;
+ double WritebackUrgentWatermark;
+ double StutterExitWatermark;
+ double StutterEnterPlusExitWatermark;
+ double DRAMClockChangeWatermark;
+ double WritebackDRAMClockChangeWatermark;
+ double StutterEfficiency;
+ double StutterEfficiencyNotIncludingVBlank;
+ double MinUrgentLatencySupportUs;
+ double NonUrgentLatencyTolerance;
+ double MinActiveDRAMClockChangeLatencySupported;
+ enum clock_change_support DRAMClockChangeSupport;
+
+ // These are the clocks calcuated by the library but they are not actually
+ // used explicitly. They are fetched by tests and then possibly used. The
+ // ultimate values to use are the ones specified by the parameters to DML
+ double DISPCLK_calculated;
+ double DSCCLK_calculated[DC__NUM_DPP__MAX];
+ double DPPCLK_calculated[DC__NUM_DPP__MAX];
+
+ unsigned int VStartup[DC__NUM_DPP__MAX];
+ unsigned int VUpdateOffsetPix[DC__NUM_DPP__MAX];
+ unsigned int VUpdateWidthPix[DC__NUM_DPP__MAX];
+ unsigned int VReadyOffsetPix[DC__NUM_DPP__MAX];
+ unsigned int VStartupRequiredWhenNotEnoughTimeForDynamicMetadata;
+
+ double ImmediateFlipBW;
+ unsigned int TotImmediateFlipBytes;
+ double TCalc;
+ double MinTTUVBlank[DC__NUM_DPP__MAX];
+ double VRatioPrefetchY[DC__NUM_DPP__MAX];
+ double VRatioPrefetchC[DC__NUM_DPP__MAX];
+ double DSTXAfterScaler[DC__NUM_DPP__MAX];
+ double DSTYAfterScaler[DC__NUM_DPP__MAX];
+
+ double DestinationLinesToRequestVMInVBlank[DC__NUM_DPP__MAX];
+ double DestinationLinesToRequestRowInVBlank[DC__NUM_DPP__MAX];
+ double DestinationLinesForPrefetch[DC__NUM_DPP__MAX];
+ double DestinationLinesToRequestRowInImmediateFlip[DC__NUM_DPP__MAX];
+ double DestinationLinesToRequestVMInImmediateFlip[DC__NUM_DPP__MAX];
+
+ double XFCTransferDelay[DC__NUM_DPP__MAX];
+ double XFCPrechargeDelay[DC__NUM_DPP__MAX];
+ double XFCRemoteSurfaceFlipLatency[DC__NUM_DPP__MAX];
+ double XFCPrefetchMargin[DC__NUM_DPP__MAX];
+
+ display_e2e_pipe_params_st cache_pipes[DC__NUM_DPP__MAX];
+ unsigned int cache_num_pipes;
+ unsigned int pipe_plane[DC__NUM_DPP__MAX];
+
+ /* vba mode support */
+ /*inputs*/
+ bool SupportGFX7CompatibleTilingIn32bppAnd64bpp;
+ double MaxHSCLRatio;
+ double MaxVSCLRatio;
+ unsigned int MaxNumWriteback;
+ bool WritebackLumaAndChromaScalingSupported;
+ bool Cursor64BppSupport;
+ double DCFCLKPerState[DC__VOLTAGE_STATES + 1];
+ double FabricClockPerState[DC__VOLTAGE_STATES + 1];
+ double SOCCLKPerState[DC__VOLTAGE_STATES + 1];
+ double PHYCLKPerState[DC__VOLTAGE_STATES + 1];
+ double MaxDppclk[DC__VOLTAGE_STATES + 1];
+ double MaxDSCCLK[DC__VOLTAGE_STATES + 1];
+ double DRAMSpeedPerState[DC__VOLTAGE_STATES + 1];
+ double MaxDispclk[DC__VOLTAGE_STATES + 1];
+
+ /*outputs*/
+ bool ScaleRatioAndTapsSupport;
+ bool SourceFormatPixelAndScanSupport;
+ unsigned int SwathWidthYSingleDPP[DC__NUM_DPP__MAX];
+ double BytePerPixelInDETY[DC__NUM_DPP__MAX];
+ double BytePerPixelInDETC[DC__NUM_DPP__MAX];
+ double TotalReadBandwidthConsumedGBytePerSecond;
+ double ReadBandwidth[DC__NUM_DPP__MAX];
+ double TotalWriteBandwidthConsumedGBytePerSecond;
+ double WriteBandwidth[DC__NUM_DPP__MAX];
+ double TotalBandwidthConsumedGBytePerSecond;
+ bool DCCEnabledInAnyPlane;
+ bool WritebackLatencySupport;
+ bool WritebackModeSupport;
+ bool Writeback10bpc420Supported;
+ bool BandwidthSupport[DC__VOLTAGE_STATES + 1];
+ unsigned int TotalNumberOfActiveWriteback;
+ double CriticalPoint;
+ double ReturnBWToDCNPerState;
+ double FabricAndDRAMBandwidthPerState[DC__VOLTAGE_STATES + 1];
+ double ReturnBWPerState[DC__VOLTAGE_STATES + 1];
+ double UrgentRoundTripAndOutOfOrderLatencyPerState[DC__VOLTAGE_STATES + 1];
+ bool ODMCombineEnablePerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ bool PTEBufferSizeNotExceededY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ bool PTEBufferSizeNotExceededC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ bool PrefetchSupported[DC__VOLTAGE_STATES + 1];
+ bool VRatioInPrefetchSupported[DC__VOLTAGE_STATES + 1];
+ bool DISPCLK_DPPCLK_Support[DC__VOLTAGE_STATES + 1];
+ bool TotalAvailablePipesSupport[DC__VOLTAGE_STATES + 1];
+ bool UrgentLatencySupport[DC__VOLTAGE_STATES + 1];
+ bool ModeSupport[DC__VOLTAGE_STATES + 1];
+ bool DIOSupport[DC__VOLTAGE_STATES + 1];
+ bool NotEnoughDSCUnits[DC__VOLTAGE_STATES + 1];
+ bool DSCCLKRequiredMoreThanSupported[DC__VOLTAGE_STATES + 1];
+ bool ROBSupport[DC__VOLTAGE_STATES + 1];
+ bool PTEBufferSizeNotExceeded[DC__VOLTAGE_STATES + 1];
+ bool RequiresDSC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ bool IsErrorResult[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ bool ViewportSizeSupport[DC__VOLTAGE_STATES + 1];
+ bool prefetch_vm_bw_valid;
+ bool prefetch_row_bw_valid;
+ bool NumberOfOTGSupport;
+ bool NonsupportedDSCInputBPC;
+ bool WritebackScaleRatioAndTapsSupport;
+ bool CursorSupport;
+ bool PitchSupport;
+
+ double WritebackLineBufferLumaBufferSize;
+ double WritebackLineBufferChromaBufferSize;
+ double WritebackMinHSCLRatio;
+ double WritebackMinVSCLRatio;
+ double WritebackMaxHSCLRatio;
+ double WritebackMaxVSCLRatio;
+ double WritebackMaxHSCLTaps;
+ double WritebackMaxVSCLTaps;
+ unsigned int MaxNumDPP;
+ unsigned int MaxNumOTG;
+ double CursorBufferSize;
+ double CursorChunkSize;
+ unsigned int Mode;
+ unsigned int NoOfDPP[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double OutputLinkDPLanes[DC__NUM_DPP__MAX];
+ double SwathWidthYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double SwathHeightYPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double SwathHeightCPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double UrgentLatencySupportUsPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double VRatioPreY[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double VRatioPreC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double RequiredPrefetchPixelDataBW[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double RequiredDPPCLK[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double RequiredDISPCLK[DC__VOLTAGE_STATES + 1];
+ double TotalNumberOfActiveDPP[DC__VOLTAGE_STATES + 1];
+ double TotalNumberOfDCCActiveDPP[DC__VOLTAGE_STATES + 1];
+ double PrefetchBW[DC__NUM_DPP__MAX];
+ double PDEAndMetaPTEBytesPerFrame[DC__NUM_DPP__MAX];
+ double MetaRowBytes[DC__NUM_DPP__MAX];
+ double DPTEBytesPerRow[DC__NUM_DPP__MAX];
+ double PrefetchLinesY[DC__NUM_DPP__MAX];
+ double PrefetchLinesC[DC__NUM_DPP__MAX];
+ unsigned int MaxNumSwY[DC__NUM_DPP__MAX];
+ unsigned int MaxNumSwC[DC__NUM_DPP__MAX];
+ double PrefillY[DC__NUM_DPP__MAX];
+ double PrefillC[DC__NUM_DPP__MAX];
+ double LineTimesForPrefetch[DC__NUM_DPP__MAX];
+ double LinesForMetaPTE[DC__NUM_DPP__MAX];
+ double LinesForMetaAndDPTERow[DC__NUM_DPP__MAX];
+ double MinDPPCLKUsingSingleDPP[DC__NUM_DPP__MAX];
+ double RequiresFEC[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ unsigned int OutputBppPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ double DSCDelayPerState[DC__VOLTAGE_STATES + 1][DC__NUM_DPP__MAX];
+ unsigned int Read256BlockHeightY[DC__NUM_DPP__MAX];
+ unsigned int Read256BlockWidthY[DC__NUM_DPP__MAX];
+ unsigned int Read256BlockHeightC[DC__NUM_DPP__MAX];
+ unsigned int Read256BlockWidthC[DC__NUM_DPP__MAX];
+ unsigned int ImmediateFlipBytes[DC__NUM_DPP__MAX];
+ double MaxSwathHeightY[DC__NUM_DPP__MAX];
+ double MaxSwathHeightC[DC__NUM_DPP__MAX];
+ double MinSwathHeightY[DC__NUM_DPP__MAX];
+ double MinSwathHeightC[DC__NUM_DPP__MAX];
+ double PSCL_FACTOR[DC__NUM_DPP__MAX];
+ double PSCL_FACTOR_CHROMA[DC__NUM_DPP__MAX];
+ double MaximumVStartup[DC__NUM_DPP__MAX];
+ double AlignedDCCMetaPitch[DC__NUM_DPP__MAX];
+ double AlignedYPitch[DC__NUM_DPP__MAX];
+ double AlignedCPitch[DC__NUM_DPP__MAX];
+ double MaximumSwathWidth[DC__NUM_DPP__MAX];
+ double final_flip_bw[DC__NUM_DPP__MAX];
+ double ImmediateFlipSupportedForState[DC__VOLTAGE_STATES + 1];
+
+ double WritebackLumaVExtra;
+ double WritebackChromaVExtra;
+ double WritebackRequiredDISPCLK;
+ double MaximumSwathWidthSupport;
+ double MaximumSwathWidthInDETBuffer;
+ double MaximumSwathWidthInLineBuffer;
+ double MaxDispclkRoundedDownToDFSGranularity;
+ double MaxDppclkRoundedDownToDFSGranularity;
+ double PlaneRequiredDISPCLKWithoutODMCombine;
+ double PlaneRequiredDISPCLK;
+ double TotalNumberOfActiveOTG;
+ double FECOverhead;
+ double EffectiveFECOverhead;
+ unsigned int Outbpp;
+ unsigned int OutbppDSC;
+ double TotalDSCUnitsRequired;
+ double bpp;
+ unsigned int slices;
+ double SwathWidthGranularityY;
+ double RoundedUpMaxSwathSizeBytesY;
+ double SwathWidthGranularityC;
+ double RoundedUpMaxSwathSizeBytesC;
+ double LinesInDETLuma;
+ double LinesInDETChroma;
+ double EffectiveDETLBLinesLuma;
+ double EffectiveDETLBLinesChroma;
+ double ProjectedDCFCLKDeepSleep;
+ double PDEAndMetaPTEBytesPerFrameY;
+ double PDEAndMetaPTEBytesPerFrameC;
+ unsigned int MetaRowBytesY;
+ unsigned int MetaRowBytesC;
+ unsigned int DPTEBytesPerRowC;
+ unsigned int DPTEBytesPerRowY;
+ double ExtraLatency;
+ double TimeCalc;
+ double TWait;
+ double MaximumReadBandwidthWithPrefetch;
+ double total_dcn_read_bw_with_flip;
+};
+
+#endif /* _DML2_DISPLAY_MODE_VBA_H_ */
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 @@
* Authors: AMD
*
*/
-#include "display_rq_dlg_calc.h"
+
#include "display_mode_lib.h"
+#include "display_mode_vba.h"
+#include "display_rq_dlg_calc.h"
+
+static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+ double *refcyc_per_req_delivery_pre_cur,
+ double *refcyc_per_req_delivery_cur,
+ double refclk_freq_in_mhz,
+ double ref_freq_to_pix_freq,
+ double hscale_pixel_rate_l,
+ double hscl_ratio,
+ double vratio_pre_l,
+ double vratio_l,
+ unsigned int cur_width,
+ enum cursor_bpp cur_bpp);
#include "dml_inline_defs.h"
@@ -50,6 +64,8 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format
ret_val = 4;
else
ret_val = 2;
+ } else if (source_format == dm_444_8) {
+ ret_val = 1;
}
return ret_val;
}
@@ -64,123 +80,43 @@ static bool is_dual_plane(enum source_format_class source_format)
return ret_val;
}
-static void get_blk256_size(
- unsigned int *blk256_width,
- unsigned int *blk256_height,
- unsigned int bytes_per_element)
-{
- if (bytes_per_element == 1) {
- *blk256_width = 16;
- *blk256_height = 16;
- } else if (bytes_per_element == 2) {
- *blk256_width = 16;
- *blk256_height = 8;
- } else if (bytes_per_element == 4) {
- *blk256_width = 8;
- *blk256_height = 8;
- } else if (bytes_per_element == 8) {
- *blk256_width = 8;
- *blk256_height = 4;
- }
-}
-
-static double get_refcyc_per_delivery(
- struct display_mode_lib *mode_lib,
+static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib,
double refclk_freq_in_mhz,
double pclk_freq_in_mhz,
- int unsigned recout_width,
+ bool odm_combine,
+ unsigned int recout_width,
+ unsigned int hactive,
double vratio,
double hscale_pixel_rate,
- int unsigned delivery_width,
- int unsigned req_per_swath_ub)
+ unsigned int delivery_width,
+ unsigned int req_per_swath_ub)
{
double refcyc_per_delivery = 0.0;
+
if (vratio <= 1.0) {
- refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
- / pclk_freq_in_mhz / (double) req_per_swath_ub;
+ if (odm_combine)
+ refcyc_per_delivery = (double) refclk_freq_in_mhz
+ * dml_min((double) recout_width, (double) hactive / 2.0)
+ / pclk_freq_in_mhz / (double) req_per_swath_ub;
+ else
+ refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
+ / pclk_freq_in_mhz / (double) req_per_swath_ub;
} else {
refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
/ (double) hscale_pixel_rate / (double) req_per_swath_ub;
}
- DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
- DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
- DTRACE("DLG: %s: recout_width = %d", __func__, recout_width);
- DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio);
- DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub);
- DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery);
+ dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
+ dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz);
+ dml_print("DML_DLG: %s: recout_width = %d\n", __func__, recout_width);
+ dml_print("DML_DLG: %s: vratio = %3.2f\n", __func__, vratio);
+ dml_print("DML_DLG: %s: req_per_swath_ub = %d\n", __func__, req_per_swath_ub);
+ dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery);
return refcyc_per_delivery;
}
-static double get_vratio_pre(
- struct display_mode_lib *mode_lib,
- unsigned int max_num_sw,
- unsigned int max_partial_sw,
- unsigned int swath_height,
- double vinit,
- double l_sw)
-{
- double prefill = dml_floor(vinit);
- double vratio_pre = 1.0;
-
- vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw;
-
- if (swath_height > 4) {
- double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0);
- if (tmp0 > vratio_pre)
- vratio_pre = tmp0;
- }
-
- DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw);
- DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw);
- DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
- DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
- DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre);
-
- if (vratio_pre < 1.0) {
- DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre);
- vratio_pre = 1.0;
- }
-
- if (vratio_pre > 4.0) {
- DTRACE(
- "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0",
- __func__,
- vratio_pre);
- vratio_pre = 4.0;
- }
-
- return vratio_pre;
-}
-
-static void get_swath_need(
- struct display_mode_lib *mode_lib,
- unsigned int *max_num_sw,
- unsigned int *max_partial_sw,
- unsigned int swath_height,
- double vinit)
-{
- double prefill = dml_floor(vinit);
- unsigned int max_partial_sw_int;
-
- DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
- DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
-
- ASSERT(prefill > 0.0 && prefill <= 8.0);
-
- *max_num_sw = (int unsigned) (dml_ceil((prefill - 1.0) / (double) swath_height) + 1.0); /* prefill has to be >= 1 */
- max_partial_sw_int =
- (prefill == 1) ?
- (swath_height - 1) :
- ((int unsigned) (prefill - 2.0) % swath_height);
- *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */
-
- DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw);
- DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw);
-}
-
static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
{
if (tile_size == dm_256k_tile)
@@ -191,12 +127,11 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si
return (4 * 1024);
}
-static void extract_rq_sizing_regs(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_regs_st *rq_regs,
- const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
+static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib,
+ display_data_rq_regs_st *rq_regs,
+ const display_data_rq_sizing_params_st rq_sizing)
{
- DTRACE("DLG: %s: rq_sizing param", __func__);
+ dml_print("DML_DLG: %s: rq_sizing param\n", __func__);
print__data_rq_sizing_params_st(mode_lib, rq_sizing);
rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
@@ -216,25 +151,30 @@ static void extract_rq_sizing_regs(
rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
}
-void extract_rq_regs(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_regs_st *rq_regs,
- const struct _vcs_dpi_display_rq_params_st rq_param)
+static void extract_rq_regs(struct display_mode_lib *mode_lib,
+ display_rq_regs_st *rq_regs,
+ const display_rq_params_st rq_param)
{
unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
unsigned int detile_buf_plane1_addr = 0;
extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
- if (rq_param.yuv420)
+
+ rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height),
+ 1) - 3;
+
+ if (rq_param.yuv420) {
extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
+ rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height),
+ 1) - 3;
+ }
rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
- /* FIXME: take the max between luma, chroma chunk size?
- * okay for now, as we are setting chunk_bytes to 8kb anyways
- */
- if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */
+ // FIXME: take the max between luma, chroma chunk size?
+ // okay for now, as we are setting chunk_bytes to 8kb anyways
+ if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb
rq_regs->drq_expansion_mode = 0;
} else {
rq_regs->drq_expansion_mode = 2;
@@ -246,21 +186,19 @@ void extract_rq_regs(
if (rq_param.yuv420) {
if ((double) rq_param.misc.rq_l.stored_swath_bytes
/ (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
- detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */
+ detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma
} else {
- detile_buf_plane1_addr = dml_round_to_multiple(
- (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
+ detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
256,
- 0) / 64.0; /* 2/3 to chroma */
+ 0) / 64.0; // 2/3 to chroma
}
}
rq_regs->plane1_base_address = detile_buf_plane1_addr;
}
-static void handle_det_buf_split(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_params_st *rq_param,
- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
+static void handle_det_buf_split(struct display_mode_lib *mode_lib,
+ display_rq_params_st *rq_param,
+ const display_pipe_source_params_st pipe_src_param)
{
unsigned int total_swath_bytes = 0;
unsigned int swath_bytes_l = 0;
@@ -279,12 +217,10 @@ static void handle_det_buf_split(
full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
if (rq_param->yuv420_10bpc) {
- full_swath_bytes_packed_l = dml_round_to_multiple(
- rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
+ full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
256,
1) + 256;
- full_swath_bytes_packed_c = dml_round_to_multiple(
- rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
+ full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
256,
1) + 256;
}
@@ -292,29 +228,19 @@ static void handle_det_buf_split(
if (rq_param->yuv420) {
total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
- if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */
+ if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request
req128_l = 0;
req128_c = 0;
swath_bytes_l = full_swath_bytes_packed_l;
swath_bytes_c = full_swath_bytes_packed_c;
- } else { /*128b request (for luma only for yuv420 8bpc) */
+ } else { //128b request (for luma only for yuv420 8bpc)
req128_l = 1;
req128_c = 0;
swath_bytes_l = full_swath_bytes_packed_l / 2;
swath_bytes_c = full_swath_bytes_packed_c;
}
-
- /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137)
- * TODO: Remove after rtl fix
- */
- if (req128_l == 1) {
- req128_c = 1;
- DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__);
- }
-
- /* Note: assumption, the config that pass in will fit into
- * the detiled buffer.
- */
+ // Note: assumption, the config that pass in will fit into
+ // the detiled buffer.
} else {
total_swath_bytes = 2 * full_swath_bytes_packed_l;
@@ -342,207 +268,47 @@ static void handle_det_buf_split(
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
- DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l);
- DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c);
- DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l);
- DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c);
+ dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l);
+ dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c);
+ dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n",
+ __func__,
+ full_swath_bytes_packed_l);
+ dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n",
+ __func__,
+ full_swath_bytes_packed_c);
}
-/* Need refactor. */
-void dml_rq_dlg_get_row_heights(
- struct display_mode_lib *mode_lib,
- unsigned int *o_dpte_row_height,
- unsigned int *o_meta_row_height,
+static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
+ display_data_rq_dlg_params_st *rq_dlg_param,
+ display_data_rq_misc_params_st *rq_misc_param,
+ display_data_rq_sizing_params_st *rq_sizing_param,
unsigned int vp_width,
+ unsigned int vp_height,
unsigned int data_pitch,
- int source_format,
- int tiling,
- int macro_tile_size,
- int source_scan,
- int is_chroma)
+ unsigned int meta_pitch,
+ unsigned int source_format,
+ unsigned int tiling,
+ unsigned int macro_tile_size,
+ unsigned int source_scan,
+ unsigned int is_chroma)
{
bool surf_linear = (tiling == dm_sw_linear);
bool surf_vert = (source_scan == dm_vert);
- unsigned int bytes_per_element = get_bytes_per_element(
- (enum source_format_class) source_format,
- is_chroma);
- unsigned int log2_bytes_per_element = dml_log2(bytes_per_element);
+ unsigned int bytes_per_element;
+ unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format),
+ false);
+ unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format),
+ true);
+
unsigned int blk256_width = 0;
unsigned int blk256_height = 0;
- unsigned int log2_blk256_height;
- unsigned int blk_bytes;
- unsigned int log2_blk_bytes;
- unsigned int log2_blk_height;
- unsigned int log2_blk_width;
- unsigned int log2_meta_req_bytes;
- unsigned int log2_meta_req_height;
- unsigned int log2_meta_req_width;
- unsigned int log2_meta_row_height;
- unsigned int log2_vmpg_bytes;
- unsigned int dpte_buf_in_pte_reqs;
- unsigned int log2_vmpg_height;
- unsigned int log2_vmpg_width;
- unsigned int log2_dpte_req_height_ptes;
- unsigned int log2_dpte_req_width_ptes;
- unsigned int log2_dpte_req_height;
- unsigned int log2_dpte_req_width;
- unsigned int log2_dpte_row_height_linear;
- unsigned int log2_dpte_row_height;
- unsigned int dpte_req_width;
-
- if (surf_linear) {
- blk256_width = 256;
- blk256_height = 1;
- } else {
- get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
- }
-
- log2_blk256_height = dml_log2((double) blk256_height);
- blk_bytes = surf_linear ?
- 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
- log2_blk_bytes = dml_log2((double) blk_bytes);
- log2_blk_height = 0;
- log2_blk_width = 0;
-
- /* remember log rule
- * "+" in log is multiply
- * "-" in log is divide
- * "/2" is like square root
- * blk is vertical biased
- */
- if (tiling != dm_sw_linear)
- log2_blk_height = log2_blk256_height
- + dml_ceil((double) (log2_blk_bytes - 8) / 2.0);
- else
- log2_blk_height = 0; /* blk height of 1 */
-
- log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
-
- /* ------- */
- /* meta */
- /* ------- */
- log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
-
- /* each 64b meta request for dcn is 8x8 meta elements and
- * a meta element covers one 256b block of the the data surface.
- */
- log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */
- log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
- - log2_meta_req_height;
- log2_meta_row_height = 0;
-
- /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
- * calculate upper bound of the meta_row_width
- */
- if (!surf_vert)
- log2_meta_row_height = log2_meta_req_height;
- else
- log2_meta_row_height = log2_meta_req_width;
-
- *o_meta_row_height = 1 << log2_meta_row_height;
-
- /* ------ */
- /* dpte */
- /* ------ */
- log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
- dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
-
- log2_vmpg_height = 0;
- log2_vmpg_width = 0;
- log2_dpte_req_height_ptes = 0;
- log2_dpte_req_width_ptes = 0;
- log2_dpte_req_height = 0;
- log2_dpte_req_width = 0;
- log2_dpte_row_height_linear = 0;
- log2_dpte_row_height = 0;
- dpte_req_width = 0; /* 64b dpte req width in data element */
-
- if (surf_linear) {
- log2_vmpg_height = 0; /* one line high */
- } else {
- log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
- }
- log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
-
- /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
- if (log2_blk_bytes <= log2_vmpg_bytes)
- log2_dpte_req_height_ptes = 0;
- else if (log2_blk_height - log2_vmpg_height >= 2)
- log2_dpte_req_height_ptes = 2;
- else
- log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
- log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
-
- ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
- (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
- (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
-
- /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height
- * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent
- */
- log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
- log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
- dpte_req_width = 1 << log2_dpte_req_width;
-
- /* calculate pitch dpte row buffer can hold
- * round the result down to a power of two.
- */
- if (surf_linear) {
- log2_dpte_row_height_linear = dml_floor(
- dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch));
-
- ASSERT(log2_dpte_row_height_linear >= 3);
-
- if (log2_dpte_row_height_linear > 7)
- log2_dpte_row_height_linear = 7;
-
- log2_dpte_row_height = log2_dpte_row_height_linear;
- } else {
- /* the upper bound of the dpte_row_width without dependency on viewport position follows. */
- if (!surf_vert) {
- log2_dpte_row_height = log2_dpte_req_height;
- } else {
- log2_dpte_row_height =
- (log2_blk_width < log2_dpte_req_width) ?
- log2_blk_width : log2_dpte_req_width;
- }
- }
-
- /* From programming guide:
- * There is a special case of saving only half of ptes returned due to buffer space limits.
- * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
- * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
- */
- if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
- && log2_blk_bytes >= 16) {
- log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
- }
-
- *o_dpte_row_height = 1 << log2_dpte_row_height;
-}
-
-static void get_surf_rq_param(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param,
- struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param,
- struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param,
- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param,
- bool is_chroma)
-{
- bool mode_422 = 0;
- unsigned int vp_width = 0;
- unsigned int vp_height = 0;
- unsigned int data_pitch = 0;
- unsigned int meta_pitch = 0;
- unsigned int ppe = mode_422 ? 2 : 1;
- bool surf_linear;
- bool surf_vert;
- unsigned int bytes_per_element;
+ unsigned int blk256_width_y = 0;
+ unsigned int blk256_height_y = 0;
+ unsigned int blk256_width_c = 0;
+ unsigned int blk256_height_c = 0;
unsigned int log2_bytes_per_element;
- unsigned int blk256_width;
- unsigned int blk256_height;
unsigned int log2_blk256_width;
unsigned int log2_blk256_height;
unsigned int blk_bytes;
@@ -558,6 +324,8 @@ static void get_surf_rq_param(
unsigned int meta_row_width_ub;
unsigned int log2_meta_chunk_bytes;
unsigned int log2_meta_chunk_height;
+
+ //full sized meta chunk width in unit of data elements
unsigned int log2_meta_chunk_width;
unsigned int log2_min_meta_chunk_bytes;
unsigned int min_meta_chunk_width;
@@ -572,93 +340,72 @@ static void get_surf_rq_param(
unsigned int vmpg_bytes;
unsigned int meta_pte_req_per_frame_ub;
unsigned int meta_pte_bytes_per_frame_ub;
- unsigned int log2_vmpg_bytes;
- unsigned int dpte_buf_in_pte_reqs;
- unsigned int log2_vmpg_height;
- unsigned int log2_vmpg_width;
- unsigned int log2_dpte_req_height_ptes;
- unsigned int log2_dpte_req_width_ptes;
- unsigned int log2_dpte_req_height;
- unsigned int log2_dpte_req_width;
- unsigned int log2_dpte_row_height_linear;
- unsigned int log2_dpte_row_height;
- unsigned int log2_dpte_group_width;
- unsigned int dpte_row_width_ub;
- unsigned int dpte_row_height;
- unsigned int dpte_req_height;
- unsigned int dpte_req_width;
- unsigned int dpte_group_width;
- unsigned int log2_dpte_group_bytes;
- unsigned int log2_dpte_group_length;
- unsigned int func_meta_row_height, func_dpte_row_height;
-
- /* FIXME check if ppe apply for both luma and chroma in 422 case */
- if (is_chroma) {
- vp_width = pipe_src_param.viewport_width_c / ppe;
- vp_height = pipe_src_param.viewport_height_c;
- data_pitch = pipe_src_param.data_pitch_c;
- meta_pitch = pipe_src_param.meta_pitch_c;
+ const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+ const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
+ const unsigned int pde_proc_buffer_size_64k_reqs =
+ mode_lib->ip.pde_proc_buffer_size_64k_reqs;
+
+ unsigned int log2_vmpg_height = 0;
+ unsigned int log2_vmpg_width = 0;
+ unsigned int log2_dpte_req_height_ptes = 0;
+ unsigned int log2_dpte_req_height = 0;
+ unsigned int log2_dpte_req_width = 0;
+ unsigned int log2_dpte_row_height_linear = 0;
+ unsigned int log2_dpte_row_height = 0;
+ unsigned int log2_dpte_group_width = 0;
+ unsigned int dpte_row_width_ub = 0;
+ unsigned int dpte_req_height = 0;
+ unsigned int dpte_req_width = 0;
+ unsigned int dpte_group_width = 0;
+ unsigned int log2_dpte_group_bytes = 0;
+ unsigned int log2_dpte_group_length = 0;
+ unsigned int pde_buf_entries;
+ bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10);
+
+ Calculate256BBlockSizes((enum source_format_class)(source_format),
+ (enum dm_swizzle_mode)(tiling),
+ bytes_per_element_y,
+ bytes_per_element_c,
+ &blk256_height_y,
+ &blk256_height_c,
+ &blk256_width_y,
+ &blk256_width_c);
+
+ if (!is_chroma) {
+ blk256_width = blk256_width_y;
+ blk256_height = blk256_height_y;
+ bytes_per_element = bytes_per_element_y;
} else {
- vp_width = pipe_src_param.viewport_width / ppe;
- vp_height = pipe_src_param.viewport_height;
- data_pitch = pipe_src_param.data_pitch;
- meta_pitch = pipe_src_param.meta_pitch;
+ blk256_width = blk256_width_c;
+ blk256_height = blk256_height_c;
+ bytes_per_element = bytes_per_element_c;
}
- rq_sizing_param->chunk_bytes = 8192;
-
- if (rq_sizing_param->chunk_bytes == 64 * 1024)
- rq_sizing_param->min_chunk_bytes = 0;
- else
- rq_sizing_param->min_chunk_bytes = 1024;
-
- rq_sizing_param->meta_chunk_bytes = 2048;
- rq_sizing_param->min_meta_chunk_bytes = 256;
-
- rq_sizing_param->mpte_group_bytes = 2048;
-
- surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
- surf_vert = (pipe_src_param.source_scan == dm_vert);
-
- bytes_per_element = get_bytes_per_element(
- (enum source_format_class) pipe_src_param.source_format,
- is_chroma);
log2_bytes_per_element = dml_log2(bytes_per_element);
- blk256_width = 0;
- blk256_height = 0;
- if (surf_linear) {
- blk256_width = 256 / bytes_per_element;
- blk256_height = 1;
- } else {
- get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
- }
-
- DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear);
- DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert);
- DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width);
- DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height);
+ dml_print("DML_DLG: %s: surf_linear = %d\n", __func__, surf_linear);
+ dml_print("DML_DLG: %s: surf_vert = %d\n", __func__, surf_vert);
+ dml_print("DML_DLG: %s: blk256_width = %d\n", __func__, blk256_width);
+ dml_print("DML_DLG: %s: blk256_height = %d\n", __func__, blk256_height);
log2_blk256_width = dml_log2((double) blk256_width);
log2_blk256_height = dml_log2((double) blk256_height);
- blk_bytes =
- surf_linear ? 256 : get_blk_size_bytes(
- (enum source_macro_tile_size) pipe_src_param.macro_tile_size);
+ blk_bytes = surf_linear ?
+ 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
log2_blk_bytes = dml_log2((double) blk_bytes);
log2_blk_height = 0;
log2_blk_width = 0;
- /* remember log rule
- * "+" in log is multiply
- * "-" in log is divide
- * "/2" is like square root
- * blk is vertical biased
- */
- if (pipe_src_param.sw_mode != dm_sw_linear)
+ // remember log rule
+ // "+" in log is multiply
+ // "-" in log is divide
+ // "/2" is like square root
+ // blk is vertical biased
+ if (tiling != dm_sw_linear)
log2_blk_height = log2_blk256_height
- + dml_ceil((double) (log2_blk_bytes - 8) / 2.0);
+ + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
else
- log2_blk_height = 0; /* blk height of 1 */
+ log2_blk_height = 0; // blk height of 1
log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
@@ -667,10 +414,8 @@ static void get_surf_rq_param(
+ blk256_width;
rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
} else {
- rq_dlg_param->swath_width_ub = dml_round_to_multiple(
- vp_height - 1,
- blk256_height,
- 1) + blk256_height;
+ rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_height - 1, blk256_height, 1)
+ + blk256_height;
rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
}
@@ -684,15 +429,14 @@ static void get_surf_rq_param(
rq_misc_param->blk256_height = blk256_height;
rq_misc_param->blk256_width = blk256_width;
- /* ------- */
- /* meta */
- /* ------- */
- log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
+ // -------
+ // meta
+ // -------
+ log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
- /* each 64b meta request for dcn is 8x8 meta elements and
- * a meta element covers one 256b block of the the data surface.
- */
- log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
+ // each 64b meta request for dcn is 8x8 meta elements and
+ // a meta element covers one 256b block of the the data surface.
+ log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
- log2_meta_req_height;
meta_req_width = 1 << log2_meta_req_width;
@@ -700,9 +444,8 @@ static void get_surf_rq_param(
log2_meta_row_height = 0;
meta_row_width_ub = 0;
- /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
- * calculate upper bound of the meta_row_width
- */
+ // the dimensions of a meta row are meta_row_width x meta_row_height in elements.
+ // calculate upper bound of the meta_row_width
if (!surf_vert) {
log2_meta_row_height = log2_meta_req_height;
meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1)
@@ -716,10 +459,12 @@ static void get_surf_rq_param(
}
rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
+ rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
+
log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
log2_meta_chunk_height = log2_meta_row_height;
- /*full sized meta chunk width in unit of data elements */
+ //full sized meta chunk width in unit of data elements
log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element
- log2_meta_chunk_height;
log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
@@ -734,21 +479,24 @@ static void get_surf_rq_param(
meta_blk_height = blk256_height * 64;
meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height;
meta_surface_bytes = meta_pitch
- * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1)
- + meta_blk_height) * bytes_per_element / 256;
+ * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height)
+ * bytes_per_element / 256;
vmpg_bytes = mode_lib->soc.vmm_page_size_bytes;
- meta_pte_req_per_frame_ub = (dml_round_to_multiple(
- meta_surface_bytes - vmpg_bytes,
+ meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes,
8 * vmpg_bytes,
1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
- meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */
+ meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request
rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
- DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height);
- DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width);
- DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes);
- DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub);
- DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub);
+ dml_print("DML_DLG: %s: meta_blk_height = %d\n", __func__, meta_blk_height);
+ dml_print("DML_DLG: %s: meta_blk_width = %d\n", __func__, meta_blk_width);
+ dml_print("DML_DLG: %s: meta_surface_bytes = %d\n", __func__, meta_surface_bytes);
+ dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub = %d\n",
+ __func__,
+ meta_pte_req_per_frame_ub);
+ dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n",
+ __func__,
+ meta_pte_bytes_per_frame_ub);
if (!surf_vert)
meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
@@ -760,67 +508,58 @@ static void get_surf_rq_param(
else
rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
- rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
-
- /* ------ */
- /* dpte */
- /* ------ */
- log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
- dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
-
- log2_vmpg_height = 0;
- log2_vmpg_width = 0;
- log2_dpte_req_height_ptes = 0;
- log2_dpte_req_width_ptes = 0;
- log2_dpte_req_height = 0;
- log2_dpte_req_width = 0;
- log2_dpte_row_height_linear = 0;
- log2_dpte_row_height = 0;
- log2_dpte_group_width = 0;
- dpte_row_width_ub = 0;
- dpte_row_height = 0;
- dpte_req_height = 0; /* 64b dpte req height in data element */
- dpte_req_width = 0; /* 64b dpte req width in data element */
- dpte_group_width = 0;
- log2_dpte_group_bytes = 0;
- log2_dpte_group_length = 0;
-
+ // ------
+ // dpte
+ // ------
if (surf_linear) {
- log2_vmpg_height = 0; /* one line high */
+ log2_vmpg_height = 0; // one line high
} else {
log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
}
log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
- /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
- if (log2_blk_bytes <= log2_vmpg_bytes)
+ // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4.
+ if (surf_linear) { //one 64B PTE request returns 8 PTEs
log2_dpte_req_height_ptes = 0;
- else if (log2_blk_height - log2_vmpg_height >= 2)
- log2_dpte_req_height_ptes = 2;
- else
- log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
- log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
-
- /* Ensure we only have the 3 shapes */
- ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
- (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
- (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
-
- /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
- * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
- * That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
- */
- log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
- log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
+ log2_dpte_req_width = log2_vmpg_width + 3;
+ log2_dpte_req_height = 0;
+ } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size
+ //one 64B req gives 8x1 PTEs for 4KB tile
+ log2_dpte_req_height_ptes = 0;
+ log2_dpte_req_width = log2_blk_width + 3;
+ log2_dpte_req_height = log2_blk_height + 0;
+ } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB
+ //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB
+ log2_dpte_req_height_ptes = 4;
+ log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width
+ log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height
+ } else { //64KB page size and must 64KB tile block
+ //one 64B req gives 8x1 PTEs for 64KB tile
+ log2_dpte_req_height_ptes = 0;
+ log2_dpte_req_width = log2_blk_width + 3;
+ log2_dpte_req_height = log2_blk_height + 0;
+ }
+
+ // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
+ // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
+ // That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
+ //log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
+ //log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
dpte_req_height = 1 << log2_dpte_req_height;
dpte_req_width = 1 << log2_dpte_req_width;
- /* calculate pitch dpte row buffer can hold
- * round the result down to a power of two.
- */
+ // calculate pitch dpte row buffer can hold
+ // round the result down to a power of two.
+ pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs;
if (surf_linear) {
- log2_dpte_row_height_linear = dml_floor(
- dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch));
+ unsigned int dpte_row_height;
+
+ log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries
+ / bytes_per_element,
+ dpte_buf_in_pte_reqs
+ * dpte_req_width)
+ / data_pitch),
+ 1);
ASSERT(log2_dpte_row_height_linear >= 3);
@@ -828,18 +567,16 @@ static void get_surf_rq_param(
log2_dpte_row_height_linear = 7;
log2_dpte_row_height = log2_dpte_row_height_linear;
- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
-
- /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
- * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
- */
- dpte_row_width_ub = dml_round_to_multiple(
- data_pitch * dpte_row_height - 1,
+ // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
+ // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
+ dpte_row_height = 1 << log2_dpte_row_height;
+ dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1,
dpte_req_width,
1) + dpte_req_width;
rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
} else {
- /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */
+ // the upper bound of the dpte_row_width without dependency on viewport position follows.
+ // for tiled mode, row height is the same as req height and row store up to vp size upper bound
if (!surf_vert) {
log2_dpte_row_height = log2_dpte_req_height;
dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1)
@@ -853,103 +590,117 @@ static void get_surf_rq_param(
+ dpte_req_height;
rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
}
- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
- }
- rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64;
-
- /* From programming guide:
- * There is a special case of saving only half of ptes returned due to buffer space limits.
- * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
- * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
- */
- if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
- && log2_blk_bytes >= 16) {
- log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
}
+ if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB
+ rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request
+ else
+ rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request
+
+ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
- /* the dpte_group_bytes is reduced for the specific case of vertical
- * access of a tile surface that has dpte request of 8x1 ptes.
- */
- if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */
+ // the dpte_group_bytes is reduced for the specific case of vertical
+ // access of a tile surface that has dpte request of 8x1 ptes.
+ if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group
rq_sizing_param->dpte_group_bytes = 512;
else
- /*full size */
+ //full size
rq_sizing_param->dpte_group_bytes = 2048;
- /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */
+ //since pte request size is 64byte, the number of data pte requests per full sized group is as follows.
log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
- log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */
+ log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests
- /* full sized data pte group width in elements */
+ // full sized data pte group width in elements
if (!surf_vert)
log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
else
log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
+ //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B
+ if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB
+ log2_dpte_group_width = log2_dpte_group_width - 1;
+
dpte_group_width = 1 << log2_dpte_group_width;
- /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
- * the upper bound for the dpte groups per row is as follows.
- */
- rq_dlg_param->dpte_groups_per_row_ub = dml_ceil(
- (double) dpte_row_width_ub / dpte_group_width);
+ // since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
+ // the upper bound for the dpte groups per row is as follows.
+ rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width,
+ 1);
+}
+
+static void get_surf_rq_param(struct display_mode_lib *mode_lib,
+ display_data_rq_sizing_params_st *rq_sizing_param,
+ display_data_rq_dlg_params_st *rq_dlg_param,
+ display_data_rq_misc_params_st *rq_misc_param,
+ const display_pipe_source_params_st pipe_src_param,
+ bool is_chroma)
+{
+ bool mode_422 = 0;
+ unsigned int vp_width = 0;
+ unsigned int vp_height = 0;
+ unsigned int data_pitch = 0;
+ unsigned int meta_pitch = 0;
+ unsigned int ppe = mode_422 ? 2 : 1;
+
+ // FIXME check if ppe apply for both luma and chroma in 422 case
+ if (is_chroma) {
+ vp_width = pipe_src_param.viewport_width_c / ppe;
+ vp_height = pipe_src_param.viewport_height_c;
+ data_pitch = pipe_src_param.data_pitch_c;
+ meta_pitch = pipe_src_param.meta_pitch_c;
+ } else {
+ vp_width = pipe_src_param.viewport_width / ppe;
+ vp_height = pipe_src_param.viewport_height;
+ data_pitch = pipe_src_param.data_pitch;
+ meta_pitch = pipe_src_param.meta_pitch;
+ }
+
+ rq_sizing_param->chunk_bytes = 8192;
+
+ if (rq_sizing_param->chunk_bytes == 64 * 1024)
+ rq_sizing_param->min_chunk_bytes = 0;
+ else
+ rq_sizing_param->min_chunk_bytes = 1024;
+
+ rq_sizing_param->meta_chunk_bytes = 2048;
+ rq_sizing_param->min_meta_chunk_bytes = 256;
- dml_rq_dlg_get_row_heights(
- mode_lib,
- &func_dpte_row_height,
- &func_meta_row_height,
+ rq_sizing_param->mpte_group_bytes = 2048;
+
+ get_meta_and_pte_attr(mode_lib,
+ rq_dlg_param,
+ rq_misc_param,
+ rq_sizing_param,
vp_width,
+ vp_height,
data_pitch,
+ meta_pitch,
pipe_src_param.source_format,
pipe_src_param.sw_mode,
pipe_src_param.macro_tile_size,
pipe_src_param.source_scan,
is_chroma);
-
- /* Just a check to make sure this function and the new one give the same
- * result. The standalone get_row_heights() function is based off of the
- * code in this function so the same changes need to be made to both.
- */
- if (rq_dlg_param->meta_row_height != func_meta_row_height) {
- DTRACE(
- "MISMATCH: rq_dlg_param->meta_row_height = %d",
- rq_dlg_param->meta_row_height);
- DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height);
- ASSERT(0);
- }
-
- if (rq_dlg_param->dpte_row_height != func_dpte_row_height) {
- DTRACE(
- "MISMATCH: rq_dlg_param->dpte_row_height = %d",
- rq_dlg_param->dpte_row_height);
- DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height);
- ASSERT(0);
- }
}
-void dml_rq_dlg_get_rq_params(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_params_st *rq_param,
- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
+void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
+ display_rq_params_st *rq_param,
+ const display_pipe_source_params_st pipe_src_param)
{
- /* get param for luma surface */
+ // get param for luma surface
rq_param->yuv420 = pipe_src_param.source_format == dm_420_8
|| pipe_src_param.source_format == dm_420_10;
rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10;
- get_surf_rq_param(
- mode_lib,
+ get_surf_rq_param(mode_lib,
&(rq_param->sizing.rq_l),
&(rq_param->dlg.rq_l),
&(rq_param->misc.rq_l),
pipe_src_param,
0);
- if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) {
- /* get param for chroma surface */
- get_surf_rq_param(
- mode_lib,
+ if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) {
+ // get param for chroma surface
+ get_surf_rq_param(mode_lib,
&(rq_param->sizing.rq_c),
&(rq_param->dlg.rq_c),
&(rq_param->misc.rq_c),
@@ -957,355 +708,126 @@ void dml_rq_dlg_get_rq_params(
1);
}
- /* calculate how to split the det buffer space between luma and chroma */
+ // calculate how to split the det buffer space between luma and chroma
handle_det_buf_split(mode_lib, rq_param, pipe_src_param);
print__rq_params_st(mode_lib, *rq_param);
}
-void dml_rq_dlg_get_rq_reg(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_regs_st *rq_regs,
- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
+void dml_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
+ display_rq_regs_st *rq_regs,
+ const display_pipe_source_params_st pipe_src_param)
{
- struct _vcs_dpi_display_rq_params_st rq_param = {0};
+ display_rq_params_st rq_param = {0};
memset(rq_regs, 0, sizeof(*rq_regs));
-
dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_src_param);
extract_rq_regs(mode_lib, rq_regs, rq_param);
print__rq_regs_st(mode_lib, *rq_regs);
}
-/* TODO: Need refactor, so this is used by dml_rq_dlg_get_dlg_params as well
- * The problem is that there are some intermediate terms that would need by
- * some dlg calculation (i.e. rest of prefetch and active prog guide calculation)
- */
-void dml_rq_dlg_get_dlg_params_prefetch(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param,
- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
- struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
- const bool cstate_en,
- const bool pstate_en,
- const bool vm_en)
-{
- /* Prefetch */
- unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
- bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
- unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
- const double prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
- double min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
- double t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
-
- bool dcc_en = e2e_pipe_param.pipe.src.dcc;
- bool dual_plane = is_dual_plane(
- (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
- unsigned int bytes_per_element_l = get_bytes_per_element(
- (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
- 0);
- unsigned int bytes_per_element_c = get_bytes_per_element(
- (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
- 1);
-
- double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
- double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
- double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
-
- double line_time_in_us = (htotal / pclk_freq_in_mhz);
- double vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
- double vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
- double vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
- double vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
-
- unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height;
- unsigned int swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
- unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
- unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
- unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
-
- unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height;
- unsigned int swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
- unsigned int dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
- unsigned int vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
- unsigned int vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
- unsigned int vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
-
- const unsigned int dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
- const unsigned int dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
- unsigned int pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz
- / dppclk_freq_in_mhz
- + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
- unsigned int dst_y_after_scaler = 0;
- unsigned int dst_x_after_scaler = 0;
-
- unsigned int vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
-
- double line_wait;
- double line_o;
- double line_setup;
- double line_calc;
- double dst_y_prefetch;
- double t_pre_us;
- int unsigned vm_bytes;
- int unsigned meta_row_bytes;
- int unsigned max_num_sw_l;
- int unsigned max_num_sw_c;
- int unsigned max_partial_sw_l;
- int unsigned max_partial_sw_c;
-
- double max_vinit_l;
- double max_vinit_c;
- int unsigned lsw_l;
- int unsigned lsw_c;
- int unsigned sw_bytes_ub_l;
- int unsigned sw_bytes_ub_c;
- int unsigned sw_bytes;
- int unsigned dpte_row_bytes;
-
- if (interlaced)
- vstartup_start = vstartup_start / 2;
-
- if (vstartup_start >= min_vblank) {
- min_vblank = vstartup_start + 1;
- DTRACE(
- "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
- __func__,
- vstartup_start,
- min_vblank);
- }
-
- if (e2e_pipe_param.pipe.src.is_hsplit)
- dst_x_after_scaler = pixel_rate_delay_subtotal
- + e2e_pipe_param.pipe.dest.recout_width;
- else
- dst_x_after_scaler = pixel_rate_delay_subtotal;
-
- if (e2e_pipe_param.dout.output_format == dm_420)
- dst_y_after_scaler = 1;
- else
- dst_y_after_scaler = 0;
-
- if (dst_x_after_scaler >= htotal) {
- dst_x_after_scaler = dst_x_after_scaler - htotal;
- dst_y_after_scaler = dst_y_after_scaler + 1;
- }
-
- DTRACE("DLG: %s: htotal = %d", __func__, htotal);
- DTRACE(
- "DLG: %s: pixel_rate_delay_subtotal = %d",
- __func__,
- pixel_rate_delay_subtotal);
- DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler);
- DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler);
-
- line_wait = mode_lib->soc.urgent_latency_us;
- if (cstate_en)
- line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
- if (pstate_en)
- line_wait = dml_max(
- mode_lib->soc.dram_clock_change_latency_us
- + mode_lib->soc.urgent_latency_us,
- line_wait);
- line_wait = line_wait / line_time_in_us;
-
- line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
- line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
- line_calc = t_calc_us / line_time_in_us;
-
- DTRACE(
- "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f",
- __func__,
- (double) mode_lib->soc.sr_enter_plus_exit_time_us);
- DTRACE(
- "DLG: %s: soc.dram_clock_change_latency_us = %3.2f",
- __func__,
- (double) mode_lib->soc.dram_clock_change_latency_us);
-
- DTRACE("DLG: %s: urgent_latency_us = %3.2f", __func__, mode_lib->soc.urgent_latency_us);
- DTRACE(
- "DLG: %s: t_srx_delay_us = %3.2f",
- __func__,
- (double) dlg_sys_param.t_srx_delay_us);
- DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
- DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
- DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
- DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset);
- DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait);
- DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o);
- DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup);
- DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc);
-
- dst_y_prefetch = ((double) min_vblank - 1.0)
- - (line_setup + line_calc + line_wait + line_o);
- DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
- ASSERT(dst_y_prefetch >= 2.0);
-
- dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4;
- DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
-
- t_pre_us = dst_y_prefetch * line_time_in_us;
- vm_bytes = 0;
- meta_row_bytes = 0;
-
- if (dcc_en && vm_en)
- vm_bytes = meta_pte_bytes_per_frame_ub_l;
- if (dcc_en)
- meta_row_bytes = meta_bytes_per_row_ub_l;
-
- max_num_sw_l = 0;
- max_num_sw_c = 0;
- max_partial_sw_l = 0;
- max_partial_sw_c = 0;
-
- max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
- max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
-
- get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
- if (dual_plane)
- get_swath_need(
- mode_lib,
- &max_num_sw_c,
- &max_partial_sw_c,
- swath_height_c,
- max_vinit_c);
-
- lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
- lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
- sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
- sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
- sw_bytes = 0;
- dpte_row_bytes = 0;
-
- if (vm_en) {
- if (dual_plane)
- dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
- else
- dpte_row_bytes = dpte_bytes_per_row_ub_l;
- } else {
- dpte_row_bytes = 0;
- }
-
- if (dual_plane)
- sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
- else
- sw_bytes = sw_bytes_ub_l;
-
- DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l);
- DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c);
- DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes);
- DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes);
- DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes);
- DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes);
-
- prefetch_param->prefetch_bw =
- (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
- prefetch_param->flip_bytes = (vm_bytes + dpte_row_bytes + meta_row_bytes);
-}
-
-/* Note: currently taken in as is.
- * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
- */
-void dml_rq_dlg_get_dlg_params(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs,
- struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs,
- const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
- const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
- const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+// Note: currently taken in as is.
+// Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
+void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *e2e_pipe_param,
+ const unsigned int num_pipes,
+ const unsigned int pipe_idx,
+ display_dlg_regs_st *disp_dlg_regs,
+ display_ttu_regs_st *disp_ttu_regs,
+ const display_rq_dlg_params_st rq_dlg_param,
+ const display_dlg_sys_params_st dlg_sys_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
- const bool iflip_en)
+ const bool ignore_viewport_pos,
+ const bool immediate_flip_support)
{
- /* Timing */
- unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
- unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end;
- unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start;
- unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end;
- bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
+ const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
+ const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
+ const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout;
+ const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
+ const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth;
+ const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps;
+
+ // -------------------------
+ // Section 1.15.2.1: OTG dependent Params
+ // -------------------------
+ // Timing
+ unsigned int htotal = dst->htotal;
+// unsigned int hblank_start = dst.hblank_start; // TODO: Remove
+ unsigned int hblank_end = dst->hblank_end;
+ unsigned int vblank_start = dst->vblank_start;
+ unsigned int vblank_end = dst->vblank_end;
unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
- double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
- double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz;
- double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
- double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
+ double dppclk_freq_in_mhz = clks->dppclk_mhz;
+ double dispclk_freq_in_mhz = clks->dispclk_mhz;
+ double refclk_freq_in_mhz = clks->refclk_mhz;
+ double pclk_freq_in_mhz = dst->pixel_rate_mhz;
+ bool interlaced = dst->interlaced;
+
+ double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
- double ref_freq_to_pix_freq;
- double prefetch_xy_calc_in_dcfclk;
double min_dcfclk_mhz;
double t_calc_us;
double min_ttu_vblank;
+
double min_dst_y_ttu_vblank;
- int unsigned dlg_vblank_start;
- bool dcc_en;
+ unsigned int dlg_vblank_start;
bool dual_plane;
bool mode_422;
unsigned int access_dir;
- unsigned int bytes_per_element_l;
- unsigned int bytes_per_element_c;
unsigned int vp_height_l;
unsigned int vp_width_l;
unsigned int vp_height_c;
unsigned int vp_width_c;
+
+ // Scaling
unsigned int htaps_l;
unsigned int htaps_c;
- double hratios_l;
- double hratios_c;
+ double hratio_l;
+ double hratio_c;
double vratio_l;
double vratio_c;
+ bool scl_enable;
+
double line_time_in_us;
- double vinit_l;
- double vinit_c;
- double vinit_bot_l;
- double vinit_bot_c;
- unsigned int swath_height_l;
+ // double vinit_l;
+ // double vinit_c;
+ // double vinit_bot_l;
+ // double vinit_bot_c;
+
+ // unsigned int swath_height_l;
unsigned int swath_width_ub_l;
- unsigned int dpte_bytes_per_row_ub_l;
+ // unsigned int dpte_bytes_per_row_ub_l;
unsigned int dpte_groups_per_row_ub_l;
- unsigned int meta_pte_bytes_per_frame_ub_l;
- unsigned int meta_bytes_per_row_ub_l;
- unsigned int swath_height_c;
+ // unsigned int meta_pte_bytes_per_frame_ub_l;
+ // unsigned int meta_bytes_per_row_ub_l;
+
+ // unsigned int swath_height_c;
unsigned int swath_width_ub_c;
- unsigned int dpte_bytes_per_row_ub_c;
+ // unsigned int dpte_bytes_per_row_ub_c;
unsigned int dpte_groups_per_row_ub_c;
+
unsigned int meta_chunks_per_row_ub_l;
+ unsigned int meta_chunks_per_row_ub_c;
unsigned int vupdate_offset;
unsigned int vupdate_width;
unsigned int vready_offset;
+
unsigned int dppclk_delay_subtotal;
unsigned int dispclk_delay_subtotal;
unsigned int pixel_rate_delay_subtotal;
+
unsigned int vstartup_start;
unsigned int dst_x_after_scaler;
unsigned int dst_y_after_scaler;
double line_wait;
- double line_o;
- double line_setup;
- double line_calc;
double dst_y_prefetch;
- double t_pre_us;
- int unsigned vm_bytes;
- int unsigned meta_row_bytes;
- int unsigned max_num_sw_l;
- int unsigned max_num_sw_c;
- int unsigned max_partial_sw_l;
- int unsigned max_partial_sw_c;
- double max_vinit_l;
- double max_vinit_c;
- int unsigned lsw_l;
- int unsigned lsw_c;
- int unsigned sw_bytes_ub_l;
- int unsigned sw_bytes_ub_c;
- int unsigned sw_bytes;
- int unsigned dpte_row_bytes;
- double prefetch_bw;
- double flip_bw;
- double t_vm_us;
- double t_r0_us;
double dst_y_per_vm_vblank;
double dst_y_per_row_vblank;
+ double dst_y_per_vm_flip;
+ double dst_y_per_row_flip;
double min_dst_y_per_vm_vblank;
double min_dst_y_per_row_vblank;
double lsw;
@@ -1314,6 +836,7 @@ void dml_rq_dlg_get_dlg_params(
unsigned int req_per_swath_ub_l;
unsigned int req_per_swath_ub_c;
unsigned int meta_row_height_l;
+ unsigned int meta_row_height_c;
unsigned int swath_width_pixels_ub_l;
unsigned int swath_width_pixels_ub_c;
unsigned int scaler_rec_in_width_l;
@@ -1328,59 +851,52 @@ void dml_rq_dlg_get_dlg_params(
double refcyc_per_line_delivery_pre_c;
double refcyc_per_line_delivery_l;
double refcyc_per_line_delivery_c;
+
double refcyc_per_req_delivery_pre_l;
double refcyc_per_req_delivery_pre_c;
double refcyc_per_req_delivery_l;
double refcyc_per_req_delivery_c;
+
+ unsigned int full_recout_width;
+ double xfc_transfer_delay;
+ double xfc_precharge_delay;
+ double xfc_remote_surface_flip_latency;
+ double xfc_dst_y_delta_drq_limit;
+ double xfc_prefetch_margin;
double refcyc_per_req_delivery_pre_cur0;
double refcyc_per_req_delivery_cur0;
- int unsigned full_recout_width;
- double hratios_cur0;
- unsigned int cur0_src_width;
- enum cursor_bpp cur0_bpp;
- unsigned int cur0_req_size;
- unsigned int cur0_req_width;
- double cur0_width_ub;
- double cur0_req_per_width;
- double hactive_cur0;
+ double refcyc_per_req_delivery_pre_cur1;
+ double refcyc_per_req_delivery_cur1;
memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
- DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en);
- DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en);
- DTRACE("DLG: %s: vm_en = %d", __func__, vm_en);
- DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en);
-
- /* ------------------------- */
- /* Section 1.5.2.1: OTG dependent Params */
- /* ------------------------- */
- DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz);
- DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz);
- DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
- DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
- DTRACE("DLG: %s: interlaced = %d", __func__, interlaced);
-
- ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
+ dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en);
+ dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en);
+ dml_print("DML_DLG: %s: vm_en = %d\n", __func__, vm_en);
+ dml_print("DML_DLG: %s: ignore_viewport_pos = %d\n", __func__, ignore_viewport_pos);
+ dml_print("DML_DLG: %s: immediate_flip_support = %d\n", __func__, immediate_flip_support);
+
+ dml_print("DML_DLG: %s: dppclk_freq_in_mhz = %3.2f\n", __func__, dppclk_freq_in_mhz);
+ dml_print("DML_DLG: %s: dispclk_freq_in_mhz = %3.2f\n", __func__, dispclk_freq_in_mhz);
+ dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
+ dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz);
+ dml_print("DML_DLG: %s: interlaced = %d\n", __func__, interlaced);
ASSERT(ref_freq_to_pix_freq < 4.0);
+
disp_dlg_regs->ref_freq_to_pix_freq =
(unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal
* dml_pow(2, 8));
+ disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; // 15 bits
disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end
* (double) ref_freq_to_pix_freq);
ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13));
- disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */
- prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
- t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
- min_ttu_vblank = dlg_sys_param.t_urg_wm_us;
- if (cstate_en)
- min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank);
- if (pstate_en)
- min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank);
- min_ttu_vblank = min_ttu_vblank + t_calc_us;
+ set_prefetch_mode(mode_lib, cstate_en, pstate_en, ignore_viewport_pos, immediate_flip_support);
+ t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes);
+ min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal;
dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
@@ -1389,383 +905,202 @@ void dml_rq_dlg_get_dlg_params(
+ min_dst_y_ttu_vblank) * dml_pow(2, 2));
ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18));
- DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz);
- DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank);
- DTRACE(
- "DLG: %s: min_dst_y_ttu_vblank = %3.2f",
+ dml_print("DML_DLG: %s: min_dcfclk_mhz = %3.2f\n",
+ __func__,
+ min_dcfclk_mhz);
+ dml_print("DML_DLG: %s: min_ttu_vblank = %3.2f\n",
+ __func__,
+ min_ttu_vblank);
+ dml_print("DML_DLG: %s: min_dst_y_ttu_vblank = %3.2f\n",
__func__,
min_dst_y_ttu_vblank);
- DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us);
- DTRACE(
- "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x",
+ dml_print("DML_DLG: %s: t_calc_us = %3.2f\n",
+ __func__,
+ t_calc_us);
+ dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x\n",
__func__,
disp_dlg_regs->min_dst_y_next_start);
- DTRACE(
- "DLG: %s: ref_freq_to_pix_freq = %3.2f",
+ dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n",
__func__,
ref_freq_to_pix_freq);
- /* ------------------------- */
- /* Section 1.5.2.2: Prefetch, Active and TTU */
- /* ------------------------- */
- /* Prefetch Calc */
- /* Source */
- dcc_en = e2e_pipe_param.pipe.src.dcc;
- dual_plane = is_dual_plane(
- (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
- mode_422 = 0; /* FIXME */
- access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */
- bytes_per_element_l = get_bytes_per_element(
- (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
- 0);
- bytes_per_element_c = get_bytes_per_element(
- (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
- 1);
- vp_height_l = e2e_pipe_param.pipe.src.viewport_height;
- vp_width_l = e2e_pipe_param.pipe.src.viewport_width;
- vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c;
- vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c;
-
- /* Scaling */
- htaps_l = e2e_pipe_param.pipe.scale_taps.htaps;
- htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c;
- hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
- hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c;
- vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio;
- vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c;
+ // -------------------------
+ // Section 1.15.2.2: Prefetch, Active and TTU
+ // -------------------------
+ // Prefetch Calc
+ // Source
+// dcc_en = src.dcc;
+ dual_plane = is_dual_plane((enum source_format_class)(src->source_format));
+ mode_422 = 0; // FIXME
+ access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
+// bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0);
+// bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1);
+ vp_height_l = src->viewport_height;
+ vp_width_l = src->viewport_width;
+ vp_height_c = src->viewport_height_c;
+ vp_width_c = src->viewport_width_c;
+
+ // Scaling
+ htaps_l = taps->htaps;
+ htaps_c = taps->htaps_c;
+ hratio_l = scl->hscl_ratio;
+ hratio_c = scl->hscl_ratio_c;
+ vratio_l = scl->vscl_ratio;
+ vratio_c = scl->vscl_ratio_c;
+ scl_enable = scl->scl_enable;
line_time_in_us = (htotal / pclk_freq_in_mhz);
- vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
- vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
- vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
- vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
+// vinit_l = scl.vinit;
+// vinit_c = scl.vinit_c;
+// vinit_bot_l = scl.vinit_bot;
+// vinit_bot_c = scl.vinit_bot_c;
- swath_height_l = rq_dlg_param.rq_l.swath_height;
+// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height;
swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
- dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
+// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
- meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
- meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
+// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
+// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
- swath_height_c = rq_dlg_param.rq_c.swath_height;
+// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height;
swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
- dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
+ // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
- vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
- vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
- vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
+ meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub;
+ vupdate_offset = dst->vupdate_offset;
+ vupdate_width = dst->vupdate_width;
+ vready_offset = dst->vready_offset;
dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
+
+ if (scl_enable)
+ dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl;
+ else
+ dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only;
+
+ dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter
+ + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor;
+
+ if (dout->dsc_enable) {
+ double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+
+ dispclk_delay_subtotal += dsc_delay;
+ }
+
pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
+ dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
- vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
+ vstartup_start = dst->vstartup_start;
+ if (interlaced) {
+ if (vstartup_start / 2.0
+ - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
+ <= vblank_end / 2.0)
+ disp_dlg_regs->vready_after_vcount0 = 1;
+ else
+ disp_dlg_regs->vready_after_vcount0 = 0;
+ } else {
+ if (vstartup_start
+ - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
+ <= vblank_end)
+ disp_dlg_regs->vready_after_vcount0 = 1;
+ else
+ disp_dlg_regs->vready_after_vcount0 = 0;
+ }
+ // TODO: Where is this coming from?
if (interlaced)
vstartup_start = vstartup_start / 2;
+ // TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp?
if (vstartup_start >= min_vblank) {
- DTRACE(
- "WARNING_DLG: %s: vblank_start=%d vblank_end=%d",
+ dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n",
__func__,
vblank_start,
vblank_end);
- DTRACE(
- "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
+ dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
__func__,
vstartup_start,
min_vblank);
min_vblank = vstartup_start + 1;
- DTRACE(
- "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
+ dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
__func__,
vstartup_start,
min_vblank);
}
- dst_x_after_scaler = 0;
- dst_y_after_scaler = 0;
-
- if (e2e_pipe_param.pipe.src.is_hsplit)
- dst_x_after_scaler = pixel_rate_delay_subtotal
- + e2e_pipe_param.pipe.dest.recout_width;
- else
- dst_x_after_scaler = pixel_rate_delay_subtotal;
-
- if (e2e_pipe_param.dout.output_format == dm_420)
- dst_y_after_scaler = 1;
- else
- dst_y_after_scaler = 0;
+ dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+ dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- if (dst_x_after_scaler >= htotal) {
- dst_x_after_scaler = dst_x_after_scaler - htotal;
- dst_y_after_scaler = dst_y_after_scaler + 1;
- }
-
- DTRACE("DLG: %s: htotal = %d", __func__, htotal);
- DTRACE(
- "DLG: %s: pixel_rate_delay_subtotal = %d",
+ dml_print("DML_DLG: %s: htotal = %d\n", __func__, htotal);
+ dml_print("DML_DLG: %s: pixel_rate_delay_subtotal = %d\n",
__func__,
pixel_rate_delay_subtotal);
- DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler);
- DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler);
+ dml_print("DML_DLG: %s: dst_x_after_scaler = %d\n",
+ __func__,
+ dst_x_after_scaler);
+ dml_print("DML_DLG: %s: dst_y_after_scaler = %d\n",
+ __func__,
+ dst_y_after_scaler);
+ // Lwait
line_wait = mode_lib->soc.urgent_latency_us;
if (cstate_en)
line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
if (pstate_en)
- line_wait = dml_max(
- mode_lib->soc.dram_clock_change_latency_us
+ line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us
+ mode_lib->soc.urgent_latency_us,
line_wait);
line_wait = line_wait / line_time_in_us;
- line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
- line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
- line_calc = t_calc_us / line_time_in_us;
+ dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+ dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
- DTRACE(
- "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f",
- __func__,
- (double) mode_lib->soc.sr_enter_plus_exit_time_us);
- DTRACE(
- "DLG: %s: soc.dram_clock_change_latency_us = %3.2f",
- __func__,
- (double) mode_lib->soc.dram_clock_change_latency_us);
- DTRACE(
- "DLG: %s: soc.urgent_latency_us = %3.2f",
- __func__,
- mode_lib->soc.urgent_latency_us);
-
- DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l);
- if (dual_plane)
- DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c);
-
- DTRACE(
- "DLG: %s: t_srx_delay_us = %3.2f",
- __func__,
- (double) dlg_sys_param.t_srx_delay_us);
- DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
- DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
- DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
- DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset);
- DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us);
- DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait);
- DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o);
- DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup);
- DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc);
-
- dst_y_prefetch = ((double) min_vblank - 1.0)
- - (line_setup + line_calc + line_wait + line_o);
- DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
- ASSERT(dst_y_prefetch >= 2.0);
-
- dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125)) / 4;
- DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
-
- t_pre_us = dst_y_prefetch * line_time_in_us;
- vm_bytes = 0;
- meta_row_bytes = 0;
-
- if (dcc_en && vm_en)
- vm_bytes = meta_pte_bytes_per_frame_ub_l;
- if (dcc_en)
- meta_row_bytes = meta_bytes_per_row_ub_l;
-
- max_num_sw_l = 0;
- max_num_sw_c = 0;
- max_partial_sw_l = 0;
- max_partial_sw_c = 0;
-
- max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
- max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
-
- get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
- if (dual_plane)
- get_swath_need(
- mode_lib,
- &max_num_sw_c,
- &max_partial_sw_c,
- swath_height_c,
- max_vinit_c);
-
- lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
- lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
- sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
- sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
- sw_bytes = 0;
- dpte_row_bytes = 0;
-
- if (vm_en) {
- if (dual_plane)
- dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
- else
- dpte_row_bytes = dpte_bytes_per_row_ub_l;
- } else {
- dpte_row_bytes = 0;
- }
-
- if (dual_plane)
- sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
- else
- sw_bytes = sw_bytes_ub_l;
-
- DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l);
- DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c);
- DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes);
- DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes);
- DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes);
- DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes);
-
- prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
- flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw)
- / (double) dlg_sys_param.total_flip_bytes;
- t_vm_us = line_time_in_us / 4.0;
- if (vm_en && dcc_en) {
- t_vm_us = dml_max(
- dlg_sys_param.t_extra_us,
- dml_max((double) vm_bytes / prefetch_bw, t_vm_us));
-
- if (iflip_en && !dual_plane) {
- t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us);
- if (flip_bw > 0.)
- t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us);
- }
- }
-
- t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us);
-
- if (vm_en || dcc_en) {
- t_r0_us = dml_max(
- (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw,
- dlg_sys_param.t_extra_us);
- t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us);
-
- if (iflip_en && !dual_plane) {
- t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us);
- if (flip_bw > 0.)
- t_r0_us = dml_max(
- (dpte_row_bytes + meta_row_bytes) / flip_bw,
- t_r0_us);
- }
- }
-
- disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */
- disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */
- ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
- DTRACE(
- "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x",
- __func__,
- disp_dlg_regs->dst_y_after_scaler);
- DTRACE(
- "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x",
- __func__,
- disp_dlg_regs->refcyc_x_after_scaler);
-
- disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
- DTRACE(
- "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d",
- __func__,
- disp_dlg_regs->dst_y_prefetch);
-
- dst_y_per_vm_vblank = 0.0;
- dst_y_per_row_vblank = 0.0;
-
- dst_y_per_vm_vblank = t_vm_us / line_time_in_us;
- dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125)) / 4.0;
- disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
-
- dst_y_per_row_vblank = t_r0_us / line_time_in_us;
- dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125)) / 4.0;
- disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
-
- DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l);
- DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c);
- DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l);
- DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c);
-
- DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw);
- DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw);
- DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us);
- DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us);
- DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us);
- DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank);
- DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank);
- DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch);
+ dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_idx);
+ dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_idx);
+ dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+ dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
min_dst_y_per_vm_vblank = 8.0;
min_dst_y_per_row_vblank = 16.0;
+
+ // magic!
if (htotal <= 75) {
min_vblank = 300;
min_dst_y_per_vm_vblank = 100.0;
min_dst_y_per_row_vblank = 100.0;
}
+ dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank);
+ dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank);
+
ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
- DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw);
-
- vratio_pre_l = get_vratio_pre(
- mode_lib,
- max_num_sw_l,
- max_partial_sw_l,
- swath_height_l,
- max_vinit_l,
- lsw);
- vratio_pre_c = 1.0;
- if (dual_plane)
- vratio_pre_c = get_vratio_pre(
- mode_lib,
- max_num_sw_c,
- max_partial_sw_c,
- swath_height_c,
- max_vinit_c,
- lsw);
-
- DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l);
- DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c);
-
- ASSERT(vratio_pre_l <= 4.0);
- if (vratio_pre_l >= 4.0)
- disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1;
- else
- disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
+ dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw);
- ASSERT(vratio_pre_c <= 4.0);
- if (vratio_pre_c >= 4.0)
- disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1;
- else
- disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
+ vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+ vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- disp_dlg_regs->refcyc_per_pte_group_vblank_l =
- (unsigned int) (dst_y_per_row_vblank * (double) htotal
- * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
- ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
-
- disp_dlg_regs->refcyc_per_pte_group_vblank_c =
- (unsigned int) (dst_y_per_row_vblank * (double) htotal
- * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c);
- ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13));
-
- disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
- (unsigned int) (dst_y_per_row_vblank * (double) htotal
- * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
- ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
+ dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l);
+ dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c);
- disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
- disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */
-
- /* Active */
+ // Active
req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
+ meta_row_height_c = rq_dlg_param.rq_c.meta_row_height;
swath_width_pixels_ub_l = 0;
swath_width_pixels_ub_c = 0;
scaler_rec_in_width_l = 0;
@@ -1773,40 +1108,8 @@ void dml_rq_dlg_get_dlg_params(
dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
- disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
- / (double) vratio_l * dml_pow(2, 2));
- ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
-
- disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
- / (double) vratio_c * dml_pow(2, 2));
- ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17));
-
- disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
- / (double) vratio_l * dml_pow(2, 2));
- ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
-
- disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */
-
- disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
- / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
- / (double) dpte_groups_per_row_ub_l);
- if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
-
- disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c
- / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq
- / (double) dpte_groups_per_row_ub_c);
- if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
-
- disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
- / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
- / (double) meta_chunks_per_row_ub_l);
- if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
-
if (mode_422) {
- swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */
+ swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element
swath_width_pixels_ub_c = swath_width_ub_c * 2;
} else {
swath_width_pixels_ub_l = swath_width_ub_l * 1;
@@ -1821,15 +1124,15 @@ void dml_rq_dlg_get_dlg_params(
if (htaps_l <= 1)
min_hratio_fact_l = 2.0;
else if (htaps_l <= 6) {
- if ((hratios_l * 2.0) > 4.0)
+ if ((hratio_l * 2.0) > 4.0)
min_hratio_fact_l = 4.0;
else
- min_hratio_fact_l = hratios_l * 2.0;
+ min_hratio_fact_l = hratio_l * 2.0;
} else {
- if (hratios_l > 4.0)
+ if (hratio_l > 4.0)
min_hratio_fact_l = 4.0;
else
- min_hratio_fact_l = hratios_l;
+ min_hratio_fact_l = hratio_l;
}
hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
@@ -1837,15 +1140,15 @@ void dml_rq_dlg_get_dlg_params(
if (htaps_c <= 1)
min_hratio_fact_c = 2.0;
else if (htaps_c <= 6) {
- if ((hratios_c * 2.0) > 4.0)
+ if ((hratio_c * 2.0) > 4.0)
min_hratio_fact_c = 4.0;
else
- min_hratio_fact_c = hratios_c * 2.0;
+ min_hratio_fact_c = hratio_c * 2.0;
} else {
- if (hratios_c > 4.0)
+ if (hratio_c > 4.0)
min_hratio_fact_c = 4.0;
else
- min_hratio_fact_c = hratios_c;
+ min_hratio_fact_c = hratio_c;
}
hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
@@ -1859,97 +1162,90 @@ void dml_rq_dlg_get_dlg_params(
refcyc_per_req_delivery_pre_c = 0.;
refcyc_per_req_delivery_l = 0.;
refcyc_per_req_delivery_c = 0.;
- refcyc_per_req_delivery_pre_cur0 = 0.;
- refcyc_per_req_delivery_cur0 = 0.;
full_recout_width = 0;
- if (e2e_pipe_param.pipe.src.is_hsplit) {
- if (e2e_pipe_param.pipe.dest.full_recout_width == 0) {
- DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__);
- full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */
+ // In ODM
+ if (src->is_hsplit) {
+ // This "hack" is only allowed (and valid) for MPC combine. In ODM
+ // combine, you MUST specify the full_recout_width...according to Oswin
+ if (dst->full_recout_width == 0 && !dst->odm_combine) {
+ dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n",
+ __func__);
+ full_recout_width = dst->recout_width * 2; // assume half split for dcn1
} else
- full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width;
+ full_recout_width = dst->full_recout_width;
} else
- full_recout_width = e2e_pipe_param.pipe.dest.recout_width;
+ full_recout_width = dst->recout_width;
- refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(
- mode_lib,
+ // mpc_combine and odm_combine are mutually exclusive
+ refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_pre_l,
hscale_pixel_rate_l,
swath_width_pixels_ub_l,
- 1); /* per line */
+ 1); // per line
- refcyc_per_line_delivery_l = get_refcyc_per_delivery(
- mode_lib,
+ refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_l,
hscale_pixel_rate_l,
swath_width_pixels_ub_l,
- 1); /* per line */
+ 1); // per line
- DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width);
- DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l);
- DTRACE(
- "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f",
+ dml_print("DML_DLG: %s: full_recout_width = %d\n",
__func__,
- refcyc_per_line_delivery_pre_l);
- DTRACE(
- "DLG: %s: refcyc_per_line_delivery_l = %3.2f",
+ full_recout_width);
+ dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n",
+ __func__,
+ hscale_pixel_rate_l);
+ dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n",
__func__,
- refcyc_per_line_delivery_l);
-
- disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(
refcyc_per_line_delivery_pre_l);
- disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(
+ dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n",
+ __func__,
refcyc_per_line_delivery_l);
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
if (dual_plane) {
- refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(
- mode_lib,
+ refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_pre_c,
hscale_pixel_rate_c,
swath_width_pixels_ub_c,
- 1); /* per line */
+ 1); // per line
- refcyc_per_line_delivery_c = get_refcyc_per_delivery(
- mode_lib,
+ refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_c,
hscale_pixel_rate_c,
swath_width_pixels_ub_c,
- 1); /* per line */
+ 1); // per line
- DTRACE(
- "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
+ dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n",
__func__,
refcyc_per_line_delivery_pre_c);
- DTRACE(
- "DLG: %s: refcyc_per_line_delivery_c = %3.2f",
+ dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n",
__func__,
refcyc_per_line_delivery_c);
-
- disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(
- refcyc_per_line_delivery_pre_c);
- disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(
- refcyc_per_line_delivery_c);
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13)); ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
}
- disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
- /* TTU - Luma / Chroma */
- if (access_dir) { /* vertical access */
+ // TTU - Luma / Chroma
+ if (access_dir) { // vertical access
scaler_rec_in_width_l = vp_height_l;
scaler_rec_in_width_c = vp_height_c;
} else {
@@ -1957,167 +1253,264 @@ void dml_rq_dlg_get_dlg_params(
scaler_rec_in_width_c = vp_width_c;
}
- refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(
- mode_lib,
+ refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_pre_l,
hscale_pixel_rate_l,
scaler_rec_in_width_l,
- req_per_swath_ub_l); /* per req */
- refcyc_per_req_delivery_l = get_refcyc_per_delivery(
- mode_lib,
+ req_per_swath_ub_l); // per req
+ refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_l,
hscale_pixel_rate_l,
scaler_rec_in_width_l,
- req_per_swath_ub_l); /* per req */
+ req_per_swath_ub_l); // per req
- DTRACE(
- "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
+ dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n",
__func__,
refcyc_per_req_delivery_pre_l);
- DTRACE(
- "DLG: %s: refcyc_per_req_delivery_l = %3.2f",
+ dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n",
__func__,
refcyc_per_req_delivery_l);
- disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
- * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
- * dml_pow(2, 10));
-
ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
if (dual_plane) {
- refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(
- mode_lib,
+ refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_pre_c,
hscale_pixel_rate_c,
scaler_rec_in_width_c,
- req_per_swath_ub_c); /* per req */
- refcyc_per_req_delivery_c = get_refcyc_per_delivery(
- mode_lib,
+ req_per_swath_ub_c); // per req
+ refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib,
refclk_freq_in_mhz,
pclk_freq_in_mhz,
+ dst->odm_combine,
full_recout_width,
+ dst->hactive,
vratio_c,
hscale_pixel_rate_c,
scaler_rec_in_width_c,
- req_per_swath_ub_c); /* per req */
+ req_per_swath_ub_c); // per req
- DTRACE(
- "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
+ dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n",
__func__,
refcyc_per_req_delivery_pre_c);
- DTRACE(
- "DLG: %s: refcyc_per_req_delivery_c = %3.2f",
+ dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n",
__func__,
refcyc_per_req_delivery_c);
- disp_ttu_regs->refcyc_per_req_delivery_pre_c =
- (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
- * dml_pow(2, 10));
-
ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
}
- /* TTU - Cursor */
- hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
- cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */
- cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp;
- cur0_req_size = 0;
- cur0_req_width = 0;
- cur0_width_ub = 0.0;
- cur0_req_per_width = 0.0;
- hactive_cur0 = 0.0;
-
- ASSERT(cur0_src_width <= 256);
-
- if (cur0_src_width > 0) {
- unsigned int cur0_bit_per_pixel = 0;
-
- if (cur0_bpp == dm_cur_2bit) {
- cur0_req_size = 64; /* byte */
- cur0_bit_per_pixel = 2;
- } else { /* 32bit */
- cur0_bit_per_pixel = 32;
- if (cur0_src_width >= 1 && cur0_src_width <= 16)
- cur0_req_size = 64;
- else if (cur0_src_width >= 17 && cur0_src_width <= 31)
- cur0_req_size = 128;
- else
- cur0_req_size = 256;
- }
+ // XFC
+ xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+ xfc_precharge_delay = get_xfc_precharge_delay(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_idx);
+ xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_idx);
+ xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency;
+ xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_idx);
+
+ // TTU - Cursor
+ refcyc_per_req_delivery_pre_cur0 = 0.0;
+ refcyc_per_req_delivery_cur0 = 0.0;
+ if (src->num_cursors > 0) {
+ calculate_ttu_cursor(mode_lib,
+ &refcyc_per_req_delivery_pre_cur0,
+ &refcyc_per_req_delivery_cur0,
+ refclk_freq_in_mhz,
+ ref_freq_to_pix_freq,
+ hscale_pixel_rate_l,
+ scl->hscl_ratio,
+ vratio_pre_l,
+ vratio_l,
+ src->cur0_src_width,
+ (enum cursor_bpp)(src->cur0_bpp));
+ }
- cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0);
- cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width)
- * (double) cur0_req_width;
- cur0_req_per_width = cur0_width_ub / (double) cur0_req_width;
- hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */
+ refcyc_per_req_delivery_pre_cur1 = 0.0;
+ refcyc_per_req_delivery_cur1 = 0.0;
+ if (src->num_cursors > 1) {
+ calculate_ttu_cursor(mode_lib,
+ &refcyc_per_req_delivery_pre_cur1,
+ &refcyc_per_req_delivery_cur1,
+ refclk_freq_in_mhz,
+ ref_freq_to_pix_freq,
+ hscale_pixel_rate_l,
+ scl->hscl_ratio,
+ vratio_pre_l,
+ vratio_l,
+ src->cur1_src_width,
+ (enum cursor_bpp)(src->cur1_bpp));
+ }
- if (vratio_pre_l <= 1.0) {
- refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq
- / (double) cur0_req_per_width;
- } else {
- refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz
- * (double) cur0_src_width / hscale_pixel_rate_l
- / (double) cur0_req_per_width;
- }
+ // TTU - Misc
+ // all hard-coded
- disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
- (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
- ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13));
+ // Assignment to register structures
+ disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
+ disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk
+ ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
+ disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
+ disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
+ disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
+ disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
+ disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
- if (vratio_l <= 1.0) {
- refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq
- / (double) cur0_req_per_width;
- } else {
- refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz
- * (double) cur0_src_width / hscale_pixel_rate_l
- / (double) cur0_req_per_width;
+ disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
+ disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
+
+ disp_dlg_regs->refcyc_per_pte_group_vblank_l =
+ (unsigned int) (dst_y_per_row_vblank * (double) htotal
+ * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
+ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
+
+ if (dual_plane) {
+ disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank
+ * (double) htotal * ref_freq_to_pix_freq
+ / (double) dpte_groups_per_row_ub_c);
+ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c
+ < (unsigned int) dml_pow(2, 13));
+ }
+
+ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
+ (unsigned int) (dst_y_per_row_vblank * (double) htotal
+ * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
+ ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
+
+ disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
+ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now
+
+ disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
+ * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l;
+ disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
+ * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l;
+
+ if (dual_plane) {
+ disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip
+ * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c;
+ disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip
+ * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c;
+ }
+
+ disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
+ / (double) vratio_l * dml_pow(2, 2));
+ ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
+
+ if (dual_plane) {
+ disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
+ / (double) vratio_c * dml_pow(2, 2));
+ if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
+ dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n",
+ __func__,
+ disp_dlg_regs->dst_y_per_pte_row_nom_c,
+ (unsigned int) dml_pow(2, 17) - 1);
}
+ }
- DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width);
- DTRACE(
- "DLG: %s: cur0_width_ub = %3.2f",
- __func__,
- cur0_width_ub);
- DTRACE(
- "DLG: %s: cur0_req_per_width = %3.2f",
- __func__,
- cur0_req_per_width);
- DTRACE(
- "DLG: %s: hactive_cur0 = %3.2f",
- __func__,
- hactive_cur0);
- DTRACE(
- "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f",
- __func__,
- refcyc_per_req_delivery_pre_cur0);
- DTRACE(
- "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f",
- __func__,
- refcyc_per_req_delivery_cur0);
+ disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
+ / (double) vratio_l * dml_pow(2, 2));
+ ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
- disp_ttu_regs->refcyc_per_req_delivery_cur0 =
- (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10));
- ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13));
- } else {
- disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0;
- disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0;
+ disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now
+
+ disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
+ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+ / (double) dpte_groups_per_row_ub_l);
+ if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
+ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
+ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+ / (double) meta_chunks_per_row_ub_l);
+ if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
+
+ if (dual_plane) {
+ disp_dlg_regs->refcyc_per_pte_group_nom_c =
+ (unsigned int) ((double) dpte_row_height_c / (double) vratio_c
+ * (double) htotal * ref_freq_to_pix_freq
+ / (double) dpte_groups_per_row_ub_c);
+ if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
+
+ // TODO: Is this the right calculation? Does htotal need to be halved?
+ disp_dlg_regs->refcyc_per_meta_chunk_nom_c =
+ (unsigned int) ((double) meta_row_height_c / (double) vratio_c
+ * (double) htotal * ref_freq_to_pix_freq
+ / (double) meta_chunks_per_row_ub_c);
+ if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1;
}
- /* TTU - Misc */
+ disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l,
+ 1);
+ disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l,
+ 1);
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
+
+ disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c,
+ 1);
+ disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c,
+ 1);
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
+
+ disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
+ disp_dlg_regs->dst_y_offset_cur0 = 0;
+ disp_dlg_regs->chunk_hdl_adjust_cur1 = 3;
+ disp_dlg_regs->dst_y_offset_cur1 = 0;
+
+ disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay;
+ disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay;
+ disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency;
+ disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz,
+ 1);
+
+ // slave has to have this value also set to off
+ if (src->xfc_enable && !src->xfc_slave)
+ disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1);
+ else
+ disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
+
+ disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
+ * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
+ * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c
+ * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
+ * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
+ (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0
+ * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 =
+ (unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1
+ * dml_pow(2, 10));
disp_ttu_regs->qos_level_low_wm = 0;
ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
@@ -2139,118 +1532,232 @@ void dml_rq_dlg_get_dlg_params(
print__dlg_regs_st(mode_lib, *disp_dlg_regs);
}
-void dml_rq_dlg_get_dlg_reg(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
- struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param,
- const int unsigned num_pipes,
- const int unsigned pipe_idx,
+void dml_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
+ display_dlg_regs_st *dlg_regs,
+ display_ttu_regs_st *ttu_regs,
+ display_e2e_pipe_params_st *e2e_pipe_param,
+ const unsigned int num_pipes,
+ const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
- const bool iflip_en)
+ const bool ignore_viewport_pos,
+ const bool immediate_flip_support)
{
- struct _vcs_dpi_display_rq_params_st rq_param = {0};
- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0};
- struct _vcs_dpi_wm_calc_pipe_params_st *wm_param = mode_lib->wm_param;
- struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm;
- struct _vcs_dpi_display_dlg_prefetch_param_st prefetch_param;
- double total_ret_bw;
- double total_active_bw;
- double total_prefetch_bw;
- int unsigned total_flip_bytes;
- int unsigned num_planes;
- int i;
-
- memset(wm_param, 0, sizeof(mode_lib->wm_param));
-
- /* Get watermark and Tex. */
- DTRACE("DLG: Start calculating system setting related parameters. num_pipes=%d", num_pipes);
- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e_pipe_param, num_pipes, wm_param);
-
- cstate_pstate_wm = dml_wm_cstate_pstate_e2e(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.t_mclk_wm_us = cstate_pstate_wm.pstate_change_us;
- dlg_sys_param.t_sr_wm_us = cstate_pstate_wm.cstate_enter_plus_exit_us;
- dlg_sys_param.t_urg_wm_us = dml_wm_urgent_e2e(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
- / dml_wm_dcfclk_deepsleep_mhz_e2e(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.t_extra_us = dml_wm_urgent_extra(mode_lib, wm_param, num_planes);
- dlg_sys_param.deepsleep_dcfclk_mhz = dml_wm_dcfclk_deepsleep_mhz_e2e(
- mode_lib,
+ display_rq_params_st rq_param = {0};
+ display_dlg_sys_params_st dlg_sys_param = {0};
+
+ // Get watermark and Tex.
+ dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes);
+ dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib,
e2e_pipe_param,
num_pipes);
+ dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes);
+ dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes);
+ dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes);
+ dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes);
+ dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib,
+ e2e_pipe_param,
+ num_pipes);
+ dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
+ e2e_pipe_param,
+ num_pipes);
+ dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
+ / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
print__dlg_sys_params_st(mode_lib, dlg_sys_param);
- DTRACE("DLG: Start calculating total prefetch bw. num_planes=%d", num_planes);
- total_ret_bw = dml_wm_calc_return_bw(mode_lib, wm_param, num_planes);
- total_active_bw = dml_wm_calc_total_data_read_bw(mode_lib, wm_param, num_planes);
- total_prefetch_bw = 0.0;
- total_flip_bytes = 0;
-
- for (i = 0; i < num_pipes; i++) {
- dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[i].pipe.src);
- dml_rq_dlg_get_dlg_params_prefetch(
- mode_lib,
- &prefetch_param,
- rq_param.dlg,
- dlg_sys_param,
- e2e_pipe_param[i],
- cstate_en,
- pstate_en,
- vm_en);
- total_prefetch_bw += prefetch_param.prefetch_bw;
- total_flip_bytes += prefetch_param.flip_bytes;
- DTRACE(
- "DLG: pipe=%d, total_prefetch_bw=%3.2f total_flip_bytes=%d",
- i,
- total_prefetch_bw,
- total_flip_bytes);
- }
-
- dlg_sys_param.total_flip_bw = total_ret_bw - dml_max(total_active_bw, total_prefetch_bw);
-
- DTRACE("DLG: Done calculating total prefetch bw");
- DTRACE("DLG: num_pipes = %d", num_pipes);
- DTRACE("DLG: total_ret_bw = %3.2f", total_ret_bw);
- DTRACE("DLG: total_active_bw = %3.2f", total_active_bw);
- DTRACE("DLG: total_prefetch_bw = %3.2f", total_prefetch_bw);
- DTRACE("DLG: total_flip_bw = %3.2f", dlg_sys_param.total_flip_bw);
-
- if (dlg_sys_param.total_flip_bw < 0.0 && iflip_en) {
- DTRACE("WARNING_DLG Insufficient bw for immediate flip!");
- dlg_sys_param.total_flip_bw = 0;
- }
+ // system parameter calculation done
- dlg_sys_param.total_flip_bytes = total_flip_bytes;
- DTRACE("DLG: total_flip_bytes = %d", dlg_sys_param.total_flip_bytes);
- DTRACE("DLG: Done calculating system setting related parameters.");
-
- /* system parameter calculation done */
-
- DTRACE("DLG: Calculation for pipe[%d] start", pipe_idx);
+ dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src);
- dml_rq_dlg_get_dlg_params(
- mode_lib,
+ dml_rq_dlg_get_dlg_params(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_idx,
dlg_regs,
ttu_regs,
rq_param.dlg,
dlg_sys_param,
- e2e_pipe_param[pipe_idx],
cstate_en,
pstate_en,
vm_en,
- iflip_en);
- DTRACE("DLG: Calculation for pipe[%d] end", pipe_idx);
+ ignore_viewport_pos,
+ immediate_flip_support);
+ dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx);
}
-void dml_rq_dlg_get_arb_params(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_arb_params_st *arb_param)
+void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param)
{
memset(arb_param, 0, sizeof(*arb_param));
arb_param->max_req_outstanding = 256;
arb_param->min_req_outstanding = 68;
arb_param->sat_level_us = 60;
}
+
+void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
+ double *refcyc_per_req_delivery_pre_cur,
+ double *refcyc_per_req_delivery_cur,
+ double refclk_freq_in_mhz,
+ double ref_freq_to_pix_freq,
+ double hscale_pixel_rate_l,
+ double hscl_ratio,
+ double vratio_pre_l,
+ double vratio_l,
+ unsigned int cur_width,
+ enum cursor_bpp cur_bpp)
+{
+ unsigned int cur_src_width = cur_width;
+ unsigned int cur_req_size = 0;
+ unsigned int cur_req_width = 0;
+ double cur_width_ub = 0.0;
+ double cur_req_per_width = 0.0;
+ double hactive_cur = 0.0;
+
+ ASSERT(cur_src_width <= 256);
+
+ *refcyc_per_req_delivery_pre_cur = 0.0;
+ *refcyc_per_req_delivery_cur = 0.0;
+ if (cur_src_width > 0) {
+ unsigned int cur_bit_per_pixel = 0;
+
+ if (cur_bpp == dm_cur_2bit) {
+ cur_req_size = 64; // byte
+ cur_bit_per_pixel = 2;
+ } else { // 32bit
+ cur_bit_per_pixel = 32;
+ if (cur_src_width >= 1 && cur_src_width <= 16)
+ cur_req_size = 64;
+ else if (cur_src_width >= 17 && cur_src_width <= 31)
+ cur_req_size = 128;
+ else
+ cur_req_size = 256;
+ }
+
+ cur_req_width = (double) cur_req_size / ((double) cur_bit_per_pixel / 8.0);
+ cur_width_ub = dml_ceil((double) cur_src_width / (double) cur_req_width, 1)
+ * (double) cur_req_width;
+ cur_req_per_width = cur_width_ub / (double) cur_req_width;
+ hactive_cur = (double) cur_src_width / hscl_ratio; // FIXME: oswin to think about what to do for cursor
+
+ if (vratio_pre_l <= 1.0) {
+ *refcyc_per_req_delivery_pre_cur = hactive_cur * ref_freq_to_pix_freq
+ / (double) cur_req_per_width;
+ } else {
+ *refcyc_per_req_delivery_pre_cur = (double) refclk_freq_in_mhz
+ * (double) cur_src_width / hscale_pixel_rate_l
+ / (double) cur_req_per_width;
+ }
+
+ ASSERT(*refcyc_per_req_delivery_pre_cur < dml_pow(2, 13));
+
+ if (vratio_l <= 1.0) {
+ *refcyc_per_req_delivery_cur = hactive_cur * ref_freq_to_pix_freq
+ / (double) cur_req_per_width;
+ } else {
+ *refcyc_per_req_delivery_cur = (double) refclk_freq_in_mhz
+ * (double) cur_src_width / hscale_pixel_rate_l
+ / (double) cur_req_per_width;
+ }
+
+ dml_print("DML_DLG: %s: cur_req_width = %d\n",
+ __func__,
+ cur_req_width);
+ dml_print("DML_DLG: %s: cur_width_ub = %3.2f\n",
+ __func__,
+ cur_width_ub);
+ dml_print("DML_DLG: %s: cur_req_per_width = %3.2f\n",
+ __func__,
+ cur_req_per_width);
+ dml_print("DML_DLG: %s: hactive_cur = %3.2f\n",
+ __func__,
+ hactive_cur);
+ dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_cur = %3.2f\n",
+ __func__,
+ *refcyc_per_req_delivery_pre_cur);
+ dml_print("DML_DLG: %s: refcyc_per_req_delivery_cur = %3.2f\n",
+ __func__,
+ *refcyc_per_req_delivery_cur);
+
+ ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
+ }
+}
+
+unsigned int dml_rq_dlg_get_calculated_vstartup(struct display_mode_lib *mode_lib,
+ display_e2e_pipe_params_st *e2e_pipe_param,
+ const unsigned int num_pipes,
+ const unsigned int pipe_idx)
+{
+ unsigned int vstartup_pipe[DC__NUM_PIPES__MAX];
+ bool visited[DC__NUM_PIPES__MAX];
+ unsigned int pipe_inst = 0;
+ unsigned int i, j, k;
+
+ for (k = 0; k < num_pipes; ++k)
+ visited[k] = false;
+
+ for (i = 0; i < num_pipes; i++) {
+ if (e2e_pipe_param[i].pipe.src.is_hsplit && !visited[i]) {
+ unsigned int grp = e2e_pipe_param[i].pipe.src.hsplit_grp;
+
+ for (j = i; j < num_pipes; j++) {
+ if (e2e_pipe_param[j].pipe.src.hsplit_grp == grp
+ && e2e_pipe_param[j].pipe.src.is_hsplit
+ && !visited[j]) {
+ vstartup_pipe[j] = get_vstartup_calculated(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_inst);
+ visited[j] = true;
+ }
+ }
+
+ pipe_inst++;
+ }
+
+ if (!visited[i]) {
+ vstartup_pipe[i] = get_vstartup_calculated(mode_lib,
+ e2e_pipe_param,
+ num_pipes,
+ pipe_inst);
+ visited[i] = true;
+ pipe_inst++;
+ }
+ }
+
+ return vstartup_pipe[pipe_idx];
+
+}
+
+void dml_rq_dlg_get_row_heights(struct display_mode_lib *mode_lib,
+ unsigned int *o_dpte_row_height,
+ unsigned int *o_meta_row_height,
+ unsigned int vp_width,
+ unsigned int data_pitch,
+ int source_format,
+ int tiling,
+ int macro_tile_size,
+ int source_scan,
+ int is_chroma)
+{
+ display_data_rq_dlg_params_st rq_dlg_param;
+ display_data_rq_misc_params_st rq_misc_param;
+ display_data_rq_sizing_params_st rq_sizing_param;
+
+ get_meta_and_pte_attr(mode_lib,
+ &rq_dlg_param,
+ &rq_misc_param,
+ &rq_sizing_param,
+ vp_width,
+ 0, // dummy
+ data_pitch,
+ 0, // dummy
+ source_format,
+ tiling,
+ macro_tile_size,
+ source_scan,
+ is_chroma);
+
+ *o_dpte_row_height = rq_dlg_param.dpte_row_height;
+ *o_meta_row_height = rq_dlg_param.meta_row_height;
+}
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 @@
* Authors: AMD
*
*/
-#ifndef __DISPLAY_RQ_DLG_CALC_H__
-#define __DISPLAY_RQ_DLG_CALC_H__
+
+#ifndef __DML2_DISPLAY_RQ_DLG_CALC_H__
+#define __DML2_DISPLAY_RQ_DLG_CALC_H__
#include "dml_common_defs.h"
#include "display_rq_dlg_helpers.h"
struct display_mode_lib;
-void extract_rq_regs(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_regs_st *rq_regs,
- const struct _vcs_dpi_display_rq_params_st rq_param);
-/* Function: dml_rq_dlg_get_rq_params
- * Calculate requestor related parameters that register definition agnostic
- * (i.e. this layer does try to separate real values from register defintion)
- * Input:
- * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
- * Output:
- * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
- */
+// Function: dml_rq_dlg_get_rq_params
+// Calculate requestor related parameters that register definition agnostic
+// (i.e. this layer does try to separate real values from register definition)
+// Input:
+// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+// Output:
+// rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
+//
void dml_rq_dlg_get_rq_params(
struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_params_st *rq_param,
- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
+ display_rq_params_st *rq_param,
+ const display_pipe_source_params_st pipe_src_param);
-/* Function: dml_rq_dlg_get_rq_reg
- * Main entry point for test to get the register values out of this DML class.
- * This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
- * and then populate the rq_regs struct
- * Input:
- * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
- * Output:
- * rq_regs - struct that holds all the RQ registers field value.
- * See also: <display_rq_regs_st>
- */
+// Function: dml_rq_dlg_get_rq_reg
+// Main entry point for test to get the register values out of this DML class.
+// This function calls <get_rq_param> and <extract_rq_regs> fucntions to calculate
+// and then populate the rq_regs struct
+// Input:
+// pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+// Output:
+// rq_regs - struct that holds all the RQ registers field value.
+// See also: <display_rq_regs_st>
void dml_rq_dlg_get_rq_reg(
struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_regs_st *rq_regs,
- const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
+ display_rq_regs_st *rq_regs,
+ const display_pipe_source_params_st pipe_src_param);
-/* Function: dml_rq_dlg_get_dlg_params
- * Calculate deadline related parameters
- */
-void dml_rq_dlg_get_dlg_params(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
- struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
- const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
- const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
- const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+// Function: dml_rq_dlg_get_dlg_params
+// Calculate deadline related parameters
+//
+void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib,
+ const display_e2e_pipe_params_st *e2e_pipe_param,
+ const unsigned int num_pipes,
+ const unsigned int pipe_idx,
+ display_dlg_regs_st *disp_dlg_regs,
+ display_ttu_regs_st *disp_ttu_regs,
+ const display_rq_dlg_params_st rq_dlg_param,
+ const display_dlg_sys_params_st dlg_sys_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
- const bool iflip_en);
+ const bool ignore_viewport_pos,
+ const bool immediate_flip_support);
-/* Function: dml_rq_dlg_get_dlg_param_prefetch
- * For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw
- * for ALL pipes and use this info to calculate the prefetch programming.
- * Output: prefetch_param.prefetch_bw and flip_bytes
- */
+// Function: dml_rq_dlg_get_dlg_param_prefetch
+// For flip_bw programming guide change, now dml needs to calculate the flip_bytes and prefetch_bw
+// for ALL pipes and use this info to calculate the prefetch programming.
+// Output: prefetch_param.prefetch_bw and flip_bytes
void dml_rq_dlg_get_dlg_params_prefetch(
struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_prefetch_param_st *prefetch_param,
- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
- struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+ display_dlg_prefetch_param_st *prefetch_param,
+ display_rq_dlg_params_st rq_dlg_param,
+ display_dlg_sys_params_st dlg_sys_param,
+ display_e2e_pipe_params_st e2e_pipe_param,
const bool cstate_en,
const bool pstate_en,
const bool vm_en);
-/* Function: dml_rq_dlg_get_dlg_reg
- * Calculate and return DLG and TTU register struct given the system setting
- * Output:
- * dlg_regs - output DLG register struct
- * ttu_regs - output DLG TTU register struct
- * Input:
- * e2e_pipe_param - "compacted" array of e2e pipe param struct
- * num_pipes - num of active "pipe" or "route"
- * pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
- * cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
- * Added for legacy or unrealistic timing tests.
- */
+// Function: dml_rq_dlg_get_dlg_reg
+// Calculate and return DLG and TTU register struct given the system setting
+// Output:
+// dlg_regs - output DLG register struct
+// ttu_regs - output DLG TTU register struct
+// Input:
+// e2e_pipe_param - "compacted" array of e2e pipe param struct
+// num_pipes - num of active "pipe" or "route"
+// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
+// cstate - 0: when calculate min_ttu_vblank it is assumed cstate is not required. 1: Normal mode, cstate is considered.
+// Added for legacy or unrealistic timing tests.
void dml_rq_dlg_get_dlg_reg(
struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
- struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param,
+ display_dlg_regs_st *dlg_regs,
+ display_ttu_regs_st *ttu_regs,
+ display_e2e_pipe_params_st *e2e_pipe_param,
const unsigned int num_pipes,
const unsigned int pipe_idx,
const bool cstate_en,
const bool pstate_en,
const bool vm_en,
- const bool iflip_en);
+ const bool ignore_viewport_pos,
+ const bool immediate_flip_support);
-/* Function: dml_rq_dlg_get_row_heights
- * Calculate dpte and meta row heights
- */
+// Function: dml_rq_dlg_get_calculated_vstartup
+// Calculate and return vstartup
+// Output:
+// unsigned int vstartup
+// Input:
+// e2e_pipe_param - "compacted" array of e2e pipe param struct
+// num_pipes - num of active "pipe" or "route"
+// pipe_idx - index that identifies the e2e_pipe_param that corresponding to this dlg
+// NOTE: this MUST be called after setting the prefetch mode!
+unsigned int dml_rq_dlg_get_calculated_vstartup(
+ struct display_mode_lib *mode_lib,
+ display_e2e_pipe_params_st *e2e_pipe_param,
+ const unsigned int num_pipes,
+ const unsigned int pipe_idx);
+
+// Function: dml_rq_dlg_get_row_heights
+// Calculate dpte and meta row heights
void dml_rq_dlg_get_row_heights(
struct display_mode_lib *mode_lib,
unsigned int *o_dpte_row_height,
@@ -131,9 +142,7 @@ void dml_rq_dlg_get_row_heights(
int source_scan,
int is_chroma);
-/* Function: dml_rq_dlg_get_arb_params */
-void dml_rq_dlg_get_arb_params(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_arb_params_st *arb_param);
+// Function: dml_rq_dlg_get_arb_params
+void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param);
#endif
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 @@
#include "display_rq_dlg_helpers.h"
-void print__rq_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_params_st rq_param)
+void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param)
{
- DTRACE("RQ_DLG_CALC: *************************** ");
- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST");
- DTRACE("RQ_DLG_CALC: <LUMA>");
+ dml_print("DML_RQ_DLG_CALC: ***************************\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n");
+ dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l);
- DTRACE("RQ_DLG_CALC: <CHROMA> === ");
+ dml_print("DML_RQ_DLG_CALC: <CHROMA> ===\n");
print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c);
- DTRACE("RQ_DLG_CALC: <LUMA>");
+ dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l);
- DTRACE("RQ_DLG_CALC: <CHROMA>");
+ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c);
- DTRACE("RQ_DLG_CALC: <LUMA>");
+ dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l);
- DTRACE("RQ_DLG_CALC: <CHROMA>");
+ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c);
- DTRACE("RQ_DLG_CALC: *************************** ");
+ dml_print("DML_RQ_DLG_CALC: ***************************\n");
}
-void print__data_rq_sizing_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
+void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST");
- DTRACE("RQ_DLG_CALC: chunk_bytes = %0d", rq_sizing.chunk_bytes);
- DTRACE("RQ_DLG_CALC: min_chunk_bytes = %0d", rq_sizing.min_chunk_bytes);
- DTRACE("RQ_DLG_CALC: meta_chunk_bytes = %0d", rq_sizing.meta_chunk_bytes);
- DTRACE("RQ_DLG_CALC: min_meta_chunk_bytes = %0d", rq_sizing.min_meta_chunk_bytes);
- DTRACE("RQ_DLG_CALC: mpte_group_bytes = %0d", rq_sizing.mpte_group_bytes);
- DTRACE("RQ_DLG_CALC: dpte_group_bytes = %0d", rq_sizing.dpte_group_bytes);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n");
+ dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing.chunk_bytes);
+ dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing.min_chunk_bytes);
+ dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing.meta_chunk_bytes);
+ dml_print(
+ "DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n",
+ rq_sizing.min_meta_chunk_bytes);
+ dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing.mpte_group_bytes);
+ dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing.dpte_group_bytes);
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__data_rq_dlg_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param)
+void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST");
- DTRACE("RQ_DLG_CALC: swath_width_ub = %0d", rq_dlg_param.swath_width_ub);
- DTRACE("RQ_DLG_CALC: swath_height = %0d", rq_dlg_param.swath_height);
- DTRACE("RQ_DLG_CALC: req_per_swath_ub = %0d", rq_dlg_param.req_per_swath_ub);
- DTRACE(
- "RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d",
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n");
+ dml_print(
+ "DML_RQ_DLG_CALC: swath_width_ub = %0d\n",
+ rq_dlg_param.swath_width_ub);
+ dml_print(
+ "DML_RQ_DLG_CALC: swath_height = %0d\n",
+ rq_dlg_param.swath_height);
+ dml_print(
+ "DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n",
+ rq_dlg_param.req_per_swath_ub);
+ dml_print(
+ "DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n",
rq_dlg_param.meta_pte_bytes_per_frame_ub);
- DTRACE(
- "RQ_DLG_CALC: dpte_req_per_row_ub = %0d",
+ dml_print(
+ "DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n",
rq_dlg_param.dpte_req_per_row_ub);
- DTRACE(
- "RQ_DLG_CALC: dpte_groups_per_row_ub = %0d",
+ dml_print(
+ "DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n",
rq_dlg_param.dpte_groups_per_row_ub);
- DTRACE("RQ_DLG_CALC: dpte_row_height = %0d", rq_dlg_param.dpte_row_height);
- DTRACE(
- "RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d",
+ dml_print(
+ "DML_RQ_DLG_CALC: dpte_row_height = %0d\n",
+ rq_dlg_param.dpte_row_height);
+ dml_print(
+ "DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n",
rq_dlg_param.dpte_bytes_per_row_ub);
- DTRACE(
- "RQ_DLG_CALC: meta_chunks_per_row_ub = %0d",
+ dml_print(
+ "DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n",
rq_dlg_param.meta_chunks_per_row_ub);
- DTRACE(
- "RQ_DLG_CALC: meta_req_per_row_ub = %0d",
+ dml_print(
+ "DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n",
rq_dlg_param.meta_req_per_row_ub);
- DTRACE("RQ_DLG_CALC: meta_row_height = %0d", rq_dlg_param.meta_row_height);
- DTRACE(
- "RQ_DLG_CALC: meta_bytes_per_row_ub = %0d",
+ dml_print(
+ "DML_RQ_DLG_CALC: meta_row_height = %0d\n",
+ rq_dlg_param.meta_row_height);
+ dml_print(
+ "DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n",
rq_dlg_param.meta_bytes_per_row_ub);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__data_rq_misc_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param)
+void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST");
- DTRACE("RQ_DLG_CALC: full_swath_bytes = %0d", rq_misc_param.full_swath_bytes);
- DTRACE("RQ_DLG_CALC: stored_swath_bytes = %0d", rq_misc_param.stored_swath_bytes);
- DTRACE("RQ_DLG_CALC: blk256_width = %0d", rq_misc_param.blk256_width);
- DTRACE("RQ_DLG_CALC: blk256_height = %0d", rq_misc_param.blk256_height);
- DTRACE("RQ_DLG_CALC: req_width = %0d", rq_misc_param.req_width);
- DTRACE("RQ_DLG_CALC: req_height = %0d", rq_misc_param.req_height);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n");
+ dml_print(
+ "DML_RQ_DLG_CALC: full_swath_bytes = %0d\n",
+ rq_misc_param.full_swath_bytes);
+ dml_print(
+ "DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n",
+ rq_misc_param.stored_swath_bytes);
+ dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param.blk256_width);
+ dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param.blk256_height);
+ dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param.req_width);
+ dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param.req_height);
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__rq_dlg_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param)
+void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST");
- DTRACE("RQ_DLG_CALC: <LUMA> ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
+ dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l);
- DTRACE("RQ_DLG_CALC: <CHROMA> ");
+ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__dlg_sys_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param)
+void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST");
- DTRACE("RQ_DLG_CALC: t_mclk_wm_us = %3.2f", dlg_sys_param.t_mclk_wm_us);
- DTRACE("RQ_DLG_CALC: t_urg_wm_us = %3.2f", dlg_sys_param.t_urg_wm_us);
- DTRACE("RQ_DLG_CALC: t_sr_wm_us = %3.2f", dlg_sys_param.t_sr_wm_us);
- DTRACE("RQ_DLG_CALC: t_extra_us = %3.2f", dlg_sys_param.t_extra_us);
- DTRACE("RQ_DLG_CALC: t_srx_delay_us = %3.2f", dlg_sys_param.t_srx_delay_us);
- DTRACE("RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f", dlg_sys_param.deepsleep_dcfclk_mhz);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n");
+ dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param.t_mclk_wm_us);
+ dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param.t_urg_wm_us);
+ dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param.t_sr_wm_us);
+ dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param.t_extra_us);
+ dml_print(
+ "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n",
+ dlg_sys_param.t_srx_delay_us);
+ dml_print(
+ "DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n",
+ dlg_sys_param.deepsleep_dcfclk_mhz);
+ dml_print(
+ "DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n",
+ dlg_sys_param.total_flip_bw);
+ dml_print(
+ "DML_RQ_DLG_CALC: total_flip_bytes = %i\n",
+ dlg_sys_param.total_flip_bytes);
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__data_rq_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_regs_st rq_regs)
+void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st rq_regs)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST");
- DTRACE("RQ_DLG_CALC: chunk_size = 0x%0x", rq_regs.chunk_size);
- DTRACE("RQ_DLG_CALC: min_chunk_size = 0x%0x", rq_regs.min_chunk_size);
- DTRACE("RQ_DLG_CALC: meta_chunk_size = 0x%0x", rq_regs.meta_chunk_size);
- DTRACE("RQ_DLG_CALC: min_meta_chunk_size = 0x%0x", rq_regs.min_meta_chunk_size);
- DTRACE("RQ_DLG_CALC: dpte_group_size = 0x%0x", rq_regs.dpte_group_size);
- DTRACE("RQ_DLG_CALC: mpte_group_size = 0x%0x", rq_regs.mpte_group_size);
- DTRACE("RQ_DLG_CALC: swath_height = 0x%0x", rq_regs.swath_height);
- DTRACE("RQ_DLG_CALC: pte_row_height_linear = 0x%0x", rq_regs.pte_row_height_linear);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n");
+ dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs.chunk_size);
+ dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs.min_chunk_size);
+ dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs.meta_chunk_size);
+ dml_print(
+ "DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n",
+ rq_regs.min_meta_chunk_size);
+ dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs.dpte_group_size);
+ dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs.mpte_group_size);
+ dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs.swath_height);
+ dml_print(
+ "DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n",
+ rq_regs.pte_row_height_linear);
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__rq_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_regs_st rq_regs)
+void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_RQ_REGS_ST");
- DTRACE("RQ_DLG_CALC: <LUMA> ");
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n");
+ dml_print("DML_RQ_DLG_CALC: <LUMA>\n");
print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l);
- DTRACE("RQ_DLG_CALC: <CHROMA> ");
+ dml_print("DML_RQ_DLG_CALC: <CHROMA>\n");
print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c);
- DTRACE("RQ_DLG_CALC: drq_expansion_mode = 0x%0x", rq_regs.drq_expansion_mode);
- DTRACE("RQ_DLG_CALC: prq_expansion_mode = 0x%0x", rq_regs.prq_expansion_mode);
- DTRACE("RQ_DLG_CALC: mrq_expansion_mode = 0x%0x", rq_regs.mrq_expansion_mode);
- DTRACE("RQ_DLG_CALC: crq_expansion_mode = 0x%0x", rq_regs.crq_expansion_mode);
- DTRACE("RQ_DLG_CALC: plane1_base_address = 0x%0x", rq_regs.plane1_base_address);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs.drq_expansion_mode);
+ dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs.prq_expansion_mode);
+ dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs.mrq_expansion_mode);
+ dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs.crq_expansion_mode);
+ dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address);
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__dlg_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_regs_st dlg_regs)
+void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_DLG_REGS_ST ");
- DTRACE(
- "RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x",
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n");
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n",
dlg_regs.refcyc_h_blank_end);
- DTRACE("RQ_DLG_CALC: dlg_vblank_end = 0x%0x", dlg_regs.dlg_vblank_end);
- DTRACE(
- "RQ_DLG_CALC: min_dst_y_next_start = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n",
+ dlg_regs.dlg_vblank_end);
+ dml_print(
+ "DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n",
dlg_regs.min_dst_y_next_start);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_htotal = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n",
dlg_regs.refcyc_per_htotal);
- DTRACE(
- "RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n",
dlg_regs.refcyc_x_after_scaler);
- DTRACE(
- "RQ_DLG_CALC: dst_y_after_scaler = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n",
dlg_regs.dst_y_after_scaler);
- DTRACE("RQ_DLG_CALC: dst_y_prefetch = 0x%0x", dlg_regs.dst_y_prefetch);
- DTRACE(
- "RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n",
+ dlg_regs.dst_y_prefetch);
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n",
dlg_regs.dst_y_per_vm_vblank);
- DTRACE(
- "RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n",
dlg_regs.dst_y_per_row_vblank);
- DTRACE(
- "RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n",
+ dlg_regs.dst_y_per_vm_flip);
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n",
+ dlg_regs.dst_y_per_row_flip);
+ dml_print(
+ "DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n",
dlg_regs.ref_freq_to_pix_freq);
- DTRACE("RQ_DLG_CALC: vratio_prefetch = 0x%0x", dlg_regs.vratio_prefetch);
- DTRACE(
- "RQ_DLG_CALC: vratio_prefetch_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n",
+ dlg_regs.vratio_prefetch);
+ dml_print(
+ "DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n",
dlg_regs.vratio_prefetch_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_vblank_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_vblank_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_vblank_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_vblank_c);
- DTRACE(
- "RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n",
+ dlg_regs.refcyc_per_pte_group_flip_l);
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n",
+ dlg_regs.refcyc_per_pte_group_flip_c);
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n",
+ dlg_regs.refcyc_per_meta_chunk_flip_l);
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n",
+ dlg_regs.refcyc_per_meta_chunk_flip_c);
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n",
dlg_regs.dst_y_per_pte_row_nom_l);
- DTRACE(
- "RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n",
dlg_regs.dst_y_per_pte_row_nom_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_nom_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n",
dlg_regs.refcyc_per_pte_group_nom_c);
- DTRACE(
- "RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n",
dlg_regs.dst_y_per_meta_row_nom_l);
- DTRACE(
- "RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n",
dlg_regs.dst_y_per_meta_row_nom_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_nom_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n",
dlg_regs.refcyc_per_meta_chunk_nom_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_pre_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_pre_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n",
dlg_regs.refcyc_per_line_delivery_c);
- DTRACE(
- "RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n",
dlg_regs.chunk_hdl_adjust_cur0);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n",
+ dlg_regs.dst_y_offset_cur1);
+ dml_print(
+ "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n",
+ dlg_regs.chunk_hdl_adjust_cur1);
+ dml_print(
+ "DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n",
+ dlg_regs.vready_after_vcount0);
+ dml_print(
+ "DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n",
+ dlg_regs.dst_y_delta_drq_limit);
+ dml_print(
+ "DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n",
+ dlg_regs.xfc_reg_transfer_delay);
+ dml_print(
+ "DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n",
+ dlg_regs.xfc_reg_precharge_delay);
+ dml_print(
+ "DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n",
+ dlg_regs.xfc_reg_remote_surface_flip_latency);
+
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
-void print__ttu_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_ttu_regs_st ttu_regs)
+void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs)
{
- DTRACE("RQ_DLG_CALC: ===================================== ");
- DTRACE("RQ_DLG_CALC: DISPLAY_TTU_REGS_ST ");
- DTRACE(
- "RQ_DLG_CALC: qos_level_low_wm = 0x%0x",
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
+ dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n");
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n",
ttu_regs.qos_level_low_wm);
- DTRACE(
- "RQ_DLG_CALC: qos_level_high_wm = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n",
ttu_regs.qos_level_high_wm);
- DTRACE("RQ_DLG_CALC: min_ttu_vblank = 0x%0x", ttu_regs.min_ttu_vblank);
- DTRACE("RQ_DLG_CALC: qos_level_flip = 0x%0x", ttu_regs.qos_level_flip);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n",
+ ttu_regs.min_ttu_vblank);
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n",
+ ttu_regs.qos_level_flip);
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_l);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_c);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_cur0);
- DTRACE(
- "RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n",
ttu_regs.refcyc_per_req_delivery_pre_cur0);
- DTRACE(
- "RQ_DLG_CALC: qos_level_fixed_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n",
+ ttu_regs.refcyc_per_req_delivery_cur1);
+ dml_print(
+ "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n",
+ ttu_regs.refcyc_per_req_delivery_pre_cur1);
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n",
ttu_regs.qos_level_fixed_l);
- DTRACE(
- "RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n",
ttu_regs.qos_ramp_disable_l);
- DTRACE(
- "RQ_DLG_CALC: qos_level_fixed_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n",
ttu_regs.qos_level_fixed_c);
- DTRACE(
- "RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n",
ttu_regs.qos_ramp_disable_c);
- DTRACE(
- "RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n",
ttu_regs.qos_level_fixed_cur0);
- DTRACE(
- "RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x",
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n",
ttu_regs.qos_ramp_disable_cur0);
- DTRACE("RQ_DLG_CALC: ===================================== ");
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n",
+ ttu_regs.qos_level_fixed_cur1);
+ dml_print(
+ "DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n",
+ ttu_regs.qos_ramp_disable_cur1);
+ dml_print("DML_RQ_DLG_CALC: =====================================\n");
}
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 @@
* Authors: AMD
*
*/
+
#ifndef __DISPLAY_RQ_DLG_HELPERS_H__
#define __DISPLAY_RQ_DLG_HELPERS_H__
@@ -31,36 +32,16 @@
/* Function: Printer functions
* Print various struct
*/
-void print__rq_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_params_st rq_param);
-void print__data_rq_sizing_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing);
-void print__data_rq_dlg_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_dlg_params_st rq_dlg_param);
-void print__data_rq_misc_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_misc_params_st rq_misc_param);
-void print__rq_dlg_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param);
-void print__dlg_sys_params_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param);
+void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param);
+void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing);
+void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param);
+void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param);
+void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param);
+void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param);
-void print__data_rq_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_data_rq_regs_st data_rq_regs);
-void print__rq_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_rq_regs_st rq_regs);
-void print__dlg_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_dlg_regs_st dlg_regs);
-void print__ttu_regs_st(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_ttu_regs_st ttu_regs);
+void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs);
+void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs);
+void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs);
+void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs);
#endif
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 @@
-/*
- * Copyright 2017 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-#include "display_watermark.h"
-#include "display_mode_lib.h"
-#include "dml_inline_defs.h"
-
-static void get_bytes_per_pixel(
- enum source_format_class format,
- struct _vcs_dpi_wm_calc_pipe_params_st *plane)
-{
- switch (format) {
- case dm_444_64:
- plane->bytes_per_pixel_y = 8.0;
- plane->bytes_per_pixel_c = 0.0;
- break;
- case dm_444_32:
- plane->bytes_per_pixel_y = 4.0;
- plane->bytes_per_pixel_c = 0.0;
- break;
- case dm_444_16:
- plane->bytes_per_pixel_y = 2.0;
- plane->bytes_per_pixel_c = 0.0;
- break;
- case dm_422_10:
- plane->bytes_per_pixel_y = 4.0;
- plane->bytes_per_pixel_c = 0.0;
- break;
- case dm_422_8:
- plane->bytes_per_pixel_y = 2.0;
- plane->bytes_per_pixel_c = 0.0;
- break;
- case dm_420_8:
- plane->bytes_per_pixel_y = 1.0;
- plane->bytes_per_pixel_c = 2.0;
- break;
- case dm_420_10:
- plane->bytes_per_pixel_y = 4.0 / 3;
- plane->bytes_per_pixel_c = 8.0 / 3;
- break;
- default:
- BREAK_TO_DEBUGGER(); /* invalid format in get_bytes_per_pixel */
- }
-}
-
-static unsigned int get_swath_width_y(
- struct _vcs_dpi_display_pipe_source_params_st *src_param,
- unsigned int num_dpp)
-{
- unsigned int val;
-
- /* note that we don't divide by num_dpp here because we have an interface which has already split
- * any viewports
- */
- if (src_param->source_scan == dm_horz) {
- val = src_param->viewport_width;
- } else {
- val = src_param->viewport_height;
- }
-
- return val;
-}
-
-static void get_swath_height(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_pipe_source_params_st *src_param,
- struct _vcs_dpi_wm_calc_pipe_params_st *plane,
- unsigned int swath_width_y)
-{
- double buffer_width;
-
- if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32
- || src_param->source_format == dm_444_16) {
- if (src_param->sw_mode == dm_sw_linear) {
- plane->swath_height_y = 1;
- } else if (src_param->source_format == dm_444_64) {
- plane->swath_height_y = 4;
- } else {
- plane->swath_height_y = 8;
- }
-
- if (src_param->source_scan != dm_horz) {
- plane->swath_height_y = 256 / (unsigned int) plane->bytes_per_pixel_y
- / plane->swath_height_y;
- }
-
- plane->swath_height_c = 0;
-
- } else {
- if (src_param->sw_mode == dm_sw_linear) {
- plane->swath_height_y = 1;
- plane->swath_height_c = 1;
- } else if (src_param->source_format == dm_420_8) {
- plane->swath_height_y = 16;
- plane->swath_height_c = 8;
- } else {
- plane->swath_height_y = 8;
- plane->swath_height_c = 8;
- }
-
- if (src_param->source_scan != dm_horz) {
- double bytes_per_pixel_c_ceil;
-
- plane->swath_height_y = 256 / dml_ceil(plane->bytes_per_pixel_y)
- / plane->swath_height_y;
-
- bytes_per_pixel_c_ceil = dml_ceil_2(plane->bytes_per_pixel_c);
-
- plane->swath_height_c = 256 / bytes_per_pixel_c_ceil
- / plane->swath_height_c;
- }
- }
-
- /* use swath height min if buffer isn't big enough */
-
- buffer_width = ((double) mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0)
- / (plane->bytes_per_pixel_y * (double) plane->swath_height_y
- + (plane->bytes_per_pixel_c / 2.0
- * (double) plane->swath_height_c));
-
- if ((double) swath_width_y <= buffer_width) {
- /* do nothing, just keep code structure from Gabes vba */
- } else {
- /* substitute swath height with swath height min */
- if (src_param->source_format == dm_444_64 || src_param->source_format == dm_444_32
- || src_param->source_format == dm_444_16) {
- if ((src_param->sw_mode == dm_sw_linear)
- || (src_param->source_format == dm_444_64
- && (src_param->sw_mode == dm_sw_4kb_s
- || src_param->sw_mode
- == dm_sw_4kb_s_x
- || src_param->sw_mode
- == dm_sw_64kb_s
- || src_param->sw_mode
- == dm_sw_64kb_s_t
- || src_param->sw_mode
- == dm_sw_64kb_s_x
- || src_param->sw_mode
- == dm_sw_var_s
- || src_param->sw_mode
- == dm_sw_var_s_x)
- && src_param->source_scan == dm_horz)) {
- /* do nothing, just keep code structure from Gabes vba */
- } else {
- plane->swath_height_y = plane->swath_height_y / 2;
- }
- } else {
- if (src_param->sw_mode == dm_sw_linear) {
- /* do nothing, just keep code structure from Gabes vba */
- } else if (src_param->source_format == dm_420_8
- && src_param->source_scan == dm_horz) {
- plane->swath_height_y = plane->swath_height_y / 2;
- } else if (src_param->source_format == dm_420_10
- && src_param->source_scan == dm_horz) {
- plane->swath_height_c = plane->swath_height_c / 2;
- }
- }
- }
-
- if (plane->swath_height_c == 0) {
- plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0;
- } else if (plane->swath_height_c <= plane->swath_height_y) {
- plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 / 2.0;
- } else {
- plane->det_buffer_size_y = mode_lib->ip.det_buffer_size_kbytes * 1024.0 * 2.0 / 3.0;
- }
-}
-
-static void calc_display_pipe_line_delivery_time(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- if (planes[i].v_ratio <= 1.0) {
- planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y
- * planes[i].num_dpp / planes[i].h_ratio
- / planes[i].pixclk_mhz;
- } else {
- double dchub_pscl_bw_per_clk;
-
- if (planes[i].h_ratio > 1) {
- double num_hscl_kernels;
-
- num_hscl_kernels = dml_ceil((double) planes[i].h_taps / 6);
- dchub_pscl_bw_per_clk =
- dml_min(
- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
- mode_lib->ip.max_pscl_lb_bw_pix_per_clk
- * planes[i].h_ratio
- / num_hscl_kernels);
- } else {
- dchub_pscl_bw_per_clk =
- dml_min(
- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
- (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk);
- }
-
- planes[i].display_pipe_line_delivery_time = planes[i].swath_width_y
- / dchub_pscl_bw_per_clk / planes[i].dppclk_mhz;
- }
- }
-}
-
-static double calc_total_data_read_bw(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- double val = 0.0;
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- double swath_width_y_plane = planes[i].swath_width_y * planes[i].num_dpp;
-
- planes[i].read_bw = swath_width_y_plane
- * (dml_ceil(planes[i].bytes_per_pixel_y)
- + dml_ceil_2(planes[i].bytes_per_pixel_c) / 2)
- / (planes[i].h_total / planes[i].pixclk_mhz) * planes[i].v_ratio;
-
- val += planes[i].read_bw;
-
- DTRACE("plane[%d] start", i);
- DTRACE("read_bw = %f", planes[i].read_bw);
- DTRACE("plane[%d] end", i);
- }
-
- return val;
-}
-
-double dml_wm_calc_total_data_read_bw(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- return calc_total_data_read_bw(mode_lib, planes, num_planes);
-}
-
-static double calc_dcfclk_mhz(
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- double dcfclk_mhz = -1.0;
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- /* voltage and dcfclk must be the same for all pipes */
- ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == planes[i].dcfclk_mhz);
- dcfclk_mhz = planes[i].dcfclk_mhz;
- }
-
- return dcfclk_mhz;
-}
-
-static enum voltage_state find_voltage(
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- int voltage = -1;
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- ASSERT(voltage == -1 || voltage == planes[i].voltage);
- voltage = planes[i].voltage;
- }
-
- return (enum voltage_state) voltage;
-}
-
-static bool find_dcc_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes)
-{
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- if (planes[i].dcc_enable) {
- return true;
- }
- }
-
- return false;
-}
-
-static double calc_return_bw(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- struct _vcs_dpi_soc_bounding_box_st *soc;
- double return_bw_mbps;
- double dcfclk_mhz;
- double return_bus_bw;
- enum voltage_state voltage;
- double return_bw_to_dcn;
- bool dcc_enable;
- double rob_chunk_diff;
- double urgent_latency_traffic;
- double critical_compression;
- struct _vcs_dpi_voltage_scaling_st state;
-
- soc = &mode_lib->soc;
-
- dcfclk_mhz = calc_dcfclk_mhz(planes, num_planes);
- return_bus_bw = dcfclk_mhz * soc->return_bus_width_bytes;
-
- DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz);
- DTRACE("INTERMEDIATE return_bus_bw = %f", return_bus_bw);
-
- voltage = find_voltage(planes, num_planes);
- return_bw_to_dcn = dml_socbb_return_bw_mhz(soc, voltage);
-
- dcc_enable = find_dcc_enable(planes, num_planes);
-
- return_bw_mbps = return_bw_to_dcn;
- DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps);
-
- rob_chunk_diff =
- (mode_lib->ip.rob_buffer_size_kbytes - mode_lib->ip.pixel_chunk_size_kbytes)
- * 1024.0;
- DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff);
-
- if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) {
- double dcc_return_bw =
- return_bw_to_dcn * 4.0
- * (1.0
- - soc->urgent_latency_us
- / (rob_chunk_diff
- / (return_bw_to_dcn
- - return_bus_bw
- / 4.0)
- + soc->urgent_latency_us));
- return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw);
- DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw);
- }
-
- urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us;
- DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic);
- critical_compression = 2.0 * urgent_latency_traffic
- / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff);
- DTRACE("INTERMEDIATE critical_compression = %f", critical_compression);
-
- if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) {
- double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff
- * urgent_latency_traffic);
- crit_return_bw = crit_return_bw
- / dml_pow(
- return_bw_to_dcn * soc->urgent_latency_us
- + rob_chunk_diff,
- 2);
- DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw);
- return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw);
- }
-
- /* Gabe does this again for some reason using the value of return_bw_mpbs from the previous calculation
- * and a lightly different return_bw_to_dcn
- */
-
- state = dml_socbb_voltage_scaling(soc, voltage);
- return_bw_to_dcn = dml_min(
- soc->return_bus_width_bytes * dcfclk_mhz,
- state.dram_bw_per_chan_gbps * 1000.0 * (double) soc->num_chans);
-
- DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff);
-
- if (dcc_enable && return_bw_to_dcn > return_bus_bw / 4) {
- double dcc_return_bw =
- return_bw_to_dcn * 4.0
- * (1.0
- - soc->urgent_latency_us
- / (rob_chunk_diff
- / (return_bw_to_dcn
- - return_bus_bw
- / 4.0)
- + soc->urgent_latency_us));
- return_bw_mbps = dml_min(return_bw_mbps, dcc_return_bw);
- DTRACE("INTERMEDIATE dcc_return_bw = %f", dcc_return_bw);
- }
-
- urgent_latency_traffic = return_bus_bw * soc->urgent_latency_us;
- DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic);
- critical_compression = 2.0 * urgent_latency_traffic
- / (return_bw_to_dcn * soc->urgent_latency_us + rob_chunk_diff);
- DTRACE("INTERMEDIATE critical_compression = %f", critical_compression);
-
- /* problem here? */
- if (dcc_enable && critical_compression > 1.0 && critical_compression < 4.0) {
- double crit_return_bw = (4 * return_bw_to_dcn * rob_chunk_diff
- * urgent_latency_traffic);
- crit_return_bw = crit_return_bw
- / dml_pow(
- return_bw_to_dcn * soc->urgent_latency_us
- + rob_chunk_diff,
- 2);
- DTRACE("INTERMEDIATE critical_return_bw = %f", crit_return_bw);
- DTRACE("INTERMEDIATE return_bw_to_dcn = %f", return_bw_to_dcn);
- DTRACE("INTERMEDIATE rob_chunk_diff = %f", rob_chunk_diff);
- DTRACE("INTERMEDIATE urgent_latency_traffic = %f", urgent_latency_traffic);
-
- return_bw_mbps = dml_min(return_bw_mbps, crit_return_bw);
- }
-
- DTRACE("INTERMEDIATE final return_bw_mbps = %f", return_bw_mbps);
- return return_bw_mbps;
-}
-
-double dml_wm_calc_return_bw(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- return calc_return_bw(mode_lib, planes, num_planes);
-}
-
-static double calc_last_pixel_of_line_extra_wm_us(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- double val = 0.0;
- double total_data_read_bw = calc_total_data_read_bw(mode_lib, planes, num_planes);
- int voltage = -1;
- unsigned int i;
- double return_bw_mbps;
-
- for (i = 0; i < num_planes; i++) {
- /* voltage mode must be the same for all pipes */
- ASSERT(voltage == -1 || voltage == planes[i].voltage);
- voltage = planes[i].voltage;
- }
- return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
-
- for (i = 0; i < num_planes; i++) {
- double bytes_pp_y = dml_ceil(planes[i].bytes_per_pixel_y);
- double bytes_pp_c = dml_ceil_2(planes[i].bytes_per_pixel_c);
- double swath_bytes_y = (double) planes[i].swath_width_y
- * (double) planes[i].swath_height_y * (double) bytes_pp_y;
- double swath_bytes_c = ((double) planes[i].swath_width_y / 2.0)
- * (double) planes[i].swath_height_c * (double) bytes_pp_c;
- double data_fabric_line_delivery_time = (swath_bytes_y + swath_bytes_c)
- / (return_bw_mbps * planes[i].read_bw / (double) planes[i].num_dpp
- / total_data_read_bw);
-
- DTRACE(
- "bytes_pp_y = %f, swath_width_y = %f, swath_height_y = %f, swath_bytes_y = %f",
- bytes_pp_y,
- (double) planes[i].swath_width_y,
- (double) planes[i].swath_height_y,
- swath_bytes_y);
- DTRACE(
- "bytes_pp_c = %f, swath_width_c = %f, swath_height_c = %f, swath_bytes_c = %f",
- bytes_pp_c,
- ((double) planes[i].swath_width_y / 2.0),
- (double) planes[i].swath_height_c,
- swath_bytes_c);
- DTRACE(
- "return_bw_mbps = %f, read_bw = %f, num_dpp = %d, total_data_read_bw = %f",
- return_bw_mbps,
- planes[i].read_bw,
- planes[i].num_dpp,
- total_data_read_bw);
- DTRACE("data_fabric_line_delivery_time = %f", data_fabric_line_delivery_time);
- DTRACE(
- "display_pipe_line_delivery_time = %f",
- planes[i].display_pipe_line_delivery_time);
-
- val = dml_max(
- val,
- data_fabric_line_delivery_time
- - planes[i].display_pipe_line_delivery_time);
- }
-
- DTRACE("last_pixel_of_line_extra_wm is %f us", val);
- return val;
-}
-
-static bool calc_pte_enable(struct _vcs_dpi_wm_calc_pipe_params_st *planes, unsigned int num_planes)
-{
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- if (planes[i].pte_enable) {
- return true;
- }
- }
-
- return false;
-}
-
-static void calc_lines_in_det_y(struct _vcs_dpi_wm_calc_pipe_params_st *plane)
-{
- plane->lines_in_det_y = plane->det_buffer_size_y / plane->bytes_per_pixel_y
- / plane->swath_width_y;
- plane->lines_in_det_y_rounded_down_to_swath = dml_floor(
- (double) plane->lines_in_det_y / plane->swath_height_y)
- * plane->swath_height_y;
- plane->full_det_buffering_time = plane->lines_in_det_y_rounded_down_to_swath
- * (plane->h_total / plane->pixclk_mhz);
-}
-
-/* CHECKME: not obviously 1:1 with calculation described in architectural
- * document or spreadsheet */
-static void calc_dcfclk_deepsleep_mhz_per_plane(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *plane)
-{
- double bus_width_per_pixel;
-
- if (plane->swath_height_c == 0) {
- bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 64;
- } else {
- double bus_width_per_pixel_c;
-
- bus_width_per_pixel = dml_ceil(plane->bytes_per_pixel_y) / 32;
- bus_width_per_pixel_c = dml_ceil(plane->bytes_per_pixel_c) / 32;
- if (bus_width_per_pixel < bus_width_per_pixel_c)
- bus_width_per_pixel = bus_width_per_pixel_c;
- }
-
- if (plane->v_ratio <= 1) {
- plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->pixclk_mhz / plane->num_dpp
- * plane->h_ratio * bus_width_per_pixel;
- } else if (plane->h_ratio > 1) {
- double num_hscl_kernels = dml_ceil((double) plane->h_taps / 6);
- double dchub_pscl_bw_per_clk = dml_min(
- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
- mode_lib->ip.max_pscl_lb_bw_pix_per_clk * plane->h_ratio
- / num_hscl_kernels);
-
- plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz
- * dchub_pscl_bw_per_clk * bus_width_per_pixel;
- } else {
- double dchub_pscl_bw_per_clk = dml_min(
- (double) mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
- (double) mode_lib->ip.max_pscl_lb_bw_pix_per_clk);
-
- plane->dcfclk_deepsleep_mhz_per_plane = 1.1 * plane->dppclk_mhz
- * dchub_pscl_bw_per_clk * bus_width_per_pixel;
- }
-
- plane->dcfclk_deepsleep_mhz_per_plane = dml_max(
- plane->dcfclk_deepsleep_mhz_per_plane,
- plane->pixclk_mhz / 16);
-}
-
-/* Implementation of expected stutter efficiency from DCN1_Display_Mode.docx */
-double dml_wm_expected_stutter_eff_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
- unsigned int num_pipes)
-{
- double min_full_det_buffering_time_us;
- double frame_time_for_min_full_det_buffering_time_us = 0.0;
- struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
- unsigned int num_planes;
- unsigned int i;
- double total_data_read_bw_mbps;
- double average_read_bw_gbps;
- double min_full_det_buffer_size_bytes;
- double rob_fill_size_bytes;
- double part_of_burst_that_fits_in_rob;
- int voltage;
- double dcfclk_mhz;
- unsigned int total_writeback;
- double return_bw_mbps;
- double stutter_burst_time_us;
- double stutter_eff_not_including_vblank;
- double smallest_vblank_us;
- double stutter_eff;
-
- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
- DTRACE("calculating expected stutter efficiency");
-
- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes);
-
- for (i = 0; i < num_planes; i++) {
- calc_lines_in_det_y(&planes[i]);
-
- DTRACE("swath width y plane %d = %d", i, planes[i].swath_width_y);
- DTRACE("swath height y plane %d = %d", i, planes[i].swath_height_y);
- DTRACE(
- "bytes per pixel det y plane %d = %f",
- i,
- planes[i].bytes_per_pixel_y);
- DTRACE(
- "bytes per pixel det c plane %d = %f",
- i,
- planes[i].bytes_per_pixel_c);
- DTRACE(
- "det buffer size plane %d = %d",
- i,
- planes[i].det_buffer_size_y);
- DTRACE("lines in det plane %d = %d", i, planes[i].lines_in_det_y);
- DTRACE(
- "lines in det rounded to swaths plane %d = %d",
- i,
- planes[i].lines_in_det_y_rounded_down_to_swath);
- }
-
- min_full_det_buffering_time_us = 9999.0;
- for (i = 0; i < num_planes; i++) {
- if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) {
- min_full_det_buffering_time_us = planes[i].full_det_buffering_time;
- frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total
- * planes[i].h_total / planes[i].pixclk_mhz;
- }
- }
-
- DTRACE("INTERMEDIATE: min_full_det_buffering_time_us = %f", min_full_det_buffering_time_us);
-
- total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes);
-
- average_read_bw_gbps = 0.0;
-
- for (i = 0; i < num_planes; i++) {
- if (planes[i].dcc_enable) {
- average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000;
- } else {
- average_read_bw_gbps += planes[i].read_bw / 1000;
- }
-
- if (planes[i].dcc_enable) {
- average_read_bw_gbps += planes[i].read_bw / 1000 / 256;
- }
-
- if (planes[i].pte_enable) {
- average_read_bw_gbps += planes[i].read_bw / 1000 / 512;
- }
- }
-
- min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps;
- rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps
- / (average_read_bw_gbps * 1000);
- part_of_burst_that_fits_in_rob = dml_min(
- min_full_det_buffer_size_bytes,
- rob_fill_size_bytes);
-
- voltage = -1;
- dcfclk_mhz = -1.0;
- total_writeback = 0;
-
- for (i = 0; i < num_pipes; i++) {
- /* voltage and dcfclk must be the same for all pipes */
- ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage);
- voltage = e2e[i].clks_cfg.voltage;
- ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz);
- dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
-
- if (e2e[i].dout.output_type == dm_wb)
- total_writeback++;
- }
-
- return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
-
- DTRACE("INTERMEDIATE: part_of_burst_that_fits_in_rob = %f", part_of_burst_that_fits_in_rob);
- DTRACE("INTERMEDIATE: average_read_bw_gbps = %f", average_read_bw_gbps);
- DTRACE("INTERMEDIATE: total_data_read_bw_mbps = %f", total_data_read_bw_mbps);
- DTRACE("INTERMEDIATE: return_bw_mbps = %f", return_bw_mbps);
-
- stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000)
- / total_data_read_bw_mbps / return_bw_mbps
- + (min_full_det_buffering_time_us * total_data_read_bw_mbps
- - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64);
- DTRACE("INTERMEDIATE: stutter_burst_time_us = %f", stutter_burst_time_us);
-
- if (total_writeback == 0) {
- stutter_eff_not_including_vblank = (1.0
- - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us)
- / min_full_det_buffering_time_us)) * 100.0;
- } else {
- stutter_eff_not_including_vblank = 0.0;
- }
-
- DTRACE("stutter_efficiency_not_including_vblank = %f", stutter_eff_not_including_vblank);
-
- smallest_vblank_us = 9999.0;
-
- for (i = 0; i < num_pipes; i++) {
- double vblank_us;
- if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) {
- vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1
- - e2e[i].pipe.dest.vblank_start
- + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal)
- / e2e[i].pipe.dest.pixel_rate_mhz;
- } else {
- vblank_us = 0.0;
- }
-
- smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us);
- }
-
- DTRACE("smallest vblank = %f us", smallest_vblank_us);
-
- stutter_eff = 100.0
- * (((stutter_eff_not_including_vblank / 100.0)
- * (frame_time_for_min_full_det_buffering_time_us
- - smallest_vblank_us) + smallest_vblank_us)
- / frame_time_for_min_full_det_buffering_time_us);
-
- DTRACE("stutter_efficiency = %f", stutter_eff);
-
- return stutter_eff_not_including_vblank;
-}
-
-double dml_wm_expected_stutter_eff_e2e_with_vblank(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
- unsigned int num_pipes)
-{
- double min_full_det_buffering_time_us;
- double frame_time_for_min_full_det_buffering_time_us = 0.0;
- struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
- unsigned int num_planes;
- unsigned int i;
- double total_data_read_bw_mbps;
- double average_read_bw_gbps;
- double min_full_det_buffer_size_bytes;
- double rob_fill_size_bytes;
- double part_of_burst_that_fits_in_rob;
- int voltage;
- double dcfclk_mhz;
- unsigned int total_writeback;
- double return_bw_mbps;
- double stutter_burst_time_us;
- double stutter_eff_not_including_vblank;
- double smallest_vblank_us;
- double stutter_eff;
-
- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
- num_planes = dml_wm_e2e_to_wm(mode_lib, e2e, num_pipes, planes);
-
- for (i = 0; i < num_planes; i++) {
- calc_lines_in_det_y(&planes[i]);
- }
-
- min_full_det_buffering_time_us = 9999.0;
- for (i = 0; i < num_planes; i++) {
- if (planes[i].full_det_buffering_time < min_full_det_buffering_time_us) {
- min_full_det_buffering_time_us = planes[i].full_det_buffering_time;
- frame_time_for_min_full_det_buffering_time_us = (double) planes[i].v_total
- * planes[i].h_total / planes[i].pixclk_mhz;
- }
- }
-
- total_data_read_bw_mbps = calc_total_data_read_bw(mode_lib, planes, num_planes);
- average_read_bw_gbps = 0.0;
-
- for (i = 0; i < num_planes; i++) {
- if (planes[i].dcc_enable) {
- average_read_bw_gbps += planes[i].read_bw / planes[i].dcc_rate / 1000;
- } else {
- average_read_bw_gbps += planes[i].read_bw / 1000;
- }
-
- if (planes[i].dcc_enable) {
- average_read_bw_gbps += planes[i].read_bw / 1000 / 256;
- }
-
- if (planes[i].pte_enable) {
- average_read_bw_gbps += planes[i].read_bw / 1000 / 512;
- }
- }
-
- min_full_det_buffer_size_bytes = min_full_det_buffering_time_us * total_data_read_bw_mbps;
- rob_fill_size_bytes = mode_lib->ip.rob_buffer_size_kbytes * 1024 * total_data_read_bw_mbps
- / (average_read_bw_gbps * 1000);
- part_of_burst_that_fits_in_rob = dml_min(
- min_full_det_buffer_size_bytes,
- rob_fill_size_bytes);
-
- voltage = -1;
- dcfclk_mhz = -1.0;
- total_writeback = 0;
-
- for (i = 0; i < num_pipes; i++) {
- /* voltage and dcfclk must be the same for all pipes */
- ASSERT(voltage == -1 || voltage == e2e[i].clks_cfg.voltage);
- voltage = e2e[i].clks_cfg.voltage;
- ASSERT(dcfclk_mhz == -1.0 || dcfclk_mhz == e2e[i].clks_cfg.dcfclk_mhz);
- dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
-
- if (e2e[i].dout.output_type == dm_wb)
- total_writeback++;
- }
-
- return_bw_mbps = calc_return_bw(mode_lib, planes, num_planes);
-
- stutter_burst_time_us = part_of_burst_that_fits_in_rob * (average_read_bw_gbps * 1000)
- / total_data_read_bw_mbps / return_bw_mbps
- + (min_full_det_buffering_time_us * total_data_read_bw_mbps
- - part_of_burst_that_fits_in_rob) / (dcfclk_mhz * 64);
-
- if (total_writeback == 0) {
- stutter_eff_not_including_vblank = (1.0
- - ((mode_lib->soc.sr_exit_time_us + stutter_burst_time_us)
- / min_full_det_buffering_time_us)) * 100.0;
- } else {
- stutter_eff_not_including_vblank = 0.0;
- }
-
- smallest_vblank_us = 9999.0;
-
- for (i = 0; i < num_pipes; i++) {
- double vblank_us;
- if (e2e[i].pipe.dest.syncronized_vblank_all_planes != 0 || num_pipes == 1) {
- vblank_us = (double) (e2e[i].pipe.dest.vtotal + 1
- - e2e[i].pipe.dest.vblank_start
- + e2e[i].pipe.dest.vblank_end * e2e[i].pipe.dest.htotal)
- / e2e[i].pipe.dest.pixel_rate_mhz;
- } else {
- vblank_us = 0.0;
- }
-
- smallest_vblank_us = dml_min(smallest_vblank_us, vblank_us);
- }
-
- stutter_eff = 100.0
- * (((stutter_eff_not_including_vblank / 100.0)
- * (frame_time_for_min_full_det_buffering_time_us
- - smallest_vblank_us) + smallest_vblank_us)
- / frame_time_for_min_full_det_buffering_time_us);
-
-
- return stutter_eff;
-}
-
-double urgent_extra_calc(
- struct display_mode_lib *mode_lib,
- double dcfclk_mhz,
- double return_bw_mbps,
- unsigned int total_active_dpp,
- unsigned int total_dcc_active_dpp)
-{
- double urgent_extra_latency_us = 0.0;
- double urgent_round_trip_ooo_latency_us;
-
- urgent_round_trip_ooo_latency_us =
- (((double) mode_lib->soc.round_trip_ping_latency_dcfclk_cycles + 32)
- / dcfclk_mhz)
- + (((double) (mode_lib->soc.urgent_out_of_order_return_per_channel_bytes
- * mode_lib->soc.num_chans)) / return_bw_mbps);
-
- DTRACE(
- "INTERMEDIATE round_trip_ping_latency_dcfclk_cycles = %d",
- mode_lib->soc.round_trip_ping_latency_dcfclk_cycles);
- DTRACE("INTERMEDIATE dcfclk_mhz = %f", dcfclk_mhz);
- DTRACE(
- "INTERMEDIATE urgent_out_of_order_return_per_channel_bytes = %d",
- mode_lib->soc.urgent_out_of_order_return_per_channel_bytes);
-
- urgent_extra_latency_us = urgent_round_trip_ooo_latency_us
- + ((double) total_active_dpp * mode_lib->ip.pixel_chunk_size_kbytes
- + (double) total_dcc_active_dpp
- * mode_lib->ip.meta_chunk_size_kbytes)
- * 1024.0 / return_bw_mbps; /* to us */
-
- DTRACE(
- "INTERMEDIATE urgent_round_trip_ooo_latency_us = %f",
- urgent_round_trip_ooo_latency_us);
- DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp);
- DTRACE(
- "INTERMEDIATE pixel_chunk_size_kbytes = %d",
- mode_lib->ip.pixel_chunk_size_kbytes);
- DTRACE("INTERMEDIATE total_dcc_active_dpp = %d", total_dcc_active_dpp);
- DTRACE(
- "INTERMEDIATE meta_chunk_size_kbyte = %d",
- mode_lib->ip.meta_chunk_size_kbytes);
- DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps);
-
- return urgent_extra_latency_us;
-}
-
-double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib)
-{
- unsigned int total_active_dpp = DC__NUM_DPP;
- unsigned int total_dcc_active_dpp = total_active_dpp;
- double urgent_extra_latency_us = 0.0;
- double dcfclk_mhz = 0.0;
- double return_bw_mbps = 0.0;
- int voltage = dm_vmin;
-
- /* use minimum voltage */
- return_bw_mbps = dml_socbb_return_bw_mhz(&mode_lib->soc, (enum voltage_state) voltage);
- /* use minimum dcfclk */
- dcfclk_mhz = mode_lib->soc.vmin.dcfclk_mhz;
- /* use max dpps and dpps with dcc */
-
- urgent_extra_latency_us = urgent_extra_calc(
- mode_lib,
- dcfclk_mhz,
- return_bw_mbps,
- total_active_dpp,
- total_dcc_active_dpp);
-
- DTRACE("urgent extra max = %f", urgent_extra_latency_us);
- return urgent_extra_latency_us;
-}
-
-double dml_wm_urgent_extra(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- unsigned int total_active_dpp = 0;
- unsigned int total_dcc_active_dpp = 0;
- double urgent_extra_latency_us = 0.0;
- double dcfclk_mhz = 0.0;
- double return_bw_mbps = 0.0;
- int voltage = -1;
- bool pte_enable = false;
- unsigned int i;
-
- for (i = 0; i < num_pipes; i++) {
- /* num_dpp must be greater than 0 */
- ASSERT(pipes[i].num_dpp > 0);
-
- /* voltage mode must be the same for all pipes */
- ASSERT(voltage == -1 || voltage == pipes[i].voltage);
- voltage = pipes[i].voltage;
-
- /* dcfclk for all pipes must be the same */
- ASSERT(dcfclk_mhz == 0.0 || dcfclk_mhz == pipes[i].dcfclk_mhz);
- dcfclk_mhz = pipes[i].dcfclk_mhz;
-
- total_active_dpp += pipes[i].num_dpp;
-
- if (pipes[i].dcc_enable) {
- total_dcc_active_dpp += pipes[i].num_dpp;
- }
- }
-
- DTRACE("total active dpps %d", total_active_dpp);
- DTRACE("total active dpps with dcc %d", total_dcc_active_dpp);
- DTRACE("voltage state is %d", voltage);
-
- return_bw_mbps = calc_return_bw(mode_lib, pipes, num_pipes);
-
- DTRACE("return_bandwidth is %f MBps", return_bw_mbps);
-
- pte_enable = calc_pte_enable(pipes, num_pipes);
-
- /* calculate the maximum extra latency just for comparison purposes */
- /* dml_wm_urgent_extra_max(); */
- urgent_extra_latency_us = urgent_extra_calc(
- mode_lib,
- dcfclk_mhz,
- return_bw_mbps,
- total_active_dpp,
- total_dcc_active_dpp);
-
- DTRACE("INTERMEDIATE urgent_extra_latency_us_before_pte = %f", urgent_extra_latency_us);
-
- if (pte_enable) {
- urgent_extra_latency_us += total_active_dpp * mode_lib->ip.pte_chunk_size_kbytes
- * 1024.0 / return_bw_mbps;
-
- DTRACE("INTERMEDIATE pte_enable = true");
- DTRACE("INTERMEDIATE total_active_dpp = %d", total_active_dpp);
- DTRACE(
- "INTERMEDIATE pte_chunk_size_kbytes = %d",
- mode_lib->ip.pte_chunk_size_kbytes);
- DTRACE("INTERMEDIATE return_bw_mbps = %f", return_bw_mbps);
- }
-
- return urgent_extra_latency_us;
-}
-
-double dml_wm_urgent_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
- unsigned int combined_pipes;
- double urgent_wm;
-
- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
- combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
-
- urgent_wm = dml_wm_urgent(mode_lib, wm, combined_pipes);
-
- return urgent_wm;
-}
-
-double dml_wm_urgent(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- double urgent_watermark;
- double urgent_extra_latency_us;
- double last_pixel_of_line_extra_wm_us = 0.0;
-
- DTRACE("calculating urgent watermark");
- calc_display_pipe_line_delivery_time(mode_lib, planes, num_planes);
- urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, planes, num_planes);
-
- last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us(
- mode_lib,
- planes,
- num_planes);
-
- urgent_watermark = mode_lib->soc.urgent_latency_us + last_pixel_of_line_extra_wm_us
- + urgent_extra_latency_us;
-
- DTRACE("INTERMEDIATE urgent_latency_us = %f", mode_lib->soc.urgent_latency_us);
- DTRACE("INTERMEDIATE last_pixel_of_line_extra_wm_us = %f", last_pixel_of_line_extra_wm_us);
- DTRACE("INTERMEDIATE urgent_extra_latency_us = %f", urgent_extra_latency_us);
-
- DTRACE("urgent_watermark_us = %f", urgent_watermark);
- return urgent_watermark;
-}
-
-double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us)
-{
- double val;
-
- val = urgent_wm_us + 2.0 * mode_lib->soc.urgent_latency_us;
- DTRACE("pte_meta_urgent_watermark_us = %f", val);
-
- return val;
-}
-
-double dml_wm_dcfclk_deepsleep_mhz_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- struct _vcs_dpi_wm_calc_pipe_params_st *planes = mode_lib->wm_param;
- unsigned int num_planes;
- double val;
-
- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
- num_planes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, planes);
-
- val = dml_wm_dcfclk_deepsleep_mhz(mode_lib, planes, num_planes);
-
- return val;
-}
-
-double dml_wm_dcfclk_deepsleep_mhz(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes)
-{
- double val = 8.0;
- unsigned int i;
-
- for (i = 0; i < num_planes; i++) {
- calc_dcfclk_deepsleep_mhz_per_plane(mode_lib, &planes[i]);
-
- if (val < planes[i].dcfclk_deepsleep_mhz_per_plane) {
- val = planes[i].dcfclk_deepsleep_mhz_per_plane;
- }
-
- DTRACE("plane[%d] start", i);
- DTRACE("dcfclk_deepsleep_per_plane = %f", planes[i].dcfclk_deepsleep_mhz_per_plane);
- DTRACE("plane[%d] end", i);
- }
-
- DTRACE("dcfclk_deepsleep_mhz = %f", val);
-
- return val;
-}
-
-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
- unsigned int combined_pipes;
- struct _vcs_dpi_cstate_pstate_watermarks_st cstate_pstate_wm;
-
- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
- combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
- cstate_pstate_wm = dml_wm_cstate_pstate(mode_lib, wm, combined_pipes);
-
-
- return cstate_pstate_wm;
-}
-
-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- struct _vcs_dpi_cstate_pstate_watermarks_st wm;
- double urgent_extra_latency_us;
- double urgent_watermark_us;
- double last_pixel_of_line_extra_wm_us;
- double dcfclk_deepsleep_freq;
-
- DTRACE("calculating cstate and pstate watermarks");
- urgent_extra_latency_us = dml_wm_urgent_extra(mode_lib, pipes, num_pipes);
- urgent_watermark_us = dml_wm_urgent(mode_lib, pipes, num_pipes);
-
- last_pixel_of_line_extra_wm_us = calc_last_pixel_of_line_extra_wm_us(
- mode_lib,
- pipes,
- num_pipes);
- dcfclk_deepsleep_freq = dml_wm_dcfclk_deepsleep_mhz(mode_lib, pipes, num_pipes);
-
- wm.cstate_exit_us = mode_lib->soc.sr_exit_time_us + last_pixel_of_line_extra_wm_us
- + urgent_extra_latency_us
- + mode_lib->ip.dcfclk_cstate_latency / dcfclk_deepsleep_freq;
- wm.cstate_enter_plus_exit_us = mode_lib->soc.sr_enter_plus_exit_time_us
- + last_pixel_of_line_extra_wm_us + urgent_extra_latency_us;
- wm.pstate_change_us = mode_lib->soc.dram_clock_change_latency_us + urgent_watermark_us;
-
- DTRACE("stutter_exit_watermark_us = %f", wm.cstate_exit_us);
- DTRACE("stutter_enter_plus_exit_watermark_us = %f", wm.cstate_enter_plus_exit_us);
- DTRACE("dram_clock_change_watermark_us = %f", wm.pstate_change_us);
-
- return wm;
-}
-
-double dml_wm_writeback_pstate_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- struct _vcs_dpi_wm_calc_pipe_params_st *wm = mode_lib->wm_param;
- unsigned int combined_pipes;
-
- memset(mode_lib->wm_param, 0, sizeof(mode_lib->wm_param));
- combined_pipes = dml_wm_e2e_to_wm(mode_lib, pipes, num_pipes, wm);
-
-
- return dml_wm_writeback_pstate(mode_lib, wm, combined_pipes);
-}
-
-double dml_wm_writeback_pstate(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
- unsigned int num_pipes)
-{
- unsigned int total_active_wb = 0;
- double wm = 0.0;
- double socclk_mhz = 0.0;
- unsigned int i;
-
- DTRACE("calculating wb pstate watermark");
- for (i = 0; i < num_pipes; i++) {
- if (pipes[i].output_type == dm_wb)
- total_active_wb++;
- ASSERT(socclk_mhz == 0.0 || socclk_mhz == pipes[i].socclk_mhz);
- socclk_mhz = pipes[i].socclk_mhz;
- }
-
- DTRACE("total wb outputs %d", total_active_wb);
- DTRACE("socclk frequency %f Mhz", socclk_mhz);
-
- if (total_active_wb <= 1) {
- wm = mode_lib->soc.writeback_dram_clock_change_latency_us;
- } else {
- wm = mode_lib->soc.writeback_dram_clock_change_latency_us
- + (mode_lib->ip.writeback_chunk_size_kbytes * 1024.0) / 32.0
- / socclk_mhz;
- }
-
- DTRACE("wb pstate watermark %f us", wm);
- return wm;
-}
-
-unsigned int dml_wm_e2e_to_wm(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
- unsigned int num_pipes,
- struct _vcs_dpi_wm_calc_pipe_params_st *wm)
-{
- unsigned int num_planes = 0;
- bool visited[DC__NUM_PIPES];
- unsigned int i, j;
-
- for (i = 0; i < num_pipes; i++) {
- visited[i] = false;
- }
-
- for (i = 0; i < num_pipes; i++) {
- unsigned int num_dpp = 1;
-
- if (visited[i]) {
- continue;
- }
-
- visited[i] = true;
-
- if (e2e[i].pipe.src.is_hsplit) {
- for (j = i + 1; j < num_pipes; j++) {
- if (e2e[j].pipe.src.is_hsplit && !visited[j]
- && (e2e[i].pipe.src.hsplit_grp
- == e2e[j].pipe.src.hsplit_grp)) {
- num_dpp++;
- visited[j] = true;
- }
- }
- }
-
- wm[num_planes].num_dpp = num_dpp;
- wm[num_planes].voltage = e2e[i].clks_cfg.voltage;
- wm[num_planes].output_type = e2e[i].dout.output_type;
- wm[num_planes].dcfclk_mhz = e2e[i].clks_cfg.dcfclk_mhz;
- wm[num_planes].socclk_mhz = e2e[i].clks_cfg.socclk_mhz;
- wm[num_planes].dppclk_mhz = e2e[i].clks_cfg.dppclk_mhz;
- wm[num_planes].pixclk_mhz = e2e[i].pipe.dest.pixel_rate_mhz;
-
- wm[num_planes].pte_enable = e2e[i].pipe.src.vm;
- wm[num_planes].dcc_enable = e2e[i].pipe.src.dcc;
- wm[num_planes].dcc_rate = e2e[i].pipe.src.dcc_rate;
-
- get_bytes_per_pixel(
- (enum source_format_class) e2e[i].pipe.src.source_format,
- &wm[num_planes]);
- wm[num_planes].swath_width_y = get_swath_width_y(&e2e[i].pipe.src, num_dpp);
- get_swath_height(
- mode_lib,
- &e2e[i].pipe.src,
- &wm[num_planes],
- wm[num_planes].swath_width_y);
-
- wm[num_planes].interlace_en = e2e[i].pipe.dest.interlaced;
- wm[num_planes].h_ratio = e2e[i].pipe.scale_ratio_depth.hscl_ratio;
- wm[num_planes].v_ratio = e2e[i].pipe.scale_ratio_depth.vscl_ratio;
- if (wm[num_planes].interlace_en) {
- wm[num_planes].v_ratio = 2 * wm[num_planes].v_ratio;
- }
- wm[num_planes].h_taps = e2e[i].pipe.scale_taps.htaps;
- wm[num_planes].h_total = e2e[i].pipe.dest.htotal;
- wm[num_planes].v_total = e2e[i].pipe.dest.vtotal;
- wm[num_planes].v_active = e2e[i].pipe.dest.vactive;
- wm[num_planes].e2e_index = i;
- num_planes++;
- }
-
- for (i = 0; i < num_planes; i++) {
- DTRACE("plane[%d] start", i);
- DTRACE("voltage = %d", wm[i].voltage);
- DTRACE("v_active = %d", wm[i].v_active);
- DTRACE("h_total = %d", wm[i].h_total);
- DTRACE("v_total = %d", wm[i].v_total);
- DTRACE("pixclk_mhz = %f", wm[i].pixclk_mhz);
- DTRACE("dcfclk_mhz = %f", wm[i].dcfclk_mhz);
- DTRACE("dppclk_mhz = %f", wm[i].dppclk_mhz);
- DTRACE("h_ratio = %f", wm[i].h_ratio);
- DTRACE("v_ratio = %f", wm[i].v_ratio);
- DTRACE("interlaced = %d", wm[i].interlace_en);
- DTRACE("h_taps = %d", wm[i].h_taps);
- DTRACE("num_dpp = %d", wm[i].num_dpp);
- DTRACE("swath_width_y = %d", wm[i].swath_width_y);
- DTRACE("swath_height_y = %d", wm[i].swath_height_y);
- DTRACE("swath_height_c = %d", wm[i].swath_height_c);
- DTRACE("det_buffer_size_y = %d", wm[i].det_buffer_size_y);
- DTRACE("dcc_rate = %f", wm[i].dcc_rate);
- DTRACE("dcc_enable = %s", wm[i].dcc_enable ? "true" : "false");
- DTRACE("pte_enable = %s", wm[i].pte_enable ? "true" : "false");
- DTRACE("plane[%d] end", i);
- }
-
- return num_planes;
-}
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 @@
-/*
- * Copyright 2017 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-#ifndef __DISPLAY_WATERMARK_H__
-#define __DISPLAY_WATERMARK_H__
-
-#include "dml_common_defs.h"
-
-struct display_mode_lib;
-
-double dml_wm_urgent_extra(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
- unsigned int num_pipes);
-double dml_wm_urgent_extra_max(struct display_mode_lib *mode_lib);
-
-double dml_wm_urgent_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes);
-double dml_wm_urgent(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes);
-double dml_wm_pte_meta_urgent(struct display_mode_lib *mode_lib, double urgent_wm_us);
-double dml_wm_dcfclk_deepsleep_mhz_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes);
-double dml_wm_dcfclk_deepsleep_mhz(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes);
-
-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes);
-struct _vcs_dpi_cstate_pstate_watermarks_st dml_wm_cstate_pstate(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
- unsigned int num_pipes);
-
-double dml_wm_writeback_pstate_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *pipes,
- unsigned int num_pipes);
-double dml_wm_writeback_pstate(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *pipes,
- unsigned int num_pipes);
-
-double dml_wm_expected_stutter_eff_e2e(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
- unsigned int num_pipes);
-double dml_wm_expected_stutter_eff_e2e_with_vblank(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
- unsigned int num_pipes);
-
-unsigned int dml_wm_e2e_to_wm(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_display_e2e_pipe_params_st *e2e,
- unsigned int num_pipes,
- struct _vcs_dpi_wm_calc_pipe_params_st *wm);
-
-double dml_wm_calc_total_data_read_bw(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes);
-double dml_wm_calc_return_bw(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_wm_calc_pipe_params_st *planes,
- unsigned int num_planes);
-
-#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dml/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 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dml1_display_rq_dlg_calc.h"
+#include "display_mode_lib.h"
+
+#include "dml_inline_defs.h"
+
+static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
+{
+ unsigned int ret_val = 0;
+
+ if (source_format == dm_444_16) {
+ if (!is_chroma)
+ ret_val = 2;
+ } else if (source_format == dm_444_32) {
+ if (!is_chroma)
+ ret_val = 4;
+ } else if (source_format == dm_444_64) {
+ if (!is_chroma)
+ ret_val = 8;
+ } else if (source_format == dm_420_8) {
+ if (is_chroma)
+ ret_val = 2;
+ else
+ ret_val = 1;
+ } else if (source_format == dm_420_10) {
+ if (is_chroma)
+ ret_val = 4;
+ else
+ ret_val = 2;
+ }
+ return ret_val;
+}
+
+static bool is_dual_plane(enum source_format_class source_format)
+{
+ bool ret_val = 0;
+
+ if ((source_format == dm_420_8) || (source_format == dm_420_10))
+ ret_val = 1;
+
+ return ret_val;
+}
+
+static void get_blk256_size(
+ unsigned int *blk256_width,
+ unsigned int *blk256_height,
+ unsigned int bytes_per_element)
+{
+ if (bytes_per_element == 1) {
+ *blk256_width = 16;
+ *blk256_height = 16;
+ } else if (bytes_per_element == 2) {
+ *blk256_width = 16;
+ *blk256_height = 8;
+ } else if (bytes_per_element == 4) {
+ *blk256_width = 8;
+ *blk256_height = 8;
+ } else if (bytes_per_element == 8) {
+ *blk256_width = 8;
+ *blk256_height = 4;
+ }
+}
+
+static double get_refcyc_per_delivery(
+ struct display_mode_lib *mode_lib,
+ double refclk_freq_in_mhz,
+ double pclk_freq_in_mhz,
+ unsigned int recout_width,
+ double vratio,
+ double hscale_pixel_rate,
+ unsigned int delivery_width,
+ unsigned int req_per_swath_ub)
+{
+ double refcyc_per_delivery = 0.0;
+
+ if (vratio <= 1.0) {
+ refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
+ / pclk_freq_in_mhz / (double) req_per_swath_ub;
+ } else {
+ refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
+ / (double) hscale_pixel_rate / (double) req_per_swath_ub;
+ }
+
+ DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
+ DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
+ DTRACE("DLG: %s: recout_width = %d", __func__, recout_width);
+ DTRACE("DLG: %s: vratio = %3.2f", __func__, vratio);
+ DTRACE("DLG: %s: req_per_swath_ub = %d", __func__, req_per_swath_ub);
+ DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__, refcyc_per_delivery);
+
+ return refcyc_per_delivery;
+
+}
+
+static double get_vratio_pre(
+ struct display_mode_lib *mode_lib,
+ unsigned int max_num_sw,
+ unsigned int max_partial_sw,
+ unsigned int swath_height,
+ double vinit,
+ double l_sw)
+{
+ double prefill = dml_floor(vinit, 1);
+ double vratio_pre = 1.0;
+
+ vratio_pre = (max_num_sw * swath_height + max_partial_sw) / l_sw;
+
+ if (swath_height > 4) {
+ double tmp0 = (max_num_sw * swath_height) / (l_sw - (prefill - 3.0) / 2.0);
+
+ if (tmp0 > vratio_pre)
+ vratio_pre = tmp0;
+ }
+
+ DTRACE("DLG: %s: max_num_sw = %0d", __func__, max_num_sw);
+ DTRACE("DLG: %s: max_partial_sw = %0d", __func__, max_partial_sw);
+ DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
+ DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
+ DTRACE("DLG: %s: vratio_pre = %3.2f", __func__, vratio_pre);
+
+ if (vratio_pre < 1.0) {
+ DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__, vratio_pre);
+ vratio_pre = 1.0;
+ }
+
+ if (vratio_pre > 4.0) {
+ DTRACE(
+ "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0",
+ __func__,
+ vratio_pre);
+ vratio_pre = 4.0;
+ }
+
+ return vratio_pre;
+}
+
+static void get_swath_need(
+ struct display_mode_lib *mode_lib,
+ unsigned int *max_num_sw,
+ unsigned int *max_partial_sw,
+ unsigned int swath_height,
+ double vinit)
+{
+ double prefill = dml_floor(vinit, 1);
+ unsigned int max_partial_sw_int;
+
+ DTRACE("DLG: %s: swath_height = %0d", __func__, swath_height);
+ DTRACE("DLG: %s: vinit = %3.2f", __func__, vinit);
+
+ ASSERT(prefill > 0.0 && prefill <= 8.0);
+
+ *max_num_sw = (unsigned int) (dml_ceil((prefill - 1.0) / (double) swath_height, 1) + 1.0); /* prefill has to be >= 1 */
+ max_partial_sw_int =
+ (prefill == 1) ?
+ (swath_height - 1) :
+ ((unsigned int) (prefill - 2.0) % swath_height);
+ *max_partial_sw = (max_partial_sw_int < 1) ? 1 : max_partial_sw_int; /* ensure minimum of 1 is used */
+
+ DTRACE("DLG: %s: max_num_sw = %0d", __func__, *max_num_sw);
+ DTRACE("DLG: %s: max_partial_sw = %0d", __func__, *max_partial_sw);
+}
+
+static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
+{
+ if (tile_size == dm_256k_tile)
+ return (256 * 1024);
+ else if (tile_size == dm_64k_tile)
+ return (64 * 1024);
+ else
+ return (4 * 1024);
+}
+
+static void extract_rq_sizing_regs(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_data_rq_regs_st *rq_regs,
+ const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing)
+{
+ DTRACE("DLG: %s: rq_sizing param", __func__);
+ print__data_rq_sizing_params_st(mode_lib, rq_sizing);
+
+ rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
+
+ if (rq_sizing.min_chunk_bytes == 0)
+ rq_regs->min_chunk_size = 0;
+ else
+ rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1;
+
+ rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10;
+ if (rq_sizing.min_meta_chunk_bytes == 0)
+ rq_regs->min_meta_chunk_size = 0;
+ else
+ rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1;
+
+ rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6;
+ rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
+}
+
+void dml1_extract_rq_regs(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_rq_regs_st *rq_regs,
+ const struct _vcs_dpi_display_rq_params_st rq_param)
+{
+ unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
+ unsigned int detile_buf_plane1_addr = 0;
+
+ extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
+ if (rq_param.yuv420)
+ extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
+
+ rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
+ rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
+
+ /* FIXME: take the max between luma, chroma chunk size?
+ * okay for now, as we are setting chunk_bytes to 8kb anyways
+ */
+ if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */
+ rq_regs->drq_expansion_mode = 0;
+ } else {
+ rq_regs->drq_expansion_mode = 2;
+ }
+ rq_regs->prq_expansion_mode = 1;
+ rq_regs->mrq_expansion_mode = 1;
+ rq_regs->crq_expansion_mode = 1;
+
+ if (rq_param.yuv420) {
+ if ((double) rq_param.misc.rq_l.stored_swath_bytes
+ / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
+ detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */
+ } else {
+ detile_buf_plane1_addr = dml_round_to_multiple(
+ (unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
+ 256,
+ 0) / 64.0; /* 2/3 to chroma */
+ }
+ }
+ rq_regs->plane1_base_address = detile_buf_plane1_addr;
+}
+
+static void handle_det_buf_split(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_rq_params_st *rq_param,
+ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
+{
+ unsigned int total_swath_bytes = 0;
+ unsigned int swath_bytes_l = 0;
+ unsigned int swath_bytes_c = 0;
+ unsigned int full_swath_bytes_packed_l = 0;
+ unsigned int full_swath_bytes_packed_c = 0;
+ bool req128_l = 0;
+ bool req128_c = 0;
+ bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
+ bool surf_vert = (pipe_src_param.source_scan == dm_vert);
+ unsigned int log2_swath_height_l = 0;
+ unsigned int log2_swath_height_c = 0;
+ unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
+
+ full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes;
+ full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
+
+ if (rq_param->yuv420_10bpc) {
+ full_swath_bytes_packed_l = dml_round_to_multiple(
+ rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
+ 256,
+ 1) + 256;
+ full_swath_bytes_packed_c = dml_round_to_multiple(
+ rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
+ 256,
+ 1) + 256;
+ }
+
+ if (rq_param->yuv420) {
+ total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
+
+ if (total_swath_bytes <= detile_buf_size_in_bytes) { /*full 256b request */
+ req128_l = 0;
+ req128_c = 0;
+ swath_bytes_l = full_swath_bytes_packed_l;
+ swath_bytes_c = full_swath_bytes_packed_c;
+ } else { /*128b request (for luma only for yuv420 8bpc) */
+ req128_l = 1;
+ req128_c = 0;
+ swath_bytes_l = full_swath_bytes_packed_l / 2;
+ swath_bytes_c = full_swath_bytes_packed_c;
+ }
+
+ /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137)
+ * TODO: Remove after rtl fix
+ */
+ if (req128_l == 1) {
+ req128_c = 1;
+ DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__);
+ }
+
+ /* Note: assumption, the config that pass in will fit into
+ * the detiled buffer.
+ */
+ } else {
+ total_swath_bytes = 2 * full_swath_bytes_packed_l;
+
+ if (total_swath_bytes <= detile_buf_size_in_bytes)
+ req128_l = 0;
+ else
+ req128_l = 1;
+
+ swath_bytes_l = total_swath_bytes;
+ swath_bytes_c = 0;
+ }
+ rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l;
+ rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c;
+
+ if (surf_linear) {
+ log2_swath_height_l = 0;
+ log2_swath_height_c = 0;
+ } else if (!surf_vert) {
+ log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
+ log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
+ } else {
+ log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
+ log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
+ }
+ rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
+ rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
+
+ DTRACE("DLG: %s: req128_l = %0d", __func__, req128_l);
+ DTRACE("DLG: %s: req128_c = %0d", __func__, req128_c);
+ DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__, full_swath_bytes_packed_l);
+ DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__, full_swath_bytes_packed_c);
+}
+
+/* Need refactor. */
+static void dml1_rq_dlg_get_row_heights(
+ struct display_mode_lib *mode_lib,
+ unsigned int *o_dpte_row_height,
+ unsigned int *o_meta_row_height,
+ unsigned int vp_width,
+ unsigned int data_pitch,
+ int source_format,
+ int tiling,
+ int macro_tile_size,
+ int source_scan,
+ int is_chroma)
+{
+ bool surf_linear = (tiling == dm_sw_linear);
+ bool surf_vert = (source_scan == dm_vert);
+
+ unsigned int bytes_per_element = get_bytes_per_element(
+ (enum source_format_class) source_format,
+ is_chroma);
+ unsigned int log2_bytes_per_element = dml_log2(bytes_per_element);
+ unsigned int blk256_width = 0;
+ unsigned int blk256_height = 0;
+
+ unsigned int log2_blk256_height;
+ unsigned int blk_bytes;
+ unsigned int log2_blk_bytes;
+ unsigned int log2_blk_height;
+ unsigned int log2_blk_width;
+ unsigned int log2_meta_req_bytes;
+ unsigned int log2_meta_req_height;
+ unsigned int log2_meta_req_width;
+ unsigned int log2_meta_row_height;
+ unsigned int log2_vmpg_bytes;
+ unsigned int dpte_buf_in_pte_reqs;
+ unsigned int log2_vmpg_height;
+ unsigned int log2_vmpg_width;
+ unsigned int log2_dpte_req_height_ptes;
+ unsigned int log2_dpte_req_width_ptes;
+ unsigned int log2_dpte_req_height;
+ unsigned int log2_dpte_req_width;
+ unsigned int log2_dpte_row_height_linear;
+ unsigned int log2_dpte_row_height;
+ unsigned int dpte_req_width;
+
+ if (surf_linear) {
+ blk256_width = 256;
+ blk256_height = 1;
+ } else {
+ get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
+ }
+
+ log2_blk256_height = dml_log2((double) blk256_height);
+ blk_bytes = surf_linear ?
+ 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
+ log2_blk_bytes = dml_log2((double) blk_bytes);
+ log2_blk_height = 0;
+ log2_blk_width = 0;
+
+ /* remember log rule
+ * "+" in log is multiply
+ * "-" in log is divide
+ * "/2" is like square root
+ * blk is vertical biased
+ */
+ if (tiling != dm_sw_linear)
+ log2_blk_height = log2_blk256_height
+ + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
+ else
+ log2_blk_height = 0; /* blk height of 1 */
+
+ log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
+
+ /* ------- */
+ /* meta */
+ /* ------- */
+ log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
+
+ /* each 64b meta request for dcn is 8x8 meta elements and
+ * a meta element covers one 256b block of the the data surface.
+ */
+ log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */
+ log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
+ - log2_meta_req_height;
+ log2_meta_row_height = 0;
+
+ /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
+ * calculate upper bound of the meta_row_width
+ */
+ if (!surf_vert)
+ log2_meta_row_height = log2_meta_req_height;
+ else
+ log2_meta_row_height = log2_meta_req_width;
+
+ *o_meta_row_height = 1 << log2_meta_row_height;
+
+ /* ------ */
+ /* dpte */
+ /* ------ */
+ log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+ dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
+
+ log2_vmpg_height = 0;
+ log2_vmpg_width = 0;
+ log2_dpte_req_height_ptes = 0;
+ log2_dpte_req_width_ptes = 0;
+ log2_dpte_req_height = 0;
+ log2_dpte_req_width = 0;
+ log2_dpte_row_height_linear = 0;
+ log2_dpte_row_height = 0;
+ dpte_req_width = 0; /* 64b dpte req width in data element */
+
+ if (surf_linear)
+ log2_vmpg_height = 0; /* one line high */
+ else
+ log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
+ log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
+
+ /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
+ if (log2_blk_bytes <= log2_vmpg_bytes)
+ log2_dpte_req_height_ptes = 0;
+ else if (log2_blk_height - log2_vmpg_height >= 2)
+ log2_dpte_req_height_ptes = 2;
+ else
+ log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
+ log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
+
+ ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
+ (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
+ (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
+
+ /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height
+ * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent
+ */
+ log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
+ log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
+ dpte_req_width = 1 << log2_dpte_req_width;
+
+ /* calculate pitch dpte row buffer can hold
+ * round the result down to a power of two.
+ */
+ if (surf_linear) {
+ log2_dpte_row_height_linear = dml_floor(
+ dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch),
+ 1);
+
+ ASSERT(log2_dpte_row_height_linear >= 3);
+
+ if (log2_dpte_row_height_linear > 7)
+ log2_dpte_row_height_linear = 7;
+
+ log2_dpte_row_height = log2_dpte_row_height_linear;
+ } else {
+ /* the upper bound of the dpte_row_width without dependency on viewport position follows. */
+ if (!surf_vert)
+ log2_dpte_row_height = log2_dpte_req_height;
+ else
+ log2_dpte_row_height =
+ (log2_blk_width < log2_dpte_req_width) ?
+ log2_blk_width : log2_dpte_req_width;
+ }
+
+ /* From programming guide:
+ * There is a special case of saving only half of ptes returned due to buffer space limits.
+ * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
+ * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
+ */
+ if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
+ && log2_blk_bytes >= 16)
+ log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
+
+ *o_dpte_row_height = 1 << log2_dpte_row_height;
+}
+
+static void get_surf_rq_param(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param,
+ struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param,
+ struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param,
+ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param,
+ bool is_chroma)
+{
+ bool mode_422 = 0;
+ unsigned int vp_width = 0;
+ unsigned int vp_height = 0;
+ unsigned int data_pitch = 0;
+ unsigned int meta_pitch = 0;
+ unsigned int ppe = mode_422 ? 2 : 1;
+ bool surf_linear;
+ bool surf_vert;
+ unsigned int bytes_per_element;
+ unsigned int log2_bytes_per_element;
+ unsigned int blk256_width;
+ unsigned int blk256_height;
+ unsigned int log2_blk256_width;
+ unsigned int log2_blk256_height;
+ unsigned int blk_bytes;
+ unsigned int log2_blk_bytes;
+ unsigned int log2_blk_height;
+ unsigned int log2_blk_width;
+ unsigned int log2_meta_req_bytes;
+ unsigned int log2_meta_req_height;
+ unsigned int log2_meta_req_width;
+ unsigned int meta_req_width;
+ unsigned int meta_req_height;
+ unsigned int log2_meta_row_height;
+ unsigned int meta_row_width_ub;
+ unsigned int log2_meta_chunk_bytes;
+ unsigned int log2_meta_chunk_height;
+ unsigned int log2_meta_chunk_width;
+ unsigned int log2_min_meta_chunk_bytes;
+ unsigned int min_meta_chunk_width;
+ unsigned int meta_chunk_width;
+ unsigned int meta_chunk_per_row_int;
+ unsigned int meta_row_remainder;
+ unsigned int meta_chunk_threshold;
+ unsigned int meta_blk_bytes;
+ unsigned int meta_blk_height;
+ unsigned int meta_blk_width;
+ unsigned int meta_surface_bytes;
+ unsigned int vmpg_bytes;
+ unsigned int meta_pte_req_per_frame_ub;
+ unsigned int meta_pte_bytes_per_frame_ub;
+ unsigned int log2_vmpg_bytes;
+ unsigned int dpte_buf_in_pte_reqs;
+ unsigned int log2_vmpg_height;
+ unsigned int log2_vmpg_width;
+ unsigned int log2_dpte_req_height_ptes;
+ unsigned int log2_dpte_req_width_ptes;
+ unsigned int log2_dpte_req_height;
+ unsigned int log2_dpte_req_width;
+ unsigned int log2_dpte_row_height_linear;
+ unsigned int log2_dpte_row_height;
+ unsigned int log2_dpte_group_width;
+ unsigned int dpte_row_width_ub;
+ unsigned int dpte_row_height;
+ unsigned int dpte_req_height;
+ unsigned int dpte_req_width;
+ unsigned int dpte_group_width;
+ unsigned int log2_dpte_group_bytes;
+ unsigned int log2_dpte_group_length;
+ unsigned int func_meta_row_height, func_dpte_row_height;
+
+ /* FIXME check if ppe apply for both luma and chroma in 422 case */
+ if (is_chroma) {
+ vp_width = pipe_src_param.viewport_width_c / ppe;
+ vp_height = pipe_src_param.viewport_height_c;
+ data_pitch = pipe_src_param.data_pitch_c;
+ meta_pitch = pipe_src_param.meta_pitch_c;
+ } else {
+ vp_width = pipe_src_param.viewport_width / ppe;
+ vp_height = pipe_src_param.viewport_height;
+ data_pitch = pipe_src_param.data_pitch;
+ meta_pitch = pipe_src_param.meta_pitch;
+ }
+
+ rq_sizing_param->chunk_bytes = 8192;
+
+ if (rq_sizing_param->chunk_bytes == 64 * 1024)
+ rq_sizing_param->min_chunk_bytes = 0;
+ else
+ rq_sizing_param->min_chunk_bytes = 1024;
+
+ rq_sizing_param->meta_chunk_bytes = 2048;
+ rq_sizing_param->min_meta_chunk_bytes = 256;
+
+ rq_sizing_param->mpte_group_bytes = 2048;
+
+ surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
+ surf_vert = (pipe_src_param.source_scan == dm_vert);
+
+ bytes_per_element = get_bytes_per_element(
+ (enum source_format_class) pipe_src_param.source_format,
+ is_chroma);
+ log2_bytes_per_element = dml_log2(bytes_per_element);
+ blk256_width = 0;
+ blk256_height = 0;
+
+ if (surf_linear) {
+ blk256_width = 256 / bytes_per_element;
+ blk256_height = 1;
+ } else {
+ get_blk256_size(&blk256_width, &blk256_height, bytes_per_element);
+ }
+
+ DTRACE("DLG: %s: surf_linear = %d", __func__, surf_linear);
+ DTRACE("DLG: %s: surf_vert = %d", __func__, surf_vert);
+ DTRACE("DLG: %s: blk256_width = %d", __func__, blk256_width);
+ DTRACE("DLG: %s: blk256_height = %d", __func__, blk256_height);
+
+ log2_blk256_width = dml_log2((double) blk256_width);
+ log2_blk256_height = dml_log2((double) blk256_height);
+ blk_bytes =
+ surf_linear ? 256 : get_blk_size_bytes(
+ (enum source_macro_tile_size) pipe_src_param.macro_tile_size);
+ log2_blk_bytes = dml_log2((double) blk_bytes);
+ log2_blk_height = 0;
+ log2_blk_width = 0;
+
+ /* remember log rule
+ * "+" in log is multiply
+ * "-" in log is divide
+ * "/2" is like square root
+ * blk is vertical biased
+ */
+ if (pipe_src_param.sw_mode != dm_sw_linear)
+ log2_blk_height = log2_blk256_height
+ + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
+ else
+ log2_blk_height = 0; /* blk height of 1 */
+
+ log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
+
+ if (!surf_vert) {
+ rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1)
+ + blk256_width;
+ rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
+ } else {
+ rq_dlg_param->swath_width_ub = dml_round_to_multiple(
+ vp_height - 1,
+ blk256_height,
+ 1) + blk256_height;
+ rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
+ }
+
+ if (!surf_vert)
+ rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height
+ * bytes_per_element;
+ else
+ rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width
+ * bytes_per_element;
+
+ rq_misc_param->blk256_height = blk256_height;
+ rq_misc_param->blk256_width = blk256_width;
+
+ /* ------- */
+ /* meta */
+ /* ------- */
+ log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
+
+ /* each 64b meta request for dcn is 8x8 meta elements and
+ * a meta element covers one 256b block of the the data surface.
+ */
+ log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
+ log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
+ - log2_meta_req_height;
+ meta_req_width = 1 << log2_meta_req_width;
+ meta_req_height = 1 << log2_meta_req_height;
+ log2_meta_row_height = 0;
+ meta_row_width_ub = 0;
+
+ /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
+ * calculate upper bound of the meta_row_width
+ */
+ if (!surf_vert) {
+ log2_meta_row_height = log2_meta_req_height;
+ meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1)
+ + meta_req_width;
+ rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width;
+ } else {
+ log2_meta_row_height = log2_meta_req_width;
+ meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1)
+ + meta_req_height;
+ rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height;
+ }
+ rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
+
+ log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
+ log2_meta_chunk_height = log2_meta_row_height;
+
+ /*full sized meta chunk width in unit of data elements */
+ log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element
+ - log2_meta_chunk_height;
+ log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
+ min_meta_chunk_width = 1
+ << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element
+ - log2_meta_chunk_height);
+ meta_chunk_width = 1 << log2_meta_chunk_width;
+ meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width);
+ meta_row_remainder = meta_row_width_ub % meta_chunk_width;
+ meta_chunk_threshold = 0;
+ meta_blk_bytes = 4096;
+ meta_blk_height = blk256_height * 64;
+ meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height;
+ meta_surface_bytes = meta_pitch
+ * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1)
+ + meta_blk_height) * bytes_per_element / 256;
+ vmpg_bytes = mode_lib->soc.vmm_page_size_bytes;
+ meta_pte_req_per_frame_ub = (dml_round_to_multiple(
+ meta_surface_bytes - vmpg_bytes,
+ 8 * vmpg_bytes,
+ 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
+ meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; /*64B mpte request */
+ rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
+
+ DTRACE("DLG: %s: meta_blk_height = %d", __func__, meta_blk_height);
+ DTRACE("DLG: %s: meta_blk_width = %d", __func__, meta_blk_width);
+ DTRACE("DLG: %s: meta_surface_bytes = %d", __func__, meta_surface_bytes);
+ DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__, meta_pte_req_per_frame_ub);
+ DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__, meta_pte_bytes_per_frame_ub);
+
+ if (!surf_vert)
+ meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
+ else
+ meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height;
+
+ if (meta_row_remainder <= meta_chunk_threshold)
+ rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
+ else
+ rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
+
+ rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
+
+ /* ------ */
+ /* dpte */
+ /* ------ */
+ log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
+ dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
+
+ log2_vmpg_height = 0;
+ log2_vmpg_width = 0;
+ log2_dpte_req_height_ptes = 0;
+ log2_dpte_req_width_ptes = 0;
+ log2_dpte_req_height = 0;
+ log2_dpte_req_width = 0;
+ log2_dpte_row_height_linear = 0;
+ log2_dpte_row_height = 0;
+ log2_dpte_group_width = 0;
+ dpte_row_width_ub = 0;
+ dpte_row_height = 0;
+ dpte_req_height = 0; /* 64b dpte req height in data element */
+ dpte_req_width = 0; /* 64b dpte req width in data element */
+ dpte_group_width = 0;
+ log2_dpte_group_bytes = 0;
+ log2_dpte_group_length = 0;
+
+ if (surf_linear)
+ log2_vmpg_height = 0; /* one line high */
+ else
+ log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
+ log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
+
+ /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
+ if (log2_blk_bytes <= log2_vmpg_bytes)
+ log2_dpte_req_height_ptes = 0;
+ else if (log2_blk_height - log2_vmpg_height >= 2)
+ log2_dpte_req_height_ptes = 2;
+ else
+ log2_dpte_req_height_ptes = log2_blk_height - log2_vmpg_height;
+ log2_dpte_req_width_ptes = 3 - log2_dpte_req_height_ptes;
+
+ /* Ensure we only have the 3 shapes */
+ ASSERT((log2_dpte_req_width_ptes == 3 && log2_dpte_req_height_ptes == 0) || /* 8x1 */
+ (log2_dpte_req_width_ptes == 2 && log2_dpte_req_height_ptes == 1) || /* 4x2 */
+ (log2_dpte_req_width_ptes == 1 && log2_dpte_req_height_ptes == 2)); /* 2x4 */
+
+ /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
+ * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
+ * That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
+ */
+ log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
+ log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
+ dpte_req_height = 1 << log2_dpte_req_height;
+ dpte_req_width = 1 << log2_dpte_req_width;
+
+ /* calculate pitch dpte row buffer can hold
+ * round the result down to a power of two.
+ */
+ if (surf_linear) {
+ log2_dpte_row_height_linear = dml_floor(
+ dml_log2(dpte_buf_in_pte_reqs * dpte_req_width / data_pitch),
+ 1);
+
+ ASSERT(log2_dpte_row_height_linear >= 3);
+
+ if (log2_dpte_row_height_linear > 7)
+ log2_dpte_row_height_linear = 7;
+
+ log2_dpte_row_height = log2_dpte_row_height_linear;
+ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
+
+ /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
+ * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
+ */
+ dpte_row_width_ub = dml_round_to_multiple(
+ data_pitch * dpte_row_height - 1,
+ dpte_req_width,
+ 1) + dpte_req_width;
+ rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
+ } else {
+ /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */
+ if (!surf_vert) {
+ log2_dpte_row_height = log2_dpte_req_height;
+ dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1)
+ + dpte_req_width;
+ rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
+ } else {
+ log2_dpte_row_height =
+ (log2_blk_width < log2_dpte_req_width) ?
+ log2_blk_width : log2_dpte_req_width;
+ dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1)
+ + dpte_req_height;
+ rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
+ }
+ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
+ }
+ rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64;
+
+ /* From programming guide:
+ * There is a special case of saving only half of ptes returned due to buffer space limits.
+ * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
+ * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
+ */
+ if (!surf_vert && vp_width > (2560 + 16) && bytes_per_element >= 4 && log2_vmpg_bytes == 12
+ && log2_blk_bytes >= 16) {
+ log2_dpte_row_height = log2_dpte_row_height - 1; /*half of the full height */
+ rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
+ }
+
+ /* the dpte_group_bytes is reduced for the specific case of vertical
+ * access of a tile surface that has dpte request of 8x1 ptes.
+ */
+ if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) /*reduced, in this case, will have page fault within a group */
+ rq_sizing_param->dpte_group_bytes = 512;
+ else
+ /*full size */
+ rq_sizing_param->dpte_group_bytes = 2048;
+
+ /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */
+ log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
+ log2_dpte_group_length = log2_dpte_group_bytes - 6; /*length in 64b requests */
+
+ /* full sized data pte group width in elements */
+ if (!surf_vert)
+ log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
+ else
+ log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
+
+ dpte_group_width = 1 << log2_dpte_group_width;
+
+ /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
+ * the upper bound for the dpte groups per row is as follows.
+ */
+ rq_dlg_param->dpte_groups_per_row_ub = dml_ceil(
+ (double) dpte_row_width_ub / dpte_group_width,
+ 1);
+
+ dml1_rq_dlg_get_row_heights(
+ mode_lib,
+ &func_dpte_row_height,
+ &func_meta_row_height,
+ vp_width,
+ data_pitch,
+ pipe_src_param.source_format,
+ pipe_src_param.sw_mode,
+ pipe_src_param.macro_tile_size,
+ pipe_src_param.source_scan,
+ is_chroma);
+
+ /* Just a check to make sure this function and the new one give the same
+ * result. The standalone get_row_heights() function is based off of the
+ * code in this function so the same changes need to be made to both.
+ */
+ if (rq_dlg_param->meta_row_height != func_meta_row_height) {
+ DTRACE(
+ "MISMATCH: rq_dlg_param->meta_row_height = %d",
+ rq_dlg_param->meta_row_height);
+ DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height);
+ ASSERT(0);
+ }
+
+ if (rq_dlg_param->dpte_row_height != func_dpte_row_height) {
+ DTRACE(
+ "MISMATCH: rq_dlg_param->dpte_row_height = %d",
+ rq_dlg_param->dpte_row_height);
+ DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height);
+ ASSERT(0);
+ }
+}
+
+void dml1_rq_dlg_get_rq_params(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_rq_params_st *rq_param,
+ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param)
+{
+ /* get param for luma surface */
+ rq_param->yuv420 = pipe_src_param.source_format == dm_420_8
+ || pipe_src_param.source_format == dm_420_10;
+ rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10;
+
+ get_surf_rq_param(
+ mode_lib,
+ &(rq_param->sizing.rq_l),
+ &(rq_param->dlg.rq_l),
+ &(rq_param->misc.rq_l),
+ pipe_src_param,
+ 0);
+
+ if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) {
+ /* get param for chroma surface */
+ get_surf_rq_param(
+ mode_lib,
+ &(rq_param->sizing.rq_c),
+ &(rq_param->dlg.rq_c),
+ &(rq_param->misc.rq_c),
+ pipe_src_param,
+ 1);
+ }
+
+ /* calculate how to split the det buffer space between luma and chroma */
+ handle_det_buf_split(mode_lib, rq_param, pipe_src_param);
+ print__rq_params_st(mode_lib, *rq_param);
+}
+
+/* Note: currently taken in as is.
+ * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
+ */
+void dml1_rq_dlg_get_dlg_params(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs,
+ struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs,
+ const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
+ const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
+ const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+ const bool cstate_en,
+ const bool pstate_en,
+ const bool vm_en,
+ const bool iflip_en)
+{
+ /* Timing */
+ unsigned int htotal = e2e_pipe_param.pipe.dest.htotal;
+ unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end;
+ unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start;
+ unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end;
+ bool interlaced = e2e_pipe_param.pipe.dest.interlaced;
+ unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
+
+ double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz;
+ double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz;
+ double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz;
+ double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz;
+
+ double ref_freq_to_pix_freq;
+ double prefetch_xy_calc_in_dcfclk;
+ double min_dcfclk_mhz;
+ double t_calc_us;
+ double min_ttu_vblank;
+ double min_dst_y_ttu_vblank;
+ unsigned int dlg_vblank_start;
+ bool dcc_en;
+ bool dual_plane;
+ bool mode_422;
+ unsigned int access_dir;
+ unsigned int bytes_per_element_l;
+ unsigned int bytes_per_element_c;
+ unsigned int vp_height_l;
+ unsigned int vp_width_l;
+ unsigned int vp_height_c;
+ unsigned int vp_width_c;
+ unsigned int htaps_l;
+ unsigned int htaps_c;
+ double hratios_l;
+ double hratios_c;
+ double vratio_l;
+ double vratio_c;
+ double line_time_in_us;
+ double vinit_l;
+ double vinit_c;
+ double vinit_bot_l;
+ double vinit_bot_c;
+ unsigned int swath_height_l;
+ unsigned int swath_width_ub_l;
+ unsigned int dpte_bytes_per_row_ub_l;
+ unsigned int dpte_groups_per_row_ub_l;
+ unsigned int meta_pte_bytes_per_frame_ub_l;
+ unsigned int meta_bytes_per_row_ub_l;
+ unsigned int swath_height_c;
+ unsigned int swath_width_ub_c;
+ unsigned int dpte_bytes_per_row_ub_c;
+ unsigned int dpte_groups_per_row_ub_c;
+ unsigned int meta_chunks_per_row_ub_l;
+ unsigned int vupdate_offset;
+ unsigned int vupdate_width;
+ unsigned int vready_offset;
+ unsigned int dppclk_delay_subtotal;
+ unsigned int dispclk_delay_subtotal;
+ unsigned int pixel_rate_delay_subtotal;
+ unsigned int vstartup_start;
+ unsigned int dst_x_after_scaler;
+ unsigned int dst_y_after_scaler;
+ double line_wait;
+ double line_o;
+ double line_setup;
+ double line_calc;
+ double dst_y_prefetch;
+ double t_pre_us;
+ unsigned int vm_bytes;
+ unsigned int meta_row_bytes;
+ unsigned int max_num_sw_l;
+ unsigned int max_num_sw_c;
+ unsigned int max_partial_sw_l;
+ unsigned int max_partial_sw_c;
+ double max_vinit_l;
+ double max_vinit_c;
+ unsigned int lsw_l;
+ unsigned int lsw_c;
+ unsigned int sw_bytes_ub_l;
+ unsigned int sw_bytes_ub_c;
+ unsigned int sw_bytes;
+ unsigned int dpte_row_bytes;
+ double prefetch_bw;
+ double flip_bw;
+ double t_vm_us;
+ double t_r0_us;
+ double dst_y_per_vm_vblank;
+ double dst_y_per_row_vblank;
+ double min_dst_y_per_vm_vblank;
+ double min_dst_y_per_row_vblank;
+ double lsw;
+ double vratio_pre_l;
+ double vratio_pre_c;
+ unsigned int req_per_swath_ub_l;
+ unsigned int req_per_swath_ub_c;
+ unsigned int meta_row_height_l;
+ unsigned int swath_width_pixels_ub_l;
+ unsigned int swath_width_pixels_ub_c;
+ unsigned int scaler_rec_in_width_l;
+ unsigned int scaler_rec_in_width_c;
+ unsigned int dpte_row_height_l;
+ unsigned int dpte_row_height_c;
+ double hscale_pixel_rate_l;
+ double hscale_pixel_rate_c;
+ double min_hratio_fact_l;
+ double min_hratio_fact_c;
+ double refcyc_per_line_delivery_pre_l;
+ double refcyc_per_line_delivery_pre_c;
+ double refcyc_per_line_delivery_l;
+ double refcyc_per_line_delivery_c;
+ double refcyc_per_req_delivery_pre_l;
+ double refcyc_per_req_delivery_pre_c;
+ double refcyc_per_req_delivery_l;
+ double refcyc_per_req_delivery_c;
+ double refcyc_per_req_delivery_pre_cur0;
+ double refcyc_per_req_delivery_cur0;
+ unsigned int full_recout_width;
+ double hratios_cur0;
+ unsigned int cur0_src_width;
+ enum cursor_bpp cur0_bpp;
+ unsigned int cur0_req_size;
+ unsigned int cur0_req_width;
+ double cur0_width_ub;
+ double cur0_req_per_width;
+ double hactive_cur0;
+
+ memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
+ memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
+
+ DTRACE("DLG: %s: cstate_en = %d", __func__, cstate_en);
+ DTRACE("DLG: %s: pstate_en = %d", __func__, pstate_en);
+ DTRACE("DLG: %s: vm_en = %d", __func__, vm_en);
+ DTRACE("DLG: %s: iflip_en = %d", __func__, iflip_en);
+
+ /* ------------------------- */
+ /* Section 1.5.2.1: OTG dependent Params */
+ /* ------------------------- */
+ DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__, dppclk_freq_in_mhz);
+ DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__, dispclk_freq_in_mhz);
+ DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__, refclk_freq_in_mhz);
+ DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__, pclk_freq_in_mhz);
+ DTRACE("DLG: %s: interlaced = %d", __func__, interlaced);
+
+ ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
+ ASSERT(ref_freq_to_pix_freq < 4.0);
+ disp_dlg_regs->ref_freq_to_pix_freq =
+ (unsigned int) (ref_freq_to_pix_freq * dml_pow(2, 19));
+ disp_dlg_regs->refcyc_per_htotal = (unsigned int) (ref_freq_to_pix_freq * (double) htotal
+ * dml_pow(2, 8));
+ disp_dlg_regs->refcyc_h_blank_end = (unsigned int) ((double) hblank_end
+ * (double) ref_freq_to_pix_freq);
+ ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13));
+ disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */
+
+ prefetch_xy_calc_in_dcfclk = 24.0; /* FIXME: ip_param */
+ min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
+ t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz;
+ min_ttu_vblank = dlg_sys_param.t_urg_wm_us;
+ if (cstate_en)
+ min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank);
+ if (pstate_en)
+ min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank);
+ min_ttu_vblank = min_ttu_vblank + t_calc_us;
+
+ min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal;
+ dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
+
+ disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start
+ + min_dst_y_ttu_vblank) * dml_pow(2, 2));
+ ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18));
+
+ DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__, min_dcfclk_mhz);
+ DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__, min_ttu_vblank);
+ DTRACE(
+ "DLG: %s: min_dst_y_ttu_vblank = %3.2f",
+ __func__,
+ min_dst_y_ttu_vblank);
+ DTRACE("DLG: %s: t_calc_us = %3.2f", __func__, t_calc_us);
+ DTRACE(
+ "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x",
+ __func__,
+ disp_dlg_regs->min_dst_y_next_start);
+ DTRACE(
+ "DLG: %s: ref_freq_to_pix_freq = %3.2f",
+ __func__,
+ ref_freq_to_pix_freq);
+
+ /* ------------------------- */
+ /* Section 1.5.2.2: Prefetch, Active and TTU */
+ /* ------------------------- */
+ /* Prefetch Calc */
+ /* Source */
+ dcc_en = e2e_pipe_param.pipe.src.dcc;
+ dual_plane = is_dual_plane(
+ (enum source_format_class) e2e_pipe_param.pipe.src.source_format);
+ mode_422 = 0; /* FIXME */
+ access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */
+ bytes_per_element_l = get_bytes_per_element(
+ (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
+ 0);
+ bytes_per_element_c = get_bytes_per_element(
+ (enum source_format_class) e2e_pipe_param.pipe.src.source_format,
+ 1);
+ vp_height_l = e2e_pipe_param.pipe.src.viewport_height;
+ vp_width_l = e2e_pipe_param.pipe.src.viewport_width;
+ vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c;
+ vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c;
+
+ /* Scaling */
+ htaps_l = e2e_pipe_param.pipe.scale_taps.htaps;
+ htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c;
+ hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
+ hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c;
+ vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio;
+ vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c;
+
+ line_time_in_us = (htotal / pclk_freq_in_mhz);
+ vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit;
+ vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c;
+ vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot;
+ vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c;
+
+ swath_height_l = rq_dlg_param.rq_l.swath_height;
+ swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
+ dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
+ dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
+ meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
+ meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
+
+ swath_height_c = rq_dlg_param.rq_c.swath_height;
+ swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
+ dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
+ dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
+
+ meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
+ vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset;
+ vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width;
+ vready_offset = e2e_pipe_param.pipe.dest.vready_offset;
+
+ dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
+ dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
+ pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
+ + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
+
+ vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start;
+
+ if (interlaced)
+ vstartup_start = vstartup_start / 2;
+
+ if (vstartup_start >= min_vblank) {
+ DTRACE(
+ "WARNING_DLG: %s: vblank_start=%d vblank_end=%d",
+ __func__,
+ vblank_start,
+ vblank_end);
+ DTRACE(
+ "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
+ __func__,
+ vstartup_start,
+ min_vblank);
+ min_vblank = vstartup_start + 1;
+ DTRACE(
+ "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
+ __func__,
+ vstartup_start,
+ min_vblank);
+ }
+
+ dst_x_after_scaler = 0;
+ dst_y_after_scaler = 0;
+
+ if (e2e_pipe_param.pipe.src.is_hsplit)
+ dst_x_after_scaler = pixel_rate_delay_subtotal
+ + e2e_pipe_param.pipe.dest.recout_width;
+ else
+ dst_x_after_scaler = pixel_rate_delay_subtotal;
+
+ if (e2e_pipe_param.dout.output_format == dm_420)
+ dst_y_after_scaler = 1;
+ else
+ dst_y_after_scaler = 0;
+
+ if (dst_x_after_scaler >= htotal) {
+ dst_x_after_scaler = dst_x_after_scaler - htotal;
+ dst_y_after_scaler = dst_y_after_scaler + 1;
+ }
+
+ DTRACE("DLG: %s: htotal = %d", __func__, htotal);
+ DTRACE(
+ "DLG: %s: pixel_rate_delay_subtotal = %d",
+ __func__,
+ pixel_rate_delay_subtotal);
+ DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__, dst_x_after_scaler);
+ DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__, dst_y_after_scaler);
+
+ line_wait = mode_lib->soc.urgent_latency_us;
+ if (cstate_en)
+ line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
+ if (pstate_en)
+ line_wait = dml_max(
+ mode_lib->soc.dram_clock_change_latency_us
+ + mode_lib->soc.urgent_latency_us,
+ line_wait);
+ line_wait = line_wait / line_time_in_us;
+
+ line_o = (double) dst_y_after_scaler + dst_x_after_scaler / (double) htotal;
+ line_setup = (double) (vupdate_offset + vupdate_width + vready_offset) / (double) htotal;
+ line_calc = t_calc_us / line_time_in_us;
+
+ DTRACE(
+ "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f",
+ __func__,
+ (double) mode_lib->soc.sr_enter_plus_exit_time_us);
+ DTRACE(
+ "DLG: %s: soc.dram_clock_change_latency_us = %3.2f",
+ __func__,
+ (double) mode_lib->soc.dram_clock_change_latency_us);
+ DTRACE(
+ "DLG: %s: soc.urgent_latency_us = %3.2f",
+ __func__,
+ mode_lib->soc.urgent_latency_us);
+
+ DTRACE("DLG: %s: swath_height_l = %d", __func__, swath_height_l);
+ if (dual_plane)
+ DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c);
+
+ DTRACE(
+ "DLG: %s: t_srx_delay_us = %3.2f",
+ __func__,
+ (double) dlg_sys_param.t_srx_delay_us);
+ DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us);
+ DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset);
+ DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width);
+ DTRACE("DLG: %s: vready_offset = %d", __func__, vready_offset);
+ DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, line_time_in_us);
+ DTRACE("DLG: %s: line_wait = %3.2f", __func__, line_wait);
+ DTRACE("DLG: %s: line_o = %3.2f", __func__, line_o);
+ DTRACE("DLG: %s: line_setup = %3.2f", __func__, line_setup);
+ DTRACE("DLG: %s: line_calc = %3.2f", __func__, line_calc);
+
+ dst_y_prefetch = ((double) min_vblank - 1.0)
+ - (line_setup + line_calc + line_wait + line_o);
+ DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__, dst_y_prefetch);
+ ASSERT(dst_y_prefetch >= 2.0);
+
+ dst_y_prefetch = dml_floor(4.0 * (dst_y_prefetch + 0.125), 1) / 4;
+ DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__, dst_y_prefetch);
+
+ t_pre_us = dst_y_prefetch * line_time_in_us;
+ vm_bytes = 0;
+ meta_row_bytes = 0;
+
+ if (dcc_en && vm_en)
+ vm_bytes = meta_pte_bytes_per_frame_ub_l;
+ if (dcc_en)
+ meta_row_bytes = meta_bytes_per_row_ub_l;
+
+ max_num_sw_l = 0;
+ max_num_sw_c = 0;
+ max_partial_sw_l = 0;
+ max_partial_sw_c = 0;
+
+ max_vinit_l = interlaced ? dml_max(vinit_l, vinit_bot_l) : vinit_l;
+ max_vinit_c = interlaced ? dml_max(vinit_c, vinit_bot_c) : vinit_c;
+
+ get_swath_need(mode_lib, &max_num_sw_l, &max_partial_sw_l, swath_height_l, max_vinit_l);
+ if (dual_plane)
+ get_swath_need(
+ mode_lib,
+ &max_num_sw_c,
+ &max_partial_sw_c,
+ swath_height_c,
+ max_vinit_c);
+
+ lsw_l = max_num_sw_l * swath_height_l + max_partial_sw_l;
+ lsw_c = max_num_sw_c * swath_height_c + max_partial_sw_c;
+ sw_bytes_ub_l = lsw_l * swath_width_ub_l * bytes_per_element_l;
+ sw_bytes_ub_c = lsw_c * swath_width_ub_c * bytes_per_element_c;
+ sw_bytes = 0;
+ dpte_row_bytes = 0;
+
+ if (vm_en) {
+ if (dual_plane)
+ dpte_row_bytes = dpte_bytes_per_row_ub_l + dpte_bytes_per_row_ub_c;
+ else
+ dpte_row_bytes = dpte_bytes_per_row_ub_l;
+ } else {
+ dpte_row_bytes = 0;
+ }
+
+ if (dual_plane)
+ sw_bytes = sw_bytes_ub_l + sw_bytes_ub_c;
+ else
+ sw_bytes = sw_bytes_ub_l;
+
+ DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__, sw_bytes_ub_l);
+ DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__, sw_bytes_ub_c);
+ DTRACE("DLG: %s: sw_bytes = %d", __func__, sw_bytes);
+ DTRACE("DLG: %s: vm_bytes = %d", __func__, vm_bytes);
+ DTRACE("DLG: %s: meta_row_bytes = %d", __func__, meta_row_bytes);
+ DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes);
+
+ prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us;
+ flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw)
+ / (double) dlg_sys_param.total_flip_bytes;
+ t_vm_us = line_time_in_us / 4.0;
+ if (vm_en && dcc_en) {
+ t_vm_us = dml_max(
+ dlg_sys_param.t_extra_us,
+ dml_max((double) vm_bytes / prefetch_bw, t_vm_us));
+
+ if (iflip_en && !dual_plane) {
+ t_vm_us = dml_max(mode_lib->soc.urgent_latency_us, t_vm_us);
+ if (flip_bw > 0.)
+ t_vm_us = dml_max(vm_bytes / flip_bw, t_vm_us);
+ }
+ }
+
+ t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us);
+
+ if (vm_en || dcc_en) {
+ t_r0_us = dml_max(
+ (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw,
+ dlg_sys_param.t_extra_us);
+ t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us);
+
+ if (iflip_en && !dual_plane) {
+ t_r0_us = dml_max(mode_lib->soc.urgent_latency_us * 2.0, t_r0_us);
+ if (flip_bw > 0.)
+ t_r0_us = dml_max(
+ (dpte_row_bytes + meta_row_bytes) / flip_bw,
+ t_r0_us);
+ }
+ }
+
+ disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; /* in terms of line */
+ disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; /* in terms of refclk */
+ ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
+ DTRACE(
+ "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x",
+ __func__,
+ disp_dlg_regs->dst_y_after_scaler);
+ DTRACE(
+ "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x",
+ __func__,
+ disp_dlg_regs->refcyc_x_after_scaler);
+
+ disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
+ DTRACE(
+ "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d",
+ __func__,
+ disp_dlg_regs->dst_y_prefetch);
+
+ dst_y_per_vm_vblank = 0.0;
+ dst_y_per_row_vblank = 0.0;
+
+ dst_y_per_vm_vblank = t_vm_us / line_time_in_us;
+ dst_y_per_vm_vblank = dml_floor(4.0 * (dst_y_per_vm_vblank + 0.125), 1) / 4.0;
+ disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
+
+ dst_y_per_row_vblank = t_r0_us / line_time_in_us;
+ dst_y_per_row_vblank = dml_floor(4.0 * (dst_y_per_row_vblank + 0.125), 1) / 4.0;
+ disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
+
+ DTRACE("DLG: %s: lsw_l = %d", __func__, lsw_l);
+ DTRACE("DLG: %s: lsw_c = %d", __func__, lsw_c);
+ DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__, dpte_bytes_per_row_ub_l);
+ DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__, dpte_bytes_per_row_ub_c);
+
+ DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__, prefetch_bw);
+ DTRACE("DLG: %s: flip_bw = %3.2f", __func__, flip_bw);
+ DTRACE("DLG: %s: t_pre_us = %3.2f", __func__, t_pre_us);
+ DTRACE("DLG: %s: t_vm_us = %3.2f", __func__, t_vm_us);
+ DTRACE("DLG: %s: t_r0_us = %3.2f", __func__, t_r0_us);
+ DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__, dst_y_per_vm_vblank);
+ DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__, dst_y_per_row_vblank);
+ DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__, dst_y_prefetch);
+
+ min_dst_y_per_vm_vblank = 8.0;
+ min_dst_y_per_row_vblank = 16.0;
+ if (htotal <= 75) {
+ min_vblank = 300;
+ min_dst_y_per_vm_vblank = 100.0;
+ min_dst_y_per_row_vblank = 100.0;
+ }
+
+ ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
+ ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
+
+ ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
+ lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
+
+ DTRACE("DLG: %s: lsw = %3.2f", __func__, lsw);
+
+ vratio_pre_l = get_vratio_pre(
+ mode_lib,
+ max_num_sw_l,
+ max_partial_sw_l,
+ swath_height_l,
+ max_vinit_l,
+ lsw);
+ vratio_pre_c = 1.0;
+ if (dual_plane)
+ vratio_pre_c = get_vratio_pre(
+ mode_lib,
+ max_num_sw_c,
+ max_partial_sw_c,
+ swath_height_c,
+ max_vinit_c,
+ lsw);
+
+ DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__, vratio_pre_l);
+ DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__, vratio_pre_c);
+
+ ASSERT(vratio_pre_l <= 4.0);
+ if (vratio_pre_l >= 4.0)
+ disp_dlg_regs->vratio_prefetch = (unsigned int) dml_pow(2, 21) - 1;
+ else
+ disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
+
+ ASSERT(vratio_pre_c <= 4.0);
+ if (vratio_pre_c >= 4.0)
+ disp_dlg_regs->vratio_prefetch_c = (unsigned int) dml_pow(2, 21) - 1;
+ else
+ disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
+
+ disp_dlg_regs->refcyc_per_pte_group_vblank_l =
+ (unsigned int) (dst_y_per_row_vblank * (double) htotal
+ * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
+ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
+
+ disp_dlg_regs->refcyc_per_pte_group_vblank_c =
+ (unsigned int) (dst_y_per_row_vblank * (double) htotal
+ * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_c);
+ ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c < (unsigned int) dml_pow(2, 13));
+
+ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
+ (unsigned int) (dst_y_per_row_vblank * (double) htotal
+ * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
+ ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
+
+ disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
+ disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */
+
+ /* Active */
+ req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
+ req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
+ meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
+ swath_width_pixels_ub_l = 0;
+ swath_width_pixels_ub_c = 0;
+ scaler_rec_in_width_l = 0;
+ scaler_rec_in_width_c = 0;
+ dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
+ dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
+
+ disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
+ / (double) vratio_l * dml_pow(2, 2));
+ ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
+
+ disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
+ / (double) vratio_c * dml_pow(2, 2));
+ ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_c < (unsigned int) dml_pow(2, 17));
+
+ disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
+ / (double) vratio_l * dml_pow(2, 2));
+ ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
+
+ disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */
+
+ disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
+ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+ / (double) dpte_groups_per_row_ub_l);
+ if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
+
+ disp_dlg_regs->refcyc_per_pte_group_nom_c = (unsigned int) ((double) dpte_row_height_c
+ / (double) vratio_c * (double) htotal * ref_freq_to_pix_freq
+ / (double) dpte_groups_per_row_ub_c);
+ if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
+
+ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
+ / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
+ / (double) meta_chunks_per_row_ub_l);
+ if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
+ disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
+
+ if (mode_422) {
+ swath_width_pixels_ub_l = swath_width_ub_l * 2; /* *2 for 2 pixel per element */
+ swath_width_pixels_ub_c = swath_width_ub_c * 2;
+ } else {
+ swath_width_pixels_ub_l = swath_width_ub_l * 1;
+ swath_width_pixels_ub_c = swath_width_ub_c * 1;
+ }
+
+ hscale_pixel_rate_l = 0.;
+ hscale_pixel_rate_c = 0.;
+ min_hratio_fact_l = 1.0;
+ min_hratio_fact_c = 1.0;
+
+ if (htaps_l <= 1)
+ min_hratio_fact_l = 2.0;
+ else if (htaps_l <= 6) {
+ if ((hratios_l * 2.0) > 4.0)
+ min_hratio_fact_l = 4.0;
+ else
+ min_hratio_fact_l = hratios_l * 2.0;
+ } else {
+ if (hratios_l > 4.0)
+ min_hratio_fact_l = 4.0;
+ else
+ min_hratio_fact_l = hratios_l;
+ }
+
+ hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
+
+ if (htaps_c <= 1)
+ min_hratio_fact_c = 2.0;
+ else if (htaps_c <= 6) {
+ if ((hratios_c * 2.0) > 4.0)
+ min_hratio_fact_c = 4.0;
+ else
+ min_hratio_fact_c = hratios_c * 2.0;
+ } else {
+ if (hratios_c > 4.0)
+ min_hratio_fact_c = 4.0;
+ else
+ min_hratio_fact_c = hratios_c;
+ }
+
+ hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
+
+ refcyc_per_line_delivery_pre_l = 0.;
+ refcyc_per_line_delivery_pre_c = 0.;
+ refcyc_per_line_delivery_l = 0.;
+ refcyc_per_line_delivery_c = 0.;
+
+ refcyc_per_req_delivery_pre_l = 0.;
+ refcyc_per_req_delivery_pre_c = 0.;
+ refcyc_per_req_delivery_l = 0.;
+ refcyc_per_req_delivery_c = 0.;
+ refcyc_per_req_delivery_pre_cur0 = 0.;
+ refcyc_per_req_delivery_cur0 = 0.;
+
+ full_recout_width = 0;
+ if (e2e_pipe_param.pipe.src.is_hsplit) {
+ if (e2e_pipe_param.pipe.dest.full_recout_width == 0) {
+ DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__);
+ full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */
+ } else
+ full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width;
+ } else
+ full_recout_width = e2e_pipe_param.pipe.dest.recout_width;
+
+ refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_pre_l,
+ hscale_pixel_rate_l,
+ swath_width_pixels_ub_l,
+ 1); /* per line */
+
+ refcyc_per_line_delivery_l = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_l,
+ hscale_pixel_rate_l,
+ swath_width_pixels_ub_l,
+ 1); /* per line */
+
+ DTRACE("DLG: %s: full_recout_width = %d", __func__, full_recout_width);
+ DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__, hscale_pixel_rate_l);
+ DTRACE(
+ "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f",
+ __func__,
+ refcyc_per_line_delivery_pre_l);
+ DTRACE(
+ "DLG: %s: refcyc_per_line_delivery_l = %3.2f",
+ __func__,
+ refcyc_per_line_delivery_l);
+
+ disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(
+ refcyc_per_line_delivery_pre_l,
+ 1);
+ disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(
+ refcyc_per_line_delivery_l,
+ 1);
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
+
+ if (dual_plane) {
+ refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_pre_c,
+ hscale_pixel_rate_c,
+ swath_width_pixels_ub_c,
+ 1); /* per line */
+
+ refcyc_per_line_delivery_c = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_c,
+ hscale_pixel_rate_c,
+ swath_width_pixels_ub_c,
+ 1); /* per line */
+
+ DTRACE(
+ "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
+ __func__,
+ refcyc_per_line_delivery_pre_c);
+ DTRACE(
+ "DLG: %s: refcyc_per_line_delivery_c = %3.2f",
+ __func__,
+ refcyc_per_line_delivery_c);
+
+ disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(
+ refcyc_per_line_delivery_pre_c,
+ 1);
+ disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(
+ refcyc_per_line_delivery_c,
+ 1);
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
+ ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
+ }
+ disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
+
+ /* TTU - Luma / Chroma */
+ if (access_dir) { /* vertical access */
+ scaler_rec_in_width_l = vp_height_l;
+ scaler_rec_in_width_c = vp_height_c;
+ } else {
+ scaler_rec_in_width_l = vp_width_l;
+ scaler_rec_in_width_c = vp_width_c;
+ }
+
+ refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_pre_l,
+ hscale_pixel_rate_l,
+ scaler_rec_in_width_l,
+ req_per_swath_ub_l); /* per req */
+ refcyc_per_req_delivery_l = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_l,
+ hscale_pixel_rate_l,
+ scaler_rec_in_width_l,
+ req_per_swath_ub_l); /* per req */
+
+ DTRACE(
+ "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
+ __func__,
+ refcyc_per_req_delivery_pre_l);
+ DTRACE(
+ "DLG: %s: refcyc_per_req_delivery_l = %3.2f",
+ __func__,
+ refcyc_per_req_delivery_l);
+
+ disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
+ * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
+ * dml_pow(2, 10));
+
+ ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
+ ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
+
+ if (dual_plane) {
+ refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_pre_c,
+ hscale_pixel_rate_c,
+ scaler_rec_in_width_c,
+ req_per_swath_ub_c); /* per req */
+ refcyc_per_req_delivery_c = get_refcyc_per_delivery(
+ mode_lib,
+ refclk_freq_in_mhz,
+ pclk_freq_in_mhz,
+ full_recout_width,
+ vratio_c,
+ hscale_pixel_rate_c,
+ scaler_rec_in_width_c,
+ req_per_swath_ub_c); /* per req */
+
+ DTRACE(
+ "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
+ __func__,
+ refcyc_per_req_delivery_pre_c);
+ DTRACE(
+ "DLG: %s: refcyc_per_req_delivery_c = %3.2f",
+ __func__,
+ refcyc_per_req_delivery_c);
+
+ disp_ttu_regs->refcyc_per_req_delivery_pre_c =
+ (unsigned int) (refcyc_per_req_delivery_pre_c * dml_pow(2, 10));
+ disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
+ * dml_pow(2, 10));
+
+ ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
+ ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
+ }
+
+ /* TTU - Cursor */
+ hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio;
+ cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */
+ cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp;
+ cur0_req_size = 0;
+ cur0_req_width = 0;
+ cur0_width_ub = 0.0;
+ cur0_req_per_width = 0.0;
+ hactive_cur0 = 0.0;
+
+ ASSERT(cur0_src_width <= 256);
+
+ if (cur0_src_width > 0) {
+ unsigned int cur0_bit_per_pixel = 0;
+
+ if (cur0_bpp == dm_cur_2bit) {
+ cur0_req_size = 64; /* byte */
+ cur0_bit_per_pixel = 2;
+ } else { /* 32bit */
+ cur0_bit_per_pixel = 32;
+ if (cur0_src_width >= 1 && cur0_src_width <= 16)
+ cur0_req_size = 64;
+ else if (cur0_src_width >= 17 && cur0_src_width <= 31)
+ cur0_req_size = 128;
+ else
+ cur0_req_size = 256;
+ }
+
+ cur0_req_width = (double) cur0_req_size / ((double) cur0_bit_per_pixel / 8.0);
+ cur0_width_ub = dml_ceil((double) cur0_src_width / (double) cur0_req_width, 1)
+ * (double) cur0_req_width;
+ cur0_req_per_width = cur0_width_ub / (double) cur0_req_width;
+ hactive_cur0 = (double) cur0_src_width / hratios_cur0; /* FIXME: oswin to think about what to do for cursor */
+
+ if (vratio_pre_l <= 1.0) {
+ refcyc_per_req_delivery_pre_cur0 = hactive_cur0 * ref_freq_to_pix_freq
+ / (double) cur0_req_per_width;
+ } else {
+ refcyc_per_req_delivery_pre_cur0 = (double) refclk_freq_in_mhz
+ * (double) cur0_src_width / hscale_pixel_rate_l
+ / (double) cur0_req_per_width;
+ }
+
+ disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
+ (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
+ ASSERT(refcyc_per_req_delivery_pre_cur0 < dml_pow(2, 13));
+
+ if (vratio_l <= 1.0) {
+ refcyc_per_req_delivery_cur0 = hactive_cur0 * ref_freq_to_pix_freq
+ / (double) cur0_req_per_width;
+ } else {
+ refcyc_per_req_delivery_cur0 = (double) refclk_freq_in_mhz
+ * (double) cur0_src_width / hscale_pixel_rate_l
+ / (double) cur0_req_per_width;
+ }
+
+ DTRACE("DLG: %s: cur0_req_width = %d", __func__, cur0_req_width);
+ DTRACE(
+ "DLG: %s: cur0_width_ub = %3.2f",
+ __func__,
+ cur0_width_ub);
+ DTRACE(
+ "DLG: %s: cur0_req_per_width = %3.2f",
+ __func__,
+ cur0_req_per_width);
+ DTRACE(
+ "DLG: %s: hactive_cur0 = %3.2f",
+ __func__,
+ hactive_cur0);
+ DTRACE(
+ "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f",
+ __func__,
+ refcyc_per_req_delivery_pre_cur0);
+ DTRACE(
+ "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f",
+ __func__,
+ refcyc_per_req_delivery_cur0);
+
+ disp_ttu_regs->refcyc_per_req_delivery_cur0 =
+ (unsigned int) (refcyc_per_req_delivery_cur0 * dml_pow(2, 10));
+ ASSERT(refcyc_per_req_delivery_cur0 < dml_pow(2, 13));
+ } else {
+ disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 = 0;
+ disp_ttu_regs->refcyc_per_req_delivery_cur0 = 0;
+ }
+
+ /* TTU - Misc */
+ disp_ttu_regs->qos_level_low_wm = 0;
+ ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
+ disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
+ * ref_freq_to_pix_freq);
+ ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14));
+
+ disp_ttu_regs->qos_level_flip = 14;
+ disp_ttu_regs->qos_level_fixed_l = 8;
+ disp_ttu_regs->qos_level_fixed_c = 8;
+ disp_ttu_regs->qos_level_fixed_cur0 = 8;
+ disp_ttu_regs->qos_ramp_disable_l = 0;
+ disp_ttu_regs->qos_ramp_disable_c = 0;
+ disp_ttu_regs->qos_ramp_disable_cur0 = 0;
+
+ disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz;
+ ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24));
+
+ print__ttu_regs_st(mode_lib, *disp_ttu_regs);
+ print__dlg_regs_st(mode_lib, *disp_dlg_regs);
+}
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 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DISPLAY_RQ_DLG_CALC_H__
+#define __DISPLAY_RQ_DLG_CALC_H__
+
+#include "dml_common_defs.h"
+#include "display_rq_dlg_helpers.h"
+
+struct display_mode_lib;
+
+void dml1_extract_rq_regs(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_rq_regs_st *rq_regs,
+ const struct _vcs_dpi_display_rq_params_st rq_param);
+/* Function: dml_rq_dlg_get_rq_params
+ * Calculate requestor related parameters that register definition agnostic
+ * (i.e. this layer does try to separate real values from register definition)
+ * Input:
+ * pipe_src_param - pipe source configuration (e.g. vp, pitch, etc.)
+ * Output:
+ * rq_param - values that can be used to setup RQ (e.g. swath_height, plane1_addr, etc.)
+ */
+void dml1_rq_dlg_get_rq_params(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_rq_params_st *rq_param,
+ const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param);
+
+
+/* Function: dml_rq_dlg_get_dlg_params
+ * Calculate deadline related parameters
+ */
+void dml1_rq_dlg_get_dlg_params(
+ struct display_mode_lib *mode_lib,
+ struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
+ struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
+ const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param,
+ const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param,
+ const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param,
+ const bool cstate_en,
+ const bool pstate_en,
+ const bool vm_en,
+ const bool iflip_en);
+
+#endif
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 @@
#include "../calcs/dcn_calc_math.h"
#include "dml_inline_defs.h"
+
double dml_round(double a)
{
double round_pt = 0.5;
- double ceil = dml_ceil(a);
- double floor = dml_floor(a);
+ double ceil = dml_ceil(a, 1);
+ double floor = dml_floor(a, 1);
if (a - floor >= round_pt)
return ceil;
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 @@
* Authors: AMD
*
*/
+
#ifndef __DC_COMMON_DEFS_H__
#define __DC_COMMON_DEFS_H__
@@ -30,7 +31,8 @@
#include "display_mode_structs.h"
#include "display_mode_enums.h"
-#define DTRACE(str, ...) dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__);
+#define dml_print(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
+#define DTRACE(str, ...) {dm_logger_write(mode_lib->logger, LOG_DML, str, ##__VA_ARGS__); }
double dml_round(double a);
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 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
#ifndef __DML_INLINE_DEFS_H__
#define __DML_INLINE_DEFS_H__
+
#include "dml_common_defs.h"
#include "../calcs/dcn_calc_math.h"
@@ -13,14 +39,29 @@ static inline double dml_max(double a, double b)
return (double) dcn_bw_max2(a, b);
}
-static inline double dml_ceil(double a)
+static inline double dml_max3(double a, double b, double c)
+{
+ return dml_max(dml_max(a, b), c);
+}
+
+static inline double dml_max4(double a, double b, double c, double d)
+{
+ return dml_max(dml_max(a, b), dml_max(c, d));
+}
+
+static inline double dml_max5(double a, double b, double c, double d, double e)
+{
+ return dml_max(dml_max4(a, b, c, d), e);
+}
+
+static inline double dml_ceil(double a, double granularity)
{
- return (double) dcn_bw_ceil2(a, 1);
+ return (double) dcn_bw_ceil2(a, granularity);
}
-static inline double dml_floor(double a)
+static inline double dml_floor(double a, double granularity)
{
- return (double) dcn_bw_floor2(a, 1);
+ return (double) dcn_bw_floor2(a, granularity);
}
static inline int dml_log2(double x)
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 @@
*/
#include "soc_bounding_box.h"
#include "display_mode_lib.h"
+#include "dc_features.h"
#include "dml_inline_defs.h"
-void dml_socbb_set_latencies(
- struct display_mode_lib *mode_lib,
- struct _vcs_dpi_soc_bounding_box_st *from_box)
+void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box)
{
- struct _vcs_dpi_soc_bounding_box_st *to_box = &mode_lib->soc;
-
to_box->dram_clock_change_latency_us = from_box->dram_clock_change_latency_us;
to_box->sr_exit_time_us = from_box->sr_exit_time_us;
to_box->sr_enter_plus_exit_time_us = from_box->sr_enter_plus_exit_time_us;
to_box->urgent_latency_us = from_box->urgent_latency_us;
to_box->writeback_latency_us = from_box->writeback_latency_us;
- DTRACE("box.dram_clock_change_latency_us: %f", from_box->dram_clock_change_latency_us);
- DTRACE("box.sr_exit_time_us: %f", from_box->sr_exit_time_us);
- DTRACE("box.sr_enter_plus_exit_time_us: %f", from_box->sr_enter_plus_exit_time_us);
- DTRACE("box.urgent_latency_us: %f", from_box->urgent_latency_us);
- DTRACE("box.writeback_latency_us: %f", from_box->writeback_latency_us);
-
}
-struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(
- struct _vcs_dpi_soc_bounding_box_st *box,
+voltage_scaling_st dml_socbb_voltage_scaling(
+ const soc_bounding_box_st *soc,
enum voltage_state voltage)
{
- switch (voltage) {
- case dm_vmin:
- return box->vmin;
- case dm_vnom:
- return box->vnom;
- case dm_vmax:
- default:
- return box->vmax;
+ const voltage_scaling_st *voltage_state;
+ const voltage_scaling_st * const voltage_end = soc->clock_limits + DC__VOLTAGE_STATES;
+
+ for (voltage_state = soc->clock_limits;
+ voltage_state < voltage_end && voltage_state->state != voltage;
+ voltage_state++) {
}
+
+ if (voltage_state < voltage_end)
+ return *voltage_state;
+ return soc->clock_limits[DC__VOLTAGE_STATES - 1];
}
-double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage)
+double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage)
{
double return_bw;
- struct _vcs_dpi_voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
+ voltage_scaling_st state = dml_socbb_voltage_scaling(box, voltage);
- return_bw = dml_min(
- ((double) box->return_bus_width_bytes) * state.dcfclk_mhz,
+ return_bw = dml_min((double) box->return_bus_width_bytes * state.dcfclk_mhz,
state.dram_bw_per_chan_gbps * 1000.0 * (double) box->num_chans
* box->ideal_dram_bw_after_urgent_percent / 100.0);
+
+ return_bw = dml_min((double) box->return_bus_width_bytes * state.fabricclk_mhz, return_bw);
+
return return_bw;
}
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 @@
* Authors: AMD
*
*/
+
#ifndef __SOC_BOUNDING_BOX_H__
#define __SOC_BOUNDING_BOX_H__
#include "dml_common_defs.h"
-struct display_mode_lib;
-
-void dml_socbb_set_latencies(struct display_mode_lib *mode_lib, struct _vcs_dpi_soc_bounding_box_st *from_box);
-struct _vcs_dpi_voltage_scaling_st dml_socbb_voltage_scaling(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
-double dml_socbb_return_bw_mhz(struct _vcs_dpi_soc_bounding_box_st *box, enum voltage_state voltage);
+void dml_socbb_set_latencies(soc_bounding_box_st *to_box, soc_bounding_box_st *from_box);
+voltage_scaling_st dml_socbb_voltage_scaling(const soc_bounding_box_st *box, enum voltage_state voltage);
+double dml_socbb_return_bw_mhz(soc_bounding_box_st *box, enum voltage_state voltage);
#endif
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:
slot = service->busyness[index_of_id];
- if (slot)
- kfree(slot);
- };
+ kfree(slot);
+ }
failure_1:
kfree(service);
@@ -171,8 +170,7 @@ void dal_gpio_service_destroy(
do {
uint32_t *slot = (*ptr)->busyness[index_of_id];
- if (slot)
- kfree(slot);
+ kfree(slot);
++index_of_id;
} while (index_of_id < GPIO_ID_COUNT);
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 {
DC_FAIL_CONTROLLER_VALIDATE = 5,
DC_FAIL_ENC_VALIDATE = 6,
DC_FAIL_ATTACH_SURFACES = 7,
- DC_FAIL_SURFACE_VALIDATE = 8,
- DC_NO_DP_LINK_BANDWIDTH = 9,
- DC_EXCEED_DONGLE_MAX_CLK = 10,
- DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 11,
- DC_FAIL_BANDWIDTH_VALIDATE = 12, /* BW and Watermark validation */
- DC_FAIL_SCALING = 13,
- DC_FAIL_DP_LINK_TRAINING = 14,
+ DC_FAIL_DETACH_SURFACES = 8,
+ DC_FAIL_SURFACE_VALIDATE = 9,
+ DC_NO_DP_LINK_BANDWIDTH = 10,
+ DC_EXCEED_DONGLE_MAX_CLK = 11,
+ DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED = 12,
+ DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */
+ DC_FAIL_SCALING = 14,
+ DC_FAIL_DP_LINK_TRAINING = 15,
DC_ERROR_UNEXPECTED = -1
};
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 @@
#include "ddc_service_types.h"
#include "dc_bios_types.h"
#include "mem_input.h"
+#include "hubp.h"
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
#include "mpc.h"
#endif
@@ -58,6 +59,11 @@ struct link_init_data {
TODO: remove it when DC is complete. */
};
+enum {
+ FREE_ACQUIRED_RESOURCE = 0,
+ KEEP_ACQUIRED_RESOURCE = 1,
+};
+
struct dc_link *link_create(const struct link_init_data *init_params);
void link_destroy(struct dc_link **link);
@@ -72,12 +78,13 @@ void core_link_enable_stream(
struct dc_state *state,
struct pipe_ctx *pipe_ctx);
-void core_link_disable_stream(struct pipe_ctx *pipe_ctx);
+void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option);
void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
/********** DAL Core*********************/
#include "display_clock.h"
#include "transform.h"
+#include "dpp.h"
struct resource_pool;
struct dc_state;
@@ -106,7 +113,7 @@ struct resource_funcs {
const struct resource_pool *pool,
struct dc_stream_state *stream);
- enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state);
+ enum dc_status (*validate_plane)(const struct dc_plane_state *plane_state, struct dc_caps *caps);
enum dc_status (*add_stream_to_ctx)(
struct dc *dc,
@@ -124,8 +131,10 @@ struct audio_support{
struct resource_pool {
struct mem_input *mis[MAX_PIPES];
+ struct hubp *hubps[MAX_PIPES];
struct input_pixel_processor *ipps[MAX_PIPES];
struct transform *transforms[MAX_PIPES];
+ struct dpp *dpps[MAX_PIPES];
struct output_pixel_processor *opps[MAX_PIPES];
struct timing_generator *timing_generators[MAX_PIPES];
struct stream_encoder *stream_enc[MAX_PIPES * 2];
@@ -173,10 +182,11 @@ struct stream_resource {
struct plane_resource {
struct scaler_data scl_data;
-
+ struct hubp *hubp;
struct mem_input *mi;
struct input_pixel_processor *ipp;
struct transform *xfm;
+ struct dpp *dpp;
};
struct pipe_ctx {
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 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+#ifndef __DAL_DPP_H__
+#define __DAL_DPP_H__
+
+#include "transform.h"
+
+struct dpp {
+ const struct dpp_funcs *funcs;
+ struct dc_context *ctx;
+ int inst;
+ struct dpp_caps *caps;
+ struct pwl_params regamma_params;
+};
+
+struct dpp_grph_csc_adjustment {
+ struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
+ enum graphics_gamut_adjust_type gamut_adjust_type;
+};
+
+struct dpp_funcs {
+ void (*dpp_reset)(struct dpp *dpp);
+
+ void (*dpp_set_scaler)(struct dpp *dpp,
+ const struct scaler_data *scl_data);
+
+ void (*dpp_set_pixel_storage_depth)(
+ struct dpp *dpp,
+ enum lb_pixel_depth depth,
+ const struct bit_depth_reduction_params *bit_depth_params);
+
+ bool (*dpp_get_optimal_number_of_taps)(
+ struct dpp *dpp,
+ struct scaler_data *scl_data,
+ const struct scaling_taps *in_taps);
+
+ void (*dpp_set_gamut_remap)(
+ struct dpp *dpp,
+ const struct dpp_grph_csc_adjustment *adjust);
+
+ void (*opp_set_csc_default)(
+ struct dpp *dpp,
+ const struct default_adjustment *default_adjust);
+
+ void (*opp_set_csc_adjustment)(
+ struct dpp *dpp,
+ const struct out_csc_color_matrix *tbl_entry);
+
+ void (*opp_power_on_regamma_lut)(
+ struct dpp *dpp,
+ bool power_on);
+
+ void (*opp_program_regamma_lut)(
+ struct dpp *dpp,
+ const struct pwl_result_data *rgb,
+ uint32_t num);
+
+ void (*opp_configure_regamma_lut)(
+ struct dpp *dpp,
+ bool is_ram_a);
+
+ void (*opp_program_regamma_lutb_settings)(
+ struct dpp *dpp,
+ const struct pwl_params *params);
+
+ void (*opp_program_regamma_luta_settings)(
+ struct dpp *dpp,
+ const struct pwl_params *params);
+
+ void (*opp_program_regamma_pwl)(
+ struct dpp *dpp, const struct pwl_params *params);
+
+ void (*opp_set_regamma_mode)(
+ struct dpp *dpp_base,
+ enum opp_regamma mode);
+
+ void (*ipp_set_degamma)(
+ struct dpp *dpp_base,
+ enum ipp_degamma_mode mode);
+
+ void (*ipp_program_input_lut)(
+ struct dpp *dpp_base,
+ const struct dc_gamma *gamma);
+
+ void (*ipp_program_degamma_pwl)(struct dpp *dpp_base,
+ const struct pwl_params *params);
+
+ void (*ipp_setup)(
+ struct dpp *dpp_base,
+ enum surface_pixel_format input_format,
+ enum expansion_mode mode);
+
+ void (*ipp_full_bypass)(struct dpp *dpp_base);
+
+ void (*set_cursor_attributes)(
+ struct dpp *dpp_base,
+ const struct dc_cursor_attributes *attr);
+
+ void (*set_cursor_position)(
+ struct dpp *dpp_base,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param,
+ uint32_t width
+ );
+
+};
+
+
+
+#endif
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 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HUBP_H__
+#define __DAL_HUBP_H__
+
+#include "mem_input.h"
+
+struct hubp {
+ struct hubp_funcs *funcs;
+ struct dc_context *ctx;
+ struct dc_plane_address request_address;
+ struct dc_plane_address current_address;
+ int inst;
+ int opp_id;
+ int mpcc_id;
+ struct dc_cursor_attributes curs_attr;
+};
+
+
+struct hubp_funcs {
+ void (*hubp_setup)(
+ struct hubp *hubp,
+ struct _vcs_dpi_display_dlg_regs_st *dlg_regs,
+ struct _vcs_dpi_display_ttu_regs_st *ttu_regs,
+ struct _vcs_dpi_display_rq_regs_st *rq_regs,
+ struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
+
+ void (*dcc_control)(struct hubp *hubp, bool enable,
+ bool independent_64b_blks);
+ void (*mem_program_viewport)(
+ struct hubp *hubp,
+ const struct rect *viewport,
+ const struct rect *viewport_c);
+
+ bool (*hubp_program_surface_flip_and_addr)(
+ struct hubp *hubp,
+ const struct dc_plane_address *address,
+ bool flip_immediate);
+
+ void (*hubp_program_pte_vm)(
+ struct hubp *hubp,
+ enum surface_pixel_format format,
+ union dc_tiling_info *tiling_info,
+ enum dc_rotation_angle rotation);
+
+ void (*hubp_set_vm_system_aperture_settings)(
+ struct hubp *hubp,
+ struct vm_system_aperture_param *apt);
+
+ void (*hubp_set_vm_context0_settings)(
+ struct hubp *hubp,
+ const struct vm_context0_param *vm0);
+
+ void (*hubp_program_surface_config)(
+ struct hubp *hubp,
+ enum surface_pixel_format format,
+ union dc_tiling_info *tiling_info,
+ union plane_size *plane_size,
+ enum dc_rotation_angle rotation,
+ struct dc_plane_dcc_param *dcc,
+ bool horizontal_mirror);
+
+ bool (*hubp_is_flip_pending)(struct hubp *hubp);
+
+ void (*hubp_update_dchub)(struct hubp *hubp,
+ struct dchub_init_data *dh_data);
+
+ void (*set_blank)(struct hubp *hubp, bool blank);
+ void (*set_hubp_blank_en)(struct hubp *hubp, bool blank);
+
+ void (*set_cursor_attributes)(
+ struct hubp *hubp,
+ const struct dc_cursor_attributes *attr);
+
+ void (*set_cursor_position)(
+ struct hubp *hubp,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param);
+
+};
+
+#endif
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 {
const struct dc_link_settings *link_settings,
enum clock_source_id clock_source);
void (*disable_output)(struct link_encoder *link_enc,
- enum signal_type signal);
+ enum signal_type signal, struct dc_link *link);
void (*dp_set_lane_settings)(struct link_encoder *enc,
const struct link_training_settings *link_settings);
void (*dp_set_phy_pattern)(struct link_encoder *enc,
@@ -123,10 +123,6 @@ struct link_encoder_funcs {
bool exit_link_training_required);
void (*psr_program_secondary_packet)(struct link_encoder *enc,
unsigned int sdp_transmit_line_num_deadline);
- void (*backlight_control) (struct link_encoder *enc,
- bool enable);
- void (*power_control) (struct link_encoder *enc,
- bool power_up);
void (*connect_dig_be_to_fe)(struct link_encoder *enc,
enum engine_id engine,
bool connect);
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 {
struct dc_plane_address request_address;
struct dc_plane_address current_address;
int inst;
- int opp_id;
- int mpcc_id;
struct stutter_modes stutter_mode;
};
@@ -163,6 +161,15 @@ struct mem_input_funcs {
void (*set_blank)(struct mem_input *mi, bool blank);
void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
+ void (*set_cursor_attributes)(
+ struct mem_input *mem_input,
+ const struct dc_cursor_attributes *attr);
+
+ void (*set_cursor_position)(
+ struct mem_input *mem_input,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param);
+
};
#endif
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 @@
#include "opp.h"
struct mpcc_cfg {
- struct mem_input *mi;
- struct output_pixel_processor *opp;
+ int dpp_id;
+ int opp_id;
+ struct mpc_tree_cfg *tree_cfg;
unsigned int z_index;
struct tg_color black_color;
@@ -44,11 +45,17 @@ struct mpc {
};
struct mpc_funcs {
- void (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
+ int (*add)(struct mpc *mpc, struct mpcc_cfg *cfg);
+
void (*remove)(struct mpc *mpc,
- struct output_pixel_processor *opp,
+ struct mpc_tree_cfg *tree_cfg,
+ int opp_id,
int mpcc_inst);
+
void (*wait_for_idle)(struct mpc *mpc, int id);
+
+ void (*update_blend_mode)(struct mpc *mpc, struct mpcc_cfg *cfg);
+
};
#endif
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 {
const struct transform_funcs *funcs;
struct dc_context *ctx;
int inst;
+ struct dpp_caps *caps;
struct pwl_params regamma_params;
};
@@ -109,6 +110,22 @@ enum graphics_gamut_adjust_type {
GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */
};
+enum lb_memory_config {
+ /* Enable all 3 pieces of memory */
+ LB_MEMORY_CONFIG_0 = 0,
+
+ /* Enable only the first piece of memory */
+ LB_MEMORY_CONFIG_1 = 1,
+
+ /* Enable only the second piece of memory */
+ LB_MEMORY_CONFIG_2 = 2,
+
+ /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the
+ * last piece of chroma memory used for the luma storage
+ */
+ LB_MEMORY_CONFIG_3 = 3
+};
+
struct xfm_grph_csc_adjustment {
struct fixed31_32 temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
enum graphics_gamut_adjust_type gamut_adjust_type;
@@ -238,6 +255,17 @@ struct transform_funcs {
void (*ipp_full_bypass)(struct transform *xfm_base);
+ void (*set_cursor_attributes)(
+ struct transform *xfm_base,
+ const struct dc_cursor_attributes *attr);
+
+ void (*set_cursor_position)(
+ struct transform *xfm_base,
+ const struct dc_cursor_position *pos,
+ const struct dc_cursor_mi_param *param,
+ uint32_t width
+ );
+
};
const uint16_t *get_filter_2tap_16p(void);
@@ -251,4 +279,33 @@ const uint16_t *get_filter_6tap_64p(struct fixed31_32 ratio);
const uint16_t *get_filter_7tap_64p(struct fixed31_32 ratio);
const uint16_t *get_filter_8tap_64p(struct fixed31_32 ratio);
+
+/* Defines the pixel processing capability of the DSCL */
+enum dscl_data_processing_format {
+ DSCL_DATA_PRCESSING_FIXED_FORMAT, /* The DSCL processes pixel data in fixed format */
+ DSCL_DATA_PRCESSING_FLOAT_FORMAT, /* The DSCL processes pixel data in float format */
+};
+
+/*
+ * The DPP capabilities structure contains enumerations to specify the
+ * HW processing features and an associated function pointers to
+ * provide the function interface that can be overloaded for implementations
+ * based on different capabilities
+ */
+struct dpp_caps {
+ /* DSCL processing pixel data in fixed or float format */
+ enum dscl_data_processing_format dscl_data_proc_format;
+
+ /* Calculates the number of partitions in the line buffer.
+ * The implementation of this function is overloaded for
+ * different versions of DSCL LB.
+ */
+ void (*dscl_calc_lb_num_partitions)(
+ const struct scaler_data *scl_data,
+ enum lb_memory_config lb_config,
+ int *num_part_y,
+ int *num_part_c);
+};
+
+
#endif
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 @@
#include "dc_types.h"
#include "clock_source.h"
#include "inc/hw/timing_generator.h"
+#include "inc/hw/link_encoder.h"
#include "core_status.h"
enum pipe_gating_control {
@@ -133,7 +134,8 @@ struct hw_sequencer_funcs {
void (*enable_stream)(struct pipe_ctx *pipe_ctx);
- void (*disable_stream)(struct pipe_ctx *pipe_ctx);
+ void (*disable_stream)(struct pipe_ctx *pipe_ctx,
+ int option);
void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings);
@@ -174,8 +176,14 @@ struct hw_sequencer_funcs {
struct resource_pool *res_pool,
struct pipe_ctx *pipe_ctx);
- void (*ready_shared_resources)(struct dc *dc);
+ void (*ready_shared_resources)(struct dc *dc, struct dc_state *context);
void (*optimize_shared_resources)(struct dc *dc);
+ void (*edp_power_control)(
+ struct link_encoder *enc,
+ bool enable);
+ void (*edp_backlight_control)(
+ struct dc_link *link,
+ bool enable);
};
void color_space_to_black_color(
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(
const uint8_t *data,
uint32_t size);
+struct gpio *get_hpd_gpio(struct dc_bios *dcb,
+ struct graphics_object_id link_id,
+ struct gpio_service *gpio_service);
+
void dp_enable_link_phy(
struct dc_link *link,
enum signal_type signal,
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(
void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
struct bit_depth_reduction_params *fmt_bit_depth);
+void update_audio_usage(
+ struct resource_context *res_ctx,
+ const struct resource_pool *pool,
+ struct audio *audio,
+ bool acquired);
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
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 @@
#endif
+/*
+ *
+ * general debug capabilities
+ *
+ */
+#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
+
+#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
+#define ASSERT_CRITICAL(expr) do { \
+ if (WARN_ON(!(expr))) { \
+ kgdb_breakpoint(); \
+ } \
+} while (0)
+#else
+#define ASSERT_CRITICAL(expr) do { \
+ if (WARN_ON(!(expr))) { \
+ ; \
+ } \
+} while (0)
+#endif
+
+#if defined(CONFIG_DEBUG_KERNEL_DC)
+#define ASSERT(expr) ASSERT_CRITICAL(expr)
+
+#else
+#define ASSERT(expr) WARN_ON(!(expr))
+#endif
+
+#define BREAK_TO_DEBUGGER() ASSERT(0)
+
+#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
+
+#define DC_ERR(...) do { \
+ dm_error(__VA_ARGS__); \
+ BREAK_TO_DEBUGGER(); \
+} while (0)
+
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
+#include <asm/fpu/api.h>
+#endif
#endif /* _OS_TYPES_H_ */
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(
static void virtual_link_encoder_disable_output(
struct link_encoder *link_enc,
- enum signal_type signal) {}
+ enum signal_type signal,
+ struct dc_link *link) {}
static void virtual_link_encoder_dp_set_lane_settings(
struct link_encoder *enc,
@@ -72,14 +73,6 @@ static void virtual_link_encoder_update_mst_stream_allocation_table(
struct link_encoder *enc,
const struct link_mst_stream_allocation_table *table) {}
-static void virtual_link_encoder_edp_backlight_control(
- struct link_encoder *enc,
- bool enable) {}
-
-static void virtual_link_encoder_edp_power_control(
- struct link_encoder *enc,
- bool power_up) {}
-
static void virtual_link_encoder_connect_dig_be_to_fe(
struct link_encoder *enc,
enum engine_id engine,
@@ -105,8 +98,6 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
.dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
.update_mst_stream_allocation_table =
virtual_link_encoder_update_mst_stream_allocation_table,
- .backlight_control = virtual_link_encoder_edp_backlight_control,
- .power_control = virtual_link_encoder_edp_power_control,
.connect_dig_be_to_fe = virtual_link_encoder_connect_dig_be_to_fe,
.destroy = virtual_link_encoder_destroy
};
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);
uint32_t dal_logger_destroy(struct dal_logger **logger);
+void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn);
+
void dm_logger_write(
struct dal_logger *logger,
enum dc_log_type log_type,
@@ -157,4 +159,30 @@ void context_clock_trace(
#define DTN_INFO_END() \
dm_dtn_log_end(dc_ctx)
+#define PERFORMANCE_TRACE_START() \
+ unsigned long long perf_trc_start_stmp = dm_get_timestamp(dc->ctx); \
+ unsigned long long perf_trc_start_log_msk = dc->ctx->logger->mask; \
+ unsigned int perf_trc_start_log_flags = dc->ctx->logger->flags.value; \
+ if (dc->debug.performance_trace) {\
+ dm_logger_flush_buffer(dc->ctx->logger, false);\
+ dc->ctx->logger->mask = 1<<LOG_PERF_TRACE;\
+ dc->ctx->logger->flags.bits.ENABLE_CONSOLE = 0;\
+ dc->ctx->logger->flags.bits.ENABLE_BUFFER = 1;\
+ }
+
+#define PERFORMANCE_TRACE_END() do {\
+ unsigned long long perf_trc_end_stmp = dm_get_timestamp(dc->ctx);\
+ if (dc->debug.performance_trace) {\
+ dm_logger_write(dc->ctx->logger, \
+ LOG_PERF_TRACE, \
+ "%s duration: %d ticks\n", __func__,\
+ perf_trc_end_stmp - perf_trc_start_stmp); \
+ if (perf_trc_start_log_msk != 1<<LOG_PERF_TRACE) {\
+ dc->ctx->logger->mask = perf_trc_start_log_msk;\
+ dc->ctx->logger->flags.value = perf_trc_start_log_flags;\
+ dm_logger_flush_buffer(dc->ctx->logger, false);\
+ } \
+ } \
+} while (0)
+
#endif /* __DAL_LOGGER_INTERFACE_H__ */
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 {
LOG_EVENT_LINK_LOSS,
LOG_EVENT_UNDERFLOW,
LOG_IF_TRACE,
- LOG_HW_MARKS,
- LOG_PPLIB,
+ LOG_PERF_TRACE,
LOG_SECTION_TOTAL_COUNT
};
@@ -131,4 +130,37 @@ struct dc_log_type_info {
char name[MAX_NAME_LEN];
};
+/* Structure for keeping track of offsets, buffer, etc */
+
+#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
+
+/*Connectivity log needs to output EDID, which needs at lease 256x3 bytes,
+ * change log line size to 896 to meet the request.
+ */
+#define LOG_MAX_LINE_SIZE 896
+
+struct dal_logger {
+
+ /* How far into the circular buffer has been read by dsat
+ * Read offset should never cross write offset. Write \0's to
+ * read data just to be sure?
+ */
+ uint32_t buffer_read_offset;
+
+ /* How far into the circular buffer we have written
+ * Write offset should never cross read offset
+ */
+ uint32_t buffer_write_offset;
+
+ uint32_t open_count;
+
+ char *log_buffer; /* Pointer to malloc'ed buffer */
+ uint32_t log_buffer_size; /* Size of circular buffer */
+
+ uint32_t mask; /*array of masks for major elements*/
+
+ union logger_flags flags;
+ struct dc_context *ctx;
+};
+
#endif /* __DAL_LOGGER_TYPES_H__ */