diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display')
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, ¶m); + 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(¶ms, 0, sizeof(params)); + resource_build_bit_depth_reduction_params(stream, ¶ms); + 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, ¶ms); +} + 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, ¶m); - - if (mi != NULL && mi->funcs->set_cursor_position != NULL) - mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); - - if (!hubp) - continue; - - if (hubp->funcs->set_cursor_position != NULL) - hubp->funcs->set_cursor_position(hubp, &pos_cpy, ¶m); - - if (dpp != NULL && dpp->funcs->set_cursor_position != NULL) - dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, 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, ®1); + 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, ¶ms); + + if (dc_is_dp_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); + + 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, ¶m); + if (mi->funcs->set_cursor_position) + mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); +} + +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, ¶m); + dpp->funcs->set_cursor_position(dpp, &pos_cpy, ¶m, 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_ */ |