summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display')
-rw-r--r--drivers/gpu/drm/amd/display/Makefile3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/Makefile6
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c265
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h34
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c228
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c126
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c82
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c16
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c33
-rw-r--r--drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c8
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h33
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h30
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper_struct.h66
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/Makefile14
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c30
-rw-r--r--drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c44
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c220
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link.c91
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c28
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c25
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c76
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h36
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_bios_types.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_hw_types.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_link.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h20
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_abm.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_audio.c18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c12
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c15
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h104
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_transform.c123
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c382
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c122
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.c834
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.h78
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c38
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c127
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c39
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h27
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c47
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c39
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c273
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_pp_smu.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_services.h31
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/Makefile26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c6085
-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.c1772
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h148
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_translate_dce120.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c16
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h7
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/opp.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h45
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/transform.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/link_hwss.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c3
-rw-r--r--drivers/gpu/drm/amd/display/include/dal_asic_id.h8
-rw-r--r--drivers/gpu/drm/amd/display/include/fixed31_32.h3
-rw-r--r--drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h5
-rw-r--r--drivers/gpu/drm/amd/display/include/signal_types.h5
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/Makefile31
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/color_gamma.c1403
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/color_gamma.h53
116 files changed, 3563 insertions, 10818 deletions
diff --git a/drivers/gpu/drm/amd/display/Makefile b/drivers/gpu/drm/amd/display/Makefile
index c27c81cdeed3..3d14478913de 100644
--- a/drivers/gpu/drm/amd/display/Makefile
+++ b/drivers/gpu/drm/amd/display/Makefile
@@ -32,11 +32,12 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/inc/hw
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/freesync
+subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/color
#TODO: remove when Timing Sync feature is complete
subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
-DAL_LIBS = amdgpu_dm dc modules/freesync
+DAL_LIBS = amdgpu_dm dc modules/freesync modules/color
AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/,$(DAL_LIBS)))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index 2b72009844f8..af16973f2c41 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -25,12 +25,16 @@
-AMDGPUDM = amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o
+AMDGPUDM = amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o amdgpu_dm_color.o
ifneq ($(CONFIG_DRM_AMD_DC),)
AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o
endif
+ifneq ($(CONFIG_DEBUG_FS),)
+AMDGPUDM += amdgpu_dm_crc.o
+endif
+
subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc
AMDGPU_DM = $(addprefix $(AMDDALPATH)/amdgpu_dm/,$(AMDGPUDM))
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 1ce4c98385e3..84f6fe9a448b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -61,7 +61,8 @@
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "soc15_common.h"
#endif
@@ -319,6 +320,7 @@ static void dm_crtc_high_irq(void *interrupt_params)
crtc_index = acrtc->crtc_id;
drm_handle_vblank(adev->ddev, crtc_index);
+ amdgpu_dm_crtc_handle_crc_irq(&acrtc->base);
}
static int dm_set_clockgating_state(void *handle,
@@ -345,23 +347,43 @@ static void hotplug_notify_work_func(struct work_struct *work)
}
#if defined(CONFIG_DRM_AMD_DC_FBC)
-#include "dal_asic_id.h"
/* Allocate memory for FBC compressed data */
-/* TODO: Dynamic allocation */
-#define AMDGPU_FBC_SIZE (3840 * 2160 * 4)
-
-static void amdgpu_dm_initialize_fbc(struct amdgpu_device *adev)
+static void amdgpu_dm_fbc_init(struct drm_connector *connector)
{
- int r;
+ struct drm_device *dev = connector->dev;
+ struct amdgpu_device *adev = dev->dev_private;
struct dm_comressor_info *compressor = &adev->dm.compressor;
+ struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(connector);
+ struct drm_display_mode *mode;
+ unsigned long max_size = 0;
+
+ if (adev->dm.dc->fbc_compressor == NULL)
+ return;
+
+ if (aconn->dc_link->connector_signal != SIGNAL_TYPE_EDP)
+ return;
+
+ if (compressor->bo_ptr)
+ return;
+
- if (!compressor->bo_ptr) {
- r = amdgpu_bo_create_kernel(adev, AMDGPU_FBC_SIZE, PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM, &compressor->bo_ptr,
- &compressor->gpu_addr, &compressor->cpu_addr);
+ list_for_each_entry(mode, &connector->modes, head) {
+ if (max_size < mode->htotal * mode->vtotal)
+ max_size = mode->htotal * mode->vtotal;
+ }
+
+ if (max_size) {
+ int r = amdgpu_bo_create_kernel(adev, max_size * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM, &compressor->bo_ptr,
+ &compressor->gpu_addr, &compressor->cpu_addr);
if (r)
- DRM_ERROR("DM: Failed to initialize fbc\n");
+ DRM_ERROR("DM: Failed to initialize FBC\n");
+ else {
+ adev->dm.dc->ctx->fbc_gpu_addr = compressor->gpu_addr;
+ DRM_INFO("DM: FBC alloc %lu\n", max_size*4);
+ }
+
}
}
@@ -381,12 +403,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
/* Zero all the fields */
memset(&init_data, 0, sizeof(init_data));
- /* initialize DAL's lock (for SYNC context use) */
- spin_lock_init(&adev->dm.dal_lock);
-
- /* initialize DAL's mutex */
- mutex_init(&adev->dm.dal_mutex);
-
if(amdgpu_dm_irq_init(adev)) {
DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n");
goto error;
@@ -397,7 +413,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.asic_id.pci_revision_id = adev->rev_id;
init_data.asic_id.hw_internal_rev = adev->external_rev_id;
- init_data.asic_id.vram_width = adev->mc.vram_width;
+ init_data.asic_id.vram_width = adev->gmc.vram_width;
/* TODO: initialize init_data.asic_id.vram_type here!!!! */
init_data.asic_id.atombios_base_address =
adev->mode_info.atom_context->bios;
@@ -422,11 +438,14 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
else
init_data.log_mask = DC_MIN_LOG_MASK;
-#if defined(CONFIG_DRM_AMD_DC_FBC)
- if (adev->family == FAMILY_CZ)
- amdgpu_dm_initialize_fbc(adev);
- init_data.fbc_gpu_addr = adev->dm.compressor.gpu_addr;
-#endif
+ /*
+ * TODO debug why this doesn't work on Raven
+ */
+ if (adev->flags & AMD_IS_APU &&
+ adev->asic_type >= CHIP_CARRIZO &&
+ adev->asic_type < CHIP_RAVEN)
+ init_data.flags.gpu_vm_support = true;
+
/* Display Core create. */
adev->dm.dc = dc_create(&init_data);
@@ -447,6 +466,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
DRM_DEBUG_DRIVER("amdgpu: freesync_module init done %p.\n",
adev->dm.freesync_module);
+ amdgpu_dm_init_color_mod();
+
if (amdgpu_dm_initialize_drm_device(adev)) {
DRM_ERROR(
"amdgpu: failed to initialize sw for display support.\n");
@@ -540,9 +561,9 @@ 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;
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- return detect_mst_link_for_all_connectors(dev);
+ return detect_mst_link_for_all_connectors(adev->ddev);
}
static void s3_handle_mst(struct drm_device *dev, bool suspend)
@@ -629,11 +650,13 @@ static int dm_resume(void *handle)
{
struct amdgpu_device *adev = handle;
struct amdgpu_display_manager *dm = &adev->dm;
+ int ret = 0;
/* power on hardware */
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
- return 0;
+ ret = amdgpu_dm_display_resume(adev);
+ return ret;
}
int amdgpu_dm_display_resume(struct amdgpu_device *adev)
@@ -791,7 +814,7 @@ dm_atomic_state_alloc_free(struct drm_atomic_state *state)
}
static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
- .fb_create = amdgpu_user_framebuffer_create,
+ .fb_create = amdgpu_display_user_framebuffer_create,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = amdgpu_dm_atomic_check,
.atomic_commit = amdgpu_dm_atomic_commit,
@@ -1279,9 +1302,9 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
/* indicate support of immediate flip */
adev->ddev->mode_config.async_page_flip = true;
- adev->ddev->mode_config.fb_base = adev->mc.aper_base;
+ adev->ddev->mode_config.fb_base = adev->gmc.aper_base;
- r = amdgpu_modeset_create_props(adev);
+ r = amdgpu_display_modeset_create_props(adev);
if (r)
return r;
@@ -1538,7 +1561,6 @@ static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
static const struct amdgpu_display_funcs dm_display_funcs = {
.bandwidth_update = dm_bandwidth_update, /* called unconditionally */
.vblank_get_counter = dm_vblank_get_counter,/* called unconditionally */
- .vblank_wait = NULL,
.backlight_set_level =
dm_set_backlight_level,/* called unconditionally */
.backlight_get_level =
@@ -1589,8 +1611,6 @@ static int dm_early_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- adev->ddev->driver->driver_features |= DRIVER_ATOMIC;
-
switch (adev->asic_type) {
case CHIP_BONAIRE:
case CHIP_HAWAII:
@@ -1924,32 +1944,6 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
}
-static void fill_gamma_from_crtc_state(const struct drm_crtc_state *crtc_state,
- struct dc_plane_state *plane_state)
-{
- int i;
- struct dc_gamma *gamma;
- struct drm_color_lut *lut =
- (struct drm_color_lut *) crtc_state->gamma_lut->data;
-
- gamma = dc_create_gamma();
-
- if (gamma == NULL) {
- WARN_ON(1);
- return;
- }
-
- gamma->type = GAMMA_RGB_256;
- gamma->num_entries = GAMMA_RGB_256_ENTRIES;
- for (i = 0; i < GAMMA_RGB_256_ENTRIES; i++) {
- gamma->entries.red[i] = dal_fixed31_32_from_int(lut[i].red);
- gamma->entries.green[i] = dal_fixed31_32_from_int(lut[i].green);
- gamma->entries.blue[i] = dal_fixed31_32_from_int(lut[i].blue);
- }
-
- plane_state->gamma_correction = gamma;
-}
-
static int fill_plane_attributes(struct amdgpu_device *adev,
struct dc_plane_state *dc_plane_state,
struct drm_plane_state *plane_state,
@@ -1977,14 +1971,13 @@ static int fill_plane_attributes(struct amdgpu_device *adev,
if (input_tf == NULL)
return -ENOMEM;
- input_tf->type = TF_TYPE_PREDEFINED;
- input_tf->tf = TRANSFER_FUNCTION_SRGB;
-
dc_plane_state->in_transfer_func = input_tf;
- /* In case of gamma set, update gamma value */
- if (crtc_state->gamma_lut)
- fill_gamma_from_crtc_state(crtc_state, dc_plane_state);
+ /*
+ * Always set input transfer function, since plane state is refreshed
+ * every time.
+ */
+ ret = amdgpu_dm_set_degamma_lut(crtc_state, dc_plane_state);
return ret;
}
@@ -2010,30 +2003,32 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode,
dst.width = stream->timing.h_addressable;
dst.height = stream->timing.v_addressable;
- rmx_type = dm_state->scaling;
- if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) {
- if (src.width * dst.height <
- src.height * dst.width) {
- /* height needs less upscaling/more downscaling */
- dst.width = src.width *
- dst.height / src.height;
- } else {
- /* width needs less upscaling/more downscaling */
- dst.height = src.height *
- dst.width / src.width;
+ if (dm_state) {
+ rmx_type = dm_state->scaling;
+ if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) {
+ if (src.width * dst.height <
+ src.height * dst.width) {
+ /* height needs less upscaling/more downscaling */
+ dst.width = src.width *
+ dst.height / src.height;
+ } else {
+ /* width needs less upscaling/more downscaling */
+ dst.height = src.height *
+ dst.width / src.width;
+ }
+ } else if (rmx_type == RMX_CENTER) {
+ dst = src;
}
- } else if (rmx_type == RMX_CENTER) {
- dst = src;
- }
- dst.x = (stream->timing.h_addressable - dst.width) / 2;
- dst.y = (stream->timing.v_addressable - dst.height) / 2;
+ dst.x = (stream->timing.h_addressable - dst.width) / 2;
+ dst.y = (stream->timing.v_addressable - dst.height) / 2;
- if (dm_state->underscan_enable) {
- dst.x += dm_state->underscan_hborder / 2;
- dst.y += dm_state->underscan_vborder / 2;
- dst.width -= dm_state->underscan_hborder;
- dst.height -= dm_state->underscan_vborder;
+ if (dm_state->underscan_enable) {
+ dst.x += dm_state->underscan_hborder / 2;
+ dst.y += dm_state->underscan_vborder / 2;
+ dst.width -= dm_state->underscan_hborder;
+ dst.height -= dm_state->underscan_vborder;
+ }
}
stream->src = src;
@@ -2322,7 +2317,7 @@ static void set_master_stream(struct dc_stream_state *stream_set[],
}
}
for (j = 0; j < stream_count; j++) {
- if (stream_set[j] && j != master_stream)
+ if (stream_set[j])
stream_set[j]->triggered_crtc_reset.event_source = stream_set[master_stream];
}
}
@@ -2358,12 +2353,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
if (aconnector == NULL) {
DRM_ERROR("aconnector is NULL!\n");
- goto drm_connector_null;
- }
-
- if (dm_state == NULL) {
- DRM_ERROR("dm_state is NULL!\n");
- goto dm_state_null;
+ return stream;
}
drm_connector = &aconnector->base;
@@ -2375,18 +2365,18 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
*/
if (aconnector->mst_port) {
dm_dp_mst_dc_sink_create(drm_connector);
- goto mst_dc_sink_create_done;
+ return stream;
}
if (create_fake_sink(aconnector))
- goto stream_create_fail;
+ return stream;
}
stream = dc_create_stream_for_sink(aconnector->dc_sink);
if (stream == NULL) {
DRM_ERROR("Failed to create stream for sink!\n");
- goto stream_create_fail;
+ return stream;
}
list_for_each_entry(preferred_mode, &aconnector->base.modes, head) {
@@ -2412,9 +2402,12 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
} else {
decide_crtc_timing_for_drm_display_mode(
&mode, preferred_mode,
- dm_state->scaling != RMX_OFF);
+ dm_state ? (dm_state->scaling != RMX_OFF) : false);
}
+ if (!dm_state)
+ drm_mode_set_crtcinfo(&mode, 0);
+
fill_stream_properties_from_drm_display_mode(stream,
&mode, &aconnector->base);
update_stream_scaling_settings(&mode, dm_state, stream);
@@ -2424,10 +2417,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
drm_connector,
aconnector->dc_sink);
-stream_create_fail:
-dm_state_null:
-drm_connector_null:
-mst_dc_sink_create_done:
+ update_stream_signal(stream);
+
return stream;
}
@@ -2504,6 +2495,7 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
.page_flip = drm_atomic_helper_page_flip,
.atomic_duplicate_state = dm_crtc_duplicate_state,
.atomic_destroy_state = dm_crtc_destroy_state,
+ .set_crc_source = amdgpu_dm_crtc_set_crc_source,
};
static enum drm_connector_status
@@ -2779,6 +2771,7 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
/* TODO: Unhardcode stream count */
struct dc_stream_state *stream;
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+ enum dc_status dc_result = DC_OK;
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
(mode->flags & DRM_MODE_FLAG_DBLSCAN))
@@ -2798,21 +2791,22 @@ int amdgpu_dm_connector_mode_valid(struct drm_connector *connector,
goto fail;
}
- stream = dc_create_stream_for_sink(dc_sink);
+ stream = create_stream_for_sink(aconnector, mode, NULL);
if (stream == NULL) {
DRM_ERROR("Failed to create stream for sink!\n");
goto fail;
}
- drm_mode_set_crtcinfo(mode, 0);
- fill_stream_properties_from_drm_display_mode(stream, mode, connector);
-
- stream->src.width = mode->hdisplay;
- stream->src.height = mode->vdisplay;
- stream->dst = stream->src;
+ dc_result = dc_validate_stream(adev->dm.dc, stream);
- if (dc_validate_stream(adev->dm.dc, stream) == DC_OK)
+ if (dc_result == DC_OK)
result = MODE_OK;
+ else
+ DRM_DEBUG_KMS("Mode %dx%d (clk %d) failed DC validation with error %d\n",
+ mode->vdisplay,
+ mode->hdisplay,
+ mode->clock,
+ dc_result);
dc_stream_release(stream);
@@ -2954,11 +2948,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
{
struct amdgpu_framebuffer *afb;
struct drm_gem_object *obj;
+ struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
uint64_t chroma_addr = 0;
- int r;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
unsigned int awidth;
+ uint32_t domain;
+ int r;
dm_plane_state_old = to_dm_plane_state(plane->state);
dm_plane_state_new = to_dm_plane_state(new_state);
@@ -2972,12 +2968,17 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
obj = afb->obj;
rbo = gem_to_amdgpu_bo(obj);
+ adev = amdgpu_ttm_adev(rbo->tbo.bdev);
r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
- r = amdgpu_bo_pin(rbo, AMDGPU_GEM_DOMAIN_VRAM, &afb->address);
+ if (plane->type != DRM_PLANE_TYPE_CURSOR)
+ domain = amdgpu_display_framebuffer_domains(adev);
+ else
+ domain = AMDGPU_GEM_DOMAIN_VRAM;
+ r = amdgpu_bo_pin(rbo, domain, &afb->address);
amdgpu_bo_unreserve(rbo);
@@ -3190,7 +3191,9 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
acrtc->base.enabled = false;
dm->adev->mode_info.crtcs[crtc_index] = acrtc;
- drm_mode_crtc_set_gamma_size(&acrtc->base, 256);
+ drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES,
+ true, MAX_COLOR_LUT_ENTRIES);
+ drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LUT_ENTRIES);
return 0;
@@ -3366,9 +3369,12 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
struct edid *edid = amdgpu_dm_connector->edid;
encoder = helper->best_encoder(connector);
-
amdgpu_dm_connector_ddc_get_modes(connector, edid);
amdgpu_dm_connector_add_common_modes(encoder, connector);
+
+#if defined(CONFIG_DRM_AMD_DC_FBC)
+ amdgpu_dm_fbc_init(connector);
+#endif
return amdgpu_dm_connector->num_modes;
}
@@ -3641,7 +3647,7 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
* constant is the same as PFLIP
*/
int irq_type =
- amdgpu_crtc_idx_to_irq_type(
+ amdgpu_display_crtc_idx_to_irq_type(
adev,
acrtc->crtc_id);
@@ -3860,9 +3866,9 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
* targeted by the flip
*/
while ((acrtc->enabled &&
- (amdgpu_get_crtc_scanoutpos(adev->ddev, acrtc->crtc_id, 0,
- &vpos, &hpos, NULL, NULL,
- &crtc->hwmode)
+ (amdgpu_display_get_crtc_scanoutpos(adev->ddev, acrtc->crtc_id,
+ 0, &vpos, &hpos, NULL,
+ NULL, &crtc->hwmode)
& (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
(DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
(int)(target_vblank -
@@ -4603,6 +4609,30 @@ next_crtc:
/* Release extra reference */
if (new_stream)
dc_stream_release(new_stream);
+
+ /*
+ * We want to do dc stream updates that do not require a
+ * full modeset below.
+ */
+ if (!enable || !aconnector || modereset_required(new_crtc_state))
+ continue;
+ /*
+ * Given above conditions, the dc state cannot be NULL because:
+ * 1. We're attempting to enable a CRTC. Which has a...
+ * 2. Valid connector attached, and
+ * 3. User does not want to reset it (disable or mark inactive,
+ * which can happen on a CRTC that's already disabled).
+ * => It currently exists.
+ */
+ BUG_ON(dm_new_crtc_state->stream == NULL);
+
+ /* Color managment settings */
+ if (dm_new_crtc_state->base.color_mgmt_changed) {
+ ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state);
+ if (ret)
+ goto fail;
+ amdgpu_dm_set_ctm(dm_new_crtc_state);
+ }
}
return ret;
@@ -4711,7 +4741,6 @@ static int dm_update_planes_state(struct dc *dc,
if (ret)
return ret;
-
if (!dc_add_plane_to_context(
dc,
dm_new_crtc_state->stream,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 2faa77a7eeda..aa7df5775545 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -85,8 +85,6 @@ struct amdgpu_display_manager {
struct dal *dal;
struct dc *dc;
struct cgs_device *cgs_device;
- /* lock to be used when DAL is called from SYNC IRQ context */
- spinlock_t dal_lock;
struct amdgpu_device *adev; /*AMD base driver*/
struct drm_device *ddev; /*DRM base driver*/
@@ -119,17 +117,6 @@ struct amdgpu_display_manager {
/* this spin lock synchronizes access to 'irq_handler_list_table' */
spinlock_t irq_handler_list_table_lock;
- /* Timer-related data. */
- struct list_head timer_handler_list;
- struct workqueue_struct *timer_workqueue;
-
- /* Use dal_mutex for any activity which is NOT syncronized by
- * DRM mode setting locks.
- * For example: amdgpu_dm_hpd_low_irq() calls into DAL *without*
- * DRM mode setting locks being acquired. This is where dal_mutex
- * is acquired before calling into DAL. */
- struct mutex dal_mutex;
-
struct backlight_device *backlight_dev;
const struct dc_link *backlight_link;
@@ -210,6 +197,9 @@ struct dm_plane_state {
struct dm_crtc_state {
struct drm_crtc_state base;
struct dc_stream_state *stream;
+
+ int crc_skip_count;
+ bool crc_enabled;
};
#define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
@@ -268,6 +258,24 @@ void amdgpu_dm_add_sink_to_freesync_module(struct drm_connector *connector,
void
amdgpu_dm_remove_sink_from_freesync_module(struct drm_connector *connector);
+/* amdgpu_dm_crc.c */
+#ifdef CONFIG_DEBUG_FS
+int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name,
+ size_t *values_cnt);
+void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc);
+#else
+#define amdgpu_dm_crtc_set_crc_source NULL
+#define amdgpu_dm_crtc_handle_crc_irq(x)
+#endif
+
+#define MAX_COLOR_LUT_ENTRIES 256
+
+void amdgpu_dm_init_color_mod(void);
+int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
+ struct dc_plane_state *dc_plane_state);
+void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc);
+int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc);
+
extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs;
#endif /* __AMDGPU_DM_H__ */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
new file mode 100644
index 000000000000..62bb72fe9aa5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "amdgpu_mode.h"
+#include "amdgpu_dm.h"
+#include "modules/color/color_gamma.h"
+
+/*
+ * Initialize the color module.
+ *
+ * We're not using the full color module, only certain components.
+ * Only call setup functions for components that we need.
+ */
+void amdgpu_dm_init_color_mod(void)
+{
+ setup_x_points_distribution();
+}
+
+
+/*
+ * Return true if the given lut is a linear mapping of values, i.e. it acts
+ * like a bypass LUT.
+ *
+ * It is considered linear if the lut represents:
+ * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in
+ * [0, MAX_COLOR_LUT_ENTRIES)
+ */
+static bool __is_lut_linear(struct drm_color_lut *lut)
+{
+ int i;
+ uint32_t max_os = 0xFF00;
+ uint32_t expected;
+ int delta;
+
+ for (i = 0; i < MAX_COLOR_LUT_ENTRIES; i++) {
+ /* All color values should equal */
+ if ((lut[i].red != lut[i].green) || (lut[i].green != lut[i].blue))
+ return false;
+
+ expected = i * max_os / (MAX_COLOR_LUT_ENTRIES-1);
+
+ /* Allow a +/-1 error. */
+ delta = lut[i].red - expected;
+ if (delta < -1 || 1 < delta)
+ return false;
+ }
+ return true;
+}
+
+/**
+ * amdgpu_dm_set_regamma_lut: Set regamma lut for the given CRTC.
+ * @crtc: amdgpu_dm crtc state
+ *
+ * Update the underlying dc_stream_state's output transfer function (OTF) in
+ * preparation for hardware commit. If no lut is specified by user, we default
+ * to SRGB.
+ *
+ * RETURNS:
+ * 0 on success, -ENOMEM if memory cannot be allocated to calculate the OTF.
+ */
+int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc)
+{
+ struct drm_property_blob *blob = crtc->base.gamma_lut;
+ struct dc_stream_state *stream = crtc->stream;
+ struct drm_color_lut *lut;
+ struct dc_gamma *gamma;
+ enum dc_transfer_func_type old_type = stream->out_transfer_func->type;
+
+ uint32_t r, g, b;
+ int i;
+ bool ret;
+
+ if (!blob) {
+ /* By default, use the SRGB predefined curve.*/
+ stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
+ stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
+ return 0;
+ }
+
+ lut = (struct drm_color_lut *)blob->data;
+
+ if (__is_lut_linear(lut)) {
+ /* Set to bypass if lut is set to linear */
+ stream->out_transfer_func->type = TF_TYPE_BYPASS;
+ stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+ return 0;
+ }
+
+ gamma = dc_create_gamma();
+ if (!gamma)
+ return -ENOMEM;
+
+ gamma->num_entries = MAX_COLOR_LUT_ENTRIES;
+ gamma->type = GAMMA_RGB_256;
+
+ /* Truncate, and store in dc_gamma for output tf calculation */
+ for (i = 0; i < gamma->num_entries; i++) {
+ r = drm_color_lut_extract(lut[i].red, 16);
+ g = drm_color_lut_extract(lut[i].green, 16);
+ b = drm_color_lut_extract(lut[i].blue, 16);
+
+ gamma->entries.red[i] = dal_fixed31_32_from_int(r);
+ gamma->entries.green[i] = dal_fixed31_32_from_int(g);
+ gamma->entries.blue[i] = dal_fixed31_32_from_int(b);
+ }
+
+ /* Call color module to translate into something DC understands. Namely
+ * a transfer function.
+ */
+ stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+ ret = mod_color_calculate_regamma_params(stream->out_transfer_func,
+ gamma, true);
+ dc_gamma_release(&gamma);
+ if (!ret) {
+ stream->out_transfer_func->type = old_type;
+ DRM_ERROR("Out of memory when calculating regamma params\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
+ * amdgpu_dm_set_ctm: Set the color transform matrix for the given CRTC.
+ * @crtc: amdgpu_dm crtc state
+ *
+ * Update the underlying dc_stream_state's gamut remap matrix in preparation
+ * for hardware commit. If no matrix is specified by user, gamut remap will be
+ * disabled.
+ */
+void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc)
+{
+
+ struct drm_property_blob *blob = crtc->base.ctm;
+ struct dc_stream_state *stream = crtc->stream;
+ struct drm_color_ctm *ctm;
+ int i;
+
+ if (!blob) {
+ stream->gamut_remap_matrix.enable_remap = false;
+ return;
+ }
+
+ stream->gamut_remap_matrix.enable_remap = true;
+ ctm = (struct drm_color_ctm *)blob->data;
+ /*
+ * DRM gives a 3x3 matrix, but DC wants 3x4. Assuming we're operating
+ * with homogeneous coordinates, augment the matrix with 0's.
+ *
+ * The format provided is S31.32, which is the same as our fixed31_32.
+ */
+ for (i = 0; i < 12; i++) {
+ /* Skip 4th element */
+ if (i % 4 == 3) {
+ stream->gamut_remap_matrix.matrix[i] = dal_fixed31_32_zero;
+ continue;
+ }
+ /* csc[i] = ctm[i - floor(i/4)] */
+ stream->gamut_remap_matrix.matrix[i].value = ctm->matrix[i - (i/4)];
+ }
+}
+
+
+/**
+ * amdgpu_dm_set_degamma_lut: Set degamma lut for the given CRTC.
+ * @crtc: amdgpu_dm crtc state
+ *
+ * Update the underlying dc_stream_state's input transfer function (ITF) in
+ * preparation for hardware commit. If no lut is specified by user, we default
+ * to SRGB degamma.
+ *
+ * Currently, we only support degamma bypass, or preprogrammed SRGB degamma.
+ * Programmable degamma is not supported, and an attempt to do so will return
+ * -EINVAL.
+ *
+ * RETURNS:
+ * 0 on success, -EINVAL if custom degamma curve is given.
+ */
+int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
+ struct dc_plane_state *dc_plane_state)
+{
+ struct drm_property_blob *blob = crtc_state->degamma_lut;
+ struct drm_color_lut *lut;
+
+ if (!blob) {
+ /* Default to SRGB */
+ dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED;
+ dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
+ return 0;
+ }
+
+ lut = (struct drm_color_lut *)blob->data;
+ if (__is_lut_linear(lut)) {
+ dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
+ dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+ return 0;
+ }
+
+ /* Otherwise, assume SRGB, since programmable degamma is not
+ * supported.
+ */
+ dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED;
+ dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
+ return -EINVAL;
+}
+
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
new file mode 100644
index 000000000000..52f2c01349e3
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 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 <drm/drm_crtc.h>
+
+#include "amdgpu.h"
+#include "amdgpu_dm.h"
+#include "dc.h"
+
+enum amdgpu_dm_pipe_crc_source {
+ AMDGPU_DM_PIPE_CRC_SOURCE_NONE = 0,
+ AMDGPU_DM_PIPE_CRC_SOURCE_AUTO,
+ AMDGPU_DM_PIPE_CRC_SOURCE_MAX,
+ AMDGPU_DM_PIPE_CRC_SOURCE_INVALID = -1,
+};
+
+static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
+{
+ if (!source || !strcmp(source, "none"))
+ return AMDGPU_DM_PIPE_CRC_SOURCE_NONE;
+ if (!strcmp(source, "auto"))
+ return AMDGPU_DM_PIPE_CRC_SOURCE_AUTO;
+
+ return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID;
+}
+
+int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name,
+ size_t *values_cnt)
+{
+ struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
+ struct dc_stream_state *stream_state = crtc_state->stream;
+
+ enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
+
+ if (source < 0) {
+ DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n",
+ src_name, crtc->index);
+ return -EINVAL;
+ }
+
+ /* When enabling CRC, we should also disable dithering. */
+ if (source == AMDGPU_DM_PIPE_CRC_SOURCE_AUTO) {
+ if (dc_stream_configure_crc(stream_state->ctx->dc,
+ stream_state,
+ true, true)) {
+ crtc_state->crc_enabled = true;
+ dc_stream_set_dither_option(stream_state,
+ DITHER_OPTION_TRUN8);
+ }
+ else
+ return -EINVAL;
+ } else {
+ if (dc_stream_configure_crc(stream_state->ctx->dc,
+ stream_state,
+ false, false)) {
+ crtc_state->crc_enabled = false;
+ dc_stream_set_dither_option(stream_state,
+ DITHER_OPTION_DEFAULT);
+ }
+ else
+ return -EINVAL;
+ }
+
+ *values_cnt = 3;
+ /* Reset crc_skipped on dm state */
+ crtc_state->crc_skip_count = 0;
+ return 0;
+}
+
+/**
+ * amdgpu_dm_crtc_handle_crc_irq: Report to DRM the CRC on given CRTC.
+ * @crtc: DRM CRTC object.
+ *
+ * This function should be called at the end of a vblank, when the fb has been
+ * fully processed through the pipe.
+ */
+void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
+{
+ struct dm_crtc_state *crtc_state = to_dm_crtc_state(crtc->state);
+ struct dc_stream_state *stream_state = crtc_state->stream;
+ uint32_t crcs[3];
+
+ /* Early return if CRC capture is not enabled. */
+ if (!crtc_state->crc_enabled)
+ return;
+
+ /*
+ * Since flipping and crc enablement happen asynchronously, we - more
+ * often than not - will be returning an 'uncooked' crc on first frame.
+ * Probably because hw isn't ready yet. For added security, skip the
+ * first two CRC values.
+ */
+ if (crtc_state->crc_skip_count < 2) {
+ crtc_state->crc_skip_count += 1;
+ return;
+ }
+
+ if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
+ &crcs[0], &crcs[1], &crcs[2]))
+ return;
+
+ drm_crtc_add_crc_entry(crtc, true,
+ drm_crtc_accurate_vblank_count(crtc), crcs);
+}
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 1874b6cee6af..490017df371d 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
@@ -51,11 +51,6 @@ struct amdgpu_dm_irq_handler_data {
enum dc_irq_source irq_source;
};
-struct amdgpu_dm_timer_handler_data {
- struct handler_common_data hcd;
- struct delayed_work d_work;
-};
-
#define DM_IRQ_TABLE_LOCK(adev, flags) \
spin_lock_irqsave(&adev->dm.irq_handler_list_table_lock, flags)
@@ -169,62 +164,6 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev,
return hnd_list;
}
-/* If 'handler_in == NULL' then remove ALL handlers. */
-static void remove_timer_handler(struct amdgpu_device *adev,
- struct amdgpu_dm_timer_handler_data *handler_in)
-{
- struct amdgpu_dm_timer_handler_data *handler_temp;
- struct list_head *handler_list;
- struct list_head *entry, *tmp;
- unsigned long irq_table_flags;
- bool handler_removed = false;
-
- DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
-
- handler_list = &adev->dm.timer_handler_list;
-
- list_for_each_safe(entry, tmp, handler_list) {
- /* Note that list_for_each_safe() guarantees that
- * handler_temp is NOT null. */
- handler_temp = list_entry(entry,
- struct amdgpu_dm_timer_handler_data, hcd.list);
-
- if (handler_in == NULL || handler_in == handler_temp) {
- list_del(&handler_temp->hcd.list);
- DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
-
- DRM_DEBUG_KMS("DM_IRQ: removing timer handler: %p\n",
- handler_temp);
-
- if (handler_in == NULL) {
- /* Since it is still in the queue, it must
- * be cancelled. */
- cancel_delayed_work_sync(&handler_temp->d_work);
- }
-
- kfree(handler_temp);
- handler_removed = true;
-
- DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
- }
-
- /* Remove ALL handlers. */
- if (handler_in == NULL)
- continue;
-
- /* 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)
- DRM_ERROR("DM_IRQ: handler: %p is not in the list!\n",
- handler_in);
-}
-
static bool
validate_irq_registration_params(struct dc_interrupt_params *int_params,
void (*ih)(void *))
@@ -382,16 +321,6 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
INIT_LIST_HEAD(&adev->dm.irq_handler_list_high_tab[src]);
}
- INIT_LIST_HEAD(&adev->dm.timer_handler_list);
-
- /* allocate and initialize the workqueue for DM timer */
- adev->dm.timer_workqueue = create_singlethread_workqueue(
- "dm_timer_queue");
- if (adev->dm.timer_workqueue == NULL) {
- DRM_ERROR("DM_IRQ: unable to create timer queue!\n");
- return -1;
- }
-
return 0;
}
@@ -410,11 +339,6 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
lh = &adev->dm.irq_handler_list_low_tab[src];
flush_work(&lh->work);
}
-
- /* Cancel ALL timers and release handlers (if any). */
- remove_timer_handler(adev, NULL);
- /* Release the queue itself. */
- destroy_workqueue(adev->dm.timer_workqueue);
}
int amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
@@ -683,10 +607,8 @@ static const struct amdgpu_irq_src_funcs dm_hpd_irq_funcs = {
void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev)
{
- if (adev->mode_info.num_crtc > 0)
- adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
- else
- adev->crtc_irq.num_types = 0;
+
+ adev->crtc_irq.num_types = adev->mode_info.num_crtc;
adev->crtc_irq.funcs = &dm_crtc_irq_funcs;
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
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 f3d87f418d2e..1e8a21b67df7 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,12 +174,6 @@ 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)
-{
- return drm_add_edid_modes(connector, edid);
-}
-
void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
{
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
@@ -189,6 +183,12 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
+ /*
+ * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
+ */
+ if (!aconnector->port || !aconnector->port->aux.ddc.algo)
+ return;
+
edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
if (!edid) {
@@ -222,7 +222,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
int ret = 0;
if (!aconnector)
- return dm_connector_update_modes(connector, NULL);
+ return drm_add_edid_modes(connector, NULL);
if (!aconnector->edid) {
struct edid *edid;
@@ -258,7 +258,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
&aconnector->base, edid);
}
- ret = dm_connector_update_modes(connector, aconnector->edid);
+ ret = drm_add_edid_modes(connector, aconnector->edid);
return ret;
}
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 56e549249134..89342b48be6b 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
@@ -71,15 +71,6 @@ bool dm_read_persistent_data(struct dc_context *ctx,
/**** power component interfaces ****/
-bool dm_pp_pre_dce_clock_change(
- struct dc_context *ctx,
- struct dm_pp_gpu_clock_range *requested_state,
- struct dm_pp_gpu_clock_range *actual_state)
-{
- /*TODO*/
- return false;
-}
-
bool dm_pp_apply_display_requirements(
const struct dc_context *ctx,
const struct dm_pp_display_configuration *pp_display_cfg)
@@ -151,30 +142,6 @@ bool dm_pp_apply_display_requirements(
return true;
}
-bool dc_service_get_system_clocks_range(
- const struct dc_context *ctx,
- struct dm_pp_gpu_clock_range *sys_clks)
-{
- struct amdgpu_device *adev = ctx->driver_context;
-
- /* Default values, in case PPLib is not compiled-in. */
- sys_clks->mclk.max_khz = 800000;
- sys_clks->mclk.min_khz = 800000;
-
- sys_clks->sclk.max_khz = 600000;
- sys_clks->sclk.min_khz = 300000;
-
- if (adev->pm.dpm_enabled) {
- sys_clks->mclk.max_khz = amdgpu_dpm_get_mclk(adev, false);
- sys_clks->mclk.min_khz = amdgpu_dpm_get_mclk(adev, true);
-
- sys_clks->sclk.max_khz = amdgpu_dpm_get_sclk(adev, false);
- sys_clks->sclk.min_khz = amdgpu_dpm_get_sclk(adev, true);
- }
-
- return true;
-}
-
static void get_default_clock_levels(
enum dm_pp_clock_type clk_type,
struct dm_pp_clock_levels *clks)
diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 011a97f82fb6..8a9bba879207 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -593,3 +593,12 @@ uint32_t dal_fixed31_32_clamp_u0d10(
{
return clamp_ux_dy(arg.value, 0, 10, 1);
}
+
+int32_t dal_fixed31_32_s4d19(
+ struct fixed31_32 arg)
+{
+ if (arg.value < 0)
+ return -(int32_t)ux_dy(dal_fixed31_32_abs(arg).value, 4, 19);
+ else
+ return ux_dy(arg.value, 4, 19);
+}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
index c00e405b63e8..69c59e050a96 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -3795,14 +3795,11 @@ static const struct dc_vbios_funcs vbios_funcs = {
.get_gpio_pin_info = bios_parser_get_gpio_pin_info,
- .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
-
- .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
-
.get_encoder_cap_info = bios_parser_get_encoder_cap_info,
/* bios scratch register communication */
.is_accelerated_mode = bios_is_accelerated_mode,
+ .get_vga_enabled_displays = bios_get_vga_enabled_displays,
.set_scratch_critical_state = bios_parser_set_scratch_critical_state,
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 1ee1717f2e6f..1689c670ca6f 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -1280,6 +1280,12 @@ static bool bios_parser_is_accelerated_mode(
return bios_is_accelerated_mode(dcb);
}
+static uint32_t bios_parser_get_vga_enabled_displays(
+ struct dc_bios *bios)
+{
+ return bios_get_vga_enabled_displays(bios);
+}
+
/**
* bios_parser_set_scratch_critical_state
@@ -1800,6 +1806,7 @@ static const struct dc_vbios_funcs vbios_funcs = {
.is_accelerated_mode = bios_parser_is_accelerated_mode,
+ .get_vga_enabled_displays = bios_parser_get_vga_enabled_displays,
.set_scratch_critical_state = bios_parser_set_scratch_critical_state,
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
index 5c9e5108c32c..d4589470985c 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c
@@ -78,5 +78,13 @@ void bios_set_scratch_critical_state(
REG_UPDATE(BIOS_SCRATCH_6, S6_CRITICAL_STATE, critial_state);
}
+uint32_t bios_get_vga_enabled_displays(
+ struct dc_bios *bios)
+{
+ uint32_t active_disp = 1;
+ if (bios->regs->BIOS_SCRATCH_3) /*follow up with other asic, todo*/
+ active_disp = REG_READ(BIOS_SCRATCH_3) & 0XFFFF;
+ return active_disp;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
index c0047efeb006..75a29e68fb27 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h
@@ -34,6 +34,7 @@ uint8_t *bios_get_image(struct dc_bios *bp, uint32_t offset,
bool bios_is_accelerated_mode(struct dc_bios *bios);
void bios_set_scratch_acc_mode_change(struct dc_bios *bios);
void bios_set_scratch_critical_state(struct dc_bios *bios, bool state);
+uint32_t bios_get_vga_enabled_displays(struct dc_bios *bios);
#define GET_IMAGE(type, offset) ((type *) bios_get_image(&bp->base, offset, sizeof(type)))
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h
index 1fab634b66be..4c3789df253d 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h
@@ -29,38 +29,7 @@
#include "dce80/command_table_helper_dce80.h"
#include "dce110/command_table_helper_dce110.h"
#include "dce112/command_table_helper_dce112.h"
-
-struct command_table_helper {
- bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
- uint8_t (*encoder_action_to_atom)(
- enum bp_encoder_control_action action);
- uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s,
- bool enable_dp_audio);
- bool (*engine_bp_to_atom)(enum engine_id engine_id,
- uint32_t *atom_engine_id);
- void (*assign_control_parameter)(
- const struct command_table_helper *h,
- struct bp_encoder_control *control,
- DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param);
- bool (*clock_source_id_to_atom)(enum clock_source_id id,
- uint32_t *atom_pll_id);
- bool (*clock_source_id_to_ref_clk_src)(
- enum clock_source_id id,
- uint32_t *ref_clk_src_id);
- uint8_t (*transmitter_bp_to_atom)(enum transmitter t);
- uint8_t (*encoder_id_to_atom)(enum encoder_id id);
- uint8_t (*clock_source_id_to_atom_phy_clk_src_id)(
- enum clock_source_id id);
- uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s);
- uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id);
- uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id);
- uint8_t (*phy_id_to_atom)(enum transmitter t);
- uint8_t (*disp_power_gating_action_to_atom)(
- enum bp_pipe_control_action action);
- bool (*dc_clock_type_to_atom)(enum bp_dce_clock_type id,
- uint32_t *atom_clock_type);
- uint8_t (*transmitter_color_depth_to_atom)(enum transmitter_color_depth id);
-};
+#include "command_table_helper_struct.h"
bool dal_bios_parser_init_cmd_tbl_helper(const struct command_table_helper **h,
enum dce_version dce);
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h
index 9f587c91d843..785fcb20a1b9 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h
@@ -29,35 +29,7 @@
#include "dce80/command_table_helper_dce80.h"
#include "dce110/command_table_helper_dce110.h"
#include "dce112/command_table_helper2_dce112.h"
-
-struct command_table_helper {
- bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
- uint8_t (*encoder_action_to_atom)(
- enum bp_encoder_control_action action);
- uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s,
- bool enable_dp_audio);
- bool (*engine_bp_to_atom)(enum engine_id engine_id,
- uint32_t *atom_engine_id);
- bool (*clock_source_id_to_atom)(enum clock_source_id id,
- uint32_t *atom_pll_id);
- bool (*clock_source_id_to_ref_clk_src)(
- enum clock_source_id id,
- uint32_t *ref_clk_src_id);
- uint8_t (*transmitter_bp_to_atom)(enum transmitter t);
- uint8_t (*encoder_id_to_atom)(enum encoder_id id);
- uint8_t (*clock_source_id_to_atom_phy_clk_src_id)(
- enum clock_source_id id);
- uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s);
- uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id);
- uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id);
- uint8_t (*phy_id_to_atom)(enum transmitter t);
- uint8_t (*disp_power_gating_action_to_atom)(
- enum bp_pipe_control_action action);
- bool (*dc_clock_type_to_atom)(enum bp_dce_clock_type id,
- uint32_t *atom_clock_type);
- uint8_t (*transmitter_color_depth_to_atom)(
- enum transmitter_color_depth id);
-};
+#include "command_table_helper_struct.h"
bool dal_bios_parser_init_cmd_tbl_helper2(const struct command_table_helper **h,
enum dce_version dce);
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper_struct.h b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper_struct.h
new file mode 100644
index 000000000000..1f2c0a3f06f9
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper_struct.h
@@ -0,0 +1,66 @@
+/*
+ * 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_COMMAND_TABLE_HELPER_STRUCT_H__
+#define __DAL_COMMAND_TABLE_HELPER_STRUCT_H__
+
+#include "dce80/command_table_helper_dce80.h"
+#include "dce110/command_table_helper_dce110.h"
+#include "dce112/command_table_helper_dce112.h"
+
+struct _DIG_ENCODER_CONTROL_PARAMETERS_V2;
+struct command_table_helper {
+ bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
+ uint8_t (*encoder_action_to_atom)(
+ enum bp_encoder_control_action action);
+ uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s,
+ bool enable_dp_audio);
+ bool (*engine_bp_to_atom)(enum engine_id engine_id,
+ uint32_t *atom_engine_id);
+ void (*assign_control_parameter)(
+ const struct command_table_helper *h,
+ struct bp_encoder_control *control,
+ struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param);
+ bool (*clock_source_id_to_atom)(enum clock_source_id id,
+ uint32_t *atom_pll_id);
+ bool (*clock_source_id_to_ref_clk_src)(
+ enum clock_source_id id,
+ uint32_t *ref_clk_src_id);
+ uint8_t (*transmitter_bp_to_atom)(enum transmitter t);
+ uint8_t (*encoder_id_to_atom)(enum encoder_id id);
+ uint8_t (*clock_source_id_to_atom_phy_clk_src_id)(
+ enum clock_source_id id);
+ uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s);
+ uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id);
+ uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id);
+ uint8_t (*phy_id_to_atom)(enum transmitter t);
+ uint8_t (*disp_power_gating_action_to_atom)(
+ enum bp_pipe_control_action action);
+ bool (*dc_clock_type_to_atom)(enum bp_dce_clock_type id,
+ uint32_t *atom_clock_type);
+ uint8_t (*transmitter_color_depth_to_atom)(enum transmitter_color_depth id);
+};
+
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
index 7959e382ed28..95f332ee3e7e 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
@@ -24,9 +24,17 @@
# It calculates Bandwidth and Watermarks values for HW programming
#
-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 -Wno-tautological-compare
+ifneq ($(call cc-option, -mpreferred-stack-boundary=4),)
+ cc_stack_align := -mpreferred-stack-boundary=4
+else ifneq ($(call cc-option, -mstack-alignment=16),)
+ cc_stack_align := -mstack-alignment=16
+endif
+
+calcs_ccflags := -mhard-float -msse $(cc_stack_align)
+
+CFLAGS_dcn_calcs.o := $(calcs_ccflags)
+CFLAGS_dcn_calc_auto.o := $(calcs_ccflags)
+CFLAGS_dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare
BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
index 2e11fac2a63d..6d38b8f43198 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
@@ -623,7 +623,7 @@ static void calculate_bandwidth(
}
else {
/*graphics portrait tiling mode*/
- if ((data->graphics_micro_tile_mode == bw_def_rotated_micro_tiling)) {
+ if (data->graphics_micro_tile_mode == bw_def_rotated_micro_tiling) {
data->orthogonal_rotation[i] = 0;
}
else {
@@ -634,7 +634,7 @@ static void calculate_bandwidth(
else {
if ((i < 4)) {
/*underlay landscape tiling mode is only supported*/
- if ((data->underlay_micro_tile_mode == bw_def_display_micro_tiling)) {
+ if (data->underlay_micro_tile_mode == bw_def_display_micro_tiling) {
data->orthogonal_rotation[i] = 0;
}
else {
@@ -643,7 +643,7 @@ static void calculate_bandwidth(
}
else {
/*graphics landscape tiling mode*/
- if ((data->graphics_micro_tile_mode == bw_def_display_micro_tiling)) {
+ if (data->graphics_micro_tile_mode == bw_def_display_micro_tiling) {
data->orthogonal_rotation[i] = 0;
}
else {
@@ -947,14 +947,14 @@ static void calculate_bandwidth(
}
for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
if (data->enable[i]) {
- if ((data->number_of_displays == 1 && data->number_of_underlay_surfaces == 0)) {
+ if (data->number_of_displays == 1 && data->number_of_underlay_surfaces == 0) {
/*set maximum chunk limit if only one graphic pipe is enabled*/
data->outstanding_chunk_request_limit[i] = bw_int_to_fixed(127);
}
else {
data->outstanding_chunk_request_limit[i] = bw_ceil2(bw_div(data->adjusted_data_buffer_size[i], data->pipe_chunk_size_in_bytes[i]), bw_int_to_fixed(1));
/*clamp maximum chunk limit in the graphic display pipe*/
- if ((i >= 4)) {
+ if (i >= 4) {
data->outstanding_chunk_request_limit[i] = bw_max2(bw_int_to_fixed(127), data->outstanding_chunk_request_limit[i]);
}
}
@@ -1337,7 +1337,7 @@ static void calculate_bandwidth(
/*if stutter and dram clock state change are gated before cursor then the cursor latency hiding does not limit stutter or dram clock state change*/
for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
if (data->enable[i]) {
- if ((dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1)) {
+ if (dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1) {
data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], bw_mul(bw_frc_to_fixed(8, 10), data->total_dmifmc_urgent_latency));
}
else {
@@ -1396,7 +1396,7 @@ static void calculate_bandwidth(
}
/*determine the number of displays with margin to switch in the v_active region*/
for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
- if ((data->enable[k] == 1 && data->display_pstate_change_enable[k] == 1)) {
+ if (data->enable[k] == 1 && data->display_pstate_change_enable[k] == 1) {
number_of_displays_enabled_with_margin = number_of_displays_enabled_with_margin + 1;
}
}
@@ -1442,7 +1442,7 @@ static void calculate_bandwidth(
data->nbp_state_change_enable = bw_def_no;
}
/*dram clock change is possible only in vblank if all displays are aligned and have no margin*/
- if ((number_of_aligned_displays_with_no_margin == number_of_displays_enabled)) {
+ if (number_of_aligned_displays_with_no_margin == number_of_displays_enabled) {
nbp_state_change_enable_blank = bw_def_yes;
}
else {
@@ -1470,7 +1470,7 @@ static void calculate_bandwidth(
}
}
/*compute minimum time to read one chunk from the dmif buffer*/
- if ((number_of_displays_enabled > 2)) {
+ if (number_of_displays_enabled > 2) {
data->chunk_request_delay = 0;
}
else {
@@ -1804,7 +1804,7 @@ static void calculate_bandwidth(
data->stutter_exit_watermark[i] = bw_add(bw_sub(vbios->stutter_self_refresh_exit_latency, data->total_dmifmc_urgent_latency), data->urgent_watermark[i]);
data->stutter_entry_watermark[i] = bw_add(bw_sub(bw_add(vbios->stutter_self_refresh_exit_latency, vbios->stutter_self_refresh_entry_latency), data->total_dmifmc_urgent_latency), data->urgent_watermark[i]);
/*unconditionally remove black out time from the nb p_state watermark*/
- if ((data->display_pstate_change_enable[i] == 1)) {
+ if (data->display_pstate_change_enable[i] == 1) {
data->nbp_state_change_watermark[i] = bw_add(bw_add(vbios->nbp_state_change_latency, data->dmif_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->dram_speed_change_line_source_transfer_time[i][data->y_clk_level][data->sclk_level]));
}
else {
@@ -1816,7 +1816,7 @@ static void calculate_bandwidth(
data->urgent_watermark[i] = bw_add(bw_add(bw_add(bw_add(bw_add(vbios->mcifwrmc_urgent_latency, data->mcifwr_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->line_source_transfer_time[i][data->y_clk_level][data->sclk_level])), vbios->blackout_duration), data->chunk_request_time), data->cursor_request_time);
data->stutter_exit_watermark[i] = bw_int_to_fixed(0);
data->stutter_entry_watermark[i] = bw_int_to_fixed(0);
- if ((data->display_pstate_change_enable[i] == 1)) {
+ if (data->display_pstate_change_enable[i] == 1) {
data->nbp_state_change_watermark[i] = bw_add(bw_add(vbios->nbp_state_change_latency, data->mcifwr_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->dram_speed_change_line_source_transfer_time[i][data->y_clk_level][data->sclk_level]));
}
else {
@@ -2033,8 +2033,8 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
vbios.cursor_width = 32;
vbios.average_compression_rate = 4;
vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
- vbios.blackout_duration = bw_int_to_fixed(18); /* us */
- vbios.maximum_blackout_recovery_time = bw_int_to_fixed(20);
+ vbios.blackout_duration = bw_int_to_fixed(0); /* us */
+ vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
dceip.large_cursor = false;
dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
@@ -2366,8 +2366,8 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
vbios.cursor_width = 32;
vbios.average_compression_rate = 4;
vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
- vbios.blackout_duration = bw_int_to_fixed(18); /* us */
- vbios.maximum_blackout_recovery_time = bw_int_to_fixed(20);
+ vbios.blackout_duration = bw_int_to_fixed(0); /* us */
+ vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
dceip.large_cursor = false;
dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
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 331891c2c71a..c9aa686d16b9 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
@@ -486,6 +486,7 @@ static void split_stream_across_pipes(
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];
+ secondary_pipe->plane_res.mpcc_inst = pool->dpps[secondary_pipe->pipe_idx]->inst;
if (primary_pipe->bottom_pipe) {
ASSERT(primary_pipe->bottom_pipe != secondary_pipe);
secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
@@ -625,7 +626,7 @@ static bool dcn_bw_apply_registry_override(struct dc *dc)
return updated;
}
-void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
+static void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
{
/*
* disable optional pipe split by lower dispclk bounding box
@@ -634,7 +635,7 @@ void hack_disable_optional_pipe_split(struct dcn_bw_internal_vars *v)
v->max_dispclk[0] = v->max_dppclk_vmin0p65;
}
-void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
+static void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
unsigned int pixel_rate_khz)
{
float pixel_rate_mhz = pixel_rate_khz / 1000;
@@ -647,25 +648,20 @@ void hack_force_pipe_split(struct dcn_bw_internal_vars *v,
v->max_dppclk[0] = pixel_rate_mhz;
}
-void hack_bounding_box(struct dcn_bw_internal_vars *v,
+static 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) {
+ 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) {
+ 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);
- }
+ dbg->force_single_disp_pipe_split)
+ hack_force_pipe_split(v, context->streams[0]->timing.pix_clk_khz);
}
bool dcn_validate_bandwidth(
@@ -799,23 +795,10 @@ bool dcn_validate_bandwidth(
v->phyclk_per_state[2] = v->phyclkv_nom0p8;
v->phyclk_per_state[1] = v->phyclkv_mid0p72;
v->phyclk_per_state[0] = v->phyclkv_min0p65;
-
- hack_bounding_box(v, &dc->debug, context);
-
- if (v->voltage_override == dcn_bw_v_max0p9) {
- v->voltage_override_level = number_of_states - 1;
- } else if (v->voltage_override == dcn_bw_v_nom0p8) {
- v->voltage_override_level = number_of_states - 2;
- } else if (v->voltage_override == dcn_bw_v_mid0p72) {
- v->voltage_override_level = number_of_states - 3;
- } else {
- v->voltage_override_level = 0;
- }
v->synchronized_vblank = dcn_bw_no;
v->ta_pscalculation = dcn_bw_override;
v->allow_different_hratio_vratio = dcn_bw_yes;
-
for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
@@ -948,8 +931,19 @@ bool dcn_validate_bandwidth(
v->number_of_active_planes = input_idx;
scaler_settings_calculation(v);
+
+ hack_bounding_box(v, &dc->debug, context);
+
mode_support_and_system_configuration(v);
+ /* Unhack dppclk: dont bother with trying to pipe split if we cannot maintain dpm0 */
+ if (v->voltage_level != 0
+ && context->stream_count == 1
+ && dc->debug.force_single_disp_pipe_split) {
+ v->max_dppclk[0] = v->max_dppclk_vmin0p65;
+ mode_support_and_system_configuration(v);
+ }
+
if (v->voltage_level == 0 &&
(dc->debug.sr_exit_time_dpm0_ns
|| dc->debug.sr_enter_plus_exit_time_dpm0_ns)) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 35e84ed031de..77a1bf233c3c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -29,6 +29,7 @@
#include "core_status.h"
#include "core_types.h"
#include "hw_sequencer.h"
+#include "dce/dce_hwseq.h"
#include "resource.h"
@@ -38,6 +39,7 @@
#include "bios_parser_interface.h"
#include "include/irq_service_interface.h"
#include "transform.h"
+#include "dmcu.h"
#include "dpp.h"
#include "timing_generator.h"
#include "virtual/virtual_link_encoder.h"
@@ -214,6 +216,130 @@ bool dc_stream_get_crtc_position(struct dc *dc,
return ret;
}
+/**
+ * dc_stream_configure_crc: Configure CRC capture for the given stream.
+ * @dc: DC Object
+ * @stream: The stream to configure CRC on.
+ * @enable: Enable CRC if true, disable otherwise.
+ * @continuous: Capture CRC on every frame if true. Otherwise, only capture
+ * once.
+ *
+ * By default, only CRC0 is configured, and the entire frame is used to
+ * calculate the crc.
+ */
+bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
+ bool enable, bool continuous)
+{
+ int i;
+ struct pipe_ctx *pipe;
+ struct crc_params param;
+ struct timing_generator *tg;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (pipe->stream == stream)
+ break;
+ }
+ /* Stream not found */
+ if (i == MAX_PIPES)
+ return false;
+
+ /* Always capture the full frame */
+ param.windowa_x_start = 0;
+ param.windowa_y_start = 0;
+ param.windowa_x_end = pipe->stream->timing.h_addressable;
+ param.windowa_y_end = pipe->stream->timing.v_addressable;
+ param.windowb_x_start = 0;
+ param.windowb_y_start = 0;
+ param.windowb_x_end = pipe->stream->timing.h_addressable;
+ param.windowb_y_end = pipe->stream->timing.v_addressable;
+
+ /* Default to the union of both windows */
+ param.selection = UNION_WINDOW_A_B;
+ param.continuous_mode = continuous;
+ param.enable = enable;
+
+ tg = pipe->stream_res.tg;
+
+ /* Only call if supported */
+ if (tg->funcs->configure_crc)
+ return tg->funcs->configure_crc(tg, &param);
+ dm_logger_write(dc->ctx->logger, LOG_WARNING, "CRC capture not supported.");
+ return false;
+}
+
+/**
+ * dc_stream_get_crc: Get CRC values for the given stream.
+ * @dc: DC object
+ * @stream: The DC stream state of the stream to get CRCs from.
+ * @r_cr, g_y, b_cb: CRC values for the three channels are stored here.
+ *
+ * dc_stream_configure_crc needs to be called beforehand to enable CRCs.
+ * Return false if stream is not found, or if CRCs are not enabled.
+ */
+bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream,
+ uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
+{
+ int i;
+ struct pipe_ctx *pipe;
+ struct timing_generator *tg;
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ if (pipe->stream == stream)
+ break;
+ }
+ /* Stream not found */
+ if (i == MAX_PIPES)
+ return false;
+
+ tg = pipe->stream_res.tg;
+
+ if (tg->funcs->get_crc)
+ return tg->funcs->get_crc(tg, r_cr, g_y, b_cb);
+ dm_logger_write(dc->ctx->logger, LOG_WARNING, "CRC capture not supported.");
+ return false;
+}
+
+void dc_stream_set_dither_option(struct dc_stream_state *stream,
+ enum dc_dither_option option)
+{
+ struct bit_depth_reduction_params params;
+ struct dc_link *link = stream->status.link;
+ 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;
+ }
+ }
+
+ if (!pipes)
+ return;
+ if (option > DITHER_OPTION_MAX)
+ return;
+
+ stream->dither_option = option;
+
+ memset(&params, 0, sizeof(params));
+ resource_build_bit_depth_reduction_params(stream, &params);
+ stream->bit_depth_params = params;
+
+ if (pipes->plane_res.xfm &&
+ pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) {
+ pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
+ pipes->plane_res.xfm,
+ pipes->plane_res.scl_data.lb_params.depth,
+ &stream->bit_depth_params);
+ }
+
+ pipes->stream_res.opp->funcs->
+ opp_program_bit_depth_reduction(pipes->stream_res.opp, &params);
+}
+
void dc_stream_set_static_screen_events(struct dc *dc,
struct dc_stream_state **streams,
int num_streams,
@@ -359,9 +485,6 @@ static bool construct(struct dc *dc,
dc_version = resource_parse_asic_id(init_params->asic_id);
dc_ctx->dce_version = dc_version;
-#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.
* This should be the only place where we need to parse the asic id
*/
@@ -487,6 +610,12 @@ struct dc *dc_create(const struct dc_init_data *init_params)
dc->caps.max_audios = dc->res_pool->audio_count;
dc->caps.linear_pitch_alignment = 64;
+ /* Populate versioning information */
+ dc->versions.dc_ver = DC_VER;
+
+ if (dc->res_pool->dmcu != NULL)
+ dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version;
+
dc->config = init_params->flags;
dm_logger_write(dc->ctx->logger, LOG_DC,
@@ -524,11 +653,13 @@ static void enable_timing_multisync(
if (!ctx->res_ctx.pipe_ctx[i].stream ||
!ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled)
continue;
+ if (ctx->res_ctx.pipe_ctx[i].stream == ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.event_source)
+ continue;
multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i];
multisync_count++;
}
- if (multisync_count > 1) {
+ if (multisync_count > 0) {
dc->hwss.enable_per_frame_crtc_position_reset(
dc, multisync_count, multisync_pipes);
}
@@ -650,7 +781,6 @@ bool dc_enable_stereo(
return ret;
}
-
/*
* Applies given context to HW and copy it into current context.
* It's up to the user to release the src context afterwards.
@@ -669,7 +799,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
dc_streams[i] = context->streams[i];
if (!dcb->funcs->is_accelerated_mode(dcb))
- dc->hwss.enable_accelerated_mode(dc);
+ dc->hwss.enable_accelerated_mode(dc, context);
/* re-program planes for existing stream, in case we need to
* free up plane resource for later use
@@ -973,12 +1103,18 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
if (u->plane_info->input_tf != u->surface->input_tf)
update_flags->bits.input_tf_change = 1;
+ if (u->plane_info->sdr_white_level != u->surface->sdr_white_level)
+ update_flags->bits.output_tf_change = 1;
+
if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror)
update_flags->bits.horizontal_mirror_change = 1;
if (u->plane_info->rotation != u->surface->rotation)
update_flags->bits.rotation_change = 1;
+ if (u->plane_info->format != u->surface->format)
+ update_flags->bits.pixel_format_change = 1;
+
if (u->plane_info->stereo_format != u->surface->stereo_format)
update_flags->bits.stereo_format_change = 1;
@@ -997,6 +1133,9 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
*/
update_flags->bits.bpp_change = 1;
+ if (u->gamma && dce_use_lut(u->plane_info->format))
+ update_flags->bits.gamma_change = 1;
+
if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
sizeof(union dc_tiling_info)) != 0) {
update_flags->bits.swizzle_change = 1;
@@ -1012,8 +1151,11 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa
if (update_flags->bits.rotation_change
|| update_flags->bits.stereo_format_change
+ || update_flags->bits.pixel_format_change
+ || update_flags->bits.gamma_change
|| update_flags->bits.bpp_change
- || update_flags->bits.bandwidth_change)
+ || update_flags->bits.bandwidth_change
+ || update_flags->bits.output_tf_change)
return UPDATE_TYPE_FULL;
return UPDATE_TYPE_MED;
@@ -1092,12 +1234,12 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
elevate_update_type(&overall_type, type);
if (u->in_transfer_func)
- update_flags->bits.in_transfer_func = 1;
+ update_flags->bits.in_transfer_func_change = 1;
if (u->input_csc_color_matrix)
update_flags->bits.input_csc_change = 1;
- if (update_flags->bits.in_transfer_func
+ if (update_flags->bits.in_transfer_func_change
|| update_flags->bits.input_csc_change) {
type = UPDATE_TYPE_MED;
elevate_update_type(&overall_type, type);
@@ -1183,6 +1325,7 @@ static void commit_planes_for_stream(struct dc *dc,
struct dc_state *context)
{
int i, j;
+ struct pipe_ctx *top_pipe_to_program = NULL;
if (update_type == UPDATE_TYPE_FULL) {
dc->hwss.set_bandwidth(dc, context, false);
@@ -1202,13 +1345,17 @@ static void commit_planes_for_stream(struct dc *dc,
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
- if (update_type == UPDATE_TYPE_FAST || !pipe_ctx->plane_state)
- continue;
-
if (!pipe_ctx->top_pipe &&
- pipe_ctx->stream &&
- pipe_ctx->stream == stream) {
- struct dc_stream_status *stream_status =
+ pipe_ctx->stream &&
+ pipe_ctx->stream == stream) {
+ struct dc_stream_status *stream_status = NULL;
+
+ top_pipe_to_program = pipe_ctx;
+
+ if (update_type == UPDATE_TYPE_FAST || !pipe_ctx->plane_state)
+ continue;
+
+ stream_status =
stream_get_status(context, pipe_ctx->stream);
dc->hwss.apply_ctx_for_surface(
@@ -1219,22 +1366,32 @@ static void commit_planes_for_stream(struct dc *dc,
if (update_type == UPDATE_TYPE_FULL)
context_timing_trace(dc, &context->res_ctx);
- /* Perform requested Updates */
- for (i = 0; i < surface_count; i++) {
- struct dc_plane_state *plane_state = srf_updates[i].surface;
+ /* Lock the top pipe while updating plane addrs, since freesync requires
+ * plane addr update event triggers to be synchronized.
+ * top_pipe_to_program is expected to never be NULL
+ */
+ if (update_type == UPDATE_TYPE_FAST) {
+ dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true);
- for (j = 0; j < dc->res_pool->pipe_count; j++) {
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
+ /* Perform requested Updates */
+ for (i = 0; i < surface_count; i++) {
+ struct dc_plane_state *plane_state = srf_updates[i].surface;
- if (pipe_ctx->stream != stream)
- continue;
+ 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 != plane_state)
- continue;
+ if (pipe_ctx->stream != stream)
+ continue;
- if (update_type == UPDATE_TYPE_FAST && srf_updates[i].flip_addr)
+ if (pipe_ctx->plane_state != plane_state)
+ continue;
+
+ if (srf_updates[i].flip_addr)
dc->hwss.update_plane_addr(dc, pipe_ctx);
+ }
}
+
+ dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
}
if (stream && stream_update && update_type > UPDATE_TYPE_FAST)
@@ -1487,12 +1644,17 @@ struct dc_sink *dc_link_add_remote_sink(
&dc_sink->dc_edid,
&dc_sink->edid_caps);
- if (edid_status != EDID_OK)
- goto fail;
+ /*
+ * Treat device as no EDID device if EDID
+ * parsing fails
+ */
+ if (edid_status != EDID_OK) {
+ dc_sink->dc_edid.length = 0;
+ dm_error("Bad EDID, status%d!\n", edid_status);
+ }
return dc_sink;
-fail:
- dc_link_remove_remote_sink(link, dc_sink);
+
fail_add_sink:
dc_sink_release(dc_sink);
return NULL;
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 a37428271573..95955ade4012 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -126,6 +126,8 @@ static bool program_hpd_filter(
int delay_on_connect_in_ms = 0;
int delay_on_disconnect_in_ms = 0;
+ if (link->is_hpd_filter_disabled)
+ return false;
/* Verify feature is supported */
switch (link->connector_signal) {
case SIGNAL_TYPE_DVI_SINGLE_LINK:
@@ -464,7 +466,7 @@ static void link_disconnect_sink(struct dc_link *link)
link->dpcd_sink_count = 0;
}
-static void detect_dp(
+static bool detect_dp(
struct dc_link *link,
struct display_sink_capability *sink_caps,
bool *converter_disable_audio,
@@ -478,7 +480,8 @@ static void detect_dp(
if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
- detect_dp_sink_caps(link);
+ if (!detect_dp_sink_caps(link))
+ return false;
if (is_mst_supported(link)) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
@@ -529,7 +532,7 @@ static void detect_dp(
* active dongle unplug processing for short irq
*/
link_disconnect_sink(link);
- return;
+ return true;
}
if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER)
@@ -541,6 +544,8 @@ static void detect_dp(
sink_caps,
audio_support);
}
+
+ return true;
}
bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
@@ -604,11 +609,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
}
case SIGNAL_TYPE_DISPLAY_PORT: {
- detect_dp(
+ if (!detect_dp(
link,
&sink_caps,
&converter_disable_audio,
- aud_support, reason);
+ aud_support, reason))
+ return false;
/* Active dongle downstream unplug */
if (link->type == dc_connection_active_dongle
@@ -677,8 +683,6 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
case EDID_NO_RESPONSE:
dm_logger_write(link->ctx->logger, LOG_ERROR,
"No EDID read.\n");
- return false;
-
default:
break;
}
@@ -1248,6 +1252,12 @@ static enum dc_status enable_link_dp(
pipe_ctx->clock_source->id,
&link_settings);
+ if (stream->sink->edid_caps.panel_patch.dppowerup_delay > 0) {
+ int delay_dp_power_up_in_ms = stream->sink->edid_caps.panel_patch.dppowerup_delay;
+
+ msleep(delay_dp_power_up_in_ms);
+ }
+
panel_mode = dp_get_panel_mode(link);
dpcd_configure_panel_mode(link, panel_mode);
@@ -1279,13 +1289,12 @@ static enum dc_status enable_link_edp(
enum dc_status status;
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->sink->link;
-
+ /*in case it is not on*/
link->dc->hwss.edp_power_control(link, true);
link->dc->hwss.edp_wait_for_hpd_ready(link, true);
status = enable_link_dp(state, pipe_ctx);
- link->dc->hwss.edp_backlight_control(link, true);
return status;
}
@@ -1749,8 +1758,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
link->link_enc,
pipe_ctx->clock_source->id,
display_color_depth,
- pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A,
- pipe_ctx->stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK,
+ pipe_ctx->stream->signal,
stream->phy_pix_clk);
if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
@@ -1788,9 +1796,21 @@ static enum dc_status enable_link(
}
if (pipe_ctx->stream_res.audio && status == DC_OK) {
+ struct dc *core_dc = pipe_ctx->stream->ctx->dc;
/* notify audio driver for audio modes of monitor */
+ struct pp_smu_funcs_rv *pp_smu = core_dc->res_pool->pp_smu;
+ unsigned int i, num_audio = 1;
+ for (i = 0; i < MAX_PIPES; i++) {
+ /*current_state not updated yet*/
+ if (core_dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL)
+ num_audio++;
+ }
+
pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio);
+ if (num_audio == 1 && pp_smu != NULL && pp_smu->set_pme_wa_enable != NULL)
+ /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
+ pp_smu->set_pme_wa_enable(&pp_smu->pp_smu);
/* un-mute audio */
/* TODO: audio should be per stream rather than per link */
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
@@ -2268,7 +2288,16 @@ void core_link_enable_stream(
{
struct dc *core_dc = pipe_ctx->stream->ctx->dc;
- enum dc_status status = enable_link(state, pipe_ctx);
+ enum dc_status status;
+
+ /* eDP lit up by bios already, no need to enable again. */
+ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP &&
+ core_dc->apply_edp_fast_boot_optimization) {
+ core_dc->apply_edp_fast_boot_optimization = false;
+ return;
+ }
+
+ status = enable_link(state, pipe_ctx);
if (status != DC_OK) {
dm_logger_write(pipe_ctx->stream->ctx->logger,
@@ -2298,9 +2327,8 @@ 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);
+ 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, int option)
@@ -2310,8 +2338,7 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option)
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
- if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP)
- core_dc->hwss.edp_backlight_control(pipe_ctx->stream->sink->link, false);
+ core_dc->hwss.blank_stream(pipe_ctx);
core_dc->hwss.disable_stream(pipe_ctx, option);
@@ -2328,3 +2355,33 @@ void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable)
core_dc->hwss.set_avmute(pipe_ctx, enable);
}
+void dc_link_disable_hpd_filter(struct dc_link *link)
+{
+ struct gpio *hpd;
+
+ if (!link->is_hpd_filter_disabled) {
+ link->is_hpd_filter_disabled = true;
+ /* Obtain HPD handle */
+ hpd = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
+
+ if (!hpd)
+ return;
+
+ /* Setup HPD filtering */
+ if (dal_gpio_open(hpd, GPIO_MODE_INTERRUPT) == GPIO_RESULT_OK) {
+ struct gpio_hpd_config config;
+
+ config.delay_on_connect = 0;
+ config.delay_on_disconnect = 0;
+
+ dal_irq_setup_hpd_filter(hpd, &config);
+
+ dal_gpio_close(hpd);
+ } else {
+ ASSERT_CRITICAL(false);
+ }
+ /* Release HPD handle */
+ dal_gpio_destroy_irq(&hpd);
+ }
+}
+
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 61e8c3e02d16..604fb0171ee3 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
@@ -718,7 +718,7 @@ static enum link_training_result perform_channel_equalization_sequence(
uint32_t retries_ch_eq;
enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
union lane_align_status_updated dpcd_lane_status_updated = {{0}};
- union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};;
+ union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};
hw_tr_pattern = get_supported_tp(link);
@@ -1465,7 +1465,7 @@ void decide_link_settings(struct dc_stream_state *stream,
/* MST doesn't perform link training for now
* TODO: add MST specific link training routine
*/
- if (is_mst_supported(link)) {
+ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
*link_setting = link->verified_link_cap;
return;
}
@@ -2235,13 +2235,14 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
link->wa_flags.dp_keep_receiver_powered = false;
}
-static void retrieve_link_cap(struct dc_link *link)
+static bool retrieve_link_cap(struct dc_link *link)
{
uint8_t dpcd_data[DP_TRAINING_AUX_RD_INTERVAL - DP_DPCD_REV + 1];
union down_stream_port_count down_strm_port_count;
union edp_configuration_cap edp_config_cap;
union dp_downstream_port_present ds_port = { 0 };
+ enum dc_status status = DC_ERROR_UNEXPECTED;
memset(dpcd_data, '\0', sizeof(dpcd_data));
memset(&down_strm_port_count,
@@ -2249,11 +2250,16 @@ static void retrieve_link_cap(struct dc_link *link)
memset(&edp_config_cap, '\0',
sizeof(union edp_configuration_cap));
- core_link_read_dpcd(
- link,
- DP_DPCD_REV,
- dpcd_data,
- sizeof(dpcd_data));
+ status = core_link_read_dpcd(
+ link,
+ DP_DPCD_REV,
+ dpcd_data,
+ sizeof(dpcd_data));
+
+ if (status != DC_OK) {
+ dm_error("%s: Read dpcd data failed.\n", __func__);
+ return false;
+ }
{
union training_aux_rd_interval aux_rd_interval;
@@ -2315,11 +2321,13 @@ static void retrieve_link_cap(struct dc_link *link)
/* Connectivity log: detection */
CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
+
+ return true;
}
-void detect_dp_sink_caps(struct dc_link *link)
+bool detect_dp_sink_caps(struct dc_link *link)
{
- retrieve_link_cap(link);
+ return retrieve_link_cap(link);
/* dc init_hw has power encoder using default
* signal for connector. For native DP, no
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 2096f2a179f2..bae9b0587e12 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
@@ -102,7 +102,7 @@ void dp_enable_link_phy(
dp_receiver_power_ctrl(link, true);
}
-static bool edp_receiver_ready_T9(struct dc_link *link)
+bool edp_receiver_ready_T9(struct dc_link *link)
{
unsigned int tries = 0;
unsigned char sinkstatus = 0;
@@ -123,6 +123,28 @@ static bool edp_receiver_ready_T9(struct dc_link *link)
} while (++tries < 50);
return result;
}
+bool edp_receiver_ready_T7(struct dc_link *link)
+{
+ unsigned int tries = 0;
+ unsigned char sinkstatus = 0;
+ unsigned char edpRev = 0;
+ enum dc_status result = DC_OK;
+
+ result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
+ if (result == DC_OK && edpRev < DP_EDP_12)
+ return true;
+ /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
+ do {
+ sinkstatus = 0;
+ result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
+ if (sinkstatus == 1)
+ break;
+ if (result != DC_OK)
+ break;
+ udelay(25); //MAx T7 is 50ms
+ } while (++tries < 300);
+ return result;
+}
void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
{
@@ -130,7 +152,6 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
dp_receiver_power_ctrl(link, false);
if (signal == SIGNAL_TYPE_EDP) {
- edp_receiver_ready_T9(link);
link->link_enc->funcs->disable_output(link->link_enc, signal);
link->dc->hwss.edp_power_control(link, false);
} else
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 95b8dd0e53c6..ce0e9e76eb35 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -35,6 +35,7 @@
#include "core_types.h"
#include "set_mode_types.h"
#include "virtual/virtual_stream_encoder.h"
+#include "dpcd_defs.h"
#include "dce80/dce80_resource.h"
#include "dce100/dce100_resource.h"
@@ -696,7 +697,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
/* Adjust for viewport end clip-off */
- if ((data->viewport.x + data->viewport.width) < (src.x + src.width)) {
+ if ((data->viewport.x + data->viewport.width) < (src.x + src.width) && !flip_horz_scan_dir) {
int vp_clip = src.x + src.width - data->viewport.width - data->viewport.x;
int int_part = dal_fixed31_32_floor(
dal_fixed31_32_sub(data->inits.h, data->ratios.horz));
@@ -704,7 +705,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
int_part = int_part > 0 ? int_part : 0;
data->viewport.width += int_part < vp_clip ? int_part : vp_clip;
}
- if ((data->viewport.y + data->viewport.height) < (src.y + src.height)) {
+ if ((data->viewport.y + data->viewport.height) < (src.y + src.height) && !flip_vert_scan_dir) {
int vp_clip = src.y + src.height - data->viewport.height - data->viewport.y;
int int_part = dal_fixed31_32_floor(
dal_fixed31_32_sub(data->inits.v, data->ratios.vert));
@@ -712,7 +713,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
int_part = int_part > 0 ? int_part : 0;
data->viewport.height += int_part < vp_clip ? int_part : vp_clip;
}
- if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div) {
+ if ((data->viewport_c.x + data->viewport_c.width) < (src.x + src.width) / vpc_div && !flip_horz_scan_dir) {
int vp_clip = (src.x + src.width) / vpc_div -
data->viewport_c.width - data->viewport_c.x;
int int_part = dal_fixed31_32_floor(
@@ -721,7 +722,7 @@ static void calculate_inits_and_adj_vp(struct pipe_ctx *pipe_ctx, struct view *r
int_part = int_part > 0 ? int_part : 0;
data->viewport_c.width += int_part < vp_clip ? int_part : vp_clip;
}
- if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div) {
+ if ((data->viewport_c.y + data->viewport_c.height) < (src.y + src.height) / vpc_div && !flip_vert_scan_dir) {
int vp_clip = (src.y + src.height) / vpc_div -
data->viewport_c.height - data->viewport_c.y;
int int_part = dal_fixed31_32_floor(
@@ -1054,6 +1055,7 @@ static int acquire_first_split_pipe(
pipe_ctx->plane_res.ipp = pool->ipps[i];
pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i];
+ pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
pipe_ctx->pipe_idx = i;
pipe_ctx->stream = stream;
@@ -1360,9 +1362,6 @@ bool dc_is_stream_scaling_unchanged(
return true;
}
-/* Maximum TMDS single link pixel clock 165MHz */
-#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
-
static void update_stream_engine_usage(
struct resource_context *res_ctx,
const struct resource_pool *pool,
@@ -1409,6 +1408,8 @@ static int acquire_first_free_pipe(
pipe_ctx->plane_res.xfm = pool->transforms[i];
pipe_ctx->plane_res.dpp = pool->dpps[i];
pipe_ctx->stream_res.opp = pool->opps[i];
+ if (pool->dpps[i])
+ pipe_ctx->plane_res.mpcc_inst = pool->dpps[i]->inst;
pipe_ctx->pipe_idx = i;
@@ -1555,6 +1556,9 @@ enum dc_status dc_remove_stream_from_ctx(
dc->res_pool,
del_pipe->clock_source);
+ if (dc->res_pool->funcs->remove_stream_from_ctx)
+ dc->res_pool->funcs->remove_stream_from_ctx(dc, new_ctx, stream);
+
memset(del_pipe, 0, sizeof(*del_pipe));
break;
@@ -2431,7 +2435,8 @@ static void set_vsc_info_packet(
unsigned int vscPacketRevision = 0;
unsigned int i;
- if (stream->sink->link->psr_enabled) {
+ /*VSC packet set to 2 when DP revision >= 1.2*/
+ if (stream->sink->link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
vscPacketRevision = 2;
}
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 261811e0c094..87a193ac2883 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -33,8 +33,7 @@
/*******************************************************************************
* Private functions
******************************************************************************/
-#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000
-static void update_stream_signal(struct dc_stream_state *stream)
+void update_stream_signal(struct dc_stream_state *stream)
{
struct dc_sink *dc_sink = stream->sink;
@@ -45,8 +44,9 @@ static void update_stream_signal(struct dc_stream_state *stream)
stream->signal = dc_sink->sink_signal;
if (dc_is_dvi_signal(stream->signal)) {
- if (stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST &&
- stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
+ if (stream->ctx->dc->caps.dual_link_dvi &&
+ stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK &&
+ stream->sink->sink_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
stream->signal = SIGNAL_TYPE_DVI_DUAL_LINK;
else
stream->signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
@@ -193,6 +193,7 @@ bool dc_stream_set_cursor_attributes(
core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx;
+ stream->cursor_attributes = *attributes;
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
@@ -203,34 +204,8 @@ bool dc_stream_set_cursor_attributes(
continue;
- 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->color_format);
+ core_dc->hwss.set_cursor_attribute(pipe_ctx);
}
-
- stream->cursor_attributes = *attributes;
-
return true;
}
@@ -254,21 +229,10 @@ bool dc_stream_set_cursor_position(
core_dc = stream->ctx->dc;
res_ctx = &core_dc->current_state->res_ctx;
+ stream->cursor_position = *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 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,
- .ref_clk_khz = core_dc->res_pool->ref_clock_inKhz,
- .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
- .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
- .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
- };
if (pipe_ctx->stream != stream ||
(!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) ||
@@ -276,33 +240,9 @@ bool dc_stream_set_cursor_position(
(!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp))
continue;
- if (pipe_ctx->plane_state->address.type
- == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
- pos_cpy.enable = false;
-
- if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
- pos_cpy.enable = false;
-
-
- if (ipp != NULL && 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)
- continue;
-
- if (hubp->funcs->set_cursor_position != NULL)
- hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
-
- if (dpp != NULL && dpp->funcs->set_cursor_position != NULL)
- dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
-
+ core_dc->hwss.set_cursor_position(pipe_ctx);
}
- stream->cursor_position = *position;
-
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index e2e3c9df79ea..5bb0e5defaf4 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.27"
+#define DC_VER "3.1.34"
#define MAX_SURFACES 3
#define MAX_STREAMS 6
@@ -48,6 +48,18 @@
/*******************************************************************************
* Display Core Interfaces
******************************************************************************/
+struct dmcu_version {
+ unsigned int date;
+ unsigned int month;
+ unsigned int year;
+ unsigned int interface_version;
+};
+
+struct dc_versions {
+ const char *dc_ver;
+ struct dmcu_version dmcu_version;
+};
+
struct dc_caps {
uint32_t max_streams;
uint32_t max_links;
@@ -62,6 +74,7 @@ struct dc_caps {
bool dcc_const_color;
bool dynamic_audio;
bool is_apu;
+ bool dual_link_dvi;
};
struct dc_dcc_surface_param {
@@ -94,6 +107,7 @@ struct dc_surface_dcc_cap {
};
struct dc_static_screen_events {
+ bool force_trigger;
bool cursor_update;
bool surface_update;
bool overlay_update;
@@ -211,11 +225,15 @@ struct dc_debug {
bool disable_stereo_support;
bool vsr_support;
bool performance_trace;
+ bool az_endpoint_mute_only;
+ bool always_use_regamma;
+ bool p010_mpo_support;
};
struct dc_state;
struct resource_pool;
struct dce_hwseq;
struct dc {
+ struct dc_versions versions;
struct dc_caps caps;
struct dc_cap_funcs cap_funcs;
struct dc_config config;
@@ -252,6 +270,8 @@ struct dc {
bool optimized_required;
+ bool apply_edp_fast_boot_optimization;
+
/* FBC compressor */
#if defined(CONFIG_DRM_AMD_DC_FBC)
struct compressor *fbc_compressor;
@@ -288,9 +308,6 @@ struct dc_init_data {
struct dc_config flags;
uint32_t log_mask;
-#if defined(CONFIG_DRM_AMD_DC_FBC)
- uint64_t fbc_gpu_addr;
-#endif
};
struct dc *dc_create(const struct dc_init_data *init_params);
@@ -369,6 +386,8 @@ struct dc_transfer_func {
struct dc_transfer_func_distributed_points tf_pts;
enum dc_transfer_func_type type;
enum dc_transfer_func_predefined tf;
+ /* FP16 1.0 reference level in nits, default is 80 nits, only for PQ*/
+ uint32_t sdr_ref_white_level;
struct dc_context *ctx;
};
@@ -397,12 +416,15 @@ union surface_update_flags {
uint32_t swizzle_change:1;
uint32_t scaling_change:1;
uint32_t position_change:1;
- uint32_t in_transfer_func:1;
+ uint32_t in_transfer_func_change:1;
uint32_t input_csc_change:1;
+ uint32_t output_tf_change:1;
+ uint32_t pixel_format_change:1;
/* Full updates */
uint32_t new_plane:1;
uint32_t bpp_change:1;
+ uint32_t gamma_change:1;
uint32_t bandwidth_change:1;
uint32_t clock_change:1;
uint32_t stereo_format_change:1;
@@ -429,6 +451,7 @@ struct dc_plane_state {
struct dc_bias_and_scale *bias_and_scale;
struct csc_transform input_csc_color_matrix;
struct fixed31_32 coeff_reduction_factor;
+ uint32_t sdr_white_level;
// TODO: No longer used, remove
struct dc_hdr_static_metadata hdr_static_ctx;
@@ -465,6 +488,7 @@ struct dc_plane_info {
enum plane_stereo_format stereo_format;
enum dc_color_space color_space;
enum color_transfer_func input_tf;
+ unsigned int sdr_white_level;
bool horizontal_mirror;
bool visible;
bool per_pixel_alpha;
@@ -489,10 +513,8 @@ struct dc_surface_update {
/* following updates require alloc/sleep/spin that is not isr safe,
* null means no updates
*/
- /* gamma TO BE REMOVED */
struct dc_gamma *gamma;
enum color_transfer_func color_input_tf;
- enum color_transfer_func color_output_tf;
struct dc_transfer_func *in_transfer_func;
struct csc_transform *input_csc_color_matrix;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
index 273d80a4ebce..d9b84ec7954c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_bios_types.h
@@ -111,6 +111,8 @@ struct dc_vbios_funcs {
struct dc_bios *bios);
bool (*is_accelerated_mode)(
struct dc_bios *bios);
+ uint32_t (*get_vga_enabled_displays)(
+ struct dc_bios *bios);
void (*get_bios_event_info)(
struct dc_bios *bios,
struct bios_event_info *info);
@@ -199,6 +201,7 @@ struct dc_vbios_funcs {
};
struct bios_registers {
+ uint32_t BIOS_SCRATCH_3;
uint32_t BIOS_SCRATCH_6;
};
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 03029f72dc3f..e91ac6811990 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -413,12 +413,14 @@ struct dc_cursor_mi_param {
enum {
GAMMA_RGB_256_ENTRIES = 256,
GAMMA_RGB_FLOAT_1024_ENTRIES = 1024,
- GAMMA_MAX_ENTRIES = 1024
+ GAMMA_CS_TFM_1D_ENTRIES = 4096,
+ GAMMA_MAX_ENTRIES = 4096
};
enum dc_gamma_type {
GAMMA_RGB_256 = 1,
- GAMMA_RGB_FLOAT_1024 = 2
+ GAMMA_RGB_FLOAT_1024 = 2,
+ GAMMA_CS_TFM_1D = 3,
};
struct dc_gamma {
@@ -434,6 +436,8 @@ struct dc_gamma {
/* private to DC core */
struct dc_context *ctx;
+
+ bool is_identity;
};
/* Used by both ipp amd opp functions*/
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index f11a734da1db..ac0f617b43c9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -64,6 +64,8 @@ struct dc_link {
enum signal_type connector_signal;
enum dc_irq_source irq_source_hpd;
enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */
+ bool is_hpd_filter_disabled;
+
/* caps is the same as reported_link_cap. link_traing use
* reported_link_cap. Will clean up. TODO
*/
@@ -195,6 +197,8 @@ bool dc_link_dp_set_test_pattern(
const unsigned char *p_custom_pattern,
unsigned int cust_pattern_size);
+void dc_link_disable_hpd_filter(struct dc_link *link);
+
/*
* DPCD access interfaces
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 01c60f11b2bd..78a2bbe0b272 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -65,6 +65,7 @@ struct dc_stream_state {
enum dc_dither_option dither_option;
enum view_3d_format view_format;
+ enum color_transfer_func output_tf;
bool ignore_msa_timing_param;
/* TODO: custom INFO packets */
@@ -103,6 +104,7 @@ struct dc_stream_update {
struct rect dst;
struct dc_transfer_func *out_transfer_func;
struct dc_hdr_static_metadata *hdr_static_metadata;
+ enum color_transfer_func color_output_tf;
};
bool dc_is_stream_unchanged(
@@ -152,7 +154,7 @@ struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i);
uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream);
/* TODO: Return parsed values rather than direct register read
- * This has a dependency on the caller (amdgpu_get_crtc_scanoutpos)
+ * This has a dependency on the caller (amdgpu_display_get_crtc_scanoutpos)
* being refactored properly to be dce-specific
*/
bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
@@ -237,6 +239,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
*/
struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink);
+void update_stream_signal(struct dc_stream_state *stream);
+
void dc_stream_retain(struct dc_stream_state *dc_stream);
void dc_stream_release(struct dc_stream_state *dc_stream);
@@ -267,11 +271,25 @@ bool dc_stream_get_crtc_position(struct dc *dc,
unsigned int *v_pos,
unsigned int *nom_v_pos);
+bool dc_stream_configure_crc(struct dc *dc,
+ struct dc_stream_state *stream,
+ bool enable,
+ bool continuous);
+
+bool dc_stream_get_crc(struct dc *dc,
+ struct dc_stream_state *stream,
+ uint32_t *r_cr,
+ uint32_t *g_y,
+ uint32_t *b_cb);
+
void dc_stream_set_static_screen_events(struct dc *dc,
struct dc_stream_state **stream,
int num_streams,
const struct dc_static_screen_events *events);
+void dc_stream_set_dither_option(struct dc_stream_state *stream,
+ enum dc_dither_option option);
+
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
struct dc_stream_state **stream,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 9faddfae241d..8811b6f86bff 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -193,6 +193,10 @@ union display_content_support {
} bits;
};
+struct dc_panel_patch {
+ unsigned int dppowerup_delay;
+};
+
struct dc_edid_caps {
/* sink identification */
uint16_t manufacturer_id;
@@ -219,6 +223,8 @@ struct dc_edid_caps {
bool edid_hdmi;
bool hdr_supported;
+
+ struct dc_panel_patch panel_patch;
};
struct view {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
index b48190f54907..b231bd53613e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c
@@ -323,6 +323,15 @@ static bool dce_abm_immediate_disable(struct abm *abm)
/* notifyDMCUMsg */
REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
+ abm->stored_backlight_registers.BL_PWM_CNTL =
+ REG_READ(BL_PWM_CNTL);
+ abm->stored_backlight_registers.BL_PWM_CNTL2 =
+ REG_READ(BL_PWM_CNTL2);
+ abm->stored_backlight_registers.BL_PWM_PERIOD_CNTL =
+ REG_READ(BL_PWM_PERIOD_CNTL);
+
+ REG_GET(LVTMA_PWRSEQ_REF_DIV, BL_PWM_REF_DIV,
+ &abm->stored_backlight_registers.LVTMA_PWRSEQ_REF_DIV_BL_PWM_REF_DIV);
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index 0df9ecb2710c..e366bfd7cf6f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -359,7 +359,10 @@ void dce_aud_az_enable(struct audio *audio)
AUDIO_ENABLED);
AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
- value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+ set_reg_field_value(value, 0,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
dm_logger_write(CTX->logger, LOG_HW_AUDIO,
"\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n",
@@ -372,6 +375,10 @@ void dce_aud_az_disable(struct audio *audio)
struct dce_audio *aud = DCE_AUD(audio);
value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+ set_reg_field_value(value, 1,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
set_reg_field_value(value, 0,
AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
@@ -716,6 +723,11 @@ void dce_aud_az_configure(
DESCRIPTION17);
AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value);
+ value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
+ set_reg_field_value(value, 0,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
}
/*
@@ -897,6 +909,10 @@ void dce_aud_hw_init(
REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
CLKSTOP, 1,
EPSS, 1);
+ set_reg_field_value(value, 0,
+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
+ CLOCK_GATING_DISABLE);
+ AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
}
static const struct audio_funcs funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
index 31280d252753..5036b674f68b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
@@ -908,19 +908,9 @@ static bool dce110_program_pix_clk(
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) {
unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0;
- unsigned dp_dto_ref_kHz = 600000;
- /* DPREF clock from FPGA TODO: Does FPGA have this value? */
+ unsigned dp_dto_ref_kHz = 700000;
unsigned clock_kHz = pll_settings->actual_pix_clk;
- /* For faster simulation, if mode pixe clock less than 290MHz,
- * pixel clock can be hard coded to 290Mhz. For 4K mode, pixel clock
- * is greater than 500Mhz, need real pixel clock
- * clock_kHz = 290000;
- */
- /* TODO: un-hardcode when we can set display clock properly*/
- /*clock_kHz = pix_clk_params->requested_pix_clk;*/
- clock_kHz = 290000;
-
/* Set DTO values: phase = target clock, modulo = reference clock */
REG_WRITE(PHASE[inst], clock_kHz);
REG_WRITE(MODULO[inst], dp_dto_ref_kHz);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
index 9e98a5f39a6d..046658c8498a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
@@ -34,6 +34,7 @@
#include "dcn_calcs.h"
#endif
#include "core_types.h"
+#include "dc_types.h"
#define TO_DCE_CLOCKS(clocks)\
@@ -292,7 +293,10 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state(
low_req_clk = i + 1;
if (low_req_clk > clk->max_clks_state) {
dm_logger_write(clk->ctx->logger, LOG_WARNING,
- "%s: clocks unsupported", __func__);
+ "%s: clocks unsupported disp_clk %d pix_clk %d",
+ __func__,
+ req_clocks->display_clk_khz,
+ req_clocks->pixel_clk_khz);
low_req_clk = DM_PP_CLOCKS_STATE_INVALID;
}
@@ -415,9 +419,12 @@ static int dce112_set_clock(
bp->funcs->set_dce_clock(bp, &dce_clk_params);
- if (clk_dce->dfs_bypass_disp_clk != actual_clock)
- dmcu->funcs->set_psr_wait_loop(dmcu,
- actual_clock / 1000 / 7);
+ if (!IS_FPGA_MAXIMUS_DC(core_dc->ctx->dce_environment)) {
+ if (clk_dce->dfs_bypass_disp_clk != actual_clock)
+ dmcu->funcs->set_psr_wait_loop(dmcu,
+ actual_clock / 1000 / 7);
+ }
+
clk_dce->dfs_bypass_disp_clk = actual_clock;
return actual_clock;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index f663adb33584..2ee3d9bf1062 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -360,7 +360,7 @@ static void dcn10_get_dmcu_version(struct dmcu *dmcu)
dmcu->dmcu_version.year = ((REG_READ(DMCU_IRAM_RD_DATA) << 8) |
REG_READ(DMCU_IRAM_RD_DATA));
dmcu->dmcu_version.month = REG_READ(DMCU_IRAM_RD_DATA);
- dmcu->dmcu_version.day = REG_READ(DMCU_IRAM_RD_DATA);
+ dmcu->dmcu_version.date = REG_READ(DMCU_IRAM_RD_DATA);
/* Disable write access to IRAM to allow dynamic sleep state */
REG_UPDATE_2(DMCU_RAM_ACCESS_CTRL,
@@ -521,6 +521,9 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
if (dmcu->dmcu_state != DMCU_RUNNING)
return;
+ dcn10_get_dmcu_psr_state(dmcu, &psr_state);
+ if (psr_state == 0 && !enable)
+ return;
/* waitDMCUReadyForCmd */
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
dmcu_wait_reg_ready_interval,
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
index d2e66b1bc0ef..4b8e7ce2de8c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
@@ -197,9 +197,9 @@ void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
}
/* Only use LUT for 8 bit formats */
-bool dce_use_lut(const struct dc_plane_state *plane_state)
+bool dce_use_lut(enum surface_pixel_format format)
{
- switch (plane_state->format) {
+ switch (format) {
case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
return true;
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 b73db9e78437..3336428b1fed 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h
@@ -140,42 +140,8 @@
BL_REG_LIST()
#define HWSEQ_DCN_REG_LIST()\
- SRII(DCHUBP_CNTL, HUBP, 0), \
- SRII(DCHUBP_CNTL, HUBP, 1), \
- SRII(DCHUBP_CNTL, HUBP, 2), \
- SRII(DCHUBP_CNTL, HUBP, 3), \
- SRII(HUBP_CLK_CNTL, HUBP, 0), \
- SRII(HUBP_CLK_CNTL, HUBP, 1), \
- SRII(HUBP_CLK_CNTL, HUBP, 2), \
- SRII(HUBP_CLK_CNTL, HUBP, 3), \
- SRII(DPP_CONTROL, DPP_TOP, 0), \
- SRII(DPP_CONTROL, DPP_TOP, 1), \
- SRII(DPP_CONTROL, DPP_TOP, 2), \
- SRII(DPP_CONTROL, DPP_TOP, 3), \
- SRII(OPP_PIPE_CONTROL, OPP_PIPE, 0), \
- SRII(OPP_PIPE_CONTROL, OPP_PIPE, 1), \
- SRII(OPP_PIPE_CONTROL, OPP_PIPE, 2), \
- SRII(OPP_PIPE_CONTROL, OPP_PIPE, 3), \
SR(REFCLK_CNTL), \
- SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\
- SR(DCHUBBUB_ARB_PTE_META_URGENCY_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_DRAM_CLK_CHANGE_WATERMARK_B),\
- SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\
- SR(DCHUBBUB_ARB_PTE_META_URGENCY_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_DRAM_CLK_CHANGE_WATERMARK_D),\
- SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\
- SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\
- SR(DCHUBBUB_ARB_SAT_LEVEL),\
- SR(DCHUBBUB_ARB_DF_REQ_OUTSTAND),\
SR(DCHUBBUB_GLOBAL_TIMER_CNTL), \
- SR(DCHUBBUB_TEST_DEBUG_INDEX), \
- SR(DCHUBBUB_TEST_DEBUG_DATA), \
SR(DIO_MEM_PWR_CTRL), \
SR(DCCG_GATE_DISABLE_CNTL), \
SR(DCCG_GATE_DISABLE_CNTL2), \
@@ -195,22 +161,10 @@
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),\
@@ -260,39 +214,9 @@ struct dce_hwseq_registers {
uint32_t DCHUB_AGP_BOT;
uint32_t DCHUB_AGP_TOP;
- uint32_t DCHUBP_CNTL[4];
- uint32_t HUBP_CLK_CNTL[4];
- uint32_t DPP_CONTROL[4];
- uint32_t OPP_PIPE_CONTROL[4];
uint32_t REFCLK_CNTL;
- uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A;
- uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A;
- uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A;
- uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B;
- uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B;
- uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B;
- uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C;
- uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C;
- uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C;
- uint32_t DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D;
- uint32_t DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D;
- uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D;
- uint32_t DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D;
- uint32_t DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL;
- uint32_t DCHUBBUB_ARB_SAT_LEVEL;
- uint32_t DCHUBBUB_ARB_DF_REQ_OUTSTAND;
+
uint32_t DCHUBBUB_GLOBAL_TIMER_CNTL;
- uint32_t DCHUBBUB_ARB_DRAM_STATE_CNTL;
- uint32_t DCHUBBUB_TEST_DEBUG_INDEX;
- uint32_t DCHUBBUB_TEST_DEBUG_DATA;
- uint32_t DCHUBBUB_SDPIF_FB_TOP;
uint32_t DCHUBBUB_SDPIF_FB_BASE;
uint32_t DCHUBBUB_SDPIF_FB_OFFSET;
uint32_t DCHUBBUB_SDPIF_AGP_BASE;
@@ -433,31 +357,17 @@ struct dce_hwseq_registers {
#define HWSEQ_DCN_MASK_SH_LIST(mask_sh)\
HWSEQ_PIXEL_RATE_MASK_SH_LIST(mask_sh, OTG0_),\
HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PHYPLL_PIXEL_RATE_SOURCE, mask_sh), \
- HWS_SF(HUBP0_, DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh), \
- HWS_SF(HUBP0_, HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh), \
- 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(, 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)
#define HWSEQ_DCN1_MASK_SH_LIST(mask_sh)\
HWSEQ_DCN_MASK_SH_LIST(mask_sh), \
HWS_SF1(OTG0_, PHYPLL_PIXEL_RATE_CNTL, PIXEL_RATE_PLL_SOURCE, mask_sh), \
- HWS_SF(, DCHUBBUB_SDPIF_FB_TOP, SDPIF_FB_TOP, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_BASE, SDPIF_AGP_BASE, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_BOT, SDPIF_AGP_BOT, mask_sh), \
HWS_SF(, DCHUBBUB_SDPIF_AGP_TOP, SDPIF_AGP_TOP, mask_sh), \
- HWS_SF(DPP_TOP0_, DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh), \
/* todo: get these from GVM instead of reading registers ourselves */\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, PAGE_DIRECTORY_ENTRY_HI32, mask_sh),\
HWS_SF(, VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, PAGE_DIRECTORY_ENTRY_LO32, mask_sh),\
@@ -532,8 +442,6 @@ struct dce_hwseq_registers {
type HUBP_VTG_SEL; \
type HUBP_CLOCK_ENABLE; \
type DPP_CLOCK_ENABLE; \
- type DPPCLK_RATE_CONTROL; \
- type SDPIF_FB_TOP;\
type SDPIF_FB_BASE;\
type SDPIF_FB_OFFSET;\
type SDPIF_AGP_BASE;\
@@ -546,14 +454,6 @@ struct dce_hwseq_registers {
type AGP_BOT;\
type AGP_TOP;\
type DCHUBBUB_GLOBAL_TIMER_ENABLE; \
- type DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST;\
- 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;\
type IP_REQUEST_EN; \
type DOMAIN0_POWER_FORCEON; \
@@ -619,5 +519,5 @@ void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
struct clock_source *clk_src,
unsigned int tg_inst);
-bool dce_use_lut(const struct dc_plane_state *plane_state);
+bool dce_use_lut(enum surface_pixel_format format);
#endif /*__DCE_HWSEQ_H__*/
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 a266e3f5e75f..11f50588b3f4 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
-/* 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 */
-#define TMDS_MAX_PIXEL_CLOCK 165000
-/* For current ASICs pixel clock - 600MHz */
-#define MAX_ENCODER_CLOCK 600000
-
enum {
DP_MST_UPDATE_MAX_RETRY = 50
};
@@ -828,6 +821,9 @@ void dce110_link_encoder_hw_init(
cntl.coherent = false;
cntl.hpd_sel = enc110->base.hpd_source;
+ if (enc110->base.connector.id == CONNECTOR_ID_EDP)
+ cntl.signal = SIGNAL_TYPE_EDP;
+
result = link_transmitter_control(enc110, &cntl);
if (result != BP_RESULT_OK) {
@@ -904,8 +900,7 @@ void dce110_link_encoder_enable_tmds_output(
struct link_encoder *enc,
enum clock_source_id clock_source,
enum dc_color_depth color_depth,
- bool hdmi,
- bool dual_link,
+ enum signal_type signal,
uint32_t pixel_clock)
{
struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
@@ -919,16 +914,12 @@ void dce110_link_encoder_enable_tmds_output(
cntl.engine_id = enc->preferred_engine;
cntl.transmitter = enc110->base.transmitter;
cntl.pll_id = clock_source;
- if (hdmi) {
- cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
- cntl.lanes_number = 4;
- } else if (dual_link) {
- cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
+ cntl.signal = signal;
+ if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
cntl.lanes_number = 8;
- } else {
- cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
+ else
cntl.lanes_number = 4;
- }
+
cntl.hpd_sel = enc110->base.hpd_source;
cntl.pixel_clock = pixel_clock;
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 8ca9afe47a2b..0ec3433d34b6 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
@@ -210,8 +210,7 @@ void dce110_link_encoder_enable_tmds_output(
struct link_encoder *enc,
enum clock_source_id clock_source,
enum dc_color_depth color_depth,
- bool hdmi,
- bool dual_link,
+ enum signal_type signal,
uint32_t pixel_clock);
/* enables DP PHY output */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
index 83bae207371d..8146b9079d51 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
@@ -920,6 +920,7 @@ static void dce110_stream_encoder_dp_blank(
{
struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
uint32_t retries = 0;
+ uint32_t reg1 = 0;
uint32_t max_retries = DP_BLANK_MAX_RETRY * 10;
/* Note: For CZ, we are changing driver default to disable
@@ -928,7 +929,10 @@ static void dce110_stream_encoder_dp_blank(
* handful of panels that cannot handle disable stream at
* HBLANK and will result in a white line flash across the
* screen on stream disable. */
-
+ REG_GET(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, &reg1);
+ if ((reg1 & 0x1) == 0)
+ /*stream not enabled*/
+ return;
/* Specify the video stream disable point
* (2 = start of the next vertical blank) */
REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, 2);
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
index 0f662e6ee9bd..ad411dac5639 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c
@@ -618,80 +618,48 @@ static void program_bit_depth_reduction(
enum dc_color_depth depth,
const struct bit_depth_reduction_params *bit_depth_params)
{
- enum dcp_bit_depth_reduction_mode depth_reduction_mode;
- enum dcp_spatial_dither_mode spatial_dither_mode;
- bool frame_random_enable;
- bool rgb_random_enable;
- bool highpass_random_enable;
+ enum dcp_out_trunc_round_depth trunc_round_depth;
+ enum dcp_out_trunc_round_mode trunc_mode;
+ bool spatial_dither_enable;
ASSERT(depth < COLOR_DEPTH_121212); /* Invalid clamp bit depth */
- if (bit_depth_params->flags.SPATIAL_DITHER_ENABLED) {
- depth_reduction_mode = DCP_BIT_DEPTH_REDUCTION_MODE_DITHER;
- frame_random_enable = true;
- rgb_random_enable = true;
- highpass_random_enable = true;
-
- } else {
- depth_reduction_mode = DCP_BIT_DEPTH_REDUCTION_MODE_DISABLED;
- frame_random_enable = false;
- rgb_random_enable = false;
- highpass_random_enable = false;
+ spatial_dither_enable = bit_depth_params->flags.SPATIAL_DITHER_ENABLED;
+ /* Default to 12 bit truncation without rounding */
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_12BIT;
+ trunc_mode = DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE;
+
+ if (bit_depth_params->flags.TRUNCATE_ENABLED) {
+ /* Don't enable dithering if truncation is enabled */
+ spatial_dither_enable = false;
+ trunc_mode = bit_depth_params->flags.TRUNCATE_MODE ?
+ DCP_OUT_TRUNC_ROUND_MODE_ROUND :
+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE;
+
+ if (bit_depth_params->flags.TRUNCATE_DEPTH == 0 ||
+ bit_depth_params->flags.TRUNCATE_DEPTH == 1)
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_8BIT;
+ else if (bit_depth_params->flags.TRUNCATE_DEPTH == 2)
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_10BIT;
+ else {
+ /*
+ * Invalid truncate/round depth. Setting here to 12bit
+ * to prevent use-before-initialize errors.
+ */
+ trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_12BIT;
+ BREAK_TO_DEBUGGER();
+ }
}
- spatial_dither_mode = DCP_SPATIAL_DITHER_MODE_A_AA_A;
-
set_clamp(xfm_dce, depth);
-
- switch (depth_reduction_mode) {
- case DCP_BIT_DEPTH_REDUCTION_MODE_DITHER:
- /* Spatial Dither: Set round/truncate to bypass (12bit),
- * enable Dither (30bpp) */
- set_round(xfm_dce,
- DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
- DCP_OUT_TRUNC_ROUND_DEPTH_12BIT);
-
- set_dither(xfm_dce, true, spatial_dither_mode,
- DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
- rgb_random_enable, highpass_random_enable);
- break;
- case DCP_BIT_DEPTH_REDUCTION_MODE_ROUND:
- /* Round: Enable round (10bit), disable Dither */
- set_round(xfm_dce,
- DCP_OUT_TRUNC_ROUND_MODE_ROUND,
- DCP_OUT_TRUNC_ROUND_DEPTH_10BIT);
-
- set_dither(xfm_dce, false, spatial_dither_mode,
- DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
- rgb_random_enable, highpass_random_enable);
- break;
- case DCP_BIT_DEPTH_REDUCTION_MODE_TRUNCATE: /* Truncate */
- /* Truncate: Enable truncate (10bit), disable Dither */
- set_round(xfm_dce,
- DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
- DCP_OUT_TRUNC_ROUND_DEPTH_10BIT);
-
- set_dither(xfm_dce, false, spatial_dither_mode,
- DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
- rgb_random_enable, highpass_random_enable);
- break;
-
- case DCP_BIT_DEPTH_REDUCTION_MODE_DISABLED: /* Disabled */
- /* Truncate: Set round/truncate to bypass (12bit),
- * disable Dither */
- set_round(xfm_dce,
- DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
- DCP_OUT_TRUNC_ROUND_DEPTH_12BIT);
-
- set_dither(xfm_dce, false, spatial_dither_mode,
- DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
- rgb_random_enable, highpass_random_enable);
- break;
- default:
- /* Invalid DCP Depth reduction mode */
- BREAK_TO_DEBUGGER();
- break;
- }
+ set_round(xfm_dce, trunc_mode, trunc_round_depth);
+ set_dither(xfm_dce,
+ spatial_dither_enable,
+ DCP_SPATIAL_DITHER_MODE_A_AA_A,
+ DCP_SPATIAL_DITHER_DEPTH_30BPP,
+ bit_depth_params->flags.FRAME_RANDOM,
+ bit_depth_params->flags.RGB_RANDOM,
+ bit_depth_params->flags.HIGHPASS_RANDOM);
}
static int dce_transform_get_max_num_of_supported_lines(
@@ -879,6 +847,7 @@ static void dce_transform_set_gamut_remap(
const struct xfm_grph_csc_adjustment *adjust)
{
struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
+ int i = 0;
if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
/* Bypass if type is bypass or hw */
@@ -887,20 +856,8 @@ static void dce_transform_set_gamut_remap(
struct fixed31_32 arr_matrix[GAMUT_MATRIX_SIZE];
uint16_t arr_reg_val[GAMUT_MATRIX_SIZE];
- arr_matrix[0] = adjust->temperature_matrix[0];
- arr_matrix[1] = adjust->temperature_matrix[1];
- arr_matrix[2] = adjust->temperature_matrix[2];
- arr_matrix[3] = dal_fixed31_32_zero;
-
- arr_matrix[4] = adjust->temperature_matrix[3];
- arr_matrix[5] = adjust->temperature_matrix[4];
- arr_matrix[6] = adjust->temperature_matrix[5];
- arr_matrix[7] = dal_fixed31_32_zero;
-
- arr_matrix[8] = adjust->temperature_matrix[6];
- arr_matrix[9] = adjust->temperature_matrix[7];
- arr_matrix[10] = adjust->temperature_matrix[8];
- arr_matrix[11] = dal_fixed31_32_zero;
+ for (i = 0; i < GAMUT_MATRIX_SIZE; i++)
+ arr_matrix[i] = adjust->temperature_matrix[i];
convert_float_matrix(
arr_reg_val, arr_matrix, GAMUT_MATRIX_SIZE);
@@ -1126,7 +1083,7 @@ void dce110_opp_set_csc_adjustment(
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
program_color_matrix(
- xfm_dce, tbl_entry, GRAPHICS_CSC_ADJUST_TYPE_SW);
+ xfm_dce, tbl_entry, GRPH_COLOR_MATRIX_SW);
/* We did everything ,now program DxOUTPUT_CSC_CONTROL */
configure_graphics_mode(xfm_dce, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c
index 469af0587604..41f83ecd7469 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c
@@ -69,7 +69,7 @@ static const struct dce100_hw_seq_reg_offsets reg_offsets[] = {
******************************************************************************/
/***************************PIPE_CONTROL***********************************/
-static bool dce100_enable_display_power_gating(
+bool dce100_enable_display_power_gating(
struct dc *dc,
uint8_t controller_id,
struct dc_bios *dcb,
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h
index cb5384ef46c3..c6ec0ed6ec3d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.h
@@ -38,5 +38,9 @@ void dce100_set_bandwidth(
struct dc_state *context,
bool decrease_allowed);
+bool dce100_enable_display_power_gating(struct dc *dc, uint8_t controller_id,
+ struct dc_bios *dcb,
+ enum pipe_gating_control power_gating);
+
#endif /* __DC_HWSS_DCE100_H__ */
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 3ea43e2a9450..3bdbed80f7f8 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
@@ -849,9 +849,11 @@ static bool construct(
*************************************************/
pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
pool->base.pipe_count = res_cap.num_timing_generator;
+ pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 40;
dc->caps.max_cursor_size = 128;
+ dc->caps.dual_link_dvi = true;
for (i = 0; i < pool->base.pipe_count; i++) {
pool->base.timing_generators[i] =
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 86cdd7b4811f..0422c72a7579 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
@@ -57,6 +57,8 @@
#include "dce/dce_11_0_sh_mask.h"
#include "custom_float.h"
+#include "atomfirmware.h"
+
/*
* All values are in milliseconds;
* For eDP, after power-up/power/down,
@@ -275,7 +277,7 @@ dce110_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
build_prescale_params(&prescale_params, plane_state);
ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
- if (plane_state->gamma_correction && dce_use_lut(plane_state))
+ if (plane_state->gamma_correction && dce_use_lut(plane_state->format))
ipp->funcs->ipp_program_input_lut(ipp, plane_state->gamma_correction);
if (tf == NULL) {
@@ -407,6 +409,10 @@ static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted,
return true;
}
+#define MAX_LOW_POINT 25
+#define NUMBER_REGIONS 16
+#define NUMBER_SW_SEGMENTS 16
+
static bool
dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
struct pwl_params *regamma_params)
@@ -421,8 +427,8 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
struct fixed31_32 y1_min;
struct fixed31_32 y3_max;
- int32_t segment_start, segment_end;
- uint32_t i, j, k, seg_distr[16], increment, start_index, hw_points;
+ int32_t region_start, region_end;
+ uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points;
if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS)
return false;
@@ -437,34 +443,20 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
/* 16 segments
* segments are from 2^-11 to 2^5
*/
- segment_start = -11;
- segment_end = 5;
-
- seg_distr[0] = 2;
- seg_distr[1] = 2;
- seg_distr[2] = 2;
- seg_distr[3] = 2;
- seg_distr[4] = 2;
- seg_distr[5] = 2;
- seg_distr[6] = 3;
- seg_distr[7] = 4;
- seg_distr[8] = 4;
- seg_distr[9] = 4;
- seg_distr[10] = 4;
- seg_distr[11] = 5;
- seg_distr[12] = 5;
- seg_distr[13] = 5;
- seg_distr[14] = 5;
- seg_distr[15] = 5;
+ region_start = -11;
+ region_end = region_start + NUMBER_REGIONS;
+
+ for (i = 0; i < NUMBER_REGIONS; i++)
+ seg_distr[i] = 4;
} else {
/* 10 segments
* segment is from 2^-10 to 2^0
*/
- segment_start = -10;
- segment_end = 0;
+ region_start = -10;
+ region_end = 0;
- seg_distr[0] = 3;
+ seg_distr[0] = 4;
seg_distr[1] = 4;
seg_distr[2] = 4;
seg_distr[3] = 4;
@@ -472,8 +464,8 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
seg_distr[5] = 4;
seg_distr[6] = 4;
seg_distr[7] = 4;
- seg_distr[8] = 5;
- seg_distr[9] = 5;
+ seg_distr[8] = 4;
+ seg_distr[9] = 4;
seg_distr[10] = -1;
seg_distr[11] = -1;
seg_distr[12] = -1;
@@ -488,10 +480,12 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
}
j = 0;
- for (k = 0; k < (segment_end - segment_start); k++) {
- increment = 32 / (1 << seg_distr[k]);
- start_index = (segment_start + k + 25) * 32;
- for (i = start_index; i < start_index + 32; i += increment) {
+ for (k = 0; k < (region_end - region_start); k++) {
+ increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+ start_index = (region_start + k + MAX_LOW_POINT) *
+ NUMBER_SW_SEGMENTS;
+ for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+ i += increment) {
if (j == hw_points - 1)
break;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
@@ -502,15 +496,15 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf,
}
/* last point */
- start_index = (segment_end + 25) * 32;
+ start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_start));
+ dal_fixed31_32_from_int(region_start));
arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_end));
+ dal_fixed31_32_from_int(region_end));
y_r = rgb_resulted[0].red;
y_g = rgb_resulted[0].green;
@@ -625,7 +619,7 @@ static enum dc_status bios_parser_crtc_source_select(
const struct dc_sink *sink = pipe_ctx->stream->sink;
crtc_source_select.engine_id = pipe_ctx->stream_res.stream_enc->id;
- crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1;
+ crtc_source_select.controller_id = pipe_ctx->stream_res.tg->inst + 1;
/*TODO: Need to un-hardcode color depth, dp_audio and account for
* the case where signal and sink signal is different (translator
* encoder)*/
@@ -914,6 +908,7 @@ void hwss_edp_backlight_control(
/*todo: unhardcode*/
cntl.lanes_number = LANE_COUNT_FOUR;
cntl.hpd_sel = link->link_enc->hpd_source;
+ cntl.signal = SIGNAL_TYPE_EDP;
/* For eDP, the following delays might need to be considered
* after link training completed:
@@ -926,7 +921,13 @@ void hwss_edp_backlight_control(
* Enable it in the future if necessary.
*/
/* dc_service_sleep_in_milliseconds(50); */
+ /*edp 1.2*/
+ if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON)
+ edp_receiver_ready_T7(link);
link_transmitter_control(ctx->dc_bios, &cntl);
+ /*edp 1.2*/
+ if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF)
+ edp_receiver_ready_T9(link);
}
void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
@@ -946,7 +947,11 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, true);
if (pipe_ctx->stream_res.audio) {
- pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+ if (option != KEEP_ACQUIRED_RESOURCE ||
+ !dc->debug.az_endpoint_mute_only) {
+ /*only disalbe az_endpoint if power down or free*/
+ pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
+ }
if (dc_is_dp_signal(pipe_ctx->stream->signal))
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
@@ -969,9 +974,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx, int option)
*/
}
- /* blank at encoder level */
- if (dc_is_dp_signal(pipe_ctx->stream->signal))
- pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
link->link_enc->funcs->connect_dig_be_to_fe(
link->link_enc,
@@ -984,12 +986,30 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings)
{
struct encoder_unblank_param params = { { 0 } };
+ struct dc_stream_state *stream = pipe_ctx->stream;
+ struct dc_link *link = stream->sink->link;
/* only 3 items below are used by unblank */
params.pixel_clk_khz =
pipe_ctx->stream->timing.pix_clk_khz;
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 (dc_is_dp_signal(pipe_ctx->stream->signal))
+ pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, &params);
+
+ if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP)
+ link->dc->hwss.edp_backlight_control(link, true);
+}
+void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_stream_state *stream = pipe_ctx->stream;
+ struct dc_link *link = stream->sink->link;
+
+ if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP)
+ link->dc->hwss.edp_backlight_control(link, false);
+
+ if (dc_is_dp_signal(pipe_ctx->stream->signal))
+ pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
}
@@ -1091,7 +1111,7 @@ static void build_audio_output(
audio_output->pll_info.dto_source =
translate_to_dto_source(
- pipe_ctx->pipe_idx + 1);
+ pipe_ctx->stream_res.tg->inst + 1);
/* TODO hard code to enable for now. Need get from stream */
audio_output->pll_info.ss_enabled = true;
@@ -1407,6 +1427,31 @@ static void disable_vga_and_power_gate_all_controllers(
}
}
+static struct dc_link *get_link_for_edp_not_in_use(
+ struct dc *dc,
+ struct dc_state *context)
+{
+ int i;
+ struct dc_link *link = NULL;
+
+ /* check if eDP panel is suppose to be set mode, if yes, no need to disable */
+ for (i = 0; i < context->stream_count; i++) {
+ if (context->streams[i]->signal == SIGNAL_TYPE_EDP)
+ return NULL;
+ }
+
+ /* check if there is an eDP panel not in use */
+ for (i = 0; i < dc->link_count; i++) {
+ if (dc->links[i]->local_sink &&
+ dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
+ link = dc->links[i];
+ break;
+ }
+ }
+
+ return link;
+}
+
/**
* When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
* 1. Power down all DC HW blocks
@@ -1414,11 +1459,37 @@ static void disable_vga_and_power_gate_all_controllers(
* 3. Enable power gating for controller
* 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
*/
-void dce110_enable_accelerated_mode(struct dc *dc)
+void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
{
- power_down_all_hw_blocks(dc);
+ struct dc_bios *dcb = dc->ctx->dc_bios;
- disable_vga_and_power_gate_all_controllers(dc);
+ /* vbios already light up eDP, so we can leverage vbios and skip eDP
+ * programming
+ */
+ bool can_eDP_fast_boot_optimize =
+ (dcb->funcs->get_vga_enabled_displays(dc->ctx->dc_bios) == ATOM_DISPLAY_LCD1_ACTIVE);
+
+ /* if OS doesn't light up eDP and eDP link is available, we want to disable */
+ struct dc_link *edp_link_to_turnoff = NULL;
+
+ if (can_eDP_fast_boot_optimize) {
+ edp_link_to_turnoff = get_link_for_edp_not_in_use(dc, context);
+
+ if (!edp_link_to_turnoff)
+ dc->apply_edp_fast_boot_optimization = true;
+ }
+
+ if (!dc->apply_edp_fast_boot_optimization) {
+ if (edp_link_to_turnoff) {
+ /*turn off backlight before DP_blank and encoder powered down*/
+ dc->hwss.edp_backlight_control(edp_link_to_turnoff, false);
+ }
+ /*resume from S3, no vbios posting, no need to power down again*/
+ power_down_all_hw_blocks(dc);
+ disable_vga_and_power_gate_all_controllers(dc);
+ if (edp_link_to_turnoff)
+ dc->hwss.edp_power_control(edp_link_to_turnoff, false);
+ }
bios_set_scratch_acc_mode_change(dc->ctx->dc_bios);
}
@@ -1439,7 +1510,7 @@ static uint32_t compute_pstate_blackout_duration(
return total_dest_line_time_ns;
}
-void dce110_set_displaymarks(
+static void dce110_set_displaymarks(
const struct dc *dc,
struct dc_state *context)
{
@@ -1553,6 +1624,8 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
value |= 0x80;
if (events->cursor_update)
value |= 0x2;
+ if (events->force_trigger)
+ value |= 0x1;
#if defined(CONFIG_DRM_AMD_DC_FBC)
value |= 0x84;
@@ -1690,9 +1763,13 @@ static void apply_min_clocks(
* Check if FBC can be enabled
*/
static bool should_enable_fbc(struct dc *dc,
- struct dc_state *context)
+ struct dc_state *context,
+ uint32_t *pipe_idx)
{
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
+ uint32_t i;
+ struct pipe_ctx *pipe_ctx = NULL;
+ struct resource_context *res_ctx = &context->res_ctx;
+
ASSERT(dc->fbc_compressor);
@@ -1704,6 +1781,14 @@ static bool should_enable_fbc(struct dc *dc,
if (context->stream_count != 1)
return false;
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ if (res_ctx->pipe_ctx[i].stream) {
+ pipe_ctx = &res_ctx->pipe_ctx[i];
+ *pipe_idx = i;
+ break;
+ }
+ }
+
/* Only supports eDP */
if (pipe_ctx->stream->sink->link->connector_signal != SIGNAL_TYPE_EDP)
return false;
@@ -1729,11 +1814,14 @@ static bool should_enable_fbc(struct dc *dc,
static void enable_fbc(struct dc *dc,
struct dc_state *context)
{
- if (should_enable_fbc(dc, context)) {
+ uint32_t pipe_idx = 0;
+
+ if (should_enable_fbc(dc, context, &pipe_idx)) {
/* Program GRPH COMPRESSED ADDRESS and PITCH */
struct compr_addr_and_pitch_params params = {0, 0, 0};
struct compressor *compr = dc->fbc_compressor;
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[0];
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
+
params.source_view_width = pipe_ctx->stream->timing.h_addressable;
params.source_view_height = pipe_ctx->stream->timing.v_addressable;
@@ -1748,36 +1836,6 @@ static void enable_fbc(struct dc *dc,
}
#endif
-static enum dc_status apply_ctx_to_hw_fpga(
- struct dc *dc,
- struct dc_state *context)
-{
- enum dc_status status = DC_ERROR_UNEXPECTED;
- int i;
-
- for (i = 0; i < MAX_PIPES; i++) {
- struct pipe_ctx *pipe_ctx_old =
- &dc->current_state->res_ctx.pipe_ctx[i];
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-
- if (pipe_ctx->stream == NULL)
- continue;
-
- if (pipe_ctx->stream == pipe_ctx_old->stream)
- continue;
-
- status = apply_single_controller_ctx_to_hw(
- pipe_ctx,
- context,
- dc);
-
- if (status != DC_OK)
- return status;
- }
-
- return DC_OK;
-}
-
static void dce110_reset_hw_ctx_wrap(
struct dc *dc,
struct dc_state *context)
@@ -1847,11 +1905,6 @@ enum dc_status dce110_apply_ctx_to_hw(
if (context->stream_count <= 0)
return DC_OK;
- if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- apply_ctx_to_hw_fpga(dc, context);
- return DC_OK;
- }
-
/* Apply new context */
dcb->funcs->set_scratch_critical_state(dcb, true);
@@ -2134,13 +2187,14 @@ static void program_surface_visibility(const struct dc *dc,
} else if (!pipe_ctx->plane_state->visible)
blank_target = true;
- dce_set_blender_mode(dc->hwseq, pipe_ctx->pipe_idx, blender_mode);
+ dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode);
pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
}
static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
{
+ int i = 0;
struct xfm_grph_csc_adjustment adjust;
memset(&adjust, 0, sizeof(adjust));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -2148,33 +2202,10 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
- adjust.temperature_matrix[0] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[0];
- adjust.temperature_matrix[1] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[1];
- adjust.temperature_matrix[2] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[2];
- adjust.temperature_matrix[3] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[4];
- adjust.temperature_matrix[4] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[5];
- adjust.temperature_matrix[5] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[6];
- adjust.temperature_matrix[6] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[8];
- adjust.temperature_matrix[7] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[9];
- adjust.temperature_matrix[8] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[10];
+
+ for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+ adjust.temperature_matrix[i] =
+ pipe_ctx->stream->gamut_remap_matrix.matrix[i];
}
pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
@@ -2198,7 +2229,7 @@ static void set_plane_config(
memset(&tbl_entry, 0, sizeof(tbl_entry));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
- dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
+ dce_enable_fe_clock(dc->hwseq, mi->inst, true);
set_default_colors(pipe_ctx);
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) {
@@ -2215,33 +2246,10 @@ static void set_plane_config(
if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
- adjust.temperature_matrix[0] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[0];
- adjust.temperature_matrix[1] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[1];
- adjust.temperature_matrix[2] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[2];
- adjust.temperature_matrix[3] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[4];
- adjust.temperature_matrix[4] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[5];
- adjust.temperature_matrix[5] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[6];
- adjust.temperature_matrix[6] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[8];
- adjust.temperature_matrix[7] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[9];
- adjust.temperature_matrix[8] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[10];
+
+ for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+ adjust.temperature_matrix[i] =
+ pipe_ctx->stream->gamut_remap_matrix.matrix[i];
}
pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
@@ -2286,7 +2294,7 @@ static void update_plane_addr(const struct dc *dc,
plane_state->status.requested_address = plane_state->address;
}
-void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
+static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx)
{
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
@@ -2527,7 +2535,7 @@ void dce110_fill_display_configs(
num_cfgs++;
cfg->signal = pipe_ctx->stream->signal;
- cfg->pipe_idx = pipe_ctx->pipe_idx;
+ cfg->pipe_idx = pipe_ctx->stream_res.tg->inst;
cfg->src_height = stream->src.height;
cfg->src_width = stream->src.width;
cfg->ddi_channel_mapping =
@@ -2680,7 +2688,6 @@ 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));
@@ -2691,7 +2698,7 @@ static void dce110_program_front_end_for_pipe(
memset(&adjust, 0, sizeof(adjust));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
- dce_enable_fe_clock(dc->hwseq, pipe_ctx->pipe_idx, true);
+ dce_enable_fe_clock(dc->hwseq, mi->inst, true);
set_default_colors(pipe_ctx);
if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
@@ -2709,33 +2716,10 @@ static void dce110_program_front_end_for_pipe(
if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
- adjust.temperature_matrix[0] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[0];
- adjust.temperature_matrix[1] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[1];
- adjust.temperature_matrix[2] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[2];
- adjust.temperature_matrix[3] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[4];
- adjust.temperature_matrix[4] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[5];
- adjust.temperature_matrix[5] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[6];
- adjust.temperature_matrix[6] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[8];
- adjust.temperature_matrix[7] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[9];
- adjust.temperature_matrix[8] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[10];
+
+ for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+ adjust.temperature_matrix[i] =
+ pipe_ctx->stream->gamut_remap_matrix.matrix[i];
}
pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
@@ -2772,10 +2756,13 @@ static void dce110_program_front_end_for_pipe(
plane_state->rotation);
/* Moved programming gamma from dc to hwss */
- if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state) {
+ if (pipe_ctx->plane_state->update_flags.bits.full_update ||
+ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+ pipe_ctx->plane_state->update_flags.bits.gamma_change)
dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state);
+
+ if (pipe_ctx->plane_state->update_flags.bits.full_update)
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, "
@@ -2872,7 +2859,8 @@ static void dce110_apply_ctx_for_surface(
static void dce110_power_down_fe(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- int fe_idx = pipe_ctx->pipe_idx;
+ int fe_idx = pipe_ctx->plane_res.mi ?
+ pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx;
/* Do not power down fe when stream is active on dce*/
if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream)
@@ -2915,6 +2903,49 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx,
}
}
+void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+ struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+ struct mem_input *mi = pipe_ctx->plane_res.mi;
+ struct dc_cursor_mi_param param = {
+ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
+ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
+ .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
+ .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
+ .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
+ };
+
+ if (pipe_ctx->plane_state->address.type
+ == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+ pos_cpy.enable = false;
+
+ if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
+ pos_cpy.enable = false;
+
+ if (ipp->funcs->ipp_cursor_set_position)
+ ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+ if (mi->funcs->set_cursor_position)
+ mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+}
+
+void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+ if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes)
+ pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
+ pipe_ctx->plane_res.ipp, attributes);
+
+ if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes)
+ pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.mi, attributes);
+
+ if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes)
+ pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.xfm, attributes);
+}
+
static void ready_shared_resources(struct dc *dc, struct dc_state *context) {}
static void optimize_shared_resources(struct dc *dc) {}
@@ -2938,6 +2969,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.enable_stream = dce110_enable_stream,
.disable_stream = dce110_disable_stream,
.unblank_stream = dce110_unblank_stream,
+ .blank_stream = dce110_blank_stream,
.enable_display_pipe_clock_gating = enable_display_pipe_clock_gating,
.enable_display_power_gating = dce110_enable_display_power_gating,
.disable_plane = dce110_power_down_fe,
@@ -2957,6 +2989,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control,
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+ .set_cursor_position = dce110_set_cursor_position,
+ .set_cursor_attribute = dce110_set_cursor_attribute
};
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 fc637647f643..5d7e9f516827 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
@@ -39,11 +39,7 @@ enum dc_status dce110_apply_ctx_to_hw(
struct dc *dc,
struct dc_state *context);
-void dce110_set_display_clock(struct dc_state *context);
-void dce110_set_displaymarks(
- const struct dc *dc,
- struct dc_state *context);
void dce110_enable_stream(struct pipe_ctx *pipe_ctx);
@@ -52,15 +48,14 @@ 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);
+void dce110_blank_stream(struct pipe_ctx *pipe_ctx);
void dce110_update_info_frame(struct pipe_ctx *pipe_ctx);
void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
-void dce110_enable_accelerated_mode(struct dc *dc);
+void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context);
void dce110_power_down(struct dc *dc);
-void dce110_update_pending_status(struct pipe_ctx *pipe_ctx);
-
void dce110_fill_display_configs(
const struct dc_state *context,
struct dm_pp_display_configuration *pp_display_cfg);
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c
index feb397b5c1a3..4245e1f818a3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_csc_v.c
@@ -727,7 +727,7 @@ void dce110_opp_v_set_csc_adjustment(
CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
program_color_matrix_v(
- xfm_dce, tbl_entry, GRAPHICS_CSC_ADJUST_TYPE_SW);
+ xfm_dce, tbl_entry, GRPH_COLOR_MATRIX_SW);
/* We did everything ,now program DxOUTPUT_CSC_CONTROL */
configure_graphics_mode_v(xfm_dce, config, GRAPHICS_CSC_ADJUST_TYPE_SW,
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 7c4779578fb7..c4e877ac95d3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -700,7 +700,7 @@ static void get_pixel_clock_parameters(
pixel_clk_params->requested_pix_clk = stream->timing.pix_clk_khz;
pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
pixel_clk_params->signal_type = pipe_ctx->stream->signal;
- pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
+ pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
/* TODO: un-hardcode*/
pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
LINK_RATE_REF_FREQ_IN_KHZ;
@@ -973,7 +973,7 @@ static struct pipe_ctx *dce110_acquire_underlay(
dc->hwss.enable_display_power_gating(
dc,
- pipe_ctx->pipe_idx,
+ pipe_ctx->stream_res.tg->inst,
dcb, PIPE_GATING_CONTROL_DISABLE);
/*
@@ -1152,7 +1152,7 @@ static bool construct(
pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
pool->base.underlay_pipe_index = pool->base.pipe_count;
-
+ pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
dc->caps.max_downscale_ratio = 150;
dc->caps.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 128;
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
index 25ca72139e5f..be7153924a70 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
@@ -2077,6 +2077,125 @@ bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
return true;
}
+static bool dce110_is_tg_enabled(struct timing_generator *tg)
+{
+ uint32_t addr = 0;
+ uint32_t value = 0;
+ uint32_t field = 0;
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+ addr = CRTC_REG(mmCRTC_CONTROL);
+ value = dm_read_reg(tg->ctx, addr);
+ field = get_reg_field_value(value, CRTC_CONTROL,
+ CRTC_CURRENT_MASTER_EN_STATE);
+ return field == 1;
+}
+
+bool dce110_configure_crc(struct timing_generator *tg,
+ const struct crc_params *params)
+{
+ uint32_t cntl_addr = 0;
+ uint32_t addr = 0;
+ uint32_t value;
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+ /* Cannot configure crc on a CRTC that is disabled */
+ if (!dce110_is_tg_enabled(tg))
+ return false;
+
+ cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);
+
+ /* First, disable CRC before we configure it. */
+ dm_write_reg(tg->ctx, cntl_addr, 0);
+
+ if (!params->enable)
+ return true;
+
+ /* Program frame boundaries */
+ /* Window A x axis start and end. */
+ value = 0;
+ addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
+ set_reg_field_value(value, params->windowa_x_start,
+ CRTC_CRC0_WINDOWA_X_CONTROL,
+ CRTC_CRC0_WINDOWA_X_START);
+ set_reg_field_value(value, params->windowa_x_end,
+ CRTC_CRC0_WINDOWA_X_CONTROL,
+ CRTC_CRC0_WINDOWA_X_END);
+ dm_write_reg(tg->ctx, addr, value);
+
+ /* Window A y axis start and end. */
+ value = 0;
+ addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_Y_CONTROL);
+ set_reg_field_value(value, params->windowa_y_start,
+ CRTC_CRC0_WINDOWA_Y_CONTROL,
+ CRTC_CRC0_WINDOWA_Y_START);
+ set_reg_field_value(value, params->windowa_y_end,
+ CRTC_CRC0_WINDOWA_Y_CONTROL,
+ CRTC_CRC0_WINDOWA_Y_END);
+ dm_write_reg(tg->ctx, addr, value);
+
+ /* Window B x axis start and end. */
+ value = 0;
+ addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_X_CONTROL);
+ set_reg_field_value(value, params->windowb_x_start,
+ CRTC_CRC0_WINDOWB_X_CONTROL,
+ CRTC_CRC0_WINDOWB_X_START);
+ set_reg_field_value(value, params->windowb_x_end,
+ CRTC_CRC0_WINDOWB_X_CONTROL,
+ CRTC_CRC0_WINDOWB_X_END);
+ dm_write_reg(tg->ctx, addr, value);
+
+ /* Window B y axis start and end. */
+ value = 0;
+ addr = CRTC_REG(mmCRTC_CRC0_WINDOWB_Y_CONTROL);
+ set_reg_field_value(value, params->windowb_y_start,
+ CRTC_CRC0_WINDOWB_Y_CONTROL,
+ CRTC_CRC0_WINDOWB_Y_START);
+ set_reg_field_value(value, params->windowb_y_end,
+ CRTC_CRC0_WINDOWB_Y_CONTROL,
+ CRTC_CRC0_WINDOWB_Y_END);
+ dm_write_reg(tg->ctx, addr, value);
+
+ /* Set crc mode and selection, and enable. Only using CRC0*/
+ value = 0;
+ set_reg_field_value(value, params->continuous_mode ? 1 : 0,
+ CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
+ set_reg_field_value(value, params->selection,
+ CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
+ set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
+ dm_write_reg(tg->ctx, cntl_addr, value);
+
+ return true;
+}
+
+bool dce110_get_crc(struct timing_generator *tg,
+ uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
+{
+ uint32_t addr = 0;
+ uint32_t value = 0;
+ uint32_t field = 0;
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+
+ addr = CRTC_REG(mmCRTC_CRC_CNTL);
+ value = dm_read_reg(tg->ctx, addr);
+ field = get_reg_field_value(value, CRTC_CRC_CNTL, CRTC_CRC_EN);
+
+ /* Early return if CRC is not enabled for this CRTC */
+ if (!field)
+ return false;
+
+ addr = CRTC_REG(mmCRTC_CRC0_DATA_RG);
+ value = dm_read_reg(tg->ctx, addr);
+ *r_cr = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_R_CR);
+ *g_y = get_reg_field_value(value, CRTC_CRC0_DATA_RG, CRC0_G_Y);
+
+ addr = CRTC_REG(mmCRTC_CRC0_DATA_B);
+ value = dm_read_reg(tg->ctx, addr);
+ *b_cb = get_reg_field_value(value, CRTC_CRC0_DATA_B, CRC0_B_CB);
+
+ return true;
+}
+
static const struct timing_generator_funcs dce110_tg_funcs = {
.validate_timing = dce110_tg_validate_timing,
.program_timing = dce110_tg_program_timing,
@@ -2112,6 +2231,9 @@ static const struct timing_generator_funcs dce110_tg_funcs = {
dce110_timing_generator_set_static_screen_control,
.set_test_pattern = dce110_timing_generator_set_test_pattern,
.arm_vert_intr = dce110_arm_vert_intr,
+ .is_tg_enabled = dce110_is_tg_enabled,
+ .configure_crc = dce110_configure_crc,
+ .get_crc = dce110_get_crc,
};
void dce110_timing_generator_construct(
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
index 232747c7c60b..734d4965dab1 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
@@ -276,4 +276,10 @@ void dce110_tg_set_colors(struct timing_generator *tg,
bool dce110_arm_vert_intr(
struct timing_generator *tg, uint8_t width);
+bool dce110_configure_crc(struct timing_generator *tg,
+ const struct crc_params *params);
+
+bool dce110_get_crc(struct timing_generator *tg,
+ uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb);
+
#endif /* __DC_TIMING_GENERATOR_DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
index 663e0a047a4b..c0757dd6c03c 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -1100,9 +1100,12 @@ static bool construct(
*************************************************/
pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
+ pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 128;
+ dc->caps.dual_link_dvi = true;
+
/*************************************************
* Create resources *
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
index 75d029742f96..e96ff86d2fc3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
@@ -33,7 +33,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "reg_helper.h"
#define CTX \
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
index 57cd67359567..4659a4bfabaa 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
@@ -56,7 +56,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "nbio/nbio_6_1_offset.h"
#include "reg_helper.h"
@@ -830,11 +831,14 @@ static bool construct(
/* TODO: Fill more data from GreenlandAsicCapability.cpp */
pool->base.pipe_count = res_cap.num_timing_generator;
+ pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 128;
+ dc->caps.dual_link_dvi = true;
+
dc->debug = debug_defaults;
/*************************************************
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
index 0aa60e5727e0..7bee78172d85 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
@@ -27,7 +27,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "dc_types.h"
#include "dc_bios_types.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/Makefile b/drivers/gpu/drm/amd/display/dc/dce80/Makefile
index bc388aa4b2f5..666fcb2bdbba 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dce80/Makefile
@@ -23,7 +23,7 @@
# Makefile for the 'controller' sub-component of DAL.
# It provides the control and status of HW CRTC block.
-DCE80 = dce80_timing_generator.o dce80_compressor.o dce80_hw_sequencer.o \
+DCE80 = dce80_timing_generator.o dce80_hw_sequencer.o \
dce80_resource.o
AMD_DAL_DCE80 = $(addprefix $(AMDDALPATH)/dc/dce80/,$(DCE80))
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.c
deleted file mode 100644
index 951f2caba9b3..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * Copyright 2012-15 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-
-#include "dm_services.h"
-
-#include "dce/dce_8_0_d.h"
-#include "dce/dce_8_0_sh_mask.h"
-#include "gmc/gmc_7_1_sh_mask.h"
-#include "gmc/gmc_7_1_d.h"
-
-#include "include/logger_interface.h"
-#include "dce80_compressor.h"
-
-#define DCP_REG(reg)\
- (reg + cp80->offsets.dcp_offset)
-#define DMIF_REG(reg)\
- (reg + cp80->offsets.dmif_offset)
-
-static const struct dce80_compressor_reg_offsets reg_offsets[] = {
-{
- .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
- .dmif_offset = (mmDMIF_PG0_DPG_PIPE_DPM_CONTROL
- - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-},
-{
- .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
- .dmif_offset = (mmDMIF_PG1_DPG_PIPE_DPM_CONTROL
- - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-},
-{
- .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
- .dmif_offset = (mmDMIF_PG2_DPG_PIPE_DPM_CONTROL
- - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-},
-{
- .dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
- .dmif_offset = (mmDMIF_PG3_DPG_PIPE_DPM_CONTROL
- - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-},
-{
- .dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
- .dmif_offset = (mmDMIF_PG4_DPG_PIPE_DPM_CONTROL
- - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-},
-{
- .dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
- .dmif_offset = (mmDMIF_PG5_DPG_PIPE_DPM_CONTROL
- - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-}
-};
-
-static const uint32_t dce8_one_lpt_channel_max_resolution = 2048 * 1200;
-
-enum fbc_idle_force {
- /* Bit 0 - Display registers updated */
- FBC_IDLE_FORCE_DISPLAY_REGISTER_UPDATE = 0x00000001,
-
- /* Bit 2 - FBC_GRPH_COMP_EN register updated */
- FBC_IDLE_FORCE_GRPH_COMP_EN = 0x00000002,
- /* Bit 3 - FBC_SRC_SEL register updated */
- FBC_IDLE_FORCE_SRC_SEL_CHANGE = 0x00000004,
- /* Bit 4 - FBC_MIN_COMPRESSION register updated */
- FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE = 0x00000008,
- /* Bit 5 - FBC_ALPHA_COMP_EN register updated */
- FBC_IDLE_FORCE_ALPHA_COMP_EN = 0x00000010,
- /* Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated */
- FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN = 0x00000020,
- /* Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated */
- FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF = 0x00000040,
-
- /* Bit 24 - Memory write to region 0 defined by MC registers. */
- FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION0 = 0x01000000,
- /* Bit 25 - Memory write to region 1 defined by MC registers */
- FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION1 = 0x02000000,
- /* Bit 26 - Memory write to region 2 defined by MC registers */
- FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION2 = 0x04000000,
- /* Bit 27 - Memory write to region 3 defined by MC registers. */
- FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION3 = 0x08000000,
-
- /* Bit 28 - Memory write from any client other than MCIF */
- FBC_IDLE_FORCE_MEMORY_WRITE_OTHER_THAN_MCIF = 0x10000000,
- /* Bit 29 - CG statics screen signal is inactive */
- FBC_IDLE_FORCE_CG_STATIC_SCREEN_IS_INACTIVE = 0x20000000,
-};
-
-static uint32_t lpt_size_alignment(struct dce80_compressor *cp80)
-{
- /*LPT_ALIGNMENT (in bytes) = ROW_SIZE * #BANKS * # DRAM CHANNELS. */
- return cp80->base.raw_size * cp80->base.banks_num *
- cp80->base.dram_channels_num;
-}
-
-static uint32_t lpt_memory_control_config(struct dce80_compressor *cp80,
- uint32_t lpt_control)
-{
- /*LPT MC Config */
- if (cp80->base.options.bits.LPT_MC_CONFIG == 1) {
- /* POSSIBLE VALUES for LPT NUM_PIPES (DRAM CHANNELS):
- * 00 - 1 CHANNEL
- * 01 - 2 CHANNELS
- * 02 - 4 OR 6 CHANNELS
- * (Only for discrete GPU, N/A for CZ)
- * 03 - 8 OR 12 CHANNELS
- * (Only for discrete GPU, N/A for CZ) */
- switch (cp80->base.dram_channels_num) {
- case 2:
- set_reg_field_value(
- lpt_control,
- 1,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_NUM_PIPES);
- break;
- case 1:
- set_reg_field_value(
- lpt_control,
- 0,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_NUM_PIPES);
- break;
- default:
- dm_logger_write(
- cp80->base.ctx->logger, LOG_WARNING,
- "%s: Invalid LPT NUM_PIPES!!!",
- __func__);
- break;
- }
-
- /* The mapping for LPT NUM_BANKS is in
- * GRPH_CONTROL.GRPH_NUM_BANKS register field
- * Specifies the number of memory banks for tiling
- * purposes. Only applies to 2D and 3D tiling modes.
- * POSSIBLE VALUES:
- * 00 - DCP_GRPH_NUM_BANKS_2BANK: ADDR_SURF_2_BANK
- * 01 - DCP_GRPH_NUM_BANKS_4BANK: ADDR_SURF_4_BANK
- * 02 - DCP_GRPH_NUM_BANKS_8BANK: ADDR_SURF_8_BANK
- * 03 - DCP_GRPH_NUM_BANKS_16BANK: ADDR_SURF_16_BANK */
- switch (cp80->base.banks_num) {
- case 16:
- set_reg_field_value(
- lpt_control,
- 3,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_NUM_BANKS);
- break;
- case 8:
- set_reg_field_value(
- lpt_control,
- 2,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_NUM_BANKS);
- break;
- case 4:
- set_reg_field_value(
- lpt_control,
- 1,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_NUM_BANKS);
- break;
- case 2:
- set_reg_field_value(
- lpt_control,
- 0,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_NUM_BANKS);
- break;
- default:
- dm_logger_write(
- cp80->base.ctx->logger, LOG_WARNING,
- "%s: Invalid LPT NUM_BANKS!!!",
- __func__);
- break;
- }
-
- /* The mapping is in DMIF_ADDR_CALC.
- * ADDR_CONFIG_PIPE_INTERLEAVE_SIZE register field for
- * Carrizo specifies the memory interleave per pipe.
- * It effectively specifies the location of pipe bits in
- * the memory address.
- * POSSIBLE VALUES:
- * 00 - ADDR_CONFIG_PIPE_INTERLEAVE_256B: 256 byte
- * interleave
- * 01 - ADDR_CONFIG_PIPE_INTERLEAVE_512B: 512 byte
- * interleave
- */
- switch (cp80->base.channel_interleave_size) {
- case 256: /*256B */
- set_reg_field_value(
- lpt_control,
- 0,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
- break;
- case 512: /*512B */
- set_reg_field_value(
- lpt_control,
- 1,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
- break;
- default:
- dm_logger_write(
- cp80->base.ctx->logger, LOG_WARNING,
- "%s: Invalid LPT INTERLEAVE_SIZE!!!",
- __func__);
- break;
- }
-
- /* The mapping for LOW_POWER_TILING_ROW_SIZE is in
- * DMIF_ADDR_CALC.ADDR_CONFIG_ROW_SIZE register field
- * for Carrizo. Specifies the size of dram row in bytes.
- * This should match up with NOOFCOLS field in
- * MC_ARB_RAMCFG (ROW_SIZE = 4 * 2 ^^ columns).
- * This register DMIF_ADDR_CALC is not used by the
- * hardware as it is only used for addrlib assertions.
- * POSSIBLE VALUES:
- * 00 - ADDR_CONFIG_1KB_ROW: Treat 1KB as DRAM row
- * boundary
- * 01 - ADDR_CONFIG_2KB_ROW: Treat 2KB as DRAM row
- * boundary
- * 02 - ADDR_CONFIG_4KB_ROW: Treat 4KB as DRAM row
- * boundary */
- switch (cp80->base.raw_size) {
- case 4096: /*4 KB */
- set_reg_field_value(
- lpt_control,
- 2,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ROW_SIZE);
- break;
- case 2048:
- set_reg_field_value(
- lpt_control,
- 1,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ROW_SIZE);
- break;
- case 1024:
- set_reg_field_value(
- lpt_control,
- 0,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ROW_SIZE);
- break;
- default:
- dm_logger_write(
- cp80->base.ctx->logger, LOG_WARNING,
- "%s: Invalid LPT ROW_SIZE!!!",
- __func__);
- break;
- }
- } else {
- dm_logger_write(
- cp80->base.ctx->logger, LOG_WARNING,
- "%s: LPT MC Configuration is not provided",
- __func__);
- }
-
- return lpt_control;
-}
-
-static bool is_source_bigger_than_epanel_size(
- struct dce80_compressor *cp80,
- uint32_t source_view_width,
- uint32_t source_view_height)
-{
- if (cp80->base.embedded_panel_h_size != 0 &&
- cp80->base.embedded_panel_v_size != 0 &&
- ((source_view_width * source_view_height) >
- (cp80->base.embedded_panel_h_size *
- cp80->base.embedded_panel_v_size)))
- return true;
-
- return false;
-}
-
-static uint32_t align_to_chunks_number_per_line(
- struct dce80_compressor *cp80,
- uint32_t pixels)
-{
- return 256 * ((pixels + 255) / 256);
-}
-
-static void wait_for_fbc_state_changed(
- struct dce80_compressor *cp80,
- bool enabled)
-{
- uint8_t counter = 0;
- uint32_t addr = mmFBC_STATUS;
- uint32_t value;
-
- while (counter < 10) {
- value = dm_read_reg(cp80->base.ctx, addr);
- if (get_reg_field_value(
- value,
- FBC_STATUS,
- FBC_ENABLE_STATUS) == enabled)
- break;
- udelay(10);
- counter++;
- }
-
- if (counter == 10) {
- dm_logger_write(
- cp80->base.ctx->logger, LOG_WARNING,
- "%s: wait counter exceeded, changes to HW not applied",
- __func__);
- }
-}
-
-void dce80_compressor_power_up_fbc(struct compressor *compressor)
-{
- uint32_t value;
- uint32_t addr;
-
- addr = mmFBC_CNTL;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
- set_reg_field_value(value, 1, FBC_CNTL, FBC_EN);
- set_reg_field_value(value, 2, FBC_CNTL, FBC_COHERENCY_MODE);
- dm_write_reg(compressor->ctx, addr, value);
-
- addr = mmFBC_COMP_MODE;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_RLE_EN);
- set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_DPCM4_RGB_EN);
- set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_IND_EN);
- dm_write_reg(compressor->ctx, addr, value);
-
- addr = mmFBC_COMP_CNTL;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(value, 1, FBC_COMP_CNTL, FBC_DEPTH_RGB08_EN);
- dm_write_reg(compressor->ctx, addr, value);
- /*FBC_MIN_COMPRESSION 0 ==> 2:1 */
- /* 1 ==> 4:1 */
- /* 2 ==> 8:1 */
- /* 0xF ==> 1:1 */
- set_reg_field_value(value, 0xF, FBC_COMP_CNTL, FBC_MIN_COMPRESSION);
- dm_write_reg(compressor->ctx, addr, value);
- compressor->min_compress_ratio = FBC_COMPRESS_RATIO_1TO1;
-
- value = 0;
- dm_write_reg(compressor->ctx, mmFBC_IND_LUT0, value);
-
- value = 0xFFFFFF;
- dm_write_reg(compressor->ctx, mmFBC_IND_LUT1, value);
-}
-
-void dce80_compressor_enable_fbc(
- struct compressor *compressor,
- uint32_t paths_num,
- struct compr_addr_and_pitch_params *params)
-{
- struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
-
- if (compressor->options.bits.FBC_SUPPORT &&
- (compressor->options.bits.DUMMY_BACKEND == 0) &&
- (!dce80_compressor_is_fbc_enabled_in_hw(compressor, NULL)) &&
- (!is_source_bigger_than_epanel_size(
- cp80,
- params->source_view_width,
- params->source_view_height))) {
-
- uint32_t addr;
- uint32_t value;
-
- /* Before enabling FBC first need to enable LPT if applicable
- * LPT state should always be changed (enable/disable) while FBC
- * is disabled */
- if (compressor->options.bits.LPT_SUPPORT && (paths_num < 2) &&
- (params->source_view_width *
- params->source_view_height <=
- dce8_one_lpt_channel_max_resolution)) {
- dce80_compressor_enable_lpt(compressor);
- }
-
- addr = mmFBC_CNTL;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
- set_reg_field_value(
- value,
- params->inst,
- FBC_CNTL, FBC_SRC_SEL);
- dm_write_reg(compressor->ctx, addr, value);
-
- /* Keep track of enum controller_id FBC is attached to */
- compressor->is_enabled = true;
- compressor->attached_inst = params->inst;
- cp80->offsets = reg_offsets[params->inst];
-
- /*Toggle it as there is bug in HW */
- set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
- dm_write_reg(compressor->ctx, addr, value);
- set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
- dm_write_reg(compressor->ctx, addr, value);
-
- wait_for_fbc_state_changed(cp80, true);
- }
-}
-
-void dce80_compressor_disable_fbc(struct compressor *compressor)
-{
- struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
-
- if (compressor->options.bits.FBC_SUPPORT &&
- dce80_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
- uint32_t reg_data;
- /* Turn off compression */
- reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
- set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
- dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
-
- /* Reset enum controller_id to undefined */
- compressor->attached_inst = 0;
- compressor->is_enabled = false;
-
- /* Whenever disabling FBC make sure LPT is disabled if LPT
- * supported */
- if (compressor->options.bits.LPT_SUPPORT)
- dce80_compressor_disable_lpt(compressor);
-
- wait_for_fbc_state_changed(cp80, false);
- }
-}
-
-bool dce80_compressor_is_fbc_enabled_in_hw(
- struct compressor *compressor,
- uint32_t *inst)
-{
- /* Check the hardware register */
- uint32_t value;
-
- value = dm_read_reg(compressor->ctx, mmFBC_STATUS);
- if (get_reg_field_value(value, FBC_STATUS, FBC_ENABLE_STATUS)) {
- if (inst != NULL)
- *inst = compressor->attached_inst;
- return true;
- }
-
- value = dm_read_reg(compressor->ctx, mmFBC_CNTL);
- if (get_reg_field_value(value, FBC_CNTL, FBC_GRPH_COMP_EN)) {
- if (inst != NULL)
- *inst = compressor->attached_inst;
- return true;
- }
-
- return false;
-}
-
-bool dce80_compressor_is_lpt_enabled_in_hw(struct compressor *compressor)
-{
- /* Check the hardware register */
- uint32_t value = dm_read_reg(compressor->ctx,
- mmLOW_POWER_TILING_CONTROL);
-
- return get_reg_field_value(
- value,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ENABLE);
-}
-
-void dce80_compressor_program_compressed_surface_address_and_pitch(
- struct compressor *compressor,
- struct compr_addr_and_pitch_params *params)
-{
- struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
- uint32_t value = 0;
- uint32_t fbc_pitch = 0;
- uint32_t compressed_surf_address_low_part =
- compressor->compr_surface_address.addr.low_part;
-
- /* Clear content first. */
- dm_write_reg(
- compressor->ctx,
- DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
- 0);
- dm_write_reg(compressor->ctx,
- DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS), 0);
-
- if (compressor->options.bits.LPT_SUPPORT) {
- uint32_t lpt_alignment = lpt_size_alignment(cp80);
-
- if (lpt_alignment != 0) {
- compressed_surf_address_low_part =
- ((compressed_surf_address_low_part
- + (lpt_alignment - 1)) / lpt_alignment)
- * lpt_alignment;
- }
- }
-
- /* Write address, HIGH has to be first. */
- dm_write_reg(compressor->ctx,
- DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
- compressor->compr_surface_address.addr.high_part);
- dm_write_reg(compressor->ctx,
- DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS),
- compressed_surf_address_low_part);
-
- fbc_pitch = align_to_chunks_number_per_line(
- cp80,
- params->source_view_width);
-
- if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1)
- fbc_pitch = fbc_pitch / 8;
- else
- dm_logger_write(
- compressor->ctx->logger, LOG_WARNING,
- "%s: Unexpected DCE8 compression ratio",
- __func__);
-
- /* Clear content first. */
- dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), 0);
-
- /* Write FBC Pitch. */
- set_reg_field_value(
- value,
- fbc_pitch,
- GRPH_COMPRESS_PITCH,
- GRPH_COMPRESS_PITCH);
- dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), value);
-
-}
-
-void dce80_compressor_disable_lpt(struct compressor *compressor)
-{
- struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
- uint32_t value;
- uint32_t addr;
- uint32_t inx;
-
- /* Disable all pipes LPT Stutter */
- for (inx = 0; inx < 3; inx++) {
- value =
- dm_read_reg(
- compressor->ctx,
- DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH));
- set_reg_field_value(
- value,
- 0,
- DPG_PIPE_STUTTER_CONTROL_NONLPTCH,
- STUTTER_ENABLE_NONLPTCH);
- dm_write_reg(
- compressor->ctx,
- DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH),
- value);
- }
-
- /* Disable LPT */
- addr = mmLOW_POWER_TILING_CONTROL;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(
- value,
- 0,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ENABLE);
- dm_write_reg(compressor->ctx, addr, value);
-
- /* Clear selection of Channel(s) containing Compressed Surface */
- addr = mmGMCON_LPT_TARGET;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(
- value,
- 0xFFFFFFFF,
- GMCON_LPT_TARGET,
- STCTRL_LPT_TARGET);
- dm_write_reg(compressor->ctx, mmGMCON_LPT_TARGET, value);
-}
-
-void dce80_compressor_enable_lpt(struct compressor *compressor)
-{
- struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
- uint32_t value;
- uint32_t addr;
- uint32_t value_control;
- uint32_t channels;
-
- /* Enable LPT Stutter from Display pipe */
- value = dm_read_reg(compressor->ctx,
- DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH));
- set_reg_field_value(
- value,
- 1,
- DPG_PIPE_STUTTER_CONTROL_NONLPTCH,
- STUTTER_ENABLE_NONLPTCH);
- dm_write_reg(compressor->ctx,
- DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH), value);
-
- /* Selection of Channel(s) containing Compressed Surface: 0xfffffff
- * will disable LPT.
- * STCTRL_LPT_TARGETn corresponds to channel n. */
- addr = mmLOW_POWER_TILING_CONTROL;
- value_control = dm_read_reg(compressor->ctx, addr);
- channels = get_reg_field_value(value_control,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_MODE);
-
- addr = mmGMCON_LPT_TARGET;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(
- value,
- channels + 1, /* not mentioned in programming guide,
- but follow DCE8.1 */
- GMCON_LPT_TARGET,
- STCTRL_LPT_TARGET);
- dm_write_reg(compressor->ctx, addr, value);
-
- /* Enable LPT */
- addr = mmLOW_POWER_TILING_CONTROL;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(
- value,
- 1,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ENABLE);
- dm_write_reg(compressor->ctx, addr, value);
-}
-
-void dce80_compressor_program_lpt_control(
- struct compressor *compressor,
- struct compr_addr_and_pitch_params *params)
-{
- struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
- uint32_t rows_per_channel;
- uint32_t lpt_alignment;
- uint32_t source_view_width;
- uint32_t source_view_height;
- uint32_t lpt_control = 0;
-
- if (!compressor->options.bits.LPT_SUPPORT)
- return;
-
- lpt_control = dm_read_reg(compressor->ctx,
- mmLOW_POWER_TILING_CONTROL);
-
- /* POSSIBLE VALUES for Low Power Tiling Mode:
- * 00 - Use channel 0
- * 01 - Use Channel 0 and 1
- * 02 - Use Channel 0,1,2,3
- * 03 - reserved */
- switch (compressor->lpt_channels_num) {
- /* case 2:
- * Use Channel 0 & 1 / Not used for DCE 11 */
- case 1:
- /*Use Channel 0 for LPT for DCE 11 */
- set_reg_field_value(
- lpt_control,
- 0,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_MODE);
- break;
- default:
- dm_logger_write(
- compressor->ctx->logger, LOG_WARNING,
- "%s: Invalid selected DRAM channels for LPT!!!",
- __func__);
- break;
- }
-
- lpt_control = lpt_memory_control_config(cp80, lpt_control);
-
- /* Program LOW_POWER_TILING_ROWS_PER_CHAN field which depends on
- * FBC compressed surface pitch.
- * LOW_POWER_TILING_ROWS_PER_CHAN = Roundup ((Surface Height *
- * Surface Pitch) / (Row Size * Number of Channels *
- * Number of Banks)). */
- rows_per_channel = 0;
- lpt_alignment = lpt_size_alignment(cp80);
- source_view_width =
- align_to_chunks_number_per_line(
- cp80,
- params->source_view_width);
- source_view_height = (params->source_view_height + 1) & (~0x1);
-
- if (lpt_alignment != 0) {
- rows_per_channel = source_view_width * source_view_height * 4;
- rows_per_channel =
- (rows_per_channel % lpt_alignment) ?
- (rows_per_channel / lpt_alignment + 1) :
- rows_per_channel / lpt_alignment;
- }
-
- set_reg_field_value(
- lpt_control,
- rows_per_channel,
- LOW_POWER_TILING_CONTROL,
- LOW_POWER_TILING_ROWS_PER_CHAN);
-
- dm_write_reg(compressor->ctx,
- mmLOW_POWER_TILING_CONTROL, lpt_control);
-}
-
-/*
- * DCE 11 Frame Buffer Compression Implementation
- */
-
-void dce80_compressor_set_fbc_invalidation_triggers(
- struct compressor *compressor,
- uint32_t fbc_trigger)
-{
- /* Disable region hit event, FBC_MEMORY_REGION_MASK = 0 (bits 16-19)
- * for DCE 11 regions cannot be used - does not work with S/G
- */
- uint32_t addr = mmFBC_CLIENT_REGION_MASK;
- uint32_t value = dm_read_reg(compressor->ctx, addr);
-
- set_reg_field_value(
- value,
- 0,
- FBC_CLIENT_REGION_MASK,
- FBC_MEMORY_REGION_MASK);
- dm_write_reg(compressor->ctx, addr, value);
-
- /* Setup events when to clear all CSM entries (effectively marking
- * current compressed data invalid)
- * For DCE 11 CSM metadata 11111 means - "Not Compressed"
- * Used as the initial value of the metadata sent to the compressor
- * after invalidation, to indicate that the compressor should attempt
- * to compress all chunks on the current pass. Also used when the chunk
- * is not successfully written to memory.
- * When this CSM value is detected, FBC reads from the uncompressed
- * buffer. Set events according to passed in value, these events are
- * valid for DCE8:
- * - bit 0 - display register updated
- * - bit 28 - memory write from any client except from MCIF
- * - bit 29 - CG static screen signal is inactive
- * In addition, DCE8.1 also needs to set new DCE8.1 specific events
- * that are used to trigger invalidation on certain register changes,
- * for example enabling of Alpha Compression may trigger invalidation of
- * FBC once bit is set. These events are as follows:
- * - Bit 2 - FBC_GRPH_COMP_EN register updated
- * - Bit 3 - FBC_SRC_SEL register updated
- * - Bit 4 - FBC_MIN_COMPRESSION register updated
- * - Bit 5 - FBC_ALPHA_COMP_EN register updated
- * - Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated
- * - Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated
- */
- addr = mmFBC_IDLE_FORCE_CLEAR_MASK;
- value = dm_read_reg(compressor->ctx, addr);
- set_reg_field_value(
- value,
- fbc_trigger |
- FBC_IDLE_FORCE_GRPH_COMP_EN |
- FBC_IDLE_FORCE_SRC_SEL_CHANGE |
- FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE |
- FBC_IDLE_FORCE_ALPHA_COMP_EN |
- FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN |
- FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF,
- FBC_IDLE_FORCE_CLEAR_MASK,
- FBC_IDLE_FORCE_CLEAR_MASK);
- dm_write_reg(compressor->ctx, addr, value);
-}
-
-void dce80_compressor_construct(struct dce80_compressor *compressor,
- struct dc_context *ctx)
-{
- struct dc_bios *bp = ctx->dc_bios;
- struct embedded_panel_info panel_info;
-
- compressor->base.options.raw = 0;
- compressor->base.options.bits.FBC_SUPPORT = true;
- compressor->base.options.bits.LPT_SUPPORT = true;
- /* For DCE 11 always use one DRAM channel for LPT */
- compressor->base.lpt_channels_num = 1;
- compressor->base.options.bits.DUMMY_BACKEND = false;
-
- /* Check if this system has more than 1 DRAM channel; if only 1 then LPT
- * should not be supported */
- if (compressor->base.memory_bus_width == 64)
- compressor->base.options.bits.LPT_SUPPORT = false;
-
- compressor->base.options.bits.CLK_GATING_DISABLED = false;
-
- compressor->base.ctx = ctx;
- compressor->base.embedded_panel_h_size = 0;
- compressor->base.embedded_panel_v_size = 0;
- compressor->base.memory_bus_width = ctx->asic_id.vram_width;
- compressor->base.allocated_size = 0;
- compressor->base.preferred_requested_size = 0;
- compressor->base.min_compress_ratio = FBC_COMPRESS_RATIO_INVALID;
- compressor->base.banks_num = 0;
- compressor->base.raw_size = 0;
- compressor->base.channel_interleave_size = 0;
- compressor->base.dram_channels_num = 0;
- compressor->base.lpt_channels_num = 0;
- compressor->base.attached_inst = 0;
- compressor->base.is_enabled = false;
-
- if (BP_RESULT_OK ==
- bp->funcs->get_embedded_panel_info(bp, &panel_info)) {
- compressor->base.embedded_panel_h_size =
- panel_info.lcd_timing.horizontal_addressable;
- compressor->base.embedded_panel_v_size =
- panel_info.lcd_timing.vertical_addressable;
- }
-}
-
-struct compressor *dce80_compressor_create(struct dc_context *ctx)
-{
- struct dce80_compressor *cp80 =
- kzalloc(sizeof(struct dce80_compressor), GFP_KERNEL);
-
- if (!cp80)
- return NULL;
-
- dce80_compressor_construct(cp80, ctx);
- return &cp80->base;
-}
-
-void dce80_compressor_destroy(struct compressor **compressor)
-{
- kfree(TO_DCE80_COMPRESSOR(*compressor));
- *compressor = NULL;
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.h b/drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.h
deleted file mode 100644
index cca58b044402..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_compressor.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 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 __DC_COMPRESSOR_DCE80_H__
-#define __DC_COMPRESSOR_DCE80_H__
-
-#include "../inc/compressor.h"
-
-#define TO_DCE80_COMPRESSOR(compressor)\
- container_of(compressor, struct dce80_compressor, base)
-
-struct dce80_compressor_reg_offsets {
- uint32_t dcp_offset;
- uint32_t dmif_offset;
-};
-
-struct dce80_compressor {
- struct compressor base;
- struct dce80_compressor_reg_offsets offsets;
-};
-
-struct compressor *dce80_compressor_create(struct dc_context *ctx);
-
-void dce80_compressor_construct(struct dce80_compressor *cp80,
- struct dc_context *ctx);
-
-void dce80_compressor_destroy(struct compressor **cp);
-
-/* FBC RELATED */
-void dce80_compressor_power_up_fbc(struct compressor *cp);
-
-void dce80_compressor_enable_fbc(struct compressor *cp, uint32_t paths_num,
- struct compr_addr_and_pitch_params *params);
-
-void dce80_compressor_disable_fbc(struct compressor *cp);
-
-void dce80_compressor_set_fbc_invalidation_triggers(struct compressor *cp,
- uint32_t fbc_trigger);
-
-void dce80_compressor_program_compressed_surface_address_and_pitch(
- struct compressor *cp,
- struct compr_addr_and_pitch_params *params);
-
-bool dce80_compressor_is_fbc_enabled_in_hw(struct compressor *cp,
- uint32_t *fbc_mapped_crtc_id);
-
-/* LPT RELATED */
-void dce80_compressor_enable_lpt(struct compressor *cp);
-
-void dce80_compressor_disable_lpt(struct compressor *cp);
-
-void dce80_compressor_program_lpt_control(struct compressor *cp,
- struct compr_addr_and_pitch_params *params);
-
-bool dce80_compressor_is_lpt_enabled_in_hw(struct compressor *cp);
-
-#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
index ccfcf1c0eeb3..6c6a1a16af19 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_hw_sequencer.c
@@ -70,47 +70,11 @@ static const struct dce80_hw_seq_reg_offsets reg_offsets[] = {
/***************************PIPE_CONTROL***********************************/
-static bool dce80_enable_display_power_gating(
- struct dc *dc,
- uint8_t controller_id,
- struct dc_bios *dcb,
- enum pipe_gating_control power_gating)
-{
- enum bp_result bp_result = BP_RESULT_OK;
- enum bp_pipe_control_action cntl;
- struct dc_context *ctx = dc->ctx;
-
- if (power_gating == PIPE_GATING_CONTROL_INIT)
- cntl = ASIC_PIPE_INIT;
- else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
- cntl = ASIC_PIPE_ENABLE;
- else
- cntl = ASIC_PIPE_DISABLE;
-
- if (!(power_gating == PIPE_GATING_CONTROL_INIT && controller_id != 0)){
-
- bp_result = dcb->funcs->enable_disp_power_gating(
- dcb, controller_id + 1, cntl);
-
- /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
- * by default when command table is called
- */
- dm_write_reg(ctx,
- HW_REG_CRTC(mmMASTER_UPDATE_MODE, controller_id),
- 0);
- }
-
- if (bp_result == BP_RESULT_OK)
- return true;
- else
- return false;
-}
-
void dce80_hw_sequencer_construct(struct dc *dc)
{
dce110_hw_sequencer_construct(dc);
- dc->hwss.enable_display_power_gating = dce80_enable_display_power_gating;
+ dc->hwss.enable_display_power_gating = dce100_enable_display_power_gating;
dc->hwss.pipe_control_lock = dce_pipe_control_lock;
dc->hwss.set_bandwidth = dce100_set_bandwidth;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
index 8f2bd56f3461..a36c14d3d9a8 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
@@ -790,9 +790,11 @@ static bool dce80_construct(
*************************************************/
pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
pool->base.pipe_count = res_cap.num_timing_generator;
+ pool->base.timing_generator_count = res_cap.num_timing_generator;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 40;
dc->caps.max_cursor_size = 128;
+ dc->caps.dual_link_dvi = true;
/*************************************************
* Create resources *
@@ -954,6 +956,7 @@ static bool dce81_construct(
*************************************************/
pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
pool->base.pipe_count = res_cap_81.num_timing_generator;
+ pool->base.timing_generator_count = res_cap_81.num_timing_generator;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 40;
dc->caps.max_cursor_size = 128;
@@ -1119,6 +1122,7 @@ static bool dce83_construct(
*************************************************/
pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
pool->base.pipe_count = res_cap_83.num_timing_generator;
+ pool->base.timing_generator_count = res_cap_83.num_timing_generator;
dc->caps.max_downscale_ratio = 200;
dc->caps.i2c_speed_in_khz = 40;
dc->caps.max_cursor_size = 128;
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
index 265894851493..3ba4712a35ab 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
@@ -84,7 +84,7 @@ static const struct dce110_timing_generator_offsets reg_offsets[] = {
#define DCP_REG(reg) (reg + tg110->offsets.dcp)
#define DMIF_REG(reg) (reg + tg110->offsets.dmif)
-void program_pix_dur(struct timing_generator *tg, uint32_t pix_clk_khz)
+static void program_pix_dur(struct timing_generator *tg, uint32_t pix_clk_khz)
{
uint64_t pix_dur;
uint32_t addr = mmDMIF_PG0_DPG_PIPE_ARBITRATION_CONTROL1
@@ -115,6 +115,68 @@ static void program_timing(struct timing_generator *tg,
dce110_tg_program_timing(tg, timing, use_vbios);
}
+static void dce80_timing_generator_enable_advanced_request(
+ struct timing_generator *tg,
+ bool enable,
+ const struct dc_crtc_timing *timing)
+{
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+ uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
+ uint32_t value = dm_read_reg(tg->ctx, addr);
+
+ if (enable) {
+ set_reg_field_value(
+ value,
+ 0,
+ CRTC_START_LINE_CONTROL,
+ CRTC_LEGACY_REQUESTOR_EN);
+ } else {
+ set_reg_field_value(
+ value,
+ 1,
+ CRTC_START_LINE_CONTROL,
+ CRTC_LEGACY_REQUESTOR_EN);
+ }
+
+ if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
+ set_reg_field_value(
+ value,
+ 3,
+ CRTC_START_LINE_CONTROL,
+ CRTC_ADVANCED_START_LINE_POSITION);
+ set_reg_field_value(
+ value,
+ 0,
+ CRTC_START_LINE_CONTROL,
+ CRTC_PREFETCH_EN);
+ } else {
+ set_reg_field_value(
+ value,
+ 4,
+ CRTC_START_LINE_CONTROL,
+ CRTC_ADVANCED_START_LINE_POSITION);
+ set_reg_field_value(
+ value,
+ 1,
+ CRTC_START_LINE_CONTROL,
+ CRTC_PREFETCH_EN);
+ }
+
+ set_reg_field_value(
+ value,
+ 1,
+ CRTC_START_LINE_CONTROL,
+ CRTC_PROGRESSIVE_START_LINE_EARLY);
+
+ set_reg_field_value(
+ value,
+ 1,
+ CRTC_START_LINE_CONTROL,
+ CRTC_INTERLACE_START_LINE_EARLY);
+
+ dm_write_reg(tg->ctx, addr, value);
+}
+
static const struct timing_generator_funcs dce80_tg_funcs = {
.validate_timing = dce110_tg_validate_timing,
.program_timing = program_timing,
@@ -150,6 +212,8 @@ static const struct timing_generator_funcs dce80_tg_funcs = {
/* DCE8.0 overrides */
.enable_advanced_request =
dce80_timing_generator_enable_advanced_request,
+ .configure_crc = dce110_configure_crc,
+ .get_crc = dce110_get_crc,
};
void dce80_timing_generator_construct(
@@ -176,64 +240,3 @@ void dce80_timing_generator_construct(
tg110->min_h_back_porch = 4;
}
-void dce80_timing_generator_enable_advanced_request(
- struct timing_generator *tg,
- bool enable,
- const struct dc_crtc_timing *timing)
-{
- struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
- uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
- uint32_t value = dm_read_reg(tg->ctx, addr);
-
- if (enable) {
- set_reg_field_value(
- value,
- 0,
- CRTC_START_LINE_CONTROL,
- CRTC_LEGACY_REQUESTOR_EN);
- } else {
- set_reg_field_value(
- value,
- 1,
- CRTC_START_LINE_CONTROL,
- CRTC_LEGACY_REQUESTOR_EN);
- }
-
- if ((timing->v_sync_width + timing->v_front_porch) <= 3) {
- set_reg_field_value(
- value,
- 3,
- CRTC_START_LINE_CONTROL,
- CRTC_ADVANCED_START_LINE_POSITION);
- set_reg_field_value(
- value,
- 0,
- CRTC_START_LINE_CONTROL,
- CRTC_PREFETCH_EN);
- } else {
- set_reg_field_value(
- value,
- 4,
- CRTC_START_LINE_CONTROL,
- CRTC_ADVANCED_START_LINE_POSITION);
- set_reg_field_value(
- value,
- 1,
- CRTC_START_LINE_CONTROL,
- CRTC_PREFETCH_EN);
- }
-
- set_reg_field_value(
- value,
- 1,
- CRTC_START_LINE_CONTROL,
- CRTC_PROGRESSIVE_START_LINE_EARLY);
-
- set_reg_field_value(
- value,
- 1,
- CRTC_START_LINE_CONTROL,
- CRTC_INTERLACE_START_LINE_EARLY);
-
- dm_write_reg(tg->ctx, addr, value);
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.h b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.h
index 9cebb24c94c8..8ff1b06bcd8b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.h
@@ -36,10 +36,4 @@ void dce80_timing_generator_construct(
uint32_t instance,
const struct dce110_timing_generator_offsets *offsets);
-/******** HW programming ************/
-void dce80_timing_generator_enable_advanced_request(
- struct timing_generator *tg,
- bool enable,
- const struct dc_crtc_timing *timing);
-
#endif /* __DC_TIMING_GENERATOR_DCE80_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 53ba3600ee6a..b3db6397d353 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -232,10 +232,11 @@ bool cm_helper_convert_to_custom_float(
return true;
}
-
+/* driver uses 32 regions or less, but DCN HW has 34, extra 2 are set to 0 */
#define MAX_REGIONS_NUMBER 34
#define MAX_LOW_POINT 25
-#define NUMBER_SEGMENTS 32
+#define NUMBER_REGIONS 32
+#define NUMBER_SW_SEGMENTS 16
bool cm_helper_translate_curve_to_hw_format(
const struct dc_transfer_func *output_tf,
@@ -251,7 +252,7 @@ bool cm_helper_translate_curve_to_hw_format(
struct fixed31_32 y1_min;
struct fixed31_32 y3_max;
- int32_t segment_start, segment_end;
+ int32_t region_start, region_end;
int32_t i;
uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points;
@@ -271,11 +272,11 @@ bool cm_helper_translate_curve_to_hw_format(
/* 32 segments
* segments are from 2^-25 to 2^7
*/
- for (i = 0; i < 32 ; i++)
+ for (i = 0; i < NUMBER_REGIONS ; i++)
seg_distr[i] = 3;
- segment_start = -25;
- segment_end = 7;
+ region_start = -MAX_LOW_POINT;
+ region_end = NUMBER_REGIONS - MAX_LOW_POINT;
} else {
/* 10 segments
* segment is from 2^-10 to 2^0
@@ -289,14 +290,14 @@ bool cm_helper_translate_curve_to_hw_format(
seg_distr[5] = 4;
seg_distr[6] = 4;
seg_distr[7] = 4;
- seg_distr[8] = 5;
- seg_distr[9] = 5;
+ seg_distr[8] = 4;
+ seg_distr[9] = 4;
- segment_start = -10;
- segment_end = 0;
+ region_start = -10;
+ region_end = 0;
}
- for (i = segment_end - segment_start; i < MAX_REGIONS_NUMBER ; i++)
+ for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
seg_distr[i] = -1;
for (k = 0; k < MAX_REGIONS_NUMBER; k++) {
@@ -305,10 +306,12 @@ bool cm_helper_translate_curve_to_hw_format(
}
j = 0;
- for (k = 0; k < (segment_end - segment_start); k++) {
- increment = NUMBER_SEGMENTS / (1 << seg_distr[k]);
- start_index = (segment_start + k + MAX_LOW_POINT) * NUMBER_SEGMENTS;
- for (i = start_index; i < start_index + NUMBER_SEGMENTS; i += increment) {
+ for (k = 0; k < (region_end - region_start); k++) {
+ increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+ start_index = (region_start + k + MAX_LOW_POINT) *
+ NUMBER_SW_SEGMENTS;
+ for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+ i += increment) {
if (j == hw_points - 1)
break;
rgb_resulted[j].red = output_tf->tf_pts.red[i];
@@ -319,15 +322,15 @@ bool cm_helper_translate_curve_to_hw_format(
}
/* last point */
- start_index = (segment_end + MAX_LOW_POINT) * NUMBER_SEGMENTS;
+ start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index];
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_start));
+ dal_fixed31_32_from_int(region_start));
arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
- dal_fixed31_32_from_int(segment_end));
+ dal_fixed31_32_from_int(region_end));
y_r = rgb_resulted[0].red;
y_g = rgb_resulted[0].green;
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 f2a08b156cf0..8725cab9ec00 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -196,7 +196,7 @@ static void dpp1_cm_set_regamma_pwl(
case OPP_REGAMMA_SRGB:
re_mode = 1;
break;
- case OPP_REGAMMA_3_6:
+ case OPP_REGAMMA_XVYCC:
re_mode = 2;
break;
case OPP_REGAMMA_USER:
@@ -424,6 +424,26 @@ void dpp1_set_cursor_position(
}
+void dpp1_dppclk_control(
+ struct dpp *dpp_base,
+ bool dppclk_div,
+ bool enable)
+{
+ struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+
+ if (enable) {
+ if (dpp->tf_mask->DPPCLK_RATE_CONTROL) {
+ REG_UPDATE_2(DPP_CONTROL,
+ DPPCLK_RATE_CONTROL, dppclk_div,
+ DPP_CLOCK_ENABLE, 1);
+ } else {
+ ASSERT(dppclk_div == false);
+ REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 1);
+ }
+ } else
+ REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 0);
+}
+
static const struct dpp_funcs dcn10_dpp_funcs = {
.dpp_reset = dpp_reset,
.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
@@ -445,6 +465,7 @@ static const struct dpp_funcs dcn10_dpp_funcs = {
.dpp_full_bypass = dpp1_full_bypass,
.set_cursor_attributes = dpp1_set_cursor_attributes,
.set_cursor_position = dpp1_set_cursor_position,
+ .dpp_dppclk_control = dpp1_dppclk_control,
};
static struct dpp_caps dcn10_dpp_cap = {
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 f56ee4d08d89..07003d9c6bba 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -112,7 +112,8 @@
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
- SRI(CURSOR0_COLOR1, CNVC_CUR, id)
+ SRI(CURSOR0_COLOR1, CNVC_CUR, id), \
+ SRI(DPP_CONTROL, DPP_TOP, id)
@@ -306,7 +307,8 @@
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_COLOR0, CUR0_COLOR0, mask_sh), \
- TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
+ TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh), \
+ TF_SF(DPP_TOP0_DPP_CONTROL, DPP_CLOCK_ENABLE, mask_sh)
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@@ -410,7 +412,8 @@
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), \
- TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh)
+ TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
+ TF_SF(DPP_TOP0_DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh)
#define TF_REG_FIELD_LIST(type) \
type EXT_OVERSCAN_LEFT; \
@@ -1007,7 +1010,9 @@
type CM_BYPASS; \
type FORMAT_CONTROL__ALPHA_EN; \
type CUR0_COLOR0; \
- type CUR0_COLOR1;
+ type CUR0_COLOR1; \
+ type DPPCLK_RATE_CONTROL; \
+ type DPP_CLOCK_ENABLE;
struct dcn_dpp_shift {
TF_REG_FIELD_LIST(uint8_t)
@@ -1252,7 +1257,8 @@ struct dcn_dpp_mask {
uint32_t CURSOR_CONTROL; \
uint32_t CURSOR0_CONTROL; \
uint32_t CURSOR0_COLOR0; \
- uint32_t CURSOR0_COLOR1;
+ uint32_t CURSOR0_COLOR1; \
+ uint32_t DPP_CONTROL;
struct dcn_dpp_registers {
DPP_COMMON_REG_VARIABLE_LIST
@@ -1287,6 +1293,12 @@ void dpp1_set_cursor_attributes(
struct dpp *dpp_base,
enum dc_cursor_color_format color_format);
+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);
+
bool dpp1_dscl_is_lb_conf_valid(
int ceil_vratio,
int num_partitions,
@@ -1397,6 +1409,11 @@ void dpp1_cnv_setup (
void dpp1_full_bypass(struct dpp *dpp_base);
+void dpp1_dppclk_control(
+ struct dpp *dpp_base,
+ bool dppclk_div,
+ bool enable);
+
void dpp1_construct(struct dcn10_dpp *dpp1,
struct dc_context *ctx,
uint32_t inst,
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 a5b099023652..bd3fcdfb79c5 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
@@ -193,6 +193,7 @@ void dpp1_cm_set_gamut_remap(
const struct dpp_grph_csc_adjustment *adjust)
{
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
+ int i = 0;
if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
/* Bypass if type is bypass or hw */
@@ -201,20 +202,8 @@ void dpp1_cm_set_gamut_remap(
struct fixed31_32 arr_matrix[12];
uint16_t arr_reg_val[12];
- arr_matrix[0] = adjust->temperature_matrix[0];
- arr_matrix[1] = adjust->temperature_matrix[1];
- arr_matrix[2] = adjust->temperature_matrix[2];
- arr_matrix[3] = dal_fixed31_32_zero;
-
- arr_matrix[4] = adjust->temperature_matrix[3];
- arr_matrix[5] = adjust->temperature_matrix[4];
- arr_matrix[6] = adjust->temperature_matrix[5];
- arr_matrix[7] = dal_fixed31_32_zero;
-
- arr_matrix[8] = adjust->temperature_matrix[6];
- arr_matrix[9] = adjust->temperature_matrix[7];
- arr_matrix[10] = adjust->temperature_matrix[8];
- arr_matrix[11] = dal_fixed31_32_zero;
+ for (i = 0; i < 12; i++)
+ arr_matrix[i] = adjust->temperature_matrix[i];
convert_float_matrix(
arr_reg_val, arr_matrix, 12);
@@ -309,6 +298,32 @@ static void dpp1_cm_get_reg_field(
reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B;
}
+static void dpp1_cm_get_degamma_reg_field(
+ struct dcn10_dpp *dpp,
+ struct xfer_func_reg *reg)
+{
+ reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+ reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION0_LUT_OFFSET;
+ reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+ reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
+ reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+ reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION1_LUT_OFFSET;
+ reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+ reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_DGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
+
+ reg->shifts.field_region_end = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_END_B;
+ reg->masks.field_region_end = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_END_B;
+ reg->shifts.field_region_end_slope = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B;
+ reg->masks.field_region_end_slope = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_END_SLOPE_B;
+ reg->shifts.field_region_end_base = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_END_BASE_B;
+ reg->masks.field_region_end_base = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_END_BASE_B;
+ reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+ reg->masks.field_region_linear_slope = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B;
+ reg->shifts.exp_region_start = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_START_B;
+ reg->masks.exp_region_start = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_START_B;
+ reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+ reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_DGAM_RAMB_EXP_REGION_START_SEGMENT_B;
+}
void dpp1_cm_set_output_csc_adjustment(
struct dpp *dpp_base,
const uint16_t *regval)
@@ -513,7 +528,7 @@ void dpp1_program_degamma_lutb_settings(
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dpp1_cm_get_reg_field(dpp, &gam_regs);
+ dpp1_cm_get_degamma_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);
@@ -542,7 +557,7 @@ void dpp1_program_degamma_luta_settings(
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
struct xfer_func_reg gam_regs;
- dpp1_cm_get_reg_field(dpp, &gam_regs);
+ dpp1_cm_get_degamma_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);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index 585b33384002..39b72f696ae9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -73,6 +73,9 @@ static void hubp1_disconnect(struct hubp *hubp)
REG_UPDATE(DCHUBP_CNTL,
HUBP_TTU_DISABLE, 1);
+
+ REG_UPDATE(CURSOR_CONTROL,
+ CURSOR_ENABLE, 0);
}
static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
@@ -296,8 +299,9 @@ bool hubp1_program_surface_flip_and_addr(
if (address->grph.addr.quad_part == 0)
break;
- REG_UPDATE(DCSURF_SURFACE_CONTROL,
- PRIMARY_SURFACE_TMZ, address->tmz_surface);
+ REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
+ PRIMARY_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
if (address->grph.meta_addr.quad_part != 0) {
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
@@ -322,8 +326,11 @@ bool hubp1_program_surface_flip_and_addr(
|| address->video_progressive.chroma_addr.quad_part == 0)
break;
- REG_UPDATE(DCSURF_SURFACE_CONTROL,
- PRIMARY_SURFACE_TMZ, address->tmz_surface);
+ REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
+ PRIMARY_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
if (address->video_progressive.luma_meta_addr.quad_part != 0) {
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
@@ -365,8 +372,11 @@ bool hubp1_program_surface_flip_and_addr(
if (address->grph_stereo.right_addr.quad_part == 0)
break;
- REG_UPDATE(DCSURF_SURFACE_CONTROL,
- PRIMARY_SURFACE_TMZ, address->tmz_surface);
+ REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
+ PRIMARY_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
+ PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
if (address->grph_stereo.right_meta_addr.quad_part != 0) {
@@ -909,6 +919,21 @@ void hubp1_cursor_set_position(
/* TODO Handle surface pixel formats other than 4:4:4 */
}
+void hubp1_clk_cntl(struct hubp *hubp, bool enable)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+ uint32_t clk_enable = enable ? 1 : 0;
+
+ REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable);
+}
+
+void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst)
+{
+ struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
+
+ REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst);
+}
+
static struct hubp_funcs dcn10_hubp_funcs = {
.hubp_program_surface_flip_and_addr =
hubp1_program_surface_flip_and_addr,
@@ -925,6 +950,8 @@ static struct hubp_funcs dcn10_hubp_funcs = {
.set_cursor_attributes = hubp1_cursor_set_attributes,
.set_cursor_position = hubp1_cursor_set_position,
.hubp_disconnect = hubp1_disconnect,
+ .hubp_clk_cntl = hubp1_clk_cntl,
+ .hubp_vtg_sel = hubp1_vtg_sel,
};
/*****************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
index 33e91d9c010f..4a3703e12ea1 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -96,7 +96,8 @@
SRI(DCN_SURF0_TTU_CNTL1, HUBPREQ, id),\
SRI(DCN_SURF1_TTU_CNTL0, HUBPREQ, id),\
SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\
- SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id)
+ SRI(DCN_VM_MX_L1_TLB_CNTL, HUBPREQ, id),\
+ SRI(HUBP_CLK_CNTL, HUBP, id)
#define HUBP_REG_LIST_DCN10(id)\
HUBP_REG_LIST_DCN(id),\
@@ -230,7 +231,8 @@
uint32_t CURSOR_CONTROL; \
uint32_t CURSOR_POSITION; \
uint32_t CURSOR_HOT_SPOT; \
- uint32_t CURSOR_DST_OFFSET
+ uint32_t CURSOR_DST_OFFSET; \
+ uint32_t HUBP_CLK_CNTL
#define HUBP_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix
@@ -240,6 +242,7 @@
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\
HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_NO_OUTSTANDING_REQ, mask_sh),\
+ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_VTG_SEL, mask_sh),\
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_PIPES, mask_sh),\
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, NUM_BANKS, mask_sh),\
HUBP_SF(HUBP0_DCSURF_ADDR_CONFIG, PIPE_INTERLEAVE, mask_sh),\
@@ -293,6 +296,9 @@
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_C, SURFACE_EARLIEST_INUSE_ADDRESS_C, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_EARLIEST_INUSE_HIGH_C, SURFACE_EARLIEST_INUSE_ADDRESS_HIGH_C, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_TMZ, mask_sh),\
+ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_TMZ_C, mask_sh),\
+ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_META_SURFACE_TMZ, mask_sh),\
+ HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_META_SURFACE_TMZ_C, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, mask_sh),\
HUBP_SF(HUBPREQ0_DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_IND_64B_BLK, mask_sh),\
HUBP_SF(HUBPRET0_HUBPRET_CONTROL, DET_BUF_PLANE1_BASE_ADDRESS, mask_sh),\
@@ -352,7 +358,8 @@
HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL0, QoS_RAMP_DISABLE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\
HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, mask_sh),\
- HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh)
+ HUBP_SF(HUBPREQ0_DCN_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, mask_sh),\
+ HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh)
#define HUBP_MASK_SH_LIST_DCN10(mask_sh)\
HUBP_MASK_SH_LIST_DCN(mask_sh),\
@@ -398,6 +405,7 @@
type HUBP_BLANK_EN;\
type HUBP_TTU_DISABLE;\
type HUBP_NO_OUTSTANDING_REQ;\
+ type HUBP_VTG_SEL;\
type HUBP_UNDERFLOW_STATUS;\
type NUM_PIPES;\
type NUM_BANKS;\
@@ -452,6 +460,13 @@
type SURFACE_EARLIEST_INUSE_ADDRESS_C;\
type SURFACE_EARLIEST_INUSE_ADDRESS_HIGH_C;\
type PRIMARY_SURFACE_TMZ;\
+ type PRIMARY_SURFACE_TMZ_C;\
+ type SECONDARY_SURFACE_TMZ;\
+ type SECONDARY_SURFACE_TMZ_C;\
+ type PRIMARY_META_SURFACE_TMZ;\
+ type PRIMARY_META_SURFACE_TMZ_C;\
+ type SECONDARY_META_SURFACE_TMZ;\
+ type SECONDARY_META_SURFACE_TMZ_C;\
type PRIMARY_SURFACE_DCC_EN;\
type PRIMARY_SURFACE_DCC_IND_64B_BLK;\
type DET_BUF_PLANE1_BASE_ADDRESS;\
@@ -524,6 +539,7 @@
type VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB;\
type ENABLE_L1_TLB;\
type SYSTEM_ACCESS_MODE;\
+ type HUBP_CLOCK_ENABLE;\
type MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM;\
type MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;\
type MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;\
@@ -653,6 +669,9 @@ void min_set_viewport(struct hubp *hubp,
const struct rect *viewport,
const struct rect *viewport_c);
+void hubp1_clk_cntl(struct hubp *hubp, bool enable);
+void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst);
+
void dcn10_hubp_construct(
struct dcn10_hubp *hubp1,
struct dc_context *ctx,
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 82572863acab..29dc37fbdb26 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
@@ -133,7 +133,7 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("[%d]:\t %xh \t %xh \t %d \t %d \t "
"%xh \t %xh \t %xh \t "
"%d \t %d \t %d \t %xh \t",
- i,
+ hubp->inst,
s.pixel_format,
s.inuse_addr_hi,
s.viewport_width,
@@ -155,7 +155,7 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("OTG:\t v_bs \t v_be \t v_ss \t v_se \t vpol \t vmax \t vmin \t "
"h_bs \t h_be \t h_ss \t h_se \t hpol \t htot \t vtot \t underflow\n");
- for (i = 0; i < pool->res_cap->num_timing_generator; i++) {
+ for (i = 0; i < pool->timing_generator_count; i++) {
struct timing_generator *tg = pool->timing_generators[i];
struct dcn_otg_state s = {0};
@@ -168,7 +168,7 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO("[%d]:\t %d \t %d \t %d \t %d \t "
"%d \t %d \t %d \t %d \t %d \t %d \t "
"%d \t %d \t %d \t %d \t %d \t ",
- i,
+ tg->inst,
s.v_blank_start,
s.v_blank_end,
s.v_sync_a_start,
@@ -193,26 +193,6 @@ void dcn10_log_hw_state(struct dc *dc)
DTN_INFO_END();
}
-static void enable_dppclk(
- struct dce_hwseq *hws,
- uint8_t plane_id,
- uint32_t requested_pix_clk,
- bool dppclk_div)
-{
- dm_logger_write(hws->ctx->logger, LOG_SURFACE,
- "dppclk_rate_control for pipe %d programed to %d\n",
- plane_id,
- dppclk_div);
-
- if (hws->shifts->DPPCLK_RATE_CONTROL)
- REG_UPDATE_2(DPP_CONTROL[plane_id],
- DPPCLK_RATE_CONTROL, dppclk_div,
- DPP_CLOCK_ENABLE, 1);
- else
- REG_UPDATE(DPP_CONTROL[plane_id],
- DPP_CLOCK_ENABLE, 1);
-}
-
static void enable_power_gating_plane(
struct dce_hwseq *hws,
bool enable)
@@ -597,29 +577,22 @@ static void dcn10_verify_allow_pstate_change_high(struct dc *dc)
/* trigger HW to start disconnect plane from stream on the next vsync */
static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- int fe_idx = pipe_ctx->pipe_idx;
- struct hubp *hubp = dc->res_pool->hubps[fe_idx];
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ int dpp_id = pipe_ctx->plane_res.dpp->inst;
struct mpc *mpc = dc->res_pool->mpc;
- int opp_id;
struct mpc_tree *mpc_tree_params;
struct mpcc *mpcc_to_remove = NULL;
+ struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
- /* look at tree rather than mi here to know if we already reset */
- for (opp_id = 0; opp_id < dc->res_pool->pipe_count; opp_id++) {
- struct output_pixel_processor *opp = dc->res_pool->opps[opp_id];
-
- mpc_tree_params = &(opp->mpc_tree_params);
- mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, fe_idx);
- if (mpcc_to_remove != NULL)
- break;
- }
+ mpc_tree_params = &(opp->mpc_tree_params);
+ mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);
/*Already reset*/
- if (opp_id == dc->res_pool->pipe_count)
+ if (mpcc_to_remove == NULL)
return;
mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);
- dc->res_pool->opps[opp_id]->mpcc_disconnect_pending[fe_idx] = true;
+ opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
dc->optimized_required = true;
@@ -630,21 +603,21 @@ static void plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
dcn10_verify_allow_pstate_change_high(dc);
}
-static void plane_atomic_power_down(struct dc *dc, int fe_idx)
+static void plane_atomic_power_down(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
struct dce_hwseq *hws = dc->hwseq;
- struct dpp *dpp = dc->res_pool->dpps[fe_idx];
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
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_pg_control(hws, dpp->inst, false);
+ hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, 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);
+ "Power gated front end %d\n", pipe_ctx->pipe_idx);
}
}
@@ -653,26 +626,25 @@ static void plane_atomic_power_down(struct dc *dc, int fe_idx)
*/
static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- int fe_idx = pipe_ctx->pipe_idx;
- struct dce_hwseq *hws = dc->hwseq;
- struct hubp *hubp = dc->res_pool->hubps[fe_idx];
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
int opp_id = hubp->opp_id;
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx);
- REG_UPDATE(HUBP_CLK_CNTL[fe_idx],
- HUBP_CLOCK_ENABLE, 0);
- REG_UPDATE(DPP_CONTROL[fe_idx],
- DPP_CLOCK_ENABLE, 0);
+ hubp->funcs->hubp_clk_cntl(hubp, false);
- if (opp_id != 0xf && dc->res_pool->opps[opp_id]->mpc_tree_params.opp_list == NULL)
- REG_UPDATE(OPP_PIPE_CONTROL[opp_id],
- OPP_PIPE_CLOCK_EN, 0);
+ dpp->funcs->dpp_dppclk_control(dpp, false, false);
+
+ if (opp_id != 0xf && pipe_ctx->stream_res.opp->mpc_tree_params.opp_list == NULL)
+ pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+ pipe_ctx->stream_res.opp,
+ false);
hubp->power_gated = true;
dc->optimized_required = false; /* We're powering off, no need to optimize */
- plane_atomic_power_down(dc, fe_idx);
+ plane_atomic_power_down(dc, pipe_ctx);
pipe_ctx->stream = NULL;
memset(&pipe_ctx->stream_res, 0, sizeof(pipe_ctx->stream_res));
@@ -684,7 +656,7 @@ static void plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
static void dcn10_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx)
{
- if (dc->res_pool->hubps[pipe_ctx->pipe_idx]->power_gated)
+ if (!pipe_ctx->plane_res.hubp || pipe_ctx->plane_res.hubp->power_gated)
return;
plane_atomic_disable(dc, pipe_ctx);
@@ -720,26 +692,25 @@ static void dcn10_init_hw(struct dc *dc)
}
enable_power_gating_plane(dc->hwseq, true);
- return;
- }
- /* end of FPGA. Below if real ASIC */
+ } else {
- if (!dcb->funcs->is_accelerated_mode(dcb)) {
- bios_golden_init(dc);
- disable_vga(dc->hwseq);
- }
+ if (!dcb->funcs->is_accelerated_mode(dcb)) {
+ bios_golden_init(dc);
+ disable_vga(dc->hwseq);
+ }
- for (i = 0; i < dc->link_count; i++) {
- /* Power up AND update implementation according to the
- * required signal (which may be different from the
- * default signal on connector).
- */
- struct dc_link *link = dc->links[i];
+ for (i = 0; i < dc->link_count; i++) {
+ /* Power up AND update implementation according to the
+ * required signal (which may be different from the
+ * default signal on connector).
+ */
+ struct dc_link *link = dc->links[i];
- if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
- dc->hwss.edp_power_control(link, true);
+ if (link->link_enc->connector.id == CONNECTOR_ID_EDP)
+ dc->hwss.edp_power_control(link, true);
- link->link_enc->funcs->hw_init(link->link_enc);
+ link->link_enc->funcs->hw_init(link->link_enc);
+ }
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -768,18 +739,21 @@ static void dcn10_init_hw(struct dc *dc)
struct timing_generator *tg = dc->res_pool->timing_generators[i];
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
struct hubp *hubp = dc->res_pool->hubps[i];
+ struct dpp *dpp = dc->res_pool->dpps[i];
pipe_ctx->stream_res.tg = tg;
pipe_ctx->pipe_idx = i;
pipe_ctx->plane_res.hubp = hubp;
- hubp->mpcc_id = i;
+ pipe_ctx->plane_res.dpp = dpp;
+ pipe_ctx->plane_res.mpcc_inst = dpp->inst;
+ hubp->mpcc_id = dpp->inst;
hubp->opp_id = 0xf;
hubp->power_gated = false;
dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst;
dc->res_pool->opps[i]->mpc_tree_params.opp_list = NULL;
- dc->res_pool->opps[i]->mpcc_disconnect_pending[i] = true;
+ dc->res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
pipe_ctx->stream_res.opp = dc->res_pool->opps[i];
plane_atomic_disconnect(dc, pipe_ctx);
@@ -804,6 +778,10 @@ static void dcn10_init_hw(struct dc *dc)
tg->funcs->tg_init(tg);
}
+ /* end of FPGA. Below if real ASIC */
+ if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
+ return;
+
for (i = 0; i < dc->res_pool->audio_count; i++) {
struct audio *audio = dc->res_pool->audios[i];
@@ -922,7 +900,10 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
if (plane_state->in_transfer_func)
tf = plane_state->in_transfer_func;
- if (plane_state->gamma_correction && dce_use_lut(plane_state))
+ if (plane_state->gamma_correction &&
+ plane_state->gamma_correction->is_identity)
+ dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
+ else if (plane_state->gamma_correction && dce_use_lut(plane_state->format))
dpp_base->funcs->dpp_program_input_lut(dpp_base, plane_state->gamma_correction);
if (tf == NULL)
@@ -993,8 +974,6 @@ static void dcn10_pipe_control_lock(
struct pipe_ctx *pipe,
bool lock)
{
- 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
*/
@@ -1097,7 +1076,7 @@ static void dcn10_enable_per_frame_crtc_position_reset(
DC_SYNC_INFO("Waiting for trigger\n");
- for (i = 1; i < group_size; i++)
+ for (i = 0; i < group_size; i++)
wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg);
DC_SYNC_INFO("Multi-display sync is complete\n");
@@ -1323,15 +1302,15 @@ static void dcn10_enable_plane(
undo_DEGVIDCN10_253_wa(dc);
power_on_plane(dc->hwseq,
- pipe_ctx->pipe_idx);
+ pipe_ctx->plane_res.hubp->inst);
/* enable DCFCLK current DCHUB */
- REG_UPDATE(HUBP_CLK_CNTL[pipe_ctx->pipe_idx],
- HUBP_CLOCK_ENABLE, 1);
+ pipe_ctx->plane_res.hubp->funcs->hubp_clk_cntl(pipe_ctx->plane_res.hubp, true);
/* make sure OPP_PIPE_CLOCK_EN = 1 */
- REG_UPDATE(OPP_PIPE_CONTROL[pipe_ctx->stream_res.tg->inst],
- OPP_PIPE_CLOCK_EN, 1);
+ pipe_ctx->stream_res.opp->funcs->opp_pipe_clock_control(
+ pipe_ctx->stream_res.opp,
+ true);
/* TODO: enable/disable in dm as per update type.
if (plane_state) {
@@ -1380,6 +1359,7 @@ static void dcn10_enable_plane(
static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
{
+ int i = 0;
struct dpp_grph_csc_adjustment adjust;
memset(&adjust, 0, sizeof(adjust));
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
@@ -1387,33 +1367,9 @@ static void program_gamut_remap(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
- adjust.temperature_matrix[0] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[0];
- adjust.temperature_matrix[1] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[1];
- adjust.temperature_matrix[2] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[2];
- adjust.temperature_matrix[3] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[4];
- adjust.temperature_matrix[4] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[5];
- adjust.temperature_matrix[5] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[6];
- adjust.temperature_matrix[6] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[8];
- adjust.temperature_matrix[7] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[9];
- adjust.temperature_matrix[8] =
- pipe_ctx->stream->
- gamut_remap_matrix.matrix[10];
+ for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+ adjust.temperature_matrix[i] =
+ pipe_ctx->stream->gamut_remap_matrix.matrix[i];
}
pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust);
@@ -1474,7 +1430,7 @@ static bool is_pipe_tree_visible(struct pipe_ctx *pipe_ctx)
return false;
}
-static bool is_rgb_cspace(enum dc_color_space output_color_space)
+bool is_rgb_cspace(enum dc_color_space output_color_space)
{
switch (output_color_space) {
case COLOR_SPACE_SRGB:
@@ -1702,7 +1658,6 @@ static void update_dchubp_dpp(
struct pipe_ctx *pipe_ctx,
struct dc_state *context)
{
- struct dce_hwseq *hws = dc->hwseq;
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;
@@ -1710,11 +1665,11 @@ static void update_dchubp_dpp(
/* depends on DML calculation, DPP clock value may change dynamically */
if (plane_state->update_flags.bits.full_update) {
- enable_dppclk(
- dc->hwseq,
- pipe_ctx->pipe_idx,
- pipe_ctx->stream_res.pix_clk_params.requested_pix_clk,
- context->bw.dcn.calc_clk.dppclk_div);
+ dpp->funcs->dpp_dppclk_control(
+ dpp,
+ context->bw.dcn.calc_clk.dppclk_div,
+ true);
+
dc->current_state->bw.dcn.cur_clk.dppclk_div =
context->bw.dcn.calc_clk.dppclk_div;
context->bw.dcn.cur_clk.dppclk_div = context->bw.dcn.calc_clk.dppclk_div;
@@ -1725,7 +1680,7 @@ static void update_dchubp_dpp(
* VTG is 1:1 mapping with OTG. Each pipe HUBP will select which VTG
*/
if (plane_state->update_flags.bits.full_update) {
- REG_UPDATE(DCHUBP_CNTL[pipe_ctx->pipe_idx], HUBP_VTG_SEL, pipe_ctx->stream_res.tg->inst);
+ hubp->funcs->hubp_vtg_sel(hubp, pipe_ctx->stream_res.tg->inst);
hubp->funcs->hubp_setup(
hubp,
@@ -1761,6 +1716,11 @@ static void update_dchubp_dpp(
&pipe_ctx->plane_res.scl_data.viewport_c);
}
+ if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) {
+ dc->hwss.set_cursor_position(pipe_ctx);
+ dc->hwss.set_cursor_attribute(pipe_ctx);
+ }
+
if (plane_state->update_flags.bits.full_update) {
/*gamut remap*/
program_gamut_remap(pipe_ctx);
@@ -1773,6 +1733,7 @@ static void update_dchubp_dpp(
}
if (plane_state->update_flags.bits.full_update ||
+ plane_state->update_flags.bits.pixel_format_change ||
plane_state->update_flags.bits.horizontal_mirror_change ||
plane_state->update_flags.bits.rotation_change ||
plane_state->update_flags.bits.swizzle_change ||
@@ -1822,15 +1783,14 @@ static void program_all_pipe_in_tree(
}
if (pipe_ctx->plane_state != NULL) {
- struct pipe_ctx *cur_pipe_ctx =
- &dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx];
-
if (pipe_ctx->plane_state->update_flags.bits.full_update)
dcn10_enable_plane(dc, pipe_ctx, context);
update_dchubp_dpp(dc, pipe_ctx, context);
- if (cur_pipe_ctx->plane_state != pipe_ctx->plane_state)
+ if (pipe_ctx->plane_state->update_flags.bits.full_update ||
+ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+ pipe_ctx->plane_state->update_flags.bits.gamma_change)
dc->hwss.set_input_transfer_func(pipe_ctx, pipe_ctx->plane_state);
/* dcn10_translate_regamma_to_hw_format takes 750us to finish
@@ -1940,7 +1900,7 @@ static void dcn10_apply_ctx_for_surface(
tg = top_pipe_to_program->stream_res.tg;
- tg->funcs->lock(tg);
+ dcn10_pipe_control_lock(dc, top_pipe_to_program, true);
if (num_planes == 0) {
@@ -1989,7 +1949,7 @@ static void dcn10_apply_ctx_for_surface(
if (num_planes > 0)
program_all_pipe_in_tree(dc, top_pipe_to_program, context);
- tg->funcs->unlock(tg);
+ dcn10_pipe_control_lock(dc, top_pipe_to_program, false);
if (num_planes == 0)
false_optc_underflow_wa(dc, stream, tg);
@@ -2184,6 +2144,8 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
value |= 0x80;
if (events->cursor_update)
value |= 0x2;
+ if (events->force_trigger)
+ value |= 0x1;
for (i = 0; i < num_pipes; i++)
pipe_ctx[i]->stream_res.tg->funcs->
@@ -2256,12 +2218,24 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)
return;
}
+static struct hubp *get_hubp_by_inst(struct resource_pool *res_pool, int mpcc_inst)
+{
+ int i;
+
+ for (i = 0; i < res_pool->pipe_count; i++) {
+ if (res_pool->hubps[i]->inst == mpcc_inst)
+ return res_pool->hubps[i];
+ }
+ ASSERT(false);
+ return NULL;
+}
+
static void dcn10_wait_for_mpcc_disconnect(
struct dc *dc,
struct resource_pool *res_pool,
struct pipe_ctx *pipe_ctx)
{
- int i;
+ int mpcc_inst;
if (dc->debug.sanity_checks) {
dcn10_verify_allow_pstate_change_high(dc);
@@ -2270,11 +2244,13 @@ static void dcn10_wait_for_mpcc_disconnect(
if (!pipe_ctx->stream_res.opp)
return;
- for (i = 0; i < MAX_PIPES; i++) {
- 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->hubps[i]->funcs->set_blank(res_pool->hubps[i], true);
+ for (mpcc_inst = 0; mpcc_inst < MAX_PIPES; mpcc_inst++) {
+ if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
+ struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
+
+ res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
+ pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
+ hubp->funcs->set_blank(hubp, true);
/*dm_logger_write(dc->ctx->logger, LOG_ERROR,
"[debug_mpo: wait_for_mpcc finished waiting on mpcc %d]\n",
i);*/
@@ -2296,7 +2272,7 @@ static bool dcn10_dummy_display_power_gating(
return true;
}
-void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
+static void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
{
struct dc_plane_state *plane_state = pipe_ctx->plane_state;
struct timing_generator *tg = pipe_ctx->stream_res.tg;
@@ -2316,12 +2292,46 @@ void dcn10_update_pending_status(struct pipe_ctx *pipe_ctx)
}
}
-void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
+static void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
{
if (hws->ctx->dc->res_pool->hubbub != NULL)
hubbub1_update_dchub(hws->ctx->dc->res_pool->hubbub, dh_data);
}
+static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
+ struct hubp *hubp = pipe_ctx->plane_res.hubp;
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
+ struct dc_cursor_mi_param param = {
+ .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_khz,
+ .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clock_inKhz,
+ .viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x,
+ .viewport_width = pipe_ctx->plane_res.scl_data.viewport.width,
+ .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz
+ };
+
+ if (pipe_ctx->plane_state->address.type
+ == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+ pos_cpy.enable = false;
+
+ if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
+ pos_cpy.enable = false;
+
+ hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
+ dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, hubp->curs_attr.width);
+}
+
+static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
+{
+ struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;
+
+ pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.hubp, attributes);
+ pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(
+ pipe_ctx->plane_res.dpp, attributes->color_format);
+}
+
static const struct hw_sequencer_funcs dcn10_funcs = {
.program_gamut_remap = program_gamut_remap,
.program_csc_matrix = program_csc_matrix,
@@ -2342,6 +2352,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.enable_stream = dce110_enable_stream,
.disable_stream = dce110_disable_stream,
.unblank_stream = dce110_unblank_stream,
+ .blank_stream = dce110_blank_stream,
.enable_display_power_gating = dcn10_dummy_display_power_gating,
.disable_plane = dcn10_disable_plane,
.pipe_control_lock = dcn10_pipe_control_lock,
@@ -2362,6 +2373,8 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.edp_backlight_control = hwss_edp_backlight_control,
.edp_power_control = hwss_edp_power_control,
.edp_wait_for_hpd_ready = hwss_edp_wait_for_hpd_ready,
+ .set_cursor_position = dcn10_set_cursor_position,
+ .set_cursor_attribute = dcn10_set_cursor_attribute
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
index b9d326082717..6c526b5095d9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
@@ -35,5 +35,6 @@ extern void fill_display_configs(
const struct dc_state *context,
struct dm_pp_display_configuration *pp_display_cfg);
+bool is_rgb_cspace(enum dc_color_space output_color_space);
#endif /* __DC_HWSS_DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
index d7b5bd20352a..819b749c6e31 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h
@@ -33,7 +33,6 @@
#define IPP_REG_LIST_DCN(id) \
SRI(FORMAT_CONTROL, CNVC_CFG, id), \
- SRI(DPP_CONTROL, DPP_TOP, id), \
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
@@ -130,7 +129,6 @@ struct dcn10_ipp_mask {
};
struct dcn10_ipp_registers {
- uint32_t DPP_CONTROL;
uint32_t CURSOR_SETTINS;
uint32_t CURSOR_SETTINGS;
uint32_t CNVC_SURFACE_PIXEL_FORMAT;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
index f6ba0eef4489..77a1a9d541a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
@@ -367,6 +367,14 @@ void opp1_program_oppbuf(
}
+void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable)
+{
+ struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
+ uint32_t regval = enable ? 1 : 0;
+
+ REG_UPDATE(OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, regval);
+}
+
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
@@ -382,6 +390,7 @@ static struct opp_funcs dcn10_opp_funcs = {
.opp_program_fmt = opp1_program_fmt,
.opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
.opp_program_stereo = opp1_program_stereo,
+ .opp_pipe_clock_control = opp1_pipe_clock_control,
.opp_destroy = opp1_destroy
};
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
index bc5058af6266..0f10adea000c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h
@@ -44,7 +44,8 @@
SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id), \
SRI(OPPBUF_CONTROL, OPPBUF, id),\
SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, id), \
- SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id)
+ SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id), \
+ SRI(OPP_PIPE_CONTROL, OPP_PIPE, id)
#define OPP_REG_LIST_DCN10(id) \
OPP_REG_LIST_DCN(id)
@@ -61,7 +62,8 @@
uint32_t OPPBUF_CONTROL; \
uint32_t OPPBUF_CONTROL1; \
uint32_t OPPBUF_3D_PARAMETERS_0; \
- uint32_t OPPBUF_3D_PARAMETERS_1
+ uint32_t OPPBUF_3D_PARAMETERS_1; \
+ uint32_t OPP_PIPE_CONTROL
#define OPP_MASK_SH_LIST_DCN(mask_sh) \
OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh), \
@@ -89,7 +91,8 @@
OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\
OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, mask_sh),\
OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh), \
- OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh)
+ OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh), \
+ OPP_SF(OPP_PIPE0_OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh)
#define OPP_MASK_SH_LIST_DCN10(mask_sh) \
OPP_MASK_SH_LIST_DCN(mask_sh), \
@@ -125,7 +128,8 @@
type OPPBUF_OVERLAP_PIXEL_NUM;\
type OPPBUF_NUM_SEGMENT_PADDED_PIXELS; \
type OPPBUF_3D_VACT_SPACE1_SIZE; \
- type OPPBUF_3D_VACT_SPACE2_SIZE
+ type OPPBUF_3D_VACT_SPACE2_SIZE; \
+ type OPP_PIPE_CLOCK_EN
struct dcn10_opp_registers {
OPP_COMMON_REG_VARIABLE_LIST;
@@ -176,6 +180,8 @@ void opp1_program_stereo(
bool enable,
const struct dc_crtc_timing *timing);
+void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable);
+
void opp1_destroy(struct output_pixel_processor **opp);
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
index a3c7c2012f05..014543235df8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -131,7 +131,6 @@ struct dcn_optc_registers {
uint32_t OTG_GSL_WINDOW_X;
uint32_t OTG_GSL_WINDOW_Y;
uint32_t OTG_VUPDATE_KEEPOUT;
- uint32_t OTG_DSC_START_POSITION;
};
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -241,7 +240,7 @@ struct dcn_optc_registers {
SF(OTG0_OTG_TEST_PATTERN_COLOR, OTG_TEST_PATTERN_DATA, mask_sh),\
SF(ODM0_OPTC_DATA_SOURCE_SELECT, OPTC_SRC_SEL, mask_sh)
-#define TG_REG_FIELD_LIST(type) \
+#define TG_REG_FIELD_LIST_DCN1_0(type) \
type VSTARTUP_START;\
type VUPDATE_OFFSET;\
type VUPDATE_WIDTH;\
@@ -352,10 +351,11 @@ struct dcn_optc_registers {
type OTG_MASTER_UPDATE_LOCK_GSL_EN;\
type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET;\
type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET;\
- type OTG_DSC_START_POSITION_X;\
- type OTG_DSC_START_POSITION_LINE_NUM;\
type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;
+#define TG_REG_FIELD_LIST(type) \
+ TG_REG_FIELD_LIST_DCN1_0(type)
+
struct dcn_optc_shift {
TG_REG_FIELD_LIST(uint8_t)
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 44825e2c9ebb..c4a564cb56b9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -50,7 +50,8 @@
#include "dcn10_hubp.h"
#include "dcn10_hubbub.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
@@ -365,6 +366,7 @@ static const struct dcn_optc_mask tg_mask = {
static const struct bios_registers bios_regs = {
+ NBIO_SR(BIOS_SCRATCH_3),
NBIO_SR(BIOS_SCRATCH_6)
};
@@ -450,6 +452,7 @@ static const struct dc_debug debug_defaults_drv = {
.disable_stereo_support = true,
.vsr_support = true,
.performance_trace = false,
+ .az_endpoint_mute_only = true,
};
static const struct dc_debug debug_defaults_diags = {
@@ -818,7 +821,7 @@ static void get_pixel_clock_parameters(
pixel_clk_params->requested_pix_clk = stream->timing.pix_clk_khz;
pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
pixel_clk_params->signal_type = pipe_ctx->stream->signal;
- pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1;
+ pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
/* TODO: un-hardcode*/
pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
LINK_RATE_REF_FREQ_IN_KHZ;
@@ -965,6 +968,7 @@ static struct pipe_ctx *dcn10_acquire_idle_pipe_for_layer(
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.dpp = pool->dpps[idle_pipe->pipe_idx];
+ idle_pipe->plane_res.mpcc_inst = pool->dpps[idle_pipe->pipe_idx]->inst;
return idle_pipe;
}
@@ -1316,13 +1320,11 @@ static bool construct(
}
}
- if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
- pool->base.display_clock = dce120_disp_clk_create(ctx);
- if (pool->base.display_clock == NULL) {
- dm_error("DC: failed to create display clock!\n");
- BREAK_TO_DEBUGGER();
- goto fail;
- }
+ pool->base.display_clock = dce120_disp_clk_create(ctx);
+ if (pool->base.display_clock == NULL) {
+ dm_error("DC: failed to create display clock!\n");
+ BREAK_TO_DEBUGGER();
+ goto fail;
}
pool->base.dmcu = dcn10_dmcu_create(ctx,
@@ -1445,6 +1447,7 @@ static bool construct(
/* valid pipe num */
pool->base.pipe_count = j;
+ pool->base.timing_generator_count = j;
/* within dml lib, it is hard code to 4. If ASIC pipe is fused,
* the value may be changed
diff --git a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h
index bbfa83252fc1..eac4bfe12257 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h
@@ -91,7 +91,8 @@ struct pp_smu_funcs_rv {
/* which SMU message? are reader and writer WM separate SMU msg? */
void (*set_wm_ranges)(struct pp_smu *pp,
struct pp_smu_wm_range_sets *ranges);
-
+ /* PME w/a */
+ void (*set_pme_wa_enable)(struct pp_smu *pp);
};
#if 0
diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h
index 225b7bfb09a9..22e7ee7dcd26 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_services.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_services.h
@@ -192,37 +192,6 @@ unsigned int generic_reg_wait(const struct dc_context *ctx,
* Power Play (PP) interfaces
**************************************/
-/* DAL calls this function to notify PP about clocks it needs for the Mode Set.
- * This is done *before* it changes DCE clock.
- *
- * If required clock is higher than current, then PP will increase the voltage.
- *
- * If required clock is lower than current, then PP will defer reduction of
- * voltage until the call to dc_service_pp_post_dce_clock_change().
- *
- * \input - Contains clocks needed for Mode Set.
- *
- * \output - Contains clocks adjusted by PP which DAL should use for Mode Set.
- * Valid only if function returns zero.
- *
- * \returns true - call is successful
- * false - call failed
- */
-bool dm_pp_pre_dce_clock_change(
- struct dc_context *ctx,
- struct dm_pp_gpu_clock_range *requested_state,
- struct dm_pp_gpu_clock_range *actual_state);
-
-/* The returned clocks range are 'static' system clocks which will be used for
- * mode validation purposes.
- *
- * \returns true - call is successful
- * false - call failed
- */
-bool dc_service_get_system_clocks_range(
- const struct dc_context *ctx,
- struct dm_pp_gpu_clock_range *sys_clks);
-
/* Gets valid clocks levels from pplib
*
* input: clk_type - display clk / sclk / mem clk
diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
index 3488af2b5786..f83a608f93e9 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -24,19 +24,23 @@
# 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_soc_bounding_box.o := -mhard-float -msse -mpreferred-stack-boundary=4
-CFLAGS_dml_common_defs.o := -mhard-float -msse -mpreferred-stack-boundary=4
+ifneq ($(call cc-option, -mpreferred-stack-boundary=4),)
+ cc_stack_align := -mpreferred-stack-boundary=4
+else ifneq ($(call cc-option, -mstack-alignment=16),)
+ cc_stack_align := -mstack-alignment=16
+endif
+dml_ccflags := -mhard-float -msse $(cc_stack_align)
-DML = display_mode_lib.o display_rq_dlg_calc.o \
- display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
- soc_bounding_box.o dml_common_defs.o display_mode_vba.o
+CFLAGS_display_mode_lib.o := $(dml_ccflags)
+CFLAGS_display_pipe_clocks.o := $(dml_ccflags)
+CFLAGS_dml1_display_rq_dlg_calc.o := $(dml_ccflags)
+CFLAGS_display_rq_dlg_helpers.o := $(dml_ccflags)
+CFLAGS_soc_bounding_box.o := $(dml_ccflags)
+CFLAGS_dml_common_defs.o := $(dml_ccflags)
+
+DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
+ soc_bounding_box.o dml_common_defs.o
AMD_DAL_DML = $(addprefix $(AMDDALPATH)/dc/dml/,$(DML))
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 26f4f2a3d90d..3c2abcb8a1b0 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
@@ -28,8 +28,6 @@
#include "dml_common_defs.h"
#include "soc_bounding_box.h"
-#include "display_mode_vba.h"
-#include "display_rq_dlg_calc.h"
#include "dml1_display_rq_dlg_calc.h"
enum dml_project {
@@ -41,7 +39,6 @@ struct display_mode_lib {
struct _vcs_dpi_ip_params_st ip;
struct _vcs_dpi_soc_bounding_box_st soc;
enum dml_project project;
- 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 aeebd8bee628..09affa16cc43 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
@@ -140,7 +140,6 @@ struct _vcs_dpi_ip_params_st {
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;
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
deleted file mode 100644
index 260e113fcc02..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+++ /dev/null
@@ -1,6085 +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_mode_lib.h"
-#include "display_mode_vba.h"
-
-#include "dml_inline_defs.h"
-
-/*
- * NOTE:
- * This file is gcc-parseable HW gospel, coming straight from HW engineers.
- *
- * It doesn't adhere to Linux kernel style and sometimes will do things in odd
- * ways. Unless there is something clearly wrong with it the code should
- * remain as-is as it provides us with a guarantee from HW that it is correct.
- */
-
-#define BPP_INVALID 0
-#define BPP_BLENDED_PIPE 0xffffffff
-static 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->opp_input_bpc == 0 ? 12 : dout->opp_input_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 BPP_INVALID;
- } else if (Format == dm_444) {
- if (DecimalBPP >= 36)
- return 36;
- else if (DecimalBPP >= 30)
- return 30;
- else if (DecimalBPP >= 24)
- return 24;
- else
- return BPP_INVALID;
- } else {
- if (DecimalBPP / 1.5 >= 24)
- return 24;
- else if (DecimalBPP / 1.5 >= 20)
- return 20;
- else if (DecimalBPP / 1.5 >= 16)
- return 16;
- else
- return BPP_INVALID;
- }
- } else {
- if (DSCEnabled) {
- if (Format == dm_420) {
- if (DecimalBPP < 6)
- return BPP_INVALID;
- else if (DecimalBPP >= 1.5 * DSCInputBitPerComponent - 1 / 16)
- return 1.5 * DSCInputBitPerComponent - 1 / 16;
- else
- return dml_floor(16 * DecimalBPP, 1) / 16;
- } else if (Format == dm_n422) {
- if (DecimalBPP < 7)
- return BPP_INVALID;
- else if (DecimalBPP >= 2 * DSCInputBitPerComponent - 1 / 16)
- return 2 * DSCInputBitPerComponent - 1 / 16;
- else
- return dml_floor(16 * DecimalBPP, 1) / 16;
- } else {
- if (DecimalBPP < 8)
- return BPP_INVALID;
- else if (DecimalBPP >= 3 * DSCInputBitPerComponent - 1 / 16)
- return 3 * DSCInputBitPerComponent - 1 / 16;
- else
- return dml_floor(16 * DecimalBPP, 1) / 16;
- }
- } else if (Format == dm_420) {
- if (DecimalBPP >= 18)
- return 18;
- else if (DecimalBPP >= 15)
- return 15;
- else if (DecimalBPP >= 12)
- return 12;
- else
- return BPP_INVALID;
- } else if (Format == dm_s422 || Format == dm_n422) {
- if (DecimalBPP >= 24)
- return 24;
- else if (DecimalBPP >= 20)
- return 20;
- else if (DecimalBPP >= 16)
- return 16;
- else
- return BPP_INVALID;
- } else {
- if (DecimalBPP >= 36)
- return 36;
- else if (DecimalBPP >= 30)
- return 30;
- else if (DecimalBPP >= 24)
- return 24;
- else
- return BPP_INVALID;
- }
- }
-}
-
-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 == BPP_INVALID) {
- 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 == BPP_INVALID
- && mode_lib->vba.PHYCLKPerState[i]
- >= 810.0) {
- mode_lib->vba.Outbpp =
- TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0) * 810.0
- * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
- false,
- mode_lib->vba.Output[k],
- mode_lib->vba.OutputFormat[k],
- mode_lib->vba.DSCInputBitPerComponent[k]);
- mode_lib->vba.OutbppDSC =
- TruncToValidBPP((1.0 - mode_lib->vba.Downspreading / 100.0)
- * (1.0 - mode_lib->vba.EffectiveFECOverhead / 100.0) * 810.0
- * mode_lib->vba.OutputLinkDPLanes[k] / mode_lib->vba.PixelClockBackEnd[k] * 8.0,
- true,
- mode_lib->vba.Output[k],
- mode_lib->vba.OutputFormat[k],
- mode_lib->vba.DSCInputBitPerComponent[k]);
- if (mode_lib->vba.DSCEnabled[k] == true
- || mode_lib->vba.Outbpp == BPP_INVALID) {
- 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] = BPP_BLENDED_PIPE;
- }
- }
- }
- 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] == BPP_INVALID
- || (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] == BPP_BLENDED_PIPE
- || mode_lib->vba.OutputBppPerState[i][k] == BPP_INVALID) {
- 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
deleted file mode 100644
index 4112409cd974..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+++ /dev/null
@@ -1,598 +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 __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
deleted file mode 100644
index 325dd2b757d6..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.c
+++ /dev/null
@@ -1,1772 +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_mode_lib.h"
-#include "display_mode_vba.h"
-#include "display_rq_dlg_calc.h"
-
-/*
- * NOTE:
- * This file is gcc-parseable HW gospel, coming straight from HW engineers.
- *
- * It doesn't adhere to Linux kernel style and sometimes will do things in odd
- * ways. Unless there is something clearly wrong with it the code should
- * remain as-is as it provides us with a guarantee from HW that it is correct.
- */
-
-static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
- double *refcyc_per_req_delivery_pre_cur,
- double *refcyc_per_req_delivery_cur,
- double refclk_freq_in_mhz,
- double ref_freq_to_pix_freq,
- double hscale_pixel_rate_l,
- double hscl_ratio,
- double vratio_pre_l,
- double vratio_l,
- unsigned int cur_width,
- enum cursor_bpp cur_bpp);
-
-#include "dml_inline_defs.h"
-
-static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
-{
- unsigned int ret_val = 0;
-
- if (source_format == dm_444_16) {
- if (!is_chroma)
- ret_val = 2;
- } else if (source_format == dm_444_32) {
- if (!is_chroma)
- ret_val = 4;
- } else if (source_format == dm_444_64) {
- if (!is_chroma)
- ret_val = 8;
- } else if (source_format == dm_420_8) {
- if (is_chroma)
- ret_val = 2;
- else
- ret_val = 1;
- } else if (source_format == dm_420_10) {
- if (is_chroma)
- ret_val = 4;
- else
- ret_val = 2;
- } else if (source_format == dm_444_8) {
- ret_val = 1;
- }
- return ret_val;
-}
-
-static bool is_dual_plane(enum source_format_class source_format)
-{
- bool ret_val = 0;
-
- if ((source_format == dm_420_8) || (source_format == dm_420_10))
- ret_val = 1;
-
- return ret_val;
-}
-
-static double get_refcyc_per_delivery(struct display_mode_lib *mode_lib,
- double refclk_freq_in_mhz,
- double pclk_freq_in_mhz,
- bool odm_combine,
- unsigned int recout_width,
- unsigned int hactive,
- double vratio,
- double hscale_pixel_rate,
- unsigned int delivery_width,
- unsigned int req_per_swath_ub)
-{
- double refcyc_per_delivery = 0.0;
-
- if (vratio <= 1.0) {
- if (odm_combine)
- refcyc_per_delivery = (double) refclk_freq_in_mhz
- * dml_min((double) recout_width, (double) hactive / 2.0)
- / pclk_freq_in_mhz / (double) req_per_swath_ub;
- else
- refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) recout_width
- / pclk_freq_in_mhz / (double) req_per_swath_ub;
- } else {
- refcyc_per_delivery = (double) refclk_freq_in_mhz * (double) delivery_width
- / (double) hscale_pixel_rate / (double) req_per_swath_ub;
- }
-
- dml_print("DML_DLG: %s: refclk_freq_in_mhz = %3.2f\n", __func__, refclk_freq_in_mhz);
- dml_print("DML_DLG: %s: pclk_freq_in_mhz = %3.2f\n", __func__, pclk_freq_in_mhz);
- dml_print("DML_DLG: %s: recout_width = %d\n", __func__, recout_width);
- dml_print("DML_DLG: %s: vratio = %3.2f\n", __func__, vratio);
- dml_print("DML_DLG: %s: req_per_swath_ub = %d\n", __func__, req_per_swath_ub);
- dml_print("DML_DLG: %s: refcyc_per_delivery= %3.2f\n", __func__, refcyc_per_delivery);
-
- return refcyc_per_delivery;
-
-}
-
-static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size)
-{
- if (tile_size == dm_256k_tile)
- return (256 * 1024);
- else if (tile_size == dm_64k_tile)
- return (64 * 1024);
- else
- return (4 * 1024);
-}
-
-static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib,
- display_data_rq_regs_st *rq_regs,
- const display_data_rq_sizing_params_st rq_sizing)
-{
- dml_print("DML_DLG: %s: rq_sizing param\n", __func__);
- print__data_rq_sizing_params_st(mode_lib, rq_sizing);
-
- rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10;
-
- if (rq_sizing.min_chunk_bytes == 0)
- rq_regs->min_chunk_size = 0;
- else
- rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1;
-
- rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10;
- if (rq_sizing.min_meta_chunk_bytes == 0)
- rq_regs->min_meta_chunk_size = 0;
- else
- rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1;
-
- rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6;
- rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6;
-}
-
-static void extract_rq_regs(struct display_mode_lib *mode_lib,
- display_rq_regs_st *rq_regs,
- const display_rq_params_st rq_param)
-{
- unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
- unsigned int detile_buf_plane1_addr = 0;
-
- extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l);
-
- rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height),
- 1) - 3;
-
- if (rq_param.yuv420) {
- extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c);
- rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height),
- 1) - 3;
- }
-
- rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height);
- rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height);
-
- // FIXME: take the max between luma, chroma chunk size?
- // okay for now, as we are setting chunk_bytes to 8kb anyways
- if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb
- rq_regs->drq_expansion_mode = 0;
- } else {
- rq_regs->drq_expansion_mode = 2;
- }
- rq_regs->prq_expansion_mode = 1;
- rq_regs->mrq_expansion_mode = 1;
- rq_regs->crq_expansion_mode = 1;
-
- if (rq_param.yuv420) {
- if ((double) rq_param.misc.rq_l.stored_swath_bytes
- / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) {
- detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma
- } else {
- detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0),
- 256,
- 0) / 64.0; // 2/3 to chroma
- }
- }
- rq_regs->plane1_base_address = detile_buf_plane1_addr;
-}
-
-static void handle_det_buf_split(struct display_mode_lib *mode_lib,
- display_rq_params_st *rq_param,
- const display_pipe_source_params_st pipe_src_param)
-{
- unsigned int total_swath_bytes = 0;
- unsigned int swath_bytes_l = 0;
- unsigned int swath_bytes_c = 0;
- unsigned int full_swath_bytes_packed_l = 0;
- unsigned int full_swath_bytes_packed_c = 0;
- bool req128_l = 0;
- bool req128_c = 0;
- bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear);
- bool surf_vert = (pipe_src_param.source_scan == dm_vert);
- unsigned int log2_swath_height_l = 0;
- unsigned int log2_swath_height_c = 0;
- unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024;
-
- full_swath_bytes_packed_l = rq_param->misc.rq_l.full_swath_bytes;
- full_swath_bytes_packed_c = rq_param->misc.rq_c.full_swath_bytes;
-
- if (rq_param->yuv420_10bpc) {
- full_swath_bytes_packed_l = dml_round_to_multiple(rq_param->misc.rq_l.full_swath_bytes * 2 / 3,
- 256,
- 1) + 256;
- full_swath_bytes_packed_c = dml_round_to_multiple(rq_param->misc.rq_c.full_swath_bytes * 2 / 3,
- 256,
- 1) + 256;
- }
-
- if (rq_param->yuv420) {
- total_swath_bytes = 2 * full_swath_bytes_packed_l + 2 * full_swath_bytes_packed_c;
-
- if (total_swath_bytes <= detile_buf_size_in_bytes) { //full 256b request
- req128_l = 0;
- req128_c = 0;
- swath_bytes_l = full_swath_bytes_packed_l;
- swath_bytes_c = full_swath_bytes_packed_c;
- } else { //128b request (for luma only for yuv420 8bpc)
- req128_l = 1;
- req128_c = 0;
- swath_bytes_l = full_swath_bytes_packed_l / 2;
- swath_bytes_c = full_swath_bytes_packed_c;
- }
- // Note: assumption, the config that pass in will fit into
- // the detiled buffer.
- } else {
- total_swath_bytes = 2 * full_swath_bytes_packed_l;
-
- if (total_swath_bytes <= detile_buf_size_in_bytes)
- req128_l = 0;
- else
- req128_l = 1;
-
- swath_bytes_l = total_swath_bytes;
- swath_bytes_c = 0;
- }
- rq_param->misc.rq_l.stored_swath_bytes = swath_bytes_l;
- rq_param->misc.rq_c.stored_swath_bytes = swath_bytes_c;
-
- if (surf_linear) {
- log2_swath_height_l = 0;
- log2_swath_height_c = 0;
- } else if (!surf_vert) {
- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l;
- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c;
- } else {
- log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l;
- log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c;
- }
- rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
- rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
-
- dml_print("DML_DLG: %s: req128_l = %0d\n", __func__, req128_l);
- dml_print("DML_DLG: %s: req128_c = %0d\n", __func__, req128_c);
- dml_print("DML_DLG: %s: full_swath_bytes_packed_l = %0d\n",
- __func__,
- full_swath_bytes_packed_l);
- dml_print("DML_DLG: %s: full_swath_bytes_packed_c = %0d\n",
- __func__,
- full_swath_bytes_packed_c);
-}
-
-static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
- display_data_rq_dlg_params_st *rq_dlg_param,
- display_data_rq_misc_params_st *rq_misc_param,
- display_data_rq_sizing_params_st *rq_sizing_param,
- unsigned int vp_width,
- unsigned int vp_height,
- unsigned int data_pitch,
- unsigned int meta_pitch,
- unsigned int source_format,
- unsigned int tiling,
- unsigned int macro_tile_size,
- unsigned int source_scan,
- unsigned int is_chroma)
-{
- bool surf_linear = (tiling == dm_sw_linear);
- bool surf_vert = (source_scan == dm_vert);
-
- unsigned int bytes_per_element;
- unsigned int bytes_per_element_y = get_bytes_per_element((enum source_format_class)(source_format),
- false);
- unsigned int bytes_per_element_c = get_bytes_per_element((enum source_format_class)(source_format),
- true);
-
- unsigned int blk256_width = 0;
- unsigned int blk256_height = 0;
-
- unsigned int blk256_width_y = 0;
- unsigned int blk256_height_y = 0;
- unsigned int blk256_width_c = 0;
- unsigned int blk256_height_c = 0;
- unsigned int log2_bytes_per_element;
- unsigned int log2_blk256_width;
- unsigned int log2_blk256_height;
- unsigned int blk_bytes;
- unsigned int log2_blk_bytes;
- unsigned int log2_blk_height;
- unsigned int log2_blk_width;
- unsigned int log2_meta_req_bytes;
- unsigned int log2_meta_req_height;
- unsigned int log2_meta_req_width;
- unsigned int meta_req_width;
- unsigned int meta_req_height;
- unsigned int log2_meta_row_height;
- unsigned int meta_row_width_ub;
- unsigned int log2_meta_chunk_bytes;
- unsigned int log2_meta_chunk_height;
-
- //full sized meta chunk width in unit of data elements
- unsigned int log2_meta_chunk_width;
- unsigned int log2_min_meta_chunk_bytes;
- unsigned int min_meta_chunk_width;
- unsigned int meta_chunk_width;
- unsigned int meta_chunk_per_row_int;
- unsigned int meta_row_remainder;
- unsigned int meta_chunk_threshold;
- unsigned int meta_blk_bytes;
- unsigned int meta_blk_height;
- unsigned int meta_blk_width;
- unsigned int meta_surface_bytes;
- unsigned int vmpg_bytes;
- unsigned int meta_pte_req_per_frame_ub;
- unsigned int meta_pte_bytes_per_frame_ub;
- const unsigned int log2_vmpg_bytes = dml_log2(mode_lib->soc.vmm_page_size_bytes);
- const unsigned int dpte_buf_in_pte_reqs = mode_lib->ip.dpte_buffer_size_in_pte_reqs;
- const unsigned int pde_proc_buffer_size_64k_reqs =
- mode_lib->ip.pde_proc_buffer_size_64k_reqs;
-
- unsigned int log2_vmpg_height = 0;
- unsigned int log2_vmpg_width = 0;
- unsigned int log2_dpte_req_height_ptes = 0;
- unsigned int log2_dpte_req_height = 0;
- unsigned int log2_dpte_req_width = 0;
- unsigned int log2_dpte_row_height_linear = 0;
- unsigned int log2_dpte_row_height = 0;
- unsigned int log2_dpte_group_width = 0;
- unsigned int dpte_row_width_ub = 0;
- unsigned int dpte_req_height = 0;
- unsigned int dpte_req_width = 0;
- unsigned int dpte_group_width = 0;
- unsigned int log2_dpte_group_bytes = 0;
- unsigned int log2_dpte_group_length = 0;
- unsigned int pde_buf_entries;
- bool yuv420 = (source_format == dm_420_8 || source_format == dm_420_10);
-
- Calculate256BBlockSizes((enum source_format_class)(source_format),
- (enum dm_swizzle_mode)(tiling),
- bytes_per_element_y,
- bytes_per_element_c,
- &blk256_height_y,
- &blk256_height_c,
- &blk256_width_y,
- &blk256_width_c);
-
- if (!is_chroma) {
- blk256_width = blk256_width_y;
- blk256_height = blk256_height_y;
- bytes_per_element = bytes_per_element_y;
- } else {
- blk256_width = blk256_width_c;
- blk256_height = blk256_height_c;
- bytes_per_element = bytes_per_element_c;
- }
-
- log2_bytes_per_element = dml_log2(bytes_per_element);
-
- dml_print("DML_DLG: %s: surf_linear = %d\n", __func__, surf_linear);
- dml_print("DML_DLG: %s: surf_vert = %d\n", __func__, surf_vert);
- dml_print("DML_DLG: %s: blk256_width = %d\n", __func__, blk256_width);
- dml_print("DML_DLG: %s: blk256_height = %d\n", __func__, blk256_height);
-
- log2_blk256_width = dml_log2((double) blk256_width);
- log2_blk256_height = dml_log2((double) blk256_height);
- blk_bytes = surf_linear ?
- 256 : get_blk_size_bytes((enum source_macro_tile_size) macro_tile_size);
- log2_blk_bytes = dml_log2((double) blk_bytes);
- log2_blk_height = 0;
- log2_blk_width = 0;
-
- // remember log rule
- // "+" in log is multiply
- // "-" in log is divide
- // "/2" is like square root
- // blk is vertical biased
- if (tiling != dm_sw_linear)
- log2_blk_height = log2_blk256_height
- + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1);
- else
- log2_blk_height = 0; // blk height of 1
-
- log2_blk_width = log2_blk_bytes - log2_bytes_per_element - log2_blk_height;
-
- if (!surf_vert) {
- rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_width - 1, blk256_width, 1)
- + blk256_width;
- rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_width;
- } else {
- rq_dlg_param->swath_width_ub = dml_round_to_multiple(vp_height - 1, blk256_height, 1)
- + blk256_height;
- rq_dlg_param->req_per_swath_ub = rq_dlg_param->swath_width_ub >> log2_blk256_height;
- }
-
- if (!surf_vert)
- rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_height
- * bytes_per_element;
- else
- rq_misc_param->full_swath_bytes = rq_dlg_param->swath_width_ub * blk256_width
- * bytes_per_element;
-
- rq_misc_param->blk256_height = blk256_height;
- rq_misc_param->blk256_width = blk256_width;
-
- // -------
- // meta
- // -------
- log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
-
- // each 64b meta request for dcn is 8x8 meta elements and
- // a meta element covers one 256b block of the the data surface.
- log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
- log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
- - log2_meta_req_height;
- meta_req_width = 1 << log2_meta_req_width;
- meta_req_height = 1 << log2_meta_req_height;
- log2_meta_row_height = 0;
- meta_row_width_ub = 0;
-
- // the dimensions of a meta row are meta_row_width x meta_row_height in elements.
- // calculate upper bound of the meta_row_width
- if (!surf_vert) {
- log2_meta_row_height = log2_meta_req_height;
- meta_row_width_ub = dml_round_to_multiple(vp_width - 1, meta_req_width, 1)
- + meta_req_width;
- rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_width;
- } else {
- log2_meta_row_height = log2_meta_req_width;
- meta_row_width_ub = dml_round_to_multiple(vp_height - 1, meta_req_height, 1)
- + meta_req_height;
- rq_dlg_param->meta_req_per_row_ub = meta_row_width_ub / meta_req_height;
- }
- rq_dlg_param->meta_bytes_per_row_ub = rq_dlg_param->meta_req_per_row_ub * 64;
-
- rq_dlg_param->meta_row_height = 1 << log2_meta_row_height;
-
- log2_meta_chunk_bytes = dml_log2(rq_sizing_param->meta_chunk_bytes);
- log2_meta_chunk_height = log2_meta_row_height;
-
- //full sized meta chunk width in unit of data elements
- log2_meta_chunk_width = log2_meta_chunk_bytes + 8 - log2_bytes_per_element
- - log2_meta_chunk_height;
- log2_min_meta_chunk_bytes = dml_log2(rq_sizing_param->min_meta_chunk_bytes);
- min_meta_chunk_width = 1
- << (log2_min_meta_chunk_bytes + 8 - log2_bytes_per_element
- - log2_meta_chunk_height);
- meta_chunk_width = 1 << log2_meta_chunk_width;
- meta_chunk_per_row_int = (unsigned int) (meta_row_width_ub / meta_chunk_width);
- meta_row_remainder = meta_row_width_ub % meta_chunk_width;
- meta_chunk_threshold = 0;
- meta_blk_bytes = 4096;
- meta_blk_height = blk256_height * 64;
- meta_blk_width = meta_blk_bytes * 256 / bytes_per_element / meta_blk_height;
- meta_surface_bytes = meta_pitch
- * (dml_round_to_multiple(vp_height - 1, meta_blk_height, 1) + meta_blk_height)
- * bytes_per_element / 256;
- vmpg_bytes = mode_lib->soc.vmm_page_size_bytes;
- meta_pte_req_per_frame_ub = (dml_round_to_multiple(meta_surface_bytes - vmpg_bytes,
- 8 * vmpg_bytes,
- 1) + 8 * vmpg_bytes) / (8 * vmpg_bytes);
- meta_pte_bytes_per_frame_ub = meta_pte_req_per_frame_ub * 64; //64B mpte request
- rq_dlg_param->meta_pte_bytes_per_frame_ub = meta_pte_bytes_per_frame_ub;
-
- dml_print("DML_DLG: %s: meta_blk_height = %d\n", __func__, meta_blk_height);
- dml_print("DML_DLG: %s: meta_blk_width = %d\n", __func__, meta_blk_width);
- dml_print("DML_DLG: %s: meta_surface_bytes = %d\n", __func__, meta_surface_bytes);
- dml_print("DML_DLG: %s: meta_pte_req_per_frame_ub = %d\n",
- __func__,
- meta_pte_req_per_frame_ub);
- dml_print("DML_DLG: %s: meta_pte_bytes_per_frame_ub = %d\n",
- __func__,
- meta_pte_bytes_per_frame_ub);
-
- if (!surf_vert)
- meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_width;
- else
- meta_chunk_threshold = 2 * min_meta_chunk_width - meta_req_height;
-
- if (meta_row_remainder <= meta_chunk_threshold)
- rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 1;
- else
- rq_dlg_param->meta_chunks_per_row_ub = meta_chunk_per_row_int + 2;
-
- // ------
- // dpte
- // ------
- if (surf_linear) {
- log2_vmpg_height = 0; // one line high
- } else {
- log2_vmpg_height = (log2_vmpg_bytes - 8) / 2 + log2_blk256_height;
- }
- log2_vmpg_width = log2_vmpg_bytes - log2_bytes_per_element - log2_vmpg_height;
-
- // only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4.
- if (surf_linear) { //one 64B PTE request returns 8 PTEs
- log2_dpte_req_height_ptes = 0;
- log2_dpte_req_width = log2_vmpg_width + 3;
- log2_dpte_req_height = 0;
- } else if (log2_blk_bytes == 12) { //4KB tile means 4kB page size
- //one 64B req gives 8x1 PTEs for 4KB tile
- log2_dpte_req_height_ptes = 0;
- log2_dpte_req_width = log2_blk_width + 3;
- log2_dpte_req_height = log2_blk_height + 0;
- } else if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) { // tile block >= 64KB
- //two 64B reqs of 2x4 PTEs give 16 PTEs to cover 64KB
- log2_dpte_req_height_ptes = 4;
- log2_dpte_req_width = log2_blk256_width + 4; // log2_64KB_width
- log2_dpte_req_height = log2_blk256_height + 4; // log2_64KB_height
- } else { //64KB page size and must 64KB tile block
- //one 64B req gives 8x1 PTEs for 64KB tile
- log2_dpte_req_height_ptes = 0;
- log2_dpte_req_width = log2_blk_width + 3;
- log2_dpte_req_height = log2_blk_height + 0;
- }
-
- // The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
- // log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
- // That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
- //log2_dpte_req_height = log2_vmpg_height + log2_dpte_req_height_ptes;
- //log2_dpte_req_width = log2_vmpg_width + log2_dpte_req_width_ptes;
- dpte_req_height = 1 << log2_dpte_req_height;
- dpte_req_width = 1 << log2_dpte_req_width;
-
- // calculate pitch dpte row buffer can hold
- // round the result down to a power of two.
- pde_buf_entries = yuv420 ? (pde_proc_buffer_size_64k_reqs >> 1) : pde_proc_buffer_size_64k_reqs;
- if (surf_linear) {
- unsigned int dpte_row_height;
-
- log2_dpte_row_height_linear = dml_floor(dml_log2(dml_min(64 * 1024 * pde_buf_entries
- / bytes_per_element,
- dpte_buf_in_pte_reqs
- * dpte_req_width)
- / data_pitch),
- 1);
-
- ASSERT(log2_dpte_row_height_linear >= 3);
-
- if (log2_dpte_row_height_linear > 7)
- log2_dpte_row_height_linear = 7;
-
- log2_dpte_row_height = log2_dpte_row_height_linear;
- // For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
- // the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
- dpte_row_height = 1 << log2_dpte_row_height;
- dpte_row_width_ub = dml_round_to_multiple(data_pitch * dpte_row_height - 1,
- dpte_req_width,
- 1) + dpte_req_width;
- rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
- } else {
- // the upper bound of the dpte_row_width without dependency on viewport position follows.
- // for tiled mode, row height is the same as req height and row store up to vp size upper bound
- if (!surf_vert) {
- log2_dpte_row_height = log2_dpte_req_height;
- dpte_row_width_ub = dml_round_to_multiple(vp_width - 1, dpte_req_width, 1)
- + dpte_req_width;
- rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_width;
- } else {
- log2_dpte_row_height =
- (log2_blk_width < log2_dpte_req_width) ?
- log2_blk_width : log2_dpte_req_width;
- dpte_row_width_ub = dml_round_to_multiple(vp_height - 1, dpte_req_height, 1)
- + dpte_req_height;
- rq_dlg_param->dpte_req_per_row_ub = dpte_row_width_ub / dpte_req_height;
- }
- }
- if (log2_blk_bytes >= 16 && log2_vmpg_bytes == 12) // tile block >= 64KB
- rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 128; //2*64B dpte request
- else
- rq_dlg_param->dpte_bytes_per_row_ub = rq_dlg_param->dpte_req_per_row_ub * 64; //64B dpte request
-
- rq_dlg_param->dpte_row_height = 1 << log2_dpte_row_height;
-
- // the dpte_group_bytes is reduced for the specific case of vertical
- // access of a tile surface that has dpte request of 8x1 ptes.
- if (!surf_linear & (log2_dpte_req_height_ptes == 0) & surf_vert) //reduced, in this case, will have page fault within a group
- rq_sizing_param->dpte_group_bytes = 512;
- else
- //full size
- rq_sizing_param->dpte_group_bytes = 2048;
-
- //since pte request size is 64byte, the number of data pte requests per full sized group is as follows.
- log2_dpte_group_bytes = dml_log2(rq_sizing_param->dpte_group_bytes);
- log2_dpte_group_length = log2_dpte_group_bytes - 6; //length in 64b requests
-
- // full sized data pte group width in elements
- if (!surf_vert)
- log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_width;
- else
- log2_dpte_group_width = log2_dpte_group_length + log2_dpte_req_height;
-
- //But if the tile block >=64KB and the page size is 4KB, then each dPTE request is 2*64B
- if ((log2_blk_bytes >= 16) && (log2_vmpg_bytes == 12)) // tile block >= 64KB
- log2_dpte_group_width = log2_dpte_group_width - 1;
-
- dpte_group_width = 1 << log2_dpte_group_width;
-
- // since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
- // the upper bound for the dpte groups per row is as follows.
- rq_dlg_param->dpte_groups_per_row_ub = dml_ceil((double) dpte_row_width_ub / dpte_group_width,
- 1);
-}
-
-static void get_surf_rq_param(struct display_mode_lib *mode_lib,
- display_data_rq_sizing_params_st *rq_sizing_param,
- display_data_rq_dlg_params_st *rq_dlg_param,
- display_data_rq_misc_params_st *rq_misc_param,
- const display_pipe_source_params_st pipe_src_param,
- bool is_chroma)
-{
- bool mode_422 = 0;
- unsigned int vp_width = 0;
- unsigned int vp_height = 0;
- unsigned int data_pitch = 0;
- unsigned int meta_pitch = 0;
- unsigned int ppe = mode_422 ? 2 : 1;
-
- // FIXME check if ppe apply for both luma and chroma in 422 case
- if (is_chroma) {
- vp_width = pipe_src_param.viewport_width_c / ppe;
- vp_height = pipe_src_param.viewport_height_c;
- data_pitch = pipe_src_param.data_pitch_c;
- meta_pitch = pipe_src_param.meta_pitch_c;
- } else {
- vp_width = pipe_src_param.viewport_width / ppe;
- vp_height = pipe_src_param.viewport_height;
- data_pitch = pipe_src_param.data_pitch;
- meta_pitch = pipe_src_param.meta_pitch;
- }
-
- rq_sizing_param->chunk_bytes = 8192;
-
- if (rq_sizing_param->chunk_bytes == 64 * 1024)
- rq_sizing_param->min_chunk_bytes = 0;
- else
- rq_sizing_param->min_chunk_bytes = 1024;
-
- rq_sizing_param->meta_chunk_bytes = 2048;
- rq_sizing_param->min_meta_chunk_bytes = 256;
-
- rq_sizing_param->mpte_group_bytes = 2048;
-
- get_meta_and_pte_attr(mode_lib,
- rq_dlg_param,
- rq_misc_param,
- rq_sizing_param,
- vp_width,
- vp_height,
- data_pitch,
- meta_pitch,
- pipe_src_param.source_format,
- pipe_src_param.sw_mode,
- pipe_src_param.macro_tile_size,
- pipe_src_param.source_scan,
- is_chroma);
-}
-
-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
- rq_param->yuv420 = pipe_src_param.source_format == dm_420_8
- || pipe_src_param.source_format == dm_420_10;
- rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10;
-
- get_surf_rq_param(mode_lib,
- &(rq_param->sizing.rq_l),
- &(rq_param->dlg.rq_l),
- &(rq_param->misc.rq_l),
- pipe_src_param,
- 0);
-
- if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) {
- // get param for chroma surface
- get_surf_rq_param(mode_lib,
- &(rq_param->sizing.rq_c),
- &(rq_param->dlg.rq_c),
- &(rq_param->misc.rq_c),
- pipe_src_param,
- 1);
- }
-
- // calculate how to split the det buffer space between luma and chroma
- handle_det_buf_split(mode_lib, rq_param, pipe_src_param);
- print__rq_params_st(mode_lib, *rq_param);
-}
-
-void dml_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib,
- display_rq_regs_st *rq_regs,
- const display_pipe_source_params_st pipe_src_param)
-{
- 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);
-}
-
-// 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 ignore_viewport_pos,
- const bool immediate_flip_support)
-{
- const display_pipe_source_params_st *src = &e2e_pipe_param[pipe_idx].pipe.src;
- const display_pipe_dest_params_st *dst = &e2e_pipe_param[pipe_idx].pipe.dest;
- const display_output_params_st *dout = &e2e_pipe_param[pipe_idx].dout;
- const display_clocks_and_cfg_st *clks = &e2e_pipe_param[pipe_idx].clks_cfg;
- const scaler_ratio_depth_st *scl = &e2e_pipe_param[pipe_idx].pipe.scale_ratio_depth;
- const scaler_taps_st *taps = &e2e_pipe_param[pipe_idx].pipe.scale_taps;
-
- // -------------------------
- // Section 1.15.2.1: OTG dependent Params
- // -------------------------
- // Timing
- unsigned int htotal = dst->htotal;
-// unsigned int hblank_start = dst.hblank_start; // TODO: Remove
- unsigned int hblank_end = dst->hblank_end;
- unsigned int vblank_start = dst->vblank_start;
- unsigned int vblank_end = dst->vblank_end;
- unsigned int min_vblank = mode_lib->ip.min_vblank_lines;
-
- double dppclk_freq_in_mhz = clks->dppclk_mhz;
- double dispclk_freq_in_mhz = clks->dispclk_mhz;
- double refclk_freq_in_mhz = clks->refclk_mhz;
- double pclk_freq_in_mhz = dst->pixel_rate_mhz;
- bool interlaced = dst->interlaced;
-
- double ref_freq_to_pix_freq = refclk_freq_in_mhz / pclk_freq_in_mhz;
-
- double min_dcfclk_mhz;
- double t_calc_us;
- double min_ttu_vblank;
-
- double min_dst_y_ttu_vblank;
- unsigned int dlg_vblank_start;
- bool dual_plane;
- bool mode_422;
- unsigned int access_dir;
- unsigned int vp_height_l;
- unsigned int vp_width_l;
- unsigned int vp_height_c;
- unsigned int vp_width_c;
-
- // Scaling
- unsigned int htaps_l;
- unsigned int htaps_c;
- double hratio_l;
- double hratio_c;
- double vratio_l;
- double vratio_c;
- bool scl_enable;
-
- double line_time_in_us;
- // double vinit_l;
- // double vinit_c;
- // double vinit_bot_l;
- // double vinit_bot_c;
-
- // unsigned int swath_height_l;
- unsigned int swath_width_ub_l;
- // unsigned int dpte_bytes_per_row_ub_l;
- unsigned int dpte_groups_per_row_ub_l;
- // unsigned int meta_pte_bytes_per_frame_ub_l;
- // unsigned int meta_bytes_per_row_ub_l;
-
- // unsigned int swath_height_c;
- unsigned int swath_width_ub_c;
- // unsigned int dpte_bytes_per_row_ub_c;
- unsigned int dpte_groups_per_row_ub_c;
-
- unsigned int meta_chunks_per_row_ub_l;
- unsigned int meta_chunks_per_row_ub_c;
- unsigned int vupdate_offset;
- unsigned int vupdate_width;
- unsigned int vready_offset;
-
- unsigned int dppclk_delay_subtotal;
- unsigned int dispclk_delay_subtotal;
- unsigned int pixel_rate_delay_subtotal;
-
- unsigned int vstartup_start;
- unsigned int dst_x_after_scaler;
- unsigned int dst_y_after_scaler;
- double line_wait;
- double dst_y_prefetch;
- double dst_y_per_vm_vblank;
- double dst_y_per_row_vblank;
- double dst_y_per_vm_flip;
- double dst_y_per_row_flip;
- double min_dst_y_per_vm_vblank;
- double min_dst_y_per_row_vblank;
- double lsw;
- double vratio_pre_l;
- double vratio_pre_c;
- unsigned int req_per_swath_ub_l;
- unsigned int req_per_swath_ub_c;
- unsigned int meta_row_height_l;
- unsigned int meta_row_height_c;
- unsigned int swath_width_pixels_ub_l;
- unsigned int swath_width_pixels_ub_c;
- unsigned int scaler_rec_in_width_l;
- unsigned int scaler_rec_in_width_c;
- unsigned int dpte_row_height_l;
- unsigned int dpte_row_height_c;
- double hscale_pixel_rate_l;
- double hscale_pixel_rate_c;
- double min_hratio_fact_l;
- double min_hratio_fact_c;
- double refcyc_per_line_delivery_pre_l;
- double refcyc_per_line_delivery_pre_c;
- double refcyc_per_line_delivery_l;
- double refcyc_per_line_delivery_c;
-
- double refcyc_per_req_delivery_pre_l;
- double refcyc_per_req_delivery_pre_c;
- double refcyc_per_req_delivery_l;
- double refcyc_per_req_delivery_c;
-
- unsigned int full_recout_width;
- double xfc_transfer_delay;
- double xfc_precharge_delay;
- double xfc_remote_surface_flip_latency;
- double xfc_dst_y_delta_drq_limit;
- double xfc_prefetch_margin;
- double refcyc_per_req_delivery_pre_cur0;
- double refcyc_per_req_delivery_cur0;
- double refcyc_per_req_delivery_pre_cur1;
- double refcyc_per_req_delivery_cur1;
-
- memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
- memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
-
- dml_print("DML_DLG: %s: cstate_en = %d\n", __func__, cstate_en);
- dml_print("DML_DLG: %s: pstate_en = %d\n", __func__, pstate_en);
- dml_print("DML_DLG: %s: 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));
-
- min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz;
- 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;
-
- disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start
- + min_dst_y_ttu_vblank) * dml_pow(2, 2));
- ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int) dml_pow(2, 18));
-
- dml_print("DML_DLG: %s: min_dcfclk_mhz = %3.2f\n",
- __func__,
- min_dcfclk_mhz);
- dml_print("DML_DLG: %s: min_ttu_vblank = %3.2f\n",
- __func__,
- min_ttu_vblank);
- dml_print("DML_DLG: %s: min_dst_y_ttu_vblank = %3.2f\n",
- __func__,
- min_dst_y_ttu_vblank);
- dml_print("DML_DLG: %s: t_calc_us = %3.2f\n",
- __func__,
- t_calc_us);
- dml_print("DML_DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x\n",
- __func__,
- disp_dlg_regs->min_dst_y_next_start);
- dml_print("DML_DLG: %s: ref_freq_to_pix_freq = %3.2f\n",
- __func__,
- ref_freq_to_pix_freq);
-
- // -------------------------
- // Section 1.15.2.2: Prefetch, Active and TTU
- // -------------------------
- // Prefetch Calc
- // Source
-// dcc_en = src.dcc;
- dual_plane = is_dual_plane((enum source_format_class)(src->source_format));
- mode_422 = 0; // FIXME
- access_dir = (src->source_scan == dm_vert); // vp access direction: horizontal or vertical accessed
-// bytes_per_element_l = get_bytes_per_element(source_format_class(src.source_format), 0);
-// bytes_per_element_c = get_bytes_per_element(source_format_class(src.source_format), 1);
- vp_height_l = src->viewport_height;
- vp_width_l = src->viewport_width;
- vp_height_c = src->viewport_height_c;
- vp_width_c = src->viewport_width_c;
-
- // Scaling
- htaps_l = taps->htaps;
- htaps_c = taps->htaps_c;
- hratio_l = scl->hscl_ratio;
- hratio_c = scl->hscl_ratio_c;
- vratio_l = scl->vscl_ratio;
- vratio_c = scl->vscl_ratio_c;
- scl_enable = scl->scl_enable;
-
- line_time_in_us = (htotal / pclk_freq_in_mhz);
-// vinit_l = scl.vinit;
-// vinit_c = scl.vinit_c;
-// vinit_bot_l = scl.vinit_bot;
-// vinit_bot_c = scl.vinit_bot_c;
-
-// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height;
- swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub;
-// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub;
- dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub;
-// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub;
-// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub;
-
-// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height;
- swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub;
- // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub;
- dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub;
-
- meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub;
- meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub;
- vupdate_offset = dst->vupdate_offset;
- vupdate_width = dst->vupdate_width;
- vready_offset = dst->vready_offset;
-
- dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal;
- dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal;
-
- if (scl_enable)
- dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl;
- else
- dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_scl_lb_only;
-
- dppclk_delay_subtotal += mode_lib->ip.dppclk_delay_cnvc_formatter
- + src->num_cursors * mode_lib->ip.dppclk_delay_cnvc_cursor;
-
- if (dout->dsc_enable) {
- double dsc_delay = get_dsc_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
-
- dispclk_delay_subtotal += dsc_delay;
- }
-
- pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz
- + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz;
-
- vstartup_start = dst->vstartup_start;
- if (interlaced) {
- if (vstartup_start / 2.0
- - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
- <= vblank_end / 2.0)
- disp_dlg_regs->vready_after_vcount0 = 1;
- else
- disp_dlg_regs->vready_after_vcount0 = 0;
- } else {
- if (vstartup_start
- - (double) (vready_offset + vupdate_width + vupdate_offset) / htotal
- <= vblank_end)
- disp_dlg_regs->vready_after_vcount0 = 1;
- else
- disp_dlg_regs->vready_after_vcount0 = 0;
- }
-
- // TODO: Where is this coming from?
- if (interlaced)
- vstartup_start = vstartup_start / 2;
-
- // TODO: What if this min_vblank doesn't match the value in the dml_config_settings.cpp?
- if (vstartup_start >= min_vblank) {
- dml_print("WARNING: DML_DLG: %s: vblank_start=%d vblank_end=%d\n",
- __func__,
- vblank_start,
- vblank_end);
- dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
- __func__,
- vstartup_start,
- min_vblank);
- min_vblank = vstartup_start + 1;
- dml_print("WARNING: DML_DLG: %s: vstartup_start=%d should be less than min_vblank=%d\n",
- __func__,
- vstartup_start,
- min_vblank);
- }
-
- dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
-
- dml_print("DML_DLG: %s: htotal = %d\n", __func__, htotal);
- dml_print("DML_DLG: %s: pixel_rate_delay_subtotal = %d\n",
- __func__,
- pixel_rate_delay_subtotal);
- dml_print("DML_DLG: %s: dst_x_after_scaler = %d\n",
- __func__,
- dst_x_after_scaler);
- dml_print("DML_DLG: %s: dst_y_after_scaler = %d\n",
- __func__,
- dst_y_after_scaler);
-
- // Lwait
- line_wait = mode_lib->soc.urgent_latency_us;
- if (cstate_en)
- line_wait = dml_max(mode_lib->soc.sr_enter_plus_exit_time_us, line_wait);
- if (pstate_en)
- line_wait = dml_max(mode_lib->soc.dram_clock_change_latency_us
- + mode_lib->soc.urgent_latency_us,
- line_wait);
- line_wait = line_wait / line_time_in_us;
-
- dst_y_prefetch = get_dst_y_prefetch(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- dml_print("DML_DLG: %s: dst_y_prefetch (after rnd) = %3.2f\n", __func__, dst_y_prefetch);
-
- dst_y_per_vm_vblank = get_dst_y_per_vm_vblank(mode_lib,
- e2e_pipe_param,
- num_pipes,
- pipe_idx);
- dst_y_per_row_vblank = get_dst_y_per_row_vblank(mode_lib,
- e2e_pipe_param,
- num_pipes,
- pipe_idx);
- dst_y_per_vm_flip = get_dst_y_per_vm_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- dst_y_per_row_flip = get_dst_y_per_row_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
-
- min_dst_y_per_vm_vblank = 8.0;
- min_dst_y_per_row_vblank = 16.0;
-
- // magic!
- if (htotal <= 75) {
- min_vblank = 300;
- min_dst_y_per_vm_vblank = 100.0;
- min_dst_y_per_row_vblank = 100.0;
- }
-
- dml_print("DML_DLG: %s: dst_y_per_vm_vblank = %3.2f\n", __func__, dst_y_per_vm_vblank);
- dml_print("DML_DLG: %s: dst_y_per_row_vblank = %3.2f\n", __func__, dst_y_per_row_vblank);
-
- ASSERT(dst_y_per_vm_vblank < min_dst_y_per_vm_vblank);
- ASSERT(dst_y_per_row_vblank < min_dst_y_per_row_vblank);
-
- ASSERT(dst_y_prefetch > (dst_y_per_vm_vblank + dst_y_per_row_vblank));
- lsw = dst_y_prefetch - (dst_y_per_vm_vblank + dst_y_per_row_vblank);
-
- dml_print("DML_DLG: %s: lsw = %3.2f\n", __func__, lsw);
-
- vratio_pre_l = get_vratio_prefetch_l(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- vratio_pre_c = get_vratio_prefetch_c(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
-
- dml_print("DML_DLG: %s: vratio_pre_l=%3.2f\n", __func__, vratio_pre_l);
- dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c);
-
- // Active
- req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub;
- req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub;
- meta_row_height_l = rq_dlg_param.rq_l.meta_row_height;
- meta_row_height_c = rq_dlg_param.rq_c.meta_row_height;
- swath_width_pixels_ub_l = 0;
- swath_width_pixels_ub_c = 0;
- scaler_rec_in_width_l = 0;
- scaler_rec_in_width_c = 0;
- dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height;
- dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height;
-
- if (mode_422) {
- swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element
- swath_width_pixels_ub_c = swath_width_ub_c * 2;
- } else {
- swath_width_pixels_ub_l = swath_width_ub_l * 1;
- swath_width_pixels_ub_c = swath_width_ub_c * 1;
- }
-
- hscale_pixel_rate_l = 0.;
- hscale_pixel_rate_c = 0.;
- min_hratio_fact_l = 1.0;
- min_hratio_fact_c = 1.0;
-
- if (htaps_l <= 1)
- min_hratio_fact_l = 2.0;
- else if (htaps_l <= 6) {
- if ((hratio_l * 2.0) > 4.0)
- min_hratio_fact_l = 4.0;
- else
- min_hratio_fact_l = hratio_l * 2.0;
- } else {
- if (hratio_l > 4.0)
- min_hratio_fact_l = 4.0;
- else
- min_hratio_fact_l = hratio_l;
- }
-
- hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
-
- if (htaps_c <= 1)
- min_hratio_fact_c = 2.0;
- else if (htaps_c <= 6) {
- if ((hratio_c * 2.0) > 4.0)
- min_hratio_fact_c = 4.0;
- else
- min_hratio_fact_c = hratio_c * 2.0;
- } else {
- if (hratio_c > 4.0)
- min_hratio_fact_c = 4.0;
- else
- min_hratio_fact_c = hratio_c;
- }
-
- hscale_pixel_rate_c = min_hratio_fact_c * dppclk_freq_in_mhz;
-
- refcyc_per_line_delivery_pre_l = 0.;
- refcyc_per_line_delivery_pre_c = 0.;
- refcyc_per_line_delivery_l = 0.;
- refcyc_per_line_delivery_c = 0.;
-
- refcyc_per_req_delivery_pre_l = 0.;
- refcyc_per_req_delivery_pre_c = 0.;
- refcyc_per_req_delivery_l = 0.;
- refcyc_per_req_delivery_c = 0.;
-
- full_recout_width = 0;
- // In ODM
- if (src->is_hsplit) {
- // This "hack" is only allowed (and valid) for MPC combine. In ODM
- // combine, you MUST specify the full_recout_width...according to Oswin
- if (dst->full_recout_width == 0 && !dst->odm_combine) {
- dml_print("DML_DLG: %s: Warning: full_recout_width not set in hsplit mode\n",
- __func__);
- full_recout_width = dst->recout_width * 2; // assume half split for dcn1
- } else
- full_recout_width = dst->full_recout_width;
- } else
- full_recout_width = dst->recout_width;
-
- // mpc_combine and odm_combine are mutually exclusive
- refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_pre_l,
- hscale_pixel_rate_l,
- swath_width_pixels_ub_l,
- 1); // per line
-
- refcyc_per_line_delivery_l = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_l,
- hscale_pixel_rate_l,
- swath_width_pixels_ub_l,
- 1); // per line
-
- dml_print("DML_DLG: %s: full_recout_width = %d\n",
- __func__,
- full_recout_width);
- dml_print("DML_DLG: %s: hscale_pixel_rate_l = %3.2f\n",
- __func__,
- hscale_pixel_rate_l);
- dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f\n",
- __func__,
- refcyc_per_line_delivery_pre_l);
- dml_print("DML_DLG: %s: refcyc_per_line_delivery_l = %3.2f\n",
- __func__,
- refcyc_per_line_delivery_l);
-
- if (dual_plane) {
- refcyc_per_line_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_pre_c,
- hscale_pixel_rate_c,
- swath_width_pixels_ub_c,
- 1); // per line
-
- refcyc_per_line_delivery_c = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_c,
- hscale_pixel_rate_c,
- swath_width_pixels_ub_c,
- 1); // per line
-
- dml_print("DML_DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f\n",
- __func__,
- refcyc_per_line_delivery_pre_c);
- dml_print("DML_DLG: %s: refcyc_per_line_delivery_c = %3.2f\n",
- __func__,
- refcyc_per_line_delivery_c);
- }
-
- // TTU - Luma / Chroma
- if (access_dir) { // vertical access
- scaler_rec_in_width_l = vp_height_l;
- scaler_rec_in_width_c = vp_height_c;
- } else {
- scaler_rec_in_width_l = vp_width_l;
- scaler_rec_in_width_c = vp_width_c;
- }
-
- refcyc_per_req_delivery_pre_l = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_pre_l,
- hscale_pixel_rate_l,
- scaler_rec_in_width_l,
- req_per_swath_ub_l); // per req
- refcyc_per_req_delivery_l = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_l,
- hscale_pixel_rate_l,
- scaler_rec_in_width_l,
- req_per_swath_ub_l); // per req
-
- dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f\n",
- __func__,
- refcyc_per_req_delivery_pre_l);
- dml_print("DML_DLG: %s: refcyc_per_req_delivery_l = %3.2f\n",
- __func__,
- refcyc_per_req_delivery_l);
-
- ASSERT(refcyc_per_req_delivery_pre_l < dml_pow(2, 13));
- ASSERT(refcyc_per_req_delivery_l < dml_pow(2, 13));
-
- if (dual_plane) {
- refcyc_per_req_delivery_pre_c = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_pre_c,
- hscale_pixel_rate_c,
- scaler_rec_in_width_c,
- req_per_swath_ub_c); // per req
- refcyc_per_req_delivery_c = get_refcyc_per_delivery(mode_lib,
- refclk_freq_in_mhz,
- pclk_freq_in_mhz,
- dst->odm_combine,
- full_recout_width,
- dst->hactive,
- vratio_c,
- hscale_pixel_rate_c,
- scaler_rec_in_width_c,
- req_per_swath_ub_c); // per req
-
- dml_print("DML_DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f\n",
- __func__,
- refcyc_per_req_delivery_pre_c);
- dml_print("DML_DLG: %s: refcyc_per_req_delivery_c = %3.2f\n",
- __func__,
- refcyc_per_req_delivery_c);
-
- ASSERT(refcyc_per_req_delivery_pre_c < dml_pow(2, 13));
- ASSERT(refcyc_per_req_delivery_c < dml_pow(2, 13));
- }
-
- // XFC
- xfc_transfer_delay = get_xfc_transfer_delay(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
- xfc_precharge_delay = get_xfc_precharge_delay(mode_lib,
- e2e_pipe_param,
- num_pipes,
- pipe_idx);
- xfc_remote_surface_flip_latency = get_xfc_remote_surface_flip_latency(mode_lib,
- e2e_pipe_param,
- num_pipes,
- pipe_idx);
- xfc_dst_y_delta_drq_limit = xfc_remote_surface_flip_latency;
- xfc_prefetch_margin = get_xfc_prefetch_margin(mode_lib,
- e2e_pipe_param,
- num_pipes,
- pipe_idx);
-
- // TTU - Cursor
- refcyc_per_req_delivery_pre_cur0 = 0.0;
- refcyc_per_req_delivery_cur0 = 0.0;
- if (src->num_cursors > 0) {
- calculate_ttu_cursor(mode_lib,
- &refcyc_per_req_delivery_pre_cur0,
- &refcyc_per_req_delivery_cur0,
- refclk_freq_in_mhz,
- ref_freq_to_pix_freq,
- hscale_pixel_rate_l,
- scl->hscl_ratio,
- vratio_pre_l,
- vratio_l,
- src->cur0_src_width,
- (enum cursor_bpp)(src->cur0_bpp));
- }
-
- refcyc_per_req_delivery_pre_cur1 = 0.0;
- refcyc_per_req_delivery_cur1 = 0.0;
- if (src->num_cursors > 1) {
- calculate_ttu_cursor(mode_lib,
- &refcyc_per_req_delivery_pre_cur1,
- &refcyc_per_req_delivery_cur1,
- refclk_freq_in_mhz,
- ref_freq_to_pix_freq,
- hscale_pixel_rate_l,
- scl->hscl_ratio,
- vratio_pre_l,
- vratio_l,
- src->cur1_src_width,
- (enum cursor_bpp)(src->cur1_bpp));
- }
-
- // TTU - Misc
- // all hard-coded
-
- // Assignment to register structures
- disp_dlg_regs->dst_y_after_scaler = dst_y_after_scaler; // in terms of line
- disp_dlg_regs->refcyc_x_after_scaler = dst_x_after_scaler * ref_freq_to_pix_freq; // in terms of refclk
- ASSERT(disp_dlg_regs->refcyc_x_after_scaler < (unsigned int) dml_pow(2, 13));
- disp_dlg_regs->dst_y_prefetch = (unsigned int) (dst_y_prefetch * dml_pow(2, 2));
- disp_dlg_regs->dst_y_per_vm_vblank = (unsigned int) (dst_y_per_vm_vblank * dml_pow(2, 2));
- disp_dlg_regs->dst_y_per_row_vblank = (unsigned int) (dst_y_per_row_vblank * dml_pow(2, 2));
- disp_dlg_regs->dst_y_per_vm_flip = (unsigned int) (dst_y_per_vm_flip * dml_pow(2, 2));
- disp_dlg_regs->dst_y_per_row_flip = (unsigned int) (dst_y_per_row_flip * dml_pow(2, 2));
-
- disp_dlg_regs->vratio_prefetch = (unsigned int) (vratio_pre_l * dml_pow(2, 19));
- disp_dlg_regs->vratio_prefetch_c = (unsigned int) (vratio_pre_c * dml_pow(2, 19));
-
- disp_dlg_regs->refcyc_per_pte_group_vblank_l =
- (unsigned int) (dst_y_per_row_vblank * (double) htotal
- * ref_freq_to_pix_freq / (double) dpte_groups_per_row_ub_l);
- ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_l < (unsigned int) dml_pow(2, 13));
-
- if (dual_plane) {
- disp_dlg_regs->refcyc_per_pte_group_vblank_c = (unsigned int) (dst_y_per_row_vblank
- * (double) htotal * ref_freq_to_pix_freq
- / (double) dpte_groups_per_row_ub_c);
- ASSERT(disp_dlg_regs->refcyc_per_pte_group_vblank_c
- < (unsigned int) dml_pow(2, 13));
- }
-
- disp_dlg_regs->refcyc_per_meta_chunk_vblank_l =
- (unsigned int) (dst_y_per_row_vblank * (double) htotal
- * ref_freq_to_pix_freq / (double) meta_chunks_per_row_ub_l);
- ASSERT(disp_dlg_regs->refcyc_per_meta_chunk_vblank_l < (unsigned int) dml_pow(2, 13));
-
- disp_dlg_regs->refcyc_per_meta_chunk_vblank_c =
- disp_dlg_regs->refcyc_per_meta_chunk_vblank_l; // dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now
-
- disp_dlg_regs->refcyc_per_pte_group_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
- * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_l;
- disp_dlg_regs->refcyc_per_meta_chunk_flip_l = (unsigned int) (dst_y_per_row_flip * htotal
- * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_l;
-
- if (dual_plane) {
- disp_dlg_regs->refcyc_per_pte_group_flip_c = (unsigned int) (dst_y_per_row_flip
- * htotal * ref_freq_to_pix_freq) / dpte_groups_per_row_ub_c;
- disp_dlg_regs->refcyc_per_meta_chunk_flip_c = (unsigned int) (dst_y_per_row_flip
- * htotal * ref_freq_to_pix_freq) / meta_chunks_per_row_ub_c;
- }
-
- disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l
- / (double) vratio_l * dml_pow(2, 2));
- ASSERT(disp_dlg_regs->dst_y_per_pte_row_nom_l < (unsigned int) dml_pow(2, 17));
-
- if (dual_plane) {
- disp_dlg_regs->dst_y_per_pte_row_nom_c = (unsigned int) ((double) dpte_row_height_c
- / (double) vratio_c * dml_pow(2, 2));
- if (disp_dlg_regs->dst_y_per_pte_row_nom_c >= (unsigned int) dml_pow(2, 17)) {
- dml_print("DML_DLG: %s: Warning dst_y_per_pte_row_nom_c %u larger than supported by register format U15.2 %u\n",
- __func__,
- disp_dlg_regs->dst_y_per_pte_row_nom_c,
- (unsigned int) dml_pow(2, 17) - 1);
- }
- }
-
- disp_dlg_regs->dst_y_per_meta_row_nom_l = (unsigned int) ((double) meta_row_height_l
- / (double) vratio_l * dml_pow(2, 2));
- ASSERT(disp_dlg_regs->dst_y_per_meta_row_nom_l < (unsigned int) dml_pow(2, 17));
-
- disp_dlg_regs->dst_y_per_meta_row_nom_c = disp_dlg_regs->dst_y_per_meta_row_nom_l; // TODO: dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now
-
- disp_dlg_regs->refcyc_per_pte_group_nom_l = (unsigned int) ((double) dpte_row_height_l
- / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
- / (double) dpte_groups_per_row_ub_l);
- if (disp_dlg_regs->refcyc_per_pte_group_nom_l >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_pte_group_nom_l = dml_pow(2, 23) - 1;
- disp_dlg_regs->refcyc_per_meta_chunk_nom_l = (unsigned int) ((double) meta_row_height_l
- / (double) vratio_l * (double) htotal * ref_freq_to_pix_freq
- / (double) meta_chunks_per_row_ub_l);
- if (disp_dlg_regs->refcyc_per_meta_chunk_nom_l >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_meta_chunk_nom_l = dml_pow(2, 23) - 1;
-
- if (dual_plane) {
- disp_dlg_regs->refcyc_per_pte_group_nom_c =
- (unsigned int) ((double) dpte_row_height_c / (double) vratio_c
- * (double) htotal * ref_freq_to_pix_freq
- / (double) dpte_groups_per_row_ub_c);
- if (disp_dlg_regs->refcyc_per_pte_group_nom_c >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_pte_group_nom_c = dml_pow(2, 23) - 1;
-
- // TODO: Is this the right calculation? Does htotal need to be halved?
- disp_dlg_regs->refcyc_per_meta_chunk_nom_c =
- (unsigned int) ((double) meta_row_height_c / (double) vratio_c
- * (double) htotal * ref_freq_to_pix_freq
- / (double) meta_chunks_per_row_ub_c);
- if (disp_dlg_regs->refcyc_per_meta_chunk_nom_c >= (unsigned int) dml_pow(2, 23))
- disp_dlg_regs->refcyc_per_meta_chunk_nom_c = dml_pow(2, 23) - 1;
- }
-
- disp_dlg_regs->refcyc_per_line_delivery_pre_l = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_l,
- 1);
- disp_dlg_regs->refcyc_per_line_delivery_l = (unsigned int) dml_floor(refcyc_per_line_delivery_l,
- 1);
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_l < (unsigned int) dml_pow(2, 13));
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_l < (unsigned int) dml_pow(2, 13));
-
- disp_dlg_regs->refcyc_per_line_delivery_pre_c = (unsigned int) dml_floor(refcyc_per_line_delivery_pre_c,
- 1);
- disp_dlg_regs->refcyc_per_line_delivery_c = (unsigned int) dml_floor(refcyc_per_line_delivery_c,
- 1);
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_pre_c < (unsigned int) dml_pow(2, 13));
- ASSERT(disp_dlg_regs->refcyc_per_line_delivery_c < (unsigned int) dml_pow(2, 13));
-
- disp_dlg_regs->chunk_hdl_adjust_cur0 = 3;
- disp_dlg_regs->dst_y_offset_cur0 = 0;
- disp_dlg_regs->chunk_hdl_adjust_cur1 = 3;
- disp_dlg_regs->dst_y_offset_cur1 = 0;
-
- disp_dlg_regs->xfc_reg_transfer_delay = xfc_transfer_delay;
- disp_dlg_regs->xfc_reg_precharge_delay = xfc_precharge_delay;
- disp_dlg_regs->xfc_reg_remote_surface_flip_latency = xfc_remote_surface_flip_latency;
- disp_dlg_regs->xfc_reg_prefetch_margin = dml_ceil(xfc_prefetch_margin * refclk_freq_in_mhz,
- 1);
-
- // slave has to have this value also set to off
- if (src->xfc_enable && !src->xfc_slave)
- disp_dlg_regs->dst_y_delta_drq_limit = dml_ceil(xfc_dst_y_delta_drq_limit, 1);
- else
- disp_dlg_regs->dst_y_delta_drq_limit = 0x7fff; // off
-
- disp_ttu_regs->refcyc_per_req_delivery_pre_l = (unsigned int) (refcyc_per_req_delivery_pre_l
- * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_l = (unsigned int) (refcyc_per_req_delivery_l
- * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_pre_c = (unsigned int) (refcyc_per_req_delivery_pre_c
- * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_c = (unsigned int) (refcyc_per_req_delivery_c
- * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_pre_cur0 =
- (unsigned int) (refcyc_per_req_delivery_pre_cur0 * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_cur0 = (unsigned int) (refcyc_per_req_delivery_cur0
- * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_pre_cur1 =
- (unsigned int) (refcyc_per_req_delivery_pre_cur1 * dml_pow(2, 10));
- disp_ttu_regs->refcyc_per_req_delivery_cur1 = (unsigned int) (refcyc_per_req_delivery_cur1
- * dml_pow(2, 10));
- disp_ttu_regs->qos_level_low_wm = 0;
- ASSERT(disp_ttu_regs->qos_level_low_wm < dml_pow(2, 14));
- disp_ttu_regs->qos_level_high_wm = (unsigned int) (4.0 * (double) htotal
- * ref_freq_to_pix_freq);
- ASSERT(disp_ttu_regs->qos_level_high_wm < dml_pow(2, 14));
-
- disp_ttu_regs->qos_level_flip = 14;
- disp_ttu_regs->qos_level_fixed_l = 8;
- disp_ttu_regs->qos_level_fixed_c = 8;
- disp_ttu_regs->qos_level_fixed_cur0 = 8;
- disp_ttu_regs->qos_ramp_disable_l = 0;
- disp_ttu_regs->qos_ramp_disable_c = 0;
- disp_ttu_regs->qos_ramp_disable_cur0 = 0;
-
- disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz;
- ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24));
-
- print__ttu_regs_st(mode_lib, *disp_ttu_regs);
- print__dlg_regs_st(mode_lib, *disp_dlg_regs);
-}
-
-void 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 ignore_viewport_pos,
- const bool immediate_flip_support)
-{
- display_rq_params_st rq_param = {0};
- display_dlg_sys_params_st dlg_sys_param = {0};
-
- // Get watermark and Tex.
- dlg_sys_param.t_urg_wm_us = get_wm_urgent(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.deepsleep_dcfclk_mhz = get_clk_dcf_deepsleep(mode_lib,
- e2e_pipe_param,
- num_pipes);
- dlg_sys_param.t_extra_us = get_urgent_extra_latency(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.mem_trip_us = get_wm_memory_trip(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.t_mclk_wm_us = get_wm_dram_clock_change(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.t_sr_wm_us = get_wm_stutter_enter_exit(mode_lib, e2e_pipe_param, num_pipes);
- dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib,
- e2e_pipe_param,
- num_pipes);
- dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib,
- e2e_pipe_param,
- num_pipes);
- dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency
- / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated
-
- print__dlg_sys_params_st(mode_lib, dlg_sys_param);
-
- // system parameter calculation done
-
- dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx);
- 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,
- e2e_pipe_param,
- num_pipes,
- pipe_idx,
- dlg_regs,
- ttu_regs,
- rq_param.dlg,
- dlg_sys_param,
- cstate_en,
- pstate_en,
- vm_en,
- 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, 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
deleted file mode 100644
index efdd4c73d8f3..000000000000
--- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_calc.h
+++ /dev/null
@@ -1,148 +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 __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;
-
-// 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,
- 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>
-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);
-
-// 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 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
-void dml_rq_dlg_get_dlg_params_prefetch(
- struct display_mode_lib *mode_lib,
- 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.
-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 ignore_viewport_pos,
- const bool immediate_flip_support);
-
-// 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,
- unsigned int *o_meta_row_height,
- unsigned int vp_width,
- unsigned int data_pitch,
- int source_format,
- int tiling,
- int macro_tile_size,
- int source_scan,
- int is_chroma);
-
-// Function: dml_rq_dlg_get_arb_params
-void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param);
-
-#endif
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
index 987d7671cd0f..304164986bd8 100644
--- 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
@@ -27,10 +27,11 @@
#define __DISPLAY_RQ_DLG_CALC_H__
#include "dml_common_defs.h"
-#include "display_rq_dlg_helpers.h"
struct display_mode_lib;
+#include "display_rq_dlg_helpers.h"
+
void dml1_extract_rq_regs(
struct display_mode_lib *mode_lib,
struct _vcs_dpi_display_rq_regs_st *rq_regs,
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c
index 0c2314efb47e..ea3f888e5c65 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c
@@ -36,7 +36,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#define block HPD
#define reg_num 0
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_translate_dce120.c b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_translate_dce120.c
index a225b02cc779..39ef5c7dad97 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_translate_dce120.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_translate_dce120.c
@@ -35,7 +35,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
/* begin *********************
* macros to expend register list macro defined in HW object header file */
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
index 5235f69f0602..32aa47a04a0d 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
@@ -36,7 +36,8 @@
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#define block HPD
#define reg_num 0
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
index 347864810d01..fecc8688048d 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
@@ -35,7 +35,8 @@
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
/* begin *********************
* macros to expend register list macro defined in HW object header file */
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
index fc7a7d4ebca5..0b1db48fef36 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c
@@ -284,6 +284,14 @@ static bool read_command(
msleep(engine->delay);
} while (ctx.operation_succeeded && !ctx.transaction_complete);
+ if (request->payload.address_space ==
+ I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD) {
+ dm_logger_write(engine->base.ctx->logger, LOG_I2C_AUX, "READ: addr:0x%x value:0x%x Result:%d",
+ request->payload.address,
+ request->payload.data[0],
+ ctx.operation_succeeded);
+ }
+
return ctx.operation_succeeded;
}
@@ -484,6 +492,14 @@ static bool write_command(
msleep(engine->delay);
} while (ctx.operation_succeeded && !ctx.transaction_complete);
+ if (request->payload.address_space ==
+ I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD) {
+ dm_logger_write(engine->base.ctx->logger, LOG_I2C_AUX, "WRITE: addr:0x%x value:0x%x Result:%d",
+ request->payload.address,
+ request->payload.data[0],
+ ctx.operation_succeeded);
+ }
+
return ctx.operation_succeeded;
}
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
index 81f9f3e34c10..5f47f6c007ac 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c
@@ -441,10 +441,6 @@ static void construct(
static void destruct(
struct aux_engine_dce110 *engine)
{
- struct aux_engine_dce110 *aux110 = engine;
-/*temp w/a, to do*/
- REG_UPDATE(AUX_ARB_CONTROL, AUX_DMCU_DONE_USING_AUX_REG, 1);
- REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1);
dal_aux_engine_destruct(&engine->base);
}
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c b/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c
index a401636bf3f8..0e7b18260027 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c
@@ -38,7 +38,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
/* begin *********************
* macros to expend register list macro defined in HW object header file */
diff --git a/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c b/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c
index bed7cc3e77de..e44a8901f38b 100644
--- a/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c
+++ b/drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c
@@ -38,7 +38,8 @@
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
/* begin *********************
* macros to expend register list macro defined in HW object header file */
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 d6971054ec07..5509e13e7edf 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -119,6 +119,11 @@ struct resource_funcs {
struct dc *dc,
struct dc_state *new_ctx,
struct dc_stream_state *dc_stream);
+
+ enum dc_status (*remove_stream_from_ctx)(
+ struct dc *dc,
+ struct dc_state *new_ctx,
+ struct dc_stream_state *stream);
};
struct audio_support{
@@ -148,6 +153,7 @@ struct resource_pool {
unsigned int underlay_pipe_index;
unsigned int stream_enc_count;
unsigned int ref_clock_inKhz;
+ unsigned int timing_generator_count;
/*
* reserved clock source for DP
@@ -188,6 +194,7 @@ struct plane_resource {
struct input_pixel_processor *ipp;
struct transform *xfm;
struct dpp *dpp;
+ uint8_t mpcc_inst;
};
struct pipe_ctx {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index 616c73e2b0bd..2f783c650084 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -53,7 +53,7 @@ bool perform_link_training_with_retries(
bool is_mst_supported(struct dc_link *link);
-void detect_dp_sink_caps(struct dc_link *link);
+bool detect_dp_sink_caps(struct dc_link *link);
void detect_edp_sink_caps(struct dc_link *link);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
index ce206355461b..de60f940030d 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -32,13 +32,6 @@ enum dmcu_state {
DMCU_RUNNING = 1
};
-struct dmcu_version {
- unsigned int day;
- unsigned int month;
- unsigned int year;
- unsigned int interface_version;
-};
-
struct dmcu {
struct dc_context *ctx;
const struct dmcu_funcs *funcs;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index 25edbde6163e..78abc16ec4dc 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -131,6 +131,11 @@ struct dpp_funcs {
uint32_t width
);
+ void (*dpp_dppclk_control)(
+ struct dpp *dpp_base,
+ bool dppclk_div,
+ bool enable);
+
};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
index b7c7e70022e4..9ced254e652c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -119,6 +119,9 @@ struct hubp_funcs {
void (*hubp_disconnect)(struct hubp *hubp);
+ void (*hubp_clk_cntl)(struct hubp *hubp, bool enable);
+ void (*hubp_vtg_sel)(struct hubp *hubp, uint32_t otg_inst);
+
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
index e3f0b4056318..b22158190262 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -136,7 +136,7 @@ struct out_csc_color_matrix {
enum opp_regamma {
OPP_REGAMMA_BYPASS = 0,
OPP_REGAMMA_SRGB,
- OPP_REGAMMA_3_6,
+ OPP_REGAMMA_XVYCC,
OPP_REGAMMA_USER
};
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 0fd329deacd8..54d8a1386142 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
@@ -123,8 +123,7 @@ struct link_encoder_funcs {
void (*enable_tmds_output)(struct link_encoder *enc,
enum clock_source_id clock_source,
enum dc_color_depth color_depth,
- bool hdmi,
- bool dual_link,
+ enum signal_type signal,
uint32_t pixel_clock);
void (*enable_dp_output)(struct link_encoder *enc,
const struct dc_link_settings *link_settings,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
index ab8fb77f1ae5..d974d9e18612 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
@@ -297,6 +297,10 @@ struct opp_funcs {
bool enable,
const struct dc_crtc_timing *timing);
+ void (*opp_pipe_clock_control)(
+ struct output_pixel_processor *opp,
+ bool enable);
+
};
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index ec312f1a3e55..3217b5bf6c7a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -92,6 +92,36 @@ struct crtc_stereo_flags {
uint8_t DISABLE_STEREO_DP_SYNC : 1;
};
+enum crc_selection {
+ /* Order must match values expected by hardware */
+ UNION_WINDOW_A_B = 0,
+ UNION_WINDOW_A_NOT_B,
+ UNION_WINDOW_NOT_A_B,
+ UNION_WINDOW_NOT_A_NOT_B,
+ INTERSECT_WINDOW_A_B,
+ INTERSECT_WINDOW_A_NOT_B,
+ INTERSECT_WINDOW_NOT_A_B,
+ INTERSECT_WINDOW_NOT_A_NOT_B,
+};
+
+struct crc_params {
+ /* Regions used to calculate CRC*/
+ uint16_t windowa_x_start;
+ uint16_t windowa_x_end;
+ uint16_t windowa_y_start;
+ uint16_t windowa_y_end;
+
+ uint16_t windowb_x_start;
+ uint16_t windowb_x_end;
+ uint16_t windowb_y_start;
+ uint16_t windowb_y_end;
+
+ enum crc_selection selection;
+
+ bool continuous_mode;
+ bool enable;
+};
+
struct timing_generator {
const struct timing_generator_funcs *funcs;
struct dc_bios *bp;
@@ -173,6 +203,21 @@ struct timing_generator_funcs {
bool (*is_tg_enabled)(struct timing_generator *tg);
bool (*is_optc_underflow_occurred)(struct timing_generator *tg);
void (*clear_optc_underflow)(struct timing_generator *tg);
+
+ /**
+ * Configure CRCs for the given timing generator. Return false if TG is
+ * not on.
+ */
+ bool (*configure_crc)(struct timing_generator *tg,
+ const struct crc_params *params);
+
+ /**
+ * Get CRCs for the given timing generator. Return false if CRCs are
+ * not enabled (via configure_crc).
+ */
+ bool (*get_crc)(struct timing_generator *tg,
+ uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb);
+
};
#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 6f6c02b89f90..c5b3623bcbd9 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
@@ -30,7 +30,7 @@
#include "dc_hw_types.h"
#include "fixed31_32.h"
-#define CSC_TEMPERATURE_MATRIX_SIZE 9
+#define CSC_TEMPERATURE_MATRIX_SIZE 12
struct bit_depth_reduction_params;
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 4c0aa56f7bae..e764cbad881b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -114,7 +114,7 @@ struct hw_sequencer_funcs {
void (*power_down)(struct dc *dc);
- void (*enable_accelerated_mode)(struct dc *dc);
+ void (*enable_accelerated_mode)(struct dc *dc, struct dc_state *context);
void (*enable_timing_synchronization)(
struct dc *dc,
@@ -149,6 +149,7 @@ struct hw_sequencer_funcs {
void (*unblank_stream)(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings);
+ void (*blank_stream)(struct pipe_ctx *pipe_ctx);
void (*pipe_control_lock)(
struct dc *dc,
struct pipe_ctx *pipe,
@@ -198,6 +199,8 @@ struct hw_sequencer_funcs {
bool enable);
void (*edp_wait_for_hpd_ready)(struct dc_link *link, bool power_up);
+ void (*set_cursor_position)(struct pipe_ctx *pipe);
+ void (*set_cursor_attribute)(struct pipe_ctx *pipe);
};
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 f2b8c9a376d5..30be7bb4a01a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h
@@ -51,6 +51,8 @@ void dp_enable_link_phy(
const struct dc_link_settings *link_settings);
void dp_receiver_power_ctrl(struct dc_link *link, bool on);
+bool edp_receiver_ready_T9(struct dc_link *link);
+bool edp_receiver_ready_T7(struct dc_link *link);
void dp_disable_link_phy(struct dc_link *link, enum signal_type signal);
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c
index 66d52580e29f..1ea7256ec89b 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c
@@ -32,7 +32,8 @@
#include "dce/dce_12_0_offset.h"
#include "dce/dce_12_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "ivsrcid/ivsrcid_vislands30.h"
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c
index 7f7db66c48b0..e04ae49243f6 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c
@@ -31,7 +31,8 @@
#include "dcn/dcn_1_0_offset.h"
#include "dcn/dcn_1_0_sh_mask.h"
-#include "soc15ip.h"
+#include "soc15_hw_ip.h"
+#include "vega10_ip_offset.h"
#include "irq_service_dcn10.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 57a54a7b89e5..1c079ba37c30 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
@@ -42,8 +42,7 @@ static void virtual_link_encoder_enable_tmds_output(
struct link_encoder *enc,
enum clock_source_id clock_source,
enum dc_color_depth color_depth,
- bool hdmi,
- bool dual_link,
+ enum signal_type signal,
uint32_t pixel_clock) {}
static void virtual_link_encoder_enable_dp_output(
diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
index 7abe663ecc6e..9831cb5eaa7c 100644
--- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h
+++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h
@@ -109,6 +109,14 @@
#define ASIC_REV_IS_STONEY(rev) \
((rev >= STONEY_A0) && (rev < CZ_UNKNOWN))
+/* DCE12 */
+
+#define AI_GREENLAND_P_A0 1
+#define AI_GREENLAND_P_A1 2
+
+#define ASICREV_IS_GREENLAND_M(eChipRev) (eChipRev < AI_UNKNOWN)
+#define ASICREV_IS_GREENLAND_P(eChipRev) (eChipRev < AI_UNKNOWN)
+
/* DCN1_0 */
#define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */
#define RAVEN_A0 0x01
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index 4badaedbaadd..0de258622c12 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -470,4 +470,7 @@ uint32_t dal_fixed31_32_clamp_u0d14(
uint32_t dal_fixed31_32_clamp_u0d10(
struct fixed31_32 arg);
+int32_t dal_fixed31_32_s4d19(
+ struct fixed31_32 arg);
+
#endif
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
index 7a9b43f84a31..36bbad594267 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
@@ -419,11 +419,6 @@ struct bios_event_info {
bool backlight_changed;
};
-enum {
- HDMI_PIXEL_CLOCK_IN_KHZ_297 = 297000,
- TMDS_PIXEL_CLOCK_IN_KHZ_165 = 165000
-};
-
/*
* DFS-bypass flag
*/
diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h
index b5ebde642207..199c5db67cbc 100644
--- a/drivers/gpu/drm/amd/display/include/signal_types.h
+++ b/drivers/gpu/drm/amd/display/include/signal_types.h
@@ -26,6 +26,11 @@
#ifndef __DC_SIGNAL_TYPES_H__
#define __DC_SIGNAL_TYPES_H__
+/* 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 */
+#define TMDS_MAX_PIXEL_CLOCK 165000
+
enum signal_type {
SIGNAL_TYPE_NONE = 0L, /* no signal */
SIGNAL_TYPE_DVI_SINGLE_LINK = (1 << 0),
diff --git a/drivers/gpu/drm/amd/display/modules/color/Makefile b/drivers/gpu/drm/amd/display/modules/color/Makefile
new file mode 100644
index 000000000000..65c33a76951a
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/color/Makefile
@@ -0,0 +1,31 @@
+#
+# Copyright 2018 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
+# Makefile for the color sub-module of DAL.
+#
+
+MOD_COLOR = color_gamma.o
+
+AMD_DAL_MOD_COLOR = $(addprefix $(AMDDALPATH)/modules/color/,$(MOD_COLOR))
+#$(info ************ DAL COLOR MODULE MAKEFILE ************)
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MOD_COLOR)
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
new file mode 100644
index 000000000000..a5fd14a4016f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -0,0 +1,1403 @@
+/*
+ * Copyright 2016 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 "dc.h"
+#include "opp.h"
+#include "color_gamma.h"
+
+
+#define NUM_PTS_IN_REGION 16
+#define NUM_REGIONS 32
+#define NUM_DEGAMMA_REGIONS 12
+#define MAX_HW_POINTS (NUM_PTS_IN_REGION*NUM_REGIONS)
+#define MAX_HW_DEGAMMA_POINTS (NUM_PTS_IN_REGION*NUM_DEGAMMA_REGIONS)
+
+static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2];
+static struct hw_x_point degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS + 2];
+
+static struct fixed31_32 pq_table[MAX_HW_POINTS + 2];
+static struct fixed31_32 de_pq_table[MAX_HW_DEGAMMA_POINTS + 2];
+
+static bool pq_initialized; /* = false; */
+static bool de_pq_initialized; /* = false; */
+
+/* one-time setup of X points */
+void setup_x_points_distribution(void)
+{
+ struct fixed31_32 region_size = dal_fixed31_32_from_int(128);
+ int32_t segment;
+ uint32_t seg_offset;
+ uint32_t index;
+ struct fixed31_32 increment;
+
+ coordinates_x[MAX_HW_POINTS].x = region_size;
+ coordinates_x[MAX_HW_POINTS + 1].x = region_size;
+
+ for (segment = 6; segment > (6 - NUM_REGIONS); segment--) {
+ region_size = dal_fixed31_32_div_int(region_size, 2);
+ increment = dal_fixed31_32_div_int(region_size,
+ NUM_PTS_IN_REGION);
+ seg_offset = (segment + (NUM_REGIONS - 7)) * NUM_PTS_IN_REGION;
+ coordinates_x[seg_offset].x = region_size;
+
+ for (index = seg_offset + 1;
+ index < seg_offset + NUM_PTS_IN_REGION;
+ index++) {
+ coordinates_x[index].x = dal_fixed31_32_add
+ (coordinates_x[index-1].x, increment);
+ }
+ }
+
+ region_size = dal_fixed31_32_from_int(1);
+ degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS].x = region_size;
+ degamma_coordinates_x[MAX_HW_DEGAMMA_POINTS + 1].x = region_size;
+
+ for (segment = -1; segment > -(NUM_DEGAMMA_REGIONS + 1); segment--) {
+ region_size = dal_fixed31_32_div_int(region_size, 2);
+ increment = dal_fixed31_32_div_int(region_size,
+ NUM_PTS_IN_REGION);
+ seg_offset = (segment + NUM_DEGAMMA_REGIONS) * NUM_PTS_IN_REGION;
+ degamma_coordinates_x[seg_offset].x = region_size;
+
+ for (index = seg_offset + 1;
+ index < seg_offset + NUM_PTS_IN_REGION;
+ index++) {
+ degamma_coordinates_x[index].x = dal_fixed31_32_add
+ (degamma_coordinates_x[index-1].x, increment);
+ }
+ }
+
+}
+
+static void compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
+{
+ /* consts for PQ gamma formula. */
+ const struct fixed31_32 m1 =
+ dal_fixed31_32_from_fraction(159301758, 1000000000);
+ const struct fixed31_32 m2 =
+ dal_fixed31_32_from_fraction(7884375, 100000);
+ const struct fixed31_32 c1 =
+ dal_fixed31_32_from_fraction(8359375, 10000000);
+ const struct fixed31_32 c2 =
+ dal_fixed31_32_from_fraction(188515625, 10000000);
+ const struct fixed31_32 c3 =
+ dal_fixed31_32_from_fraction(186875, 10000);
+
+ struct fixed31_32 l_pow_m1;
+ struct fixed31_32 base;
+
+ if (dal_fixed31_32_lt(in_x, dal_fixed31_32_zero))
+ in_x = dal_fixed31_32_zero;
+
+ l_pow_m1 = dal_fixed31_32_pow(in_x, m1);
+ base = dal_fixed31_32_div(
+ dal_fixed31_32_add(c1,
+ (dal_fixed31_32_mul(c2, l_pow_m1))),
+ dal_fixed31_32_add(dal_fixed31_32_one,
+ (dal_fixed31_32_mul(c3, l_pow_m1))));
+ *out_y = dal_fixed31_32_pow(base, m2);
+}
+
+static void compute_de_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
+{
+ /* consts for dePQ gamma formula. */
+ const struct fixed31_32 m1 =
+ dal_fixed31_32_from_fraction(159301758, 1000000000);
+ const struct fixed31_32 m2 =
+ dal_fixed31_32_from_fraction(7884375, 100000);
+ const struct fixed31_32 c1 =
+ dal_fixed31_32_from_fraction(8359375, 10000000);
+ const struct fixed31_32 c2 =
+ dal_fixed31_32_from_fraction(188515625, 10000000);
+ const struct fixed31_32 c3 =
+ dal_fixed31_32_from_fraction(186875, 10000);
+
+ struct fixed31_32 l_pow_m1;
+ struct fixed31_32 base, div;
+
+
+ if (dal_fixed31_32_lt(in_x, dal_fixed31_32_zero))
+ in_x = dal_fixed31_32_zero;
+
+ l_pow_m1 = dal_fixed31_32_pow(in_x,
+ dal_fixed31_32_div(dal_fixed31_32_one, m2));
+ base = dal_fixed31_32_sub(l_pow_m1, c1);
+
+ if (dal_fixed31_32_lt(base, dal_fixed31_32_zero))
+ base = dal_fixed31_32_zero;
+
+ div = dal_fixed31_32_sub(c2, dal_fixed31_32_mul(c3, l_pow_m1));
+
+ *out_y = dal_fixed31_32_pow(dal_fixed31_32_div(base, div),
+ dal_fixed31_32_div(dal_fixed31_32_one, m1));
+
+}
+/* one-time pre-compute PQ values - only for sdr_white_level 80 */
+void precompute_pq(void)
+{
+ int i;
+ struct fixed31_32 x;
+ const struct hw_x_point *coord_x = coordinates_x + 32;
+ struct fixed31_32 scaling_factor =
+ dal_fixed31_32_from_fraction(80, 10000);
+
+ /* pow function has problems with arguments too small */
+ for (i = 0; i < 32; i++)
+ pq_table[i] = dal_fixed31_32_zero;
+
+ for (i = 32; i <= MAX_HW_POINTS; i++) {
+ x = dal_fixed31_32_mul(coord_x->x, scaling_factor);
+ compute_pq(x, &pq_table[i]);
+ ++coord_x;
+ }
+}
+
+/* one-time pre-compute dePQ values - only for max pixel value 125 FP16 */
+void precompute_de_pq(void)
+{
+ int i;
+ struct fixed31_32 y;
+ const struct hw_x_point *coord_x = degamma_coordinates_x;
+ struct fixed31_32 scaling_factor = dal_fixed31_32_from_int(125);
+
+
+ for (i = 0; i <= MAX_HW_DEGAMMA_POINTS; i++) {
+ compute_de_pq(coord_x->x, &y);
+ de_pq_table[i] = dal_fixed31_32_mul(y, scaling_factor);
+ ++coord_x;
+ }
+}
+struct dividers {
+ struct fixed31_32 divider1;
+ struct fixed31_32 divider2;
+ struct fixed31_32 divider3;
+};
+
+static void build_coefficients(struct gamma_coefficients *coefficients, bool is_2_4)
+{
+ static const int32_t numerator01[] = { 31308, 180000};
+ static const int32_t numerator02[] = { 12920, 4500};
+ static const int32_t numerator03[] = { 55, 99};
+ static const int32_t numerator04[] = { 55, 99};
+ static const int32_t numerator05[] = { 2400, 2200};
+
+ uint32_t i = 0;
+ uint32_t index = is_2_4 == true ? 0:1;
+
+ do {
+ coefficients->a0[i] = dal_fixed31_32_from_fraction(
+ numerator01[index], 10000000);
+ coefficients->a1[i] = dal_fixed31_32_from_fraction(
+ numerator02[index], 1000);
+ coefficients->a2[i] = dal_fixed31_32_from_fraction(
+ numerator03[index], 1000);
+ coefficients->a3[i] = dal_fixed31_32_from_fraction(
+ numerator04[index], 1000);
+ coefficients->user_gamma[i] = dal_fixed31_32_from_fraction(
+ numerator05[index], 1000);
+
+ ++i;
+ } while (i != ARRAY_SIZE(coefficients->a0));
+}
+
+static struct fixed31_32 translate_from_linear_space(
+ struct fixed31_32 arg,
+ struct fixed31_32 a0,
+ struct fixed31_32 a1,
+ struct fixed31_32 a2,
+ struct fixed31_32 a3,
+ struct fixed31_32 gamma)
+{
+ const struct fixed31_32 one = dal_fixed31_32_from_int(1);
+
+ if (dal_fixed31_32_lt(one, arg))
+ return one;
+
+ if (dal_fixed31_32_le(arg, dal_fixed31_32_neg(a0)))
+ return dal_fixed31_32_sub(
+ a2,
+ dal_fixed31_32_mul(
+ dal_fixed31_32_add(
+ one,
+ a3),
+ dal_fixed31_32_pow(
+ dal_fixed31_32_neg(arg),
+ dal_fixed31_32_recip(gamma))));
+ else if (dal_fixed31_32_le(a0, arg))
+ return dal_fixed31_32_sub(
+ dal_fixed31_32_mul(
+ dal_fixed31_32_add(
+ one,
+ a3),
+ dal_fixed31_32_pow(
+ arg,
+ dal_fixed31_32_recip(gamma))),
+ a2);
+ else
+ return dal_fixed31_32_mul(
+ arg,
+ a1);
+}
+
+static struct fixed31_32 translate_to_linear_space(
+ struct fixed31_32 arg,
+ struct fixed31_32 a0,
+ struct fixed31_32 a1,
+ struct fixed31_32 a2,
+ struct fixed31_32 a3,
+ struct fixed31_32 gamma)
+{
+ struct fixed31_32 linear;
+
+ a0 = dal_fixed31_32_mul(a0, a1);
+ if (dal_fixed31_32_le(arg, dal_fixed31_32_neg(a0)))
+
+ linear = dal_fixed31_32_neg(
+ dal_fixed31_32_pow(
+ dal_fixed31_32_div(
+ dal_fixed31_32_sub(a2, arg),
+ dal_fixed31_32_add(
+ dal_fixed31_32_one, a3)), gamma));
+
+ else if (dal_fixed31_32_le(dal_fixed31_32_neg(a0), arg) &&
+ dal_fixed31_32_le(arg, a0))
+ linear = dal_fixed31_32_div(arg, a1);
+ else
+ linear = dal_fixed31_32_pow(
+ dal_fixed31_32_div(
+ dal_fixed31_32_add(a2, arg),
+ dal_fixed31_32_add(
+ dal_fixed31_32_one, a3)), gamma);
+
+ return linear;
+}
+
+static inline struct fixed31_32 translate_from_linear_space_ex(
+ struct fixed31_32 arg,
+ struct gamma_coefficients *coeff,
+ uint32_t color_index)
+{
+ return translate_from_linear_space(
+ arg,
+ coeff->a0[color_index],
+ coeff->a1[color_index],
+ coeff->a2[color_index],
+ coeff->a3[color_index],
+ coeff->user_gamma[color_index]);
+}
+
+
+static inline struct fixed31_32 translate_to_linear_space_ex(
+ struct fixed31_32 arg,
+ struct gamma_coefficients *coeff,
+ uint32_t color_index)
+{
+ return translate_to_linear_space(
+ arg,
+ coeff->a0[color_index],
+ coeff->a1[color_index],
+ coeff->a2[color_index],
+ coeff->a3[color_index],
+ coeff->user_gamma[color_index]);
+}
+
+
+static bool find_software_points(
+ const struct dc_gamma *ramp,
+ const struct gamma_pixel *axis_x,
+ struct fixed31_32 hw_point,
+ enum channel_name channel,
+ uint32_t *index_to_start,
+ uint32_t *index_left,
+ uint32_t *index_right,
+ enum hw_point_position *pos)
+{
+ const uint32_t max_number = ramp->num_entries + 3;
+
+ struct fixed31_32 left, right;
+
+ uint32_t i = *index_to_start;
+
+ while (i < max_number) {
+ if (channel == CHANNEL_NAME_RED) {
+ left = axis_x[i].r;
+
+ if (i < max_number - 1)
+ right = axis_x[i + 1].r;
+ else
+ right = axis_x[max_number - 1].r;
+ } else if (channel == CHANNEL_NAME_GREEN) {
+ left = axis_x[i].g;
+
+ if (i < max_number - 1)
+ right = axis_x[i + 1].g;
+ else
+ right = axis_x[max_number - 1].g;
+ } else {
+ left = axis_x[i].b;
+
+ if (i < max_number - 1)
+ right = axis_x[i + 1].b;
+ else
+ right = axis_x[max_number - 1].b;
+ }
+
+ if (dal_fixed31_32_le(left, hw_point) &&
+ dal_fixed31_32_le(hw_point, right)) {
+ *index_to_start = i;
+ *index_left = i;
+
+ if (i < max_number - 1)
+ *index_right = i + 1;
+ else
+ *index_right = max_number - 1;
+
+ *pos = HW_POINT_POSITION_MIDDLE;
+
+ return true;
+ } else if ((i == *index_to_start) &&
+ dal_fixed31_32_le(hw_point, left)) {
+ *index_to_start = i;
+ *index_left = i;
+ *index_right = i;
+
+ *pos = HW_POINT_POSITION_LEFT;
+
+ return true;
+ } else if ((i == max_number - 1) &&
+ dal_fixed31_32_le(right, hw_point)) {
+ *index_to_start = i;
+ *index_left = i;
+ *index_right = i;
+
+ *pos = HW_POINT_POSITION_RIGHT;
+
+ return true;
+ }
+
+ ++i;
+ }
+
+ return false;
+}
+
+static bool build_custom_gamma_mapping_coefficients_worker(
+ const struct dc_gamma *ramp,
+ struct pixel_gamma_point *coeff,
+ const struct hw_x_point *coordinates_x,
+ const struct gamma_pixel *axis_x,
+ enum channel_name channel,
+ uint32_t number_of_points)
+{
+ uint32_t i = 0;
+
+ while (i <= number_of_points) {
+ struct fixed31_32 coord_x;
+
+ uint32_t index_to_start = 0;
+ uint32_t index_left = 0;
+ uint32_t index_right = 0;
+
+ enum hw_point_position hw_pos;
+
+ struct gamma_point *point;
+
+ struct fixed31_32 left_pos;
+ struct fixed31_32 right_pos;
+
+ if (channel == CHANNEL_NAME_RED)
+ coord_x = coordinates_x[i].regamma_y_red;
+ else if (channel == CHANNEL_NAME_GREEN)
+ coord_x = coordinates_x[i].regamma_y_green;
+ else
+ coord_x = coordinates_x[i].regamma_y_blue;
+
+ if (!find_software_points(
+ ramp, axis_x, coord_x, channel,
+ &index_to_start, &index_left, &index_right, &hw_pos)) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (index_left >= ramp->num_entries + 3) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (index_right >= ramp->num_entries + 3) {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ if (channel == CHANNEL_NAME_RED) {
+ point = &coeff[i].r;
+
+ left_pos = axis_x[index_left].r;
+ right_pos = axis_x[index_right].r;
+ } else if (channel == CHANNEL_NAME_GREEN) {
+ point = &coeff[i].g;
+
+ left_pos = axis_x[index_left].g;
+ right_pos = axis_x[index_right].g;
+ } else {
+ point = &coeff[i].b;
+
+ left_pos = axis_x[index_left].b;
+ right_pos = axis_x[index_right].b;
+ }
+
+ if (hw_pos == HW_POINT_POSITION_MIDDLE)
+ point->coeff = dal_fixed31_32_div(
+ dal_fixed31_32_sub(
+ coord_x,
+ left_pos),
+ dal_fixed31_32_sub(
+ right_pos,
+ left_pos));
+ else if (hw_pos == HW_POINT_POSITION_LEFT)
+ point->coeff = dal_fixed31_32_zero;
+ else if (hw_pos == HW_POINT_POSITION_RIGHT)
+ point->coeff = dal_fixed31_32_from_int(2);
+ else {
+ BREAK_TO_DEBUGGER();
+ return false;
+ }
+
+ point->left_index = index_left;
+ point->right_index = index_right;
+ point->pos = hw_pos;
+
+ ++i;
+ }
+
+ return true;
+}
+
+static struct fixed31_32 calculate_mapped_value(
+ struct pwl_float_data *rgb,
+ const struct pixel_gamma_point *coeff,
+ enum channel_name channel,
+ uint32_t max_index)
+{
+ const struct gamma_point *point;
+
+ struct fixed31_32 result;
+
+ if (channel == CHANNEL_NAME_RED)
+ point = &coeff->r;
+ else if (channel == CHANNEL_NAME_GREEN)
+ point = &coeff->g;
+ else
+ point = &coeff->b;
+
+ if ((point->left_index < 0) || (point->left_index > max_index)) {
+ BREAK_TO_DEBUGGER();
+ return dal_fixed31_32_zero;
+ }
+
+ if ((point->right_index < 0) || (point->right_index > max_index)) {
+ BREAK_TO_DEBUGGER();
+ return dal_fixed31_32_zero;
+ }
+
+ if (point->pos == HW_POINT_POSITION_MIDDLE)
+ if (channel == CHANNEL_NAME_RED)
+ result = dal_fixed31_32_add(
+ dal_fixed31_32_mul(
+ point->coeff,
+ dal_fixed31_32_sub(
+ rgb[point->right_index].r,
+ rgb[point->left_index].r)),
+ rgb[point->left_index].r);
+ else if (channel == CHANNEL_NAME_GREEN)
+ result = dal_fixed31_32_add(
+ dal_fixed31_32_mul(
+ point->coeff,
+ dal_fixed31_32_sub(
+ rgb[point->right_index].g,
+ rgb[point->left_index].g)),
+ rgb[point->left_index].g);
+ else
+ result = dal_fixed31_32_add(
+ dal_fixed31_32_mul(
+ point->coeff,
+ dal_fixed31_32_sub(
+ rgb[point->right_index].b,
+ rgb[point->left_index].b)),
+ rgb[point->left_index].b);
+ else if (point->pos == HW_POINT_POSITION_LEFT) {
+ BREAK_TO_DEBUGGER();
+ result = dal_fixed31_32_zero;
+ } else {
+ BREAK_TO_DEBUGGER();
+ result = dal_fixed31_32_one;
+ }
+
+ return result;
+}
+
+static void build_pq(struct pwl_float_data_ex *rgb_regamma,
+ uint32_t hw_points_num,
+ const struct hw_x_point *coordinate_x,
+ uint32_t sdr_white_level)
+{
+ uint32_t i, start_index;
+
+ struct pwl_float_data_ex *rgb = rgb_regamma;
+ const struct hw_x_point *coord_x = coordinate_x;
+ struct fixed31_32 x;
+ struct fixed31_32 output;
+ struct fixed31_32 scaling_factor =
+ dal_fixed31_32_from_fraction(sdr_white_level, 10000);
+
+ if (!pq_initialized && sdr_white_level == 80) {
+ precompute_pq();
+ pq_initialized = true;
+ }
+
+ /* TODO: start index is from segment 2^-24, skipping first segment
+ * due to x values too small for power calculations
+ */
+ start_index = 32;
+ rgb += start_index;
+ coord_x += start_index;
+
+ for (i = start_index; i <= hw_points_num; i++) {
+ /* Multiply 0.008 as regamma is 0-1 and FP16 input is 0-125.
+ * FP 1.0 = 80nits
+ */
+ if (sdr_white_level == 80) {
+ output = pq_table[i];
+ } else {
+ x = dal_fixed31_32_mul(coord_x->x, scaling_factor);
+ compute_pq(x, &output);
+ }
+
+ /* should really not happen? */
+ if (dal_fixed31_32_lt(output, dal_fixed31_32_zero))
+ output = dal_fixed31_32_zero;
+ else if (dal_fixed31_32_lt(dal_fixed31_32_one, output))
+ output = dal_fixed31_32_one;
+
+ rgb->r = output;
+ rgb->g = output;
+ rgb->b = output;
+
+ ++coord_x;
+ ++rgb;
+ }
+}
+
+static void build_de_pq(struct pwl_float_data_ex *de_pq,
+ uint32_t hw_points_num,
+ const struct hw_x_point *coordinate_x)
+{
+ uint32_t i;
+ struct fixed31_32 output;
+
+ struct pwl_float_data_ex *rgb = de_pq;
+ const struct hw_x_point *coord_x = degamma_coordinates_x;
+ struct fixed31_32 scaling_factor = dal_fixed31_32_from_int(125);
+
+ if (!de_pq_initialized) {
+ precompute_de_pq();
+ de_pq_initialized = true;
+ }
+
+
+ for (i = 0; i <= hw_points_num; i++) {
+ output = de_pq_table[i];
+ /* should really not happen? */
+ if (dal_fixed31_32_lt(output, dal_fixed31_32_zero))
+ output = dal_fixed31_32_zero;
+ else if (dal_fixed31_32_lt(scaling_factor, output))
+ output = scaling_factor;
+
+ rgb->r = output;
+ rgb->g = output;
+ rgb->b = output;
+
+ ++coord_x;
+ ++rgb;
+ }
+}
+
+static void build_regamma(struct pwl_float_data_ex *rgb_regamma,
+ uint32_t hw_points_num,
+ const struct hw_x_point *coordinate_x, bool is_2_4)
+{
+ uint32_t i;
+
+ struct gamma_coefficients coeff;
+ struct pwl_float_data_ex *rgb = rgb_regamma;
+ const struct hw_x_point *coord_x = coordinate_x;
+
+ build_coefficients(&coeff, is_2_4);
+
+ i = 0;
+
+ while (i != hw_points_num + 1) {
+ /*TODO use y vs r,g,b*/
+ rgb->r = translate_from_linear_space_ex(
+ coord_x->x, &coeff, 0);
+ rgb->g = rgb->r;
+ rgb->b = rgb->r;
+ ++coord_x;
+ ++rgb;
+ ++i;
+ }
+}
+
+static void build_degamma(struct pwl_float_data_ex *curve,
+ uint32_t hw_points_num,
+ const struct hw_x_point *coordinate_x, bool is_2_4)
+{
+ uint32_t i;
+
+ struct gamma_coefficients coeff;
+ struct pwl_float_data_ex *rgb = curve;
+ const struct hw_x_point *coord_x = degamma_coordinates_x;
+
+ build_coefficients(&coeff, is_2_4);
+
+ i = 0;
+
+ while (i != hw_points_num + 1) {
+ /*TODO use y vs r,g,b*/
+ rgb->r = translate_to_linear_space_ex(
+ coord_x->x, &coeff, 0);
+ rgb->g = rgb->r;
+ rgb->b = rgb->r;
+ ++coord_x;
+ ++rgb;
+ ++i;
+ }
+}
+
+static bool scale_gamma(struct pwl_float_data *pwl_rgb,
+ const struct dc_gamma *ramp,
+ struct dividers dividers)
+{
+ const struct fixed31_32 max_driver = dal_fixed31_32_from_int(0xFFFF);
+ const struct fixed31_32 max_os = dal_fixed31_32_from_int(0xFF00);
+ struct fixed31_32 scaler = max_os;
+ uint32_t i;
+ struct pwl_float_data *rgb = pwl_rgb;
+ struct pwl_float_data *rgb_last = rgb + ramp->num_entries - 1;
+
+ i = 0;
+
+ do {
+ if (dal_fixed31_32_lt(max_os, ramp->entries.red[i]) ||
+ dal_fixed31_32_lt(max_os, ramp->entries.green[i]) ||
+ dal_fixed31_32_lt(max_os, ramp->entries.blue[i])) {
+ scaler = max_driver;
+ break;
+ }
+ ++i;
+ } while (i != ramp->num_entries);
+
+ i = 0;
+
+ do {
+ rgb->r = dal_fixed31_32_div(
+ ramp->entries.red[i], scaler);
+ rgb->g = dal_fixed31_32_div(
+ ramp->entries.green[i], scaler);
+ rgb->b = dal_fixed31_32_div(
+ ramp->entries.blue[i], scaler);
+
+ ++rgb;
+ ++i;
+ } while (i != ramp->num_entries);
+
+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
+ dividers.divider1);
+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
+ dividers.divider1);
+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
+ dividers.divider1);
+
+ ++rgb;
+
+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
+ dividers.divider2);
+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
+ dividers.divider2);
+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
+ dividers.divider2);
+
+ ++rgb;
+
+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
+ dividers.divider3);
+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
+ dividers.divider3);
+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
+ dividers.divider3);
+
+ return true;
+}
+
+static bool scale_gamma_dx(struct pwl_float_data *pwl_rgb,
+ const struct dc_gamma *ramp,
+ struct dividers dividers)
+{
+ uint32_t i;
+ struct fixed31_32 min = dal_fixed31_32_zero;
+ struct fixed31_32 max = dal_fixed31_32_one;
+
+ struct fixed31_32 delta = dal_fixed31_32_zero;
+ struct fixed31_32 offset = dal_fixed31_32_zero;
+
+ for (i = 0 ; i < ramp->num_entries; i++) {
+ if (dal_fixed31_32_lt(ramp->entries.red[i], min))
+ min = ramp->entries.red[i];
+
+ if (dal_fixed31_32_lt(ramp->entries.green[i], min))
+ min = ramp->entries.green[i];
+
+ if (dal_fixed31_32_lt(ramp->entries.blue[i], min))
+ min = ramp->entries.blue[i];
+
+ if (dal_fixed31_32_lt(max, ramp->entries.red[i]))
+ max = ramp->entries.red[i];
+
+ if (dal_fixed31_32_lt(max, ramp->entries.green[i]))
+ max = ramp->entries.green[i];
+
+ if (dal_fixed31_32_lt(max, ramp->entries.blue[i]))
+ max = ramp->entries.blue[i];
+ }
+
+ if (dal_fixed31_32_lt(min, dal_fixed31_32_zero))
+ delta = dal_fixed31_32_neg(min);
+
+ offset = dal_fixed31_32_add(min, max);
+
+ for (i = 0 ; i < ramp->num_entries; i++) {
+ pwl_rgb[i].r = dal_fixed31_32_div(
+ dal_fixed31_32_add(
+ ramp->entries.red[i], delta), offset);
+ pwl_rgb[i].g = dal_fixed31_32_div(
+ dal_fixed31_32_add(
+ ramp->entries.green[i], delta), offset);
+ pwl_rgb[i].b = dal_fixed31_32_div(
+ dal_fixed31_32_add(
+ ramp->entries.blue[i], delta), offset);
+
+ }
+
+ pwl_rgb[i].r = dal_fixed31_32_sub(dal_fixed31_32_mul_int(
+ pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r);
+ pwl_rgb[i].g = dal_fixed31_32_sub(dal_fixed31_32_mul_int(
+ pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g);
+ pwl_rgb[i].b = dal_fixed31_32_sub(dal_fixed31_32_mul_int(
+ pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b);
+ ++i;
+ pwl_rgb[i].r = dal_fixed31_32_sub(dal_fixed31_32_mul_int(
+ pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r);
+ pwl_rgb[i].g = dal_fixed31_32_sub(dal_fixed31_32_mul_int(
+ pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g);
+ pwl_rgb[i].b = dal_fixed31_32_sub(dal_fixed31_32_mul_int(
+ pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b);
+
+ return true;
+}
+
+/*
+ * RS3+ color transform DDI - 1D LUT adjustment is composed with regamma here
+ * Input is evenly distributed in the output color space as specified in
+ * SetTimings
+ *
+ * Interpolation details:
+ * 1D LUT has 4096 values which give curve correction in 0-1 float range
+ * for evenly spaced points in 0-1 range. lut1D[index] gives correction
+ * for index/4095.
+ * First we find index for which:
+ * index/4095 < regamma_y < (index+1)/4095 =>
+ * index < 4095*regamma_y < index + 1
+ * norm_y = 4095*regamma_y, and index is just truncating to nearest integer
+ * lut1 = lut1D[index], lut2 = lut1D[index+1]
+ *
+ *adjustedY is then linearly interpolating regamma Y between lut1 and lut2
+ */
+static void apply_lut_1d(
+ const struct dc_gamma *ramp,
+ uint32_t num_hw_points,
+ struct dc_transfer_func_distributed_points *tf_pts)
+{
+ int i = 0;
+ int color = 0;
+ struct fixed31_32 *regamma_y;
+ struct fixed31_32 norm_y;
+ struct fixed31_32 lut1;
+ struct fixed31_32 lut2;
+ const int max_lut_index = 4095;
+ const struct fixed31_32 max_lut_index_f =
+ dal_fixed31_32_from_int_nonconst(max_lut_index);
+ int32_t index = 0, index_next = 0;
+ struct fixed31_32 index_f;
+ struct fixed31_32 delta_lut;
+ struct fixed31_32 delta_index;
+
+ if (ramp->type != GAMMA_CS_TFM_1D)
+ return; // this is not expected
+
+ for (i = 0; i < num_hw_points; i++) {
+ for (color = 0; color < 3; color++) {
+ if (color == 0)
+ regamma_y = &tf_pts->red[i];
+ else if (color == 1)
+ regamma_y = &tf_pts->green[i];
+ else
+ regamma_y = &tf_pts->blue[i];
+
+ norm_y = dal_fixed31_32_mul(max_lut_index_f,
+ *regamma_y);
+ index = dal_fixed31_32_floor(norm_y);
+ index_f = dal_fixed31_32_from_int_nonconst(index);
+
+ if (index < 0 || index > max_lut_index)
+ continue;
+
+ index_next = (index == max_lut_index) ? index : index+1;
+
+ if (color == 0) {
+ lut1 = ramp->entries.red[index];
+ lut2 = ramp->entries.red[index_next];
+ } else if (color == 1) {
+ lut1 = ramp->entries.green[index];
+ lut2 = ramp->entries.green[index_next];
+ } else {
+ lut1 = ramp->entries.blue[index];
+ lut2 = ramp->entries.blue[index_next];
+ }
+
+ // we have everything now, so interpolate
+ delta_lut = dal_fixed31_32_sub(lut2, lut1);
+ delta_index = dal_fixed31_32_sub(norm_y, index_f);
+
+ *regamma_y = dal_fixed31_32_add(lut1,
+ dal_fixed31_32_mul(delta_index, delta_lut));
+ }
+ }
+}
+
+static void build_evenly_distributed_points(
+ struct gamma_pixel *points,
+ uint32_t numberof_points,
+ struct dividers dividers)
+{
+ struct gamma_pixel *p = points;
+ struct gamma_pixel *p_last = p + numberof_points - 1;
+
+ uint32_t i = 0;
+
+ do {
+ struct fixed31_32 value = dal_fixed31_32_from_fraction(i,
+ numberof_points - 1);
+
+ p->r = value;
+ p->g = value;
+ p->b = value;
+
+ ++p;
+ ++i;
+ } while (i != numberof_points);
+
+ p->r = dal_fixed31_32_div(p_last->r, dividers.divider1);
+ p->g = dal_fixed31_32_div(p_last->g, dividers.divider1);
+ p->b = dal_fixed31_32_div(p_last->b, dividers.divider1);
+
+ ++p;
+
+ p->r = dal_fixed31_32_div(p_last->r, dividers.divider2);
+ p->g = dal_fixed31_32_div(p_last->g, dividers.divider2);
+ p->b = dal_fixed31_32_div(p_last->b, dividers.divider2);
+
+ ++p;
+
+ p->r = dal_fixed31_32_div(p_last->r, dividers.divider3);
+ p->g = dal_fixed31_32_div(p_last->g, dividers.divider3);
+ p->b = dal_fixed31_32_div(p_last->b, dividers.divider3);
+}
+
+static inline void copy_rgb_regamma_to_coordinates_x(
+ struct hw_x_point *coordinates_x,
+ uint32_t hw_points_num,
+ const struct pwl_float_data_ex *rgb_ex)
+{
+ struct hw_x_point *coords = coordinates_x;
+ uint32_t i = 0;
+ const struct pwl_float_data_ex *rgb_regamma = rgb_ex;
+
+ while (i <= hw_points_num) {
+ coords->regamma_y_red = rgb_regamma->r;
+ coords->regamma_y_green = rgb_regamma->g;
+ coords->regamma_y_blue = rgb_regamma->b;
+
+ ++coords;
+ ++rgb_regamma;
+ ++i;
+ }
+}
+
+static bool calculate_interpolated_hardware_curve(
+ const struct dc_gamma *ramp,
+ struct pixel_gamma_point *coeff128,
+ struct pwl_float_data *rgb_user,
+ const struct hw_x_point *coordinates_x,
+ const struct gamma_pixel *axis_x,
+ uint32_t number_of_points,
+ struct dc_transfer_func_distributed_points *tf_pts)
+{
+
+ const struct pixel_gamma_point *coeff = coeff128;
+ uint32_t max_entries = 3 - 1;
+
+ uint32_t i = 0;
+
+ for (i = 0; i < 3; i++) {
+ if (!build_custom_gamma_mapping_coefficients_worker(
+ ramp, coeff128, coordinates_x, axis_x, i,
+ number_of_points))
+ return false;
+ }
+
+ i = 0;
+ max_entries += ramp->num_entries;
+
+ /* TODO: float point case */
+
+ while (i <= number_of_points) {
+ tf_pts->red[i] = calculate_mapped_value(
+ rgb_user, coeff, CHANNEL_NAME_RED, max_entries);
+ tf_pts->green[i] = calculate_mapped_value(
+ rgb_user, coeff, CHANNEL_NAME_GREEN, max_entries);
+ tf_pts->blue[i] = calculate_mapped_value(
+ rgb_user, coeff, CHANNEL_NAME_BLUE, max_entries);
+
+ ++coeff;
+ ++i;
+ }
+
+ return true;
+}
+
+static void build_new_custom_resulted_curve(
+ uint32_t hw_points_num,
+ struct dc_transfer_func_distributed_points *tf_pts)
+{
+ uint32_t i;
+
+ i = 0;
+
+ while (i != hw_points_num + 1) {
+ tf_pts->red[i] = dal_fixed31_32_clamp(
+ tf_pts->red[i], dal_fixed31_32_zero,
+ dal_fixed31_32_one);
+ tf_pts->green[i] = dal_fixed31_32_clamp(
+ tf_pts->green[i], dal_fixed31_32_zero,
+ dal_fixed31_32_one);
+ tf_pts->blue[i] = dal_fixed31_32_clamp(
+ tf_pts->blue[i], dal_fixed31_32_zero,
+ dal_fixed31_32_one);
+
+ ++i;
+ }
+}
+
+static bool map_regamma_hw_to_x_user(
+ const struct dc_gamma *ramp,
+ struct pixel_gamma_point *coeff128,
+ struct pwl_float_data *rgb_user,
+ struct hw_x_point *coords_x,
+ const struct gamma_pixel *axis_x,
+ const struct pwl_float_data_ex *rgb_regamma,
+ uint32_t hw_points_num,
+ struct dc_transfer_func_distributed_points *tf_pts,
+ bool mapUserRamp)
+{
+ /* setup to spare calculated ideal regamma values */
+
+ int i = 0;
+ struct hw_x_point *coords = coords_x;
+ const struct pwl_float_data_ex *regamma = rgb_regamma;
+
+ if (mapUserRamp) {
+ copy_rgb_regamma_to_coordinates_x(coords,
+ hw_points_num,
+ rgb_regamma);
+
+ calculate_interpolated_hardware_curve(
+ ramp, coeff128, rgb_user, coords, axis_x,
+ hw_points_num, tf_pts);
+ } else {
+ /* just copy current rgb_regamma into tf_pts */
+ while (i <= hw_points_num) {
+ tf_pts->red[i] = regamma->r;
+ tf_pts->green[i] = regamma->g;
+ tf_pts->blue[i] = regamma->b;
+
+ ++regamma;
+ ++i;
+ }
+ }
+
+ build_new_custom_resulted_curve(hw_points_num, tf_pts);
+
+ return true;
+}
+
+#define _EXTRA_POINTS 3
+
+bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
+ const struct dc_gamma *ramp, bool mapUserRamp)
+{
+ struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
+ struct dividers dividers;
+
+ struct pwl_float_data *rgb_user = NULL;
+ struct pwl_float_data_ex *rgb_regamma = NULL;
+ struct gamma_pixel *axix_x = NULL;
+ struct pixel_gamma_point *coeff = NULL;
+ enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
+ bool ret = false;
+
+ if (output_tf->type == TF_TYPE_BYPASS)
+ return false;
+
+ /* we can use hardcoded curve for plain SRGB TF */
+ if (output_tf->type == TF_TYPE_PREDEFINED &&
+ output_tf->tf == TRANSFER_FUNCTION_SRGB &&
+ (!mapUserRamp && ramp->type == GAMMA_RGB_256))
+ return true;
+
+ output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
+
+ rgb_user = kzalloc(sizeof(*rgb_user) * (ramp->num_entries + _EXTRA_POINTS),
+ GFP_KERNEL);
+ if (!rgb_user)
+ goto rgb_user_alloc_fail;
+ rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS + _EXTRA_POINTS),
+ GFP_KERNEL);
+ if (!rgb_regamma)
+ goto rgb_regamma_alloc_fail;
+ axix_x = kzalloc(sizeof(*axix_x) * (ramp->num_entries + 3),
+ GFP_KERNEL);
+ if (!axix_x)
+ goto axix_x_alloc_fail;
+ coeff = kzalloc(sizeof(*coeff) * (MAX_HW_POINTS + _EXTRA_POINTS), GFP_KERNEL);
+ if (!coeff)
+ goto coeff_alloc_fail;
+
+ dividers.divider1 = dal_fixed31_32_from_fraction(3, 2);
+ dividers.divider2 = dal_fixed31_32_from_int(2);
+ dividers.divider3 = dal_fixed31_32_from_fraction(5, 2);
+
+ tf = output_tf->tf;
+
+ build_evenly_distributed_points(
+ axix_x,
+ ramp->num_entries,
+ dividers);
+
+ if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
+ scale_gamma(rgb_user, ramp, dividers);
+ else if (ramp->type == GAMMA_RGB_FLOAT_1024)
+ scale_gamma_dx(rgb_user, ramp, dividers);
+
+ if (tf == TRANSFER_FUNCTION_PQ) {
+ tf_pts->end_exponent = 7;
+ tf_pts->x_point_at_y1_red = 125;
+ tf_pts->x_point_at_y1_green = 125;
+ tf_pts->x_point_at_y1_blue = 125;
+
+ build_pq(rgb_regamma,
+ MAX_HW_POINTS,
+ coordinates_x,
+ output_tf->sdr_ref_white_level);
+ } else {
+ tf_pts->end_exponent = 0;
+ tf_pts->x_point_at_y1_red = 1;
+ tf_pts->x_point_at_y1_green = 1;
+ tf_pts->x_point_at_y1_blue = 1;
+
+ build_regamma(rgb_regamma,
+ MAX_HW_POINTS,
+ coordinates_x, tf == TRANSFER_FUNCTION_SRGB ? true:false);
+ }
+
+ map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
+ coordinates_x, axix_x, rgb_regamma,
+ MAX_HW_POINTS, tf_pts,
+ (mapUserRamp || ramp->type != GAMMA_RGB_256) &&
+ ramp->type != GAMMA_CS_TFM_1D);
+
+ if (ramp->type == GAMMA_CS_TFM_1D)
+ apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
+
+ ret = true;
+
+ kfree(coeff);
+coeff_alloc_fail:
+ kfree(axix_x);
+axix_x_alloc_fail:
+ kfree(rgb_regamma);
+rgb_regamma_alloc_fail:
+ kfree(rgb_user);
+rgb_user_alloc_fail:
+ return ret;
+}
+
+
+/*TODO fix me should be 2*/
+#define _EXTRA_POINTS 3
+
+bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
+ const struct dc_gamma *ramp, bool mapUserRamp)
+{
+ struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
+ struct dividers dividers;
+
+ struct pwl_float_data *rgb_user = NULL;
+ struct pwl_float_data_ex *curve = NULL;
+ struct gamma_pixel *axix_x = NULL;
+ struct pixel_gamma_point *coeff = NULL;
+ enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
+ bool ret = false;
+
+ if (input_tf->type == TF_TYPE_BYPASS)
+ return false;
+
+ /* we can use hardcoded curve for plain SRGB TF */
+ if (input_tf->type == TF_TYPE_PREDEFINED &&
+ input_tf->tf == TRANSFER_FUNCTION_SRGB &&
+ (!mapUserRamp && ramp->type == GAMMA_RGB_256))
+ return true;
+
+ input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
+
+ rgb_user = kzalloc(sizeof(*rgb_user) * (ramp->num_entries + _EXTRA_POINTS),
+ GFP_KERNEL);
+ if (!rgb_user)
+ goto rgb_user_alloc_fail;
+ curve = kzalloc(sizeof(*curve) * (MAX_HW_DEGAMMA_POINTS + _EXTRA_POINTS),
+ GFP_KERNEL);
+ if (!curve)
+ goto curve_alloc_fail;
+ axix_x = kzalloc(sizeof(*axix_x) * (ramp->num_entries + _EXTRA_POINTS),
+ GFP_KERNEL);
+ if (!axix_x)
+ goto axix_x_alloc_fail;
+ coeff = kzalloc(sizeof(*coeff) * (MAX_HW_DEGAMMA_POINTS + _EXTRA_POINTS), GFP_KERNEL);
+ if (!coeff)
+ goto coeff_alloc_fail;
+
+ dividers.divider1 = dal_fixed31_32_from_fraction(3, 2);
+ dividers.divider2 = dal_fixed31_32_from_int(2);
+ dividers.divider3 = dal_fixed31_32_from_fraction(5, 2);
+
+ tf = input_tf->tf;
+
+ build_evenly_distributed_points(
+ axix_x,
+ ramp->num_entries,
+ dividers);
+
+ if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
+ scale_gamma(rgb_user, ramp, dividers);
+ else if (ramp->type == GAMMA_RGB_FLOAT_1024)
+ scale_gamma_dx(rgb_user, ramp, dividers);
+
+ if (tf == TRANSFER_FUNCTION_PQ)
+ build_de_pq(curve,
+ MAX_HW_DEGAMMA_POINTS,
+ degamma_coordinates_x);
+ else
+ build_degamma(curve,
+ MAX_HW_DEGAMMA_POINTS,
+ degamma_coordinates_x,
+ tf == TRANSFER_FUNCTION_SRGB ? true:false);
+
+ tf_pts->end_exponent = 0;
+ tf_pts->x_point_at_y1_red = 1;
+ tf_pts->x_point_at_y1_green = 1;
+ tf_pts->x_point_at_y1_blue = 1;
+
+ map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
+ degamma_coordinates_x, axix_x, curve,
+ MAX_HW_DEGAMMA_POINTS, tf_pts,
+ mapUserRamp);
+
+ ret = true;
+
+ kfree(coeff);
+coeff_alloc_fail:
+ kfree(axix_x);
+axix_x_alloc_fail:
+ kfree(curve);
+curve_alloc_fail:
+ kfree(rgb_user);
+rgb_user_alloc_fail:
+
+ return ret;
+
+}
+
+
+bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
+ struct dc_transfer_func_distributed_points *points)
+{
+ uint32_t i;
+ bool ret = false;
+ struct pwl_float_data_ex *rgb_regamma = NULL;
+
+ if (trans == TRANSFER_FUNCTION_UNITY) {
+ points->end_exponent = 0;
+ points->x_point_at_y1_red = 1;
+ points->x_point_at_y1_green = 1;
+ points->x_point_at_y1_blue = 1;
+
+ for (i = 0; i < MAX_HW_POINTS ; i++) {
+ points->red[i] = coordinates_x[i].x;
+ points->green[i] = coordinates_x[i].x;
+ points->blue[i] = coordinates_x[i].x;
+ }
+ ret = true;
+ } else if (trans == TRANSFER_FUNCTION_PQ) {
+ rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS +
+ _EXTRA_POINTS), GFP_KERNEL);
+ if (!rgb_regamma)
+ goto rgb_regamma_alloc_fail;
+ points->end_exponent = 7;
+ points->x_point_at_y1_red = 125;
+ points->x_point_at_y1_green = 125;
+ points->x_point_at_y1_blue = 125;
+
+
+ build_pq(rgb_regamma,
+ MAX_HW_POINTS,
+ coordinates_x,
+ 80);
+ for (i = 0; i < MAX_HW_POINTS ; i++) {
+ points->red[i] = rgb_regamma[i].r;
+ points->green[i] = rgb_regamma[i].g;
+ points->blue[i] = rgb_regamma[i].b;
+ }
+ ret = true;
+
+ kfree(rgb_regamma);
+ } else if (trans == TRANSFER_FUNCTION_SRGB ||
+ trans == TRANSFER_FUNCTION_BT709) {
+ rgb_regamma = kzalloc(sizeof(*rgb_regamma) * (MAX_HW_POINTS +
+ _EXTRA_POINTS), GFP_KERNEL);
+ if (!rgb_regamma)
+ goto rgb_regamma_alloc_fail;
+ points->end_exponent = 0;
+ points->x_point_at_y1_red = 1;
+ points->x_point_at_y1_green = 1;
+ points->x_point_at_y1_blue = 1;
+
+ build_regamma(rgb_regamma,
+ MAX_HW_POINTS,
+ coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false);
+ for (i = 0; i < MAX_HW_POINTS ; i++) {
+ points->red[i] = rgb_regamma[i].r;
+ points->green[i] = rgb_regamma[i].g;
+ points->blue[i] = rgb_regamma[i].b;
+ }
+ ret = true;
+
+ kfree(rgb_regamma);
+ }
+rgb_regamma_alloc_fail:
+ return ret;
+}
+
+
+bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
+ struct dc_transfer_func_distributed_points *points)
+{
+ uint32_t i;
+ bool ret = false;
+ struct pwl_float_data_ex *rgb_degamma = NULL;
+
+ if (trans == TRANSFER_FUNCTION_UNITY) {
+
+ for (i = 0; i < MAX_HW_DEGAMMA_POINTS ; i++) {
+ points->red[i] = degamma_coordinates_x[i].x;
+ points->green[i] = degamma_coordinates_x[i].x;
+ points->blue[i] = degamma_coordinates_x[i].x;
+ }
+ ret = true;
+ } else if (trans == TRANSFER_FUNCTION_PQ) {
+ rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_DEGAMMA_POINTS +
+ _EXTRA_POINTS), GFP_KERNEL);
+ if (!rgb_degamma)
+ goto rgb_degamma_alloc_fail;
+
+
+ build_de_pq(rgb_degamma,
+ MAX_HW_DEGAMMA_POINTS,
+ degamma_coordinates_x);
+ for (i = 0; i < MAX_HW_DEGAMMA_POINTS ; i++) {
+ points->red[i] = rgb_degamma[i].r;
+ points->green[i] = rgb_degamma[i].g;
+ points->blue[i] = rgb_degamma[i].b;
+ }
+ ret = true;
+
+ kfree(rgb_degamma);
+ } else if (trans == TRANSFER_FUNCTION_SRGB ||
+ trans == TRANSFER_FUNCTION_BT709) {
+ rgb_degamma = kzalloc(sizeof(*rgb_degamma) * (MAX_HW_DEGAMMA_POINTS +
+ _EXTRA_POINTS), GFP_KERNEL);
+ if (!rgb_degamma)
+ goto rgb_degamma_alloc_fail;
+
+ build_degamma(rgb_degamma,
+ MAX_HW_DEGAMMA_POINTS,
+ degamma_coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false);
+ for (i = 0; i < MAX_HW_DEGAMMA_POINTS ; i++) {
+ points->red[i] = rgb_degamma[i].r;
+ points->green[i] = rgb_degamma[i].g;
+ points->blue[i] = rgb_degamma[i].b;
+ }
+ ret = true;
+
+ kfree(rgb_degamma);
+ }
+ points->end_exponent = 0;
+ points->x_point_at_y1_red = 1;
+ points->x_point_at_y1_green = 1;
+ points->x_point_at_y1_blue = 1;
+
+rgb_degamma_alloc_fail:
+ return ret;
+}
+
+
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
new file mode 100644
index 000000000000..b7f9bc27d101
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 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 COLOR_MOD_COLOR_GAMMA_H_
+#define COLOR_MOD_COLOR_GAMMA_H_
+
+struct dc_transfer_func;
+struct dc_gamma;
+struct dc_transfer_func_distributed_points;
+struct dc_rgb_fixed;
+enum dc_transfer_func_predefined;
+
+void setup_x_points_distribution(void);
+void precompute_pq(void);
+void precompute_de_pq(void);
+
+bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
+ const struct dc_gamma *ramp, bool mapUserRamp);
+
+bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf,
+ const struct dc_gamma *ramp, bool mapUserRamp);
+
+bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
+ struct dc_transfer_func_distributed_points *points);
+
+bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
+ struct dc_transfer_func_distributed_points *points);
+
+
+
+#endif /* COLOR_MOD_COLOR_GAMMA_H_ */