diff options
author | Thomas Zimmermann <tzimmermann@suse.de> | 2022-06-20 18:21:25 +0200 |
---|---|---|
committer | Thomas Zimmermann <tzimmermann@suse.de> | 2022-06-20 18:21:25 +0200 |
commit | 2b1333b80885b896807ffb6ccf4bc21d29aa65e0 (patch) | |
tree | 51cc2d13d65603383db82c87f01a0aa93bd26010 /drivers/gpu/drm/amd/display | |
parent | cad564ca557f8d3bb3b1fa965d9a2b3f6490ec69 (diff) | |
parent | 0f95ee9a0c579ebed0309657f6918673927189f2 (diff) | |
download | linux-2b1333b80885b896807ffb6ccf4bc21d29aa65e0.tar.bz2 |
Merge drm/drm-next into drm-misc-next
Backmerging to get new regmap APIs of v5.19-rc1.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Diffstat (limited to 'drivers/gpu/drm/amd/display')
85 files changed, 1364 insertions, 1160 deletions
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 4515630fb9d2..eb6c55e9f6b5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -85,7 +85,6 @@ #include <drm/drm_audio_component.h> #include <drm/drm_gem_atomic_helper.h> -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" #include "dcn/dcn_1_0_offset.h" @@ -94,7 +93,6 @@ #include "vega10_ip_offset.h" #include "soc15_common.h" -#endif #include "modules/inc/mod_freesync.h" #include "modules/power/power_helpers.h" @@ -605,7 +603,6 @@ static void dm_crtc_high_irq(void *interrupt_params) spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); } -#if defined(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) /** * dm_dcn_vertical_interrupt0_high_irq() - Handles OTG Vertical interrupt0 for @@ -773,7 +770,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) do { dc_stat_get_dmub_notification(adev->dm.dc, ¬ify); - if (notify.type > ARRAY_SIZE(dm->dmub_thread_offload)) { + if (notify.type >= ARRAY_SIZE(dm->dmub_thread_offload)) { DRM_ERROR("DM: notify type %d invalid!", notify.type); continue; } @@ -829,7 +826,6 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) if (count > DMUB_TRACE_MAX_READ) DRM_DEBUG_DRIVER("Warning : count > DMUB_TRACE_MAX_READ"); } -#endif /* CONFIG_DRM_AMD_DC_DCN */ static int dm_set_clockgating_state(void *handle, enum amd_clockgating_state state) @@ -1127,9 +1123,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) switch (adev->ip_versions[DCE_HWIP][0]) { case IP_VERSION(3, 1, 3): /* Only for this asic hw internal rev B0 */ hw_params.dpia_supported = true; -#if defined(CONFIG_DRM_AMD_DC_DCN) hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia; -#endif break; default: break; @@ -1191,7 +1185,6 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev) } } -#if defined(CONFIG_DRM_AMD_DC_DCN) static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) { uint64_t pt_base; @@ -1246,8 +1239,7 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ pa_config->is_hvm_enabled = 0; } -#endif -#if defined(CONFIG_DRM_AMD_DC_DCN) + static void vblank_control_worker(struct work_struct *work) { struct vblank_control_work *vblank_work = @@ -1284,8 +1276,6 @@ static void vblank_control_worker(struct work_struct *work) kfree(vblank_work); } -#endif - static void dm_handle_hpd_rx_offload_work(struct work_struct *work) { struct hpd_rx_irq_offload_work *offload_work; @@ -1412,9 +1402,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) mutex_init(&adev->dm.dc_lock); mutex_init(&adev->dm.audio_lock); -#if defined(CONFIG_DRM_AMD_DC_DCN) spin_lock_init(&adev->dm.vblank_lock); -#endif if(amdgpu_dm_irq_init(adev)) { DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n"); @@ -1507,12 +1495,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_dc_feature_mask & DC_EDP_NO_POWER_SEQUENCING) init_data.flags.edp_no_power_sequencing = true; -#ifdef CONFIG_DRM_AMD_DC_DCN if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP1_4A) init_data.flags.allow_lttpr_non_transparent_mode.bits.DP1_4A = true; if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP2_0) init_data.flags.allow_lttpr_non_transparent_mode.bits.DP2_0 = true; -#endif init_data.flags.seamless_boot_edp_requested = false; @@ -1568,7 +1554,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) goto error; } -#if defined(CONFIG_DRM_AMD_DC_DCN) if ((adev->flags & AMD_IS_APU) && (adev->asic_type >= CHIP_CARRIZO)) { struct dc_phy_addr_space_config pa_config; @@ -1577,7 +1562,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) // Call the DC init_memory func dc_setup_system_context(adev->dm.dc, &pa_config); } -#endif adev->dm.freesync_module = mod_freesync_create(adev->dm.dc); if (!adev->dm.freesync_module) { @@ -1589,14 +1573,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) amdgpu_dm_init_color_mod(); -#if defined(CONFIG_DRM_AMD_DC_DCN) if (adev->dm.dc->caps.max_links > 0) { adev->dm.vblank_control_workqueue = create_singlethread_workqueue("dm_vblank_control_workqueue"); if (!adev->dm.vblank_control_workqueue) DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n"); } -#endif #ifdef CONFIG_DRM_AMD_DC_HDCP if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) { @@ -1628,7 +1610,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) } amdgpu_dm_outbox_init(adev); -#if defined(CONFIG_DRM_AMD_DC_DCN) if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_AUX_REPLY, dmub_aux_setconfig_callback, false)) { DRM_ERROR("amdgpu: fail to register dmub aux callback"); @@ -1642,7 +1623,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) DRM_ERROR("amdgpu: fail to register dmub hpd callback"); goto error; } -#endif /* CONFIG_DRM_AMD_DC_DCN */ } if (amdgpu_dm_initialize_drm_device(adev)) { @@ -1689,12 +1669,10 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) { int i; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (adev->dm.vblank_control_workqueue) { destroy_workqueue(adev->dm.vblank_control_workqueue); adev->dm.vblank_control_workqueue = NULL; } -#endif for (i = 0; i < adev->dm.display_indexes_num; i++) { drm_encoder_cleanup(&adev->dm.mst_encoders[i].base); @@ -2405,9 +2383,7 @@ static int dm_suspend(void *handle) if (amdgpu_in_reset(adev)) { mutex_lock(&dm->dc_lock); -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_allow_idle_optimizations(adev->dm.dc, false); -#endif dm->cached_dc_state = dc_copy_state(dm->dc->current_state); @@ -3560,7 +3536,6 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) return 0; } -#if defined(CONFIG_DRM_AMD_DC_DCN) /* Register IRQ sources and initialize IRQ callbacks */ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) { @@ -3749,7 +3724,6 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev) return 0; } -#endif /* * Acquires the lock for the atomic state object and returns @@ -4253,7 +4227,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail; } -#if defined(CONFIG_DRM_AMD_DC_DCN) /* Use Outbox interrupt */ switch (adev->ip_versions[DCE_HWIP][0]) { case IP_VERSION(3, 0, 0): @@ -4286,7 +4259,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) break; } } -#endif /* Disable vblank IRQs aggressively for power-saving. */ adev_to_drm(adev)->vblank_disable_immediate = true; @@ -4382,7 +4354,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) } break; default: -#if defined(CONFIG_DRM_AMD_DC_DCN) switch (adev->ip_versions[DCE_HWIP][0]) { case IP_VERSION(1, 0, 0): case IP_VERSION(1, 0, 1): @@ -4408,7 +4379,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) adev->ip_versions[DCE_HWIP][0]); goto fail; } -#endif break; } @@ -4557,7 +4527,7 @@ static int dm_early_init(void *handle) adev->mode_info.num_dig = 6; break; default: -#if defined(CONFIG_DRM_AMD_DC_DCN) + switch (adev->ip_versions[DCE_HWIP][0]) { case IP_VERSION(2, 0, 2): case IP_VERSION(3, 0, 0): @@ -4594,7 +4564,6 @@ static int dm_early_init(void *handle) adev->ip_versions[DCE_HWIP][0]); return -EINVAL; } -#endif break; } @@ -5413,17 +5382,19 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, static void fill_blending_from_plane_state(const struct drm_plane_state *plane_state, - bool *per_pixel_alpha, bool *global_alpha, - int *global_alpha_value) + bool *per_pixel_alpha, bool *pre_multiplied_alpha, + bool *global_alpha, int *global_alpha_value) { *per_pixel_alpha = false; + *pre_multiplied_alpha = true; *global_alpha = false; *global_alpha_value = 0xff; if (plane_state->plane->type != DRM_PLANE_TYPE_OVERLAY) return; - if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) { + if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI || + plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) { static const uint32_t alpha_formats[] = { DRM_FORMAT_ARGB8888, DRM_FORMAT_RGBA8888, @@ -5438,6 +5409,9 @@ fill_blending_from_plane_state(const struct drm_plane_state *plane_state, break; } } + + if (per_pixel_alpha && plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) + *pre_multiplied_alpha = false; } if (plane_state->alpha < 0xffff) { @@ -5600,7 +5574,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, return ret; fill_blending_from_plane_state( - plane_state, &plane_info->per_pixel_alpha, + plane_state, &plane_info->per_pixel_alpha, &plane_info->pre_multiplied_alpha, &plane_info->global_alpha, &plane_info->global_alpha_value); return 0; @@ -5647,6 +5621,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, dc_plane_state->tiling_info = plane_info.tiling_info; dc_plane_state->visible = plane_info.visible; dc_plane_state->per_pixel_alpha = plane_info.per_pixel_alpha; + dc_plane_state->pre_multiplied_alpha = plane_info.pre_multiplied_alpha; dc_plane_state->global_alpha = plane_info.global_alpha; dc_plane_state->global_alpha_value = plane_info.global_alpha_value; dc_plane_state->dcc = plane_info.dcc; @@ -6648,10 +6623,8 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_device *adev = drm_to_adev(crtc->dev); struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); -#if defined(CONFIG_DRM_AMD_DC_DCN) struct amdgpu_display_manager *dm = &adev->dm; struct vblank_control_work *work; -#endif int rc = 0; if (enable) { @@ -6674,7 +6647,6 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) if (amdgpu_in_reset(adev)) return 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dm->vblank_control_workqueue) { work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) @@ -6692,7 +6664,6 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) queue_work(dm->vblank_control_workqueue, &work->work); } -#endif return 0; } @@ -7951,7 +7922,8 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, if (plane->type == DRM_PLANE_TYPE_OVERLAY && plane_cap && plane_cap->per_pixel_alpha) { unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | - BIT(DRM_MODE_BLEND_PREMULTI); + BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE); drm_plane_create_alpha_property(plane); drm_plane_create_blend_mode_property(plane, blend_caps); @@ -9361,14 +9333,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, /* Update the planes if changed or disable if we don't have any. */ if ((planes_count || acrtc_state->active_planes == 0) && acrtc_state->stream) { -#if defined(CONFIG_DRM_AMD_DC_DCN) /* * If PSR or idle optimizations are enabled then flush out * any pending work before hardware programming. */ if (dm->vblank_control_workqueue) flush_workqueue(dm->vblank_control_workqueue); -#endif bundle->stream_update.stream = acrtc_state->stream; if (new_pcrtc_state->mode_changed) { @@ -9706,21 +9676,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) if (dc_state) { /* if there mode set or reset, disable eDP PSR */ if (mode_set_reset_required) { -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dm->vblank_control_workqueue) flush_workqueue(dm->vblank_control_workqueue); -#endif + amdgpu_dm_psr_disable_all(dm); } dm_enable_per_frame_crtc_master_sync(dc_state); mutex_lock(&dm->dc_lock); WARN_ON(!dc_commit_state(dm->dc, dc_state)); -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* Allow idle optimization when vblank count is 0 for display off */ - if (dm->active_vblank_irq_count == 0) - dc_allow_idle_optimizations(dm->dc,true); -#endif + + /* Allow idle optimization when vblank count is 0 for display off */ + if (dm->active_vblank_irq_count == 0) + dc_allow_idle_optimizations(dm->dc, true); mutex_unlock(&dm->dc_lock); } 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 62dc5e30d73d..aa34c0068f41 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -358,14 +358,12 @@ struct amdgpu_display_manager { */ struct mutex audio_lock; -#if defined(CONFIG_DRM_AMD_DC_DCN) /** * @vblank_lock: * * Guards access to deferred vblank work state. */ spinlock_t vblank_lock; -#endif /** * @audio_component: @@ -469,14 +467,12 @@ struct amdgpu_display_manager { struct hdcp_workqueue *hdcp_workqueue; #endif -#if defined(CONFIG_DRM_AMD_DC_DCN) /** * @vblank_control_workqueue: * * Deferred work for vblank control events. */ struct workqueue_struct *vblank_control_workqueue; -#endif struct drm_atomic_state *cached_state; struct dc_state *cached_dc_state; @@ -493,14 +489,12 @@ struct amdgpu_display_manager { */ const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; -#if defined(CONFIG_DRM_AMD_DC_DCN) /** * @active_vblank_irq_count: * * number of currently active vblank irqs */ uint32_t active_vblank_irq_count; -#endif #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) /** diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 78f3974ef7b8..2a78ae007521 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -291,9 +291,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, case LINK_RATE_RBR2: case LINK_RATE_HIGH2: case LINK_RATE_HIGH3: -#if defined(CONFIG_DRM_AMD_DC_DCN) case LINK_RATE_UHBR10: -#endif break; default: valid_input = false; @@ -3399,7 +3397,6 @@ static int disable_hpd_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(disable_hpd_ops, disable_hpd_get, disable_hpd_set, "%llu\n"); -#if defined(CONFIG_DRM_AMD_DC_DCN) /* * Temporary w/a to force sst sequence in M42D DP2 mst receiver * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_set_mst_en_for_sst @@ -3447,7 +3444,6 @@ static int dp_ignore_cable_id_get(void *data, u64 *val) } DEFINE_DEBUGFS_ATTRIBUTE(dp_ignore_cable_id_ops, dp_ignore_cable_id_get, dp_ignore_cable_id_set, "%llu\n"); -#endif /* * Sets the DC visual confirm debug option from the given string. @@ -3596,12 +3592,10 @@ void dtn_debugfs_init(struct amdgpu_device *adev) adev, &mst_topo_fops); debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev, &dtn_log_fops); -#if defined(CONFIG_DRM_AMD_DC_DCN) debugfs_create_file("amdgpu_dm_dp_set_mst_en_for_sst", 0644, root, adev, &dp_set_mst_en_for_sst_ops); debugfs_create_file("amdgpu_dm_dp_ignore_cable_id", 0644, root, adev, &dp_ignore_cable_id_ops); -#endif debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev, &visual_confirm_fops); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 28cf24f6ab32..7c799ddc1d27 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -977,9 +977,7 @@ void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz) // TODO } -#if defined(CONFIG_DRM_AMD_DC_DCN) void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable) { /* TODO: add periodic detection implementation */ } -#endif 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 4aba0e8c84f8..19f543ba7205 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 @@ -928,7 +928,11 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) to_amdgpu_dm_connector(connector); const struct dc_link *dc_link = amdgpu_dm_connector->dc_link; - dc_interrupt_set(adev->dm.dc, dc_link->irq_source_hpd, false); + if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd) { + dc_interrupt_set(adev->dm.dc, + dc_link->irq_source_hpd, + false); + } if (DC_IRQ_SOURCE_INVALID != dc_link->irq_source_hpd_rx) { dc_interrupt_set(adev->dm.dc, 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 43efd915ee6f..9221b6690a4a 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 @@ -45,12 +45,10 @@ #include "amdgpu_dm_debugfs.h" #endif -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "dc/dcn20/dcn20_resource.h" bool is_timing_changed(struct dc_stream_state *cur_stream, struct dc_stream_state *new_stream); -#endif static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index c561e0d872d6..85628ad59e6c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -46,8 +46,6 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, void dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev); -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dsc_mst_fairness_vars { int pbn; bool dsc_enabled; @@ -64,6 +62,5 @@ bool needs_dsc_aux_workaround(struct dc_link *link); void pre_validate_dsc(struct drm_atomic_state *state, struct dm_atomic_state **dm_state_ptr, struct dsc_mst_fairness_vars *vars); -#endif #endif diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index 13b1751e69bf..141fd2721501 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -29,7 +29,6 @@ #include "amdgpu_dm.h" #include "modules/power/power_helpers.h" -#ifdef CONFIG_DRM_AMD_DC_DCN static bool link_supports_psrsu(struct dc_link *link) { struct dc *dc = link->ctx->dc; @@ -53,7 +52,6 @@ static bool link_supports_psrsu(struct dc_link *link) return true; } -#endif /* * amdgpu_dm_set_psr_caps() - set link psr capabilities @@ -73,11 +71,9 @@ void amdgpu_dm_set_psr_caps(struct dc_link *link) link->psr_settings.psr_feature_enabled = false; } else { -#ifdef CONFIG_DRM_AMD_DC_DCN if (link_supports_psrsu(link)) link->psr_settings.psr_version = DC_PSR_VERSION_SU_1; else -#endif link->psr_settings.psr_version = DC_PSR_VERSION_1; link->psr_settings.psr_feature_enabled = true; diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index f05ab2bf20c5..b4eca0236435 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -63,9 +63,7 @@ DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink dc_surface.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \ dc_link_enc_cfg.o dc_link_dpia.o dc_link_dpcd.o -ifdef CONFIG_DRM_AMD_DC_DCN DISPLAY_CORE += dc_vm_helper.o -endif AMD_DISPLAY_CORE = $(addprefix $(AMDDALPATH)/dc/core/,$(DISPLAY_CORE)) diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index dd9704ef4ccc..f3792286f571 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c @@ -65,7 +65,6 @@ bool dal_bios_parser_init_cmd_tbl_helper2( case DCE_VERSION_12_1: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; -#if defined(CONFIG_DRM_AMD_DC_DCN) case DCN_VERSION_1_0: case DCN_VERSION_1_01: case DCN_VERSION_2_0: @@ -80,7 +79,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2( case DCN_VERSION_3_16: *h = dal_cmd_tbl_helper_dce112_get_table2(); return true; -#endif + default: /* Unsupported DCE */ BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index 02943ca65807..cf1b5f354ae9 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -122,7 +122,7 @@ static void rn_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, dpp_inst = clk_mgr->base.ctx->dc->res_pool->dpps[i]->inst; dppclk_khz = context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz; - prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[i]; + prev_dppclk_khz = clk_mgr->dccg->pipe_dppclk_khz[dpp_inst]; if (safe_to_lower || prev_dppclk_khz < dppclk_khz) clk_mgr->dccg->funcs->update_dpp_dto( diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c index d9920d91838d..1cae01a91a69 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c @@ -94,6 +94,8 @@ static int dcn301_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, { uint32_t result; + result = dcn301_smu_wait_for_response(clk_mgr, 10, 200000); + /* First clear response register */ REG_WRITE(MP1_SMN_C2PMSG_91, VBIOSSMC_Status_BUSY); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index 969b40250434..bca5f01da763 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -287,8 +287,11 @@ static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base) void dcn31_init_clocks(struct clk_mgr *clk_mgr) { + uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz; + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); // Assumption is that boot state always supports pstate + clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk clk_mgr->clks.p_state_change_support = true; clk_mgr->clks.prev_p_state_change_support = true; clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; @@ -615,7 +618,7 @@ static void dcn31_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk } } -void dcn31_set_low_power_state(struct clk_mgr *clk_mgr_base) +static void dcn31_set_low_power_state(struct clk_mgr *clk_mgr_base) { int display_count; struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); @@ -638,8 +641,14 @@ void dcn31_set_low_power_state(struct clk_mgr *clk_mgr_base) } } +int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base) +{ + return clk_mgr_base->clks.ref_dtbclk_khz; +} + static struct clk_mgr_funcs dcn31_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, .update_clocks = dcn31_update_clocks, .init_clocks = dcn31_init_clocks, .enable_pme_wa = dcn31_enable_pme_wa, @@ -719,7 +728,7 @@ void dcn31_clk_mgr_construct( } clk_mgr->base.base.dprefclk_khz = 600000; - clk_mgr->base.dccg->ref_dtbclk_khz = 600000; + clk_mgr->base.base.clks.ref_dtbclk_khz = 600000; dce_clock_read_ss_info(&clk_mgr->base); /*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/ //clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(clk_mgr_internal, clk_mgr->base.base.dprefclk_khz); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h index 961b10a49486..be06fdbd0c22 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h @@ -51,6 +51,8 @@ void dcn31_clk_mgr_construct(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg); +int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base); + void dcn31_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int); #endif //__DCN31_CLK_MGR_H__ diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index 8be4c1970628..fb4ae800e919 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -41,9 +41,7 @@ #include "dc_dmub_srv.h" -#if defined (CONFIG_DRM_AMD_DC_DP2_0) #include "dc_link_dp.h" -#endif #define TO_CLK_MGR_DCN315(clk_mgr)\ container_of(clk_mgr, struct clk_mgr_dcn315, base) @@ -91,7 +89,8 @@ static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) if (pipe->top_pipe || pipe->prev_odm_pipe) continue; - if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) { + if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL || + dc_is_virtual_signal(pipe->stream->signal))) { if (disable) pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); else @@ -219,8 +218,50 @@ static void dcn315_dump_clk_registers(struct clk_state_registers_and_bypass *reg static struct clk_bw_params dcn315_bw_params = { .vram_type = Ddr4MemType, - .num_channels = 1, + .num_channels = 2, .clk_table = { + .entries = { + { + .voltage = 0, + .dispclk_mhz = 640, + .dppclk_mhz = 640, + .phyclk_mhz = 810, + .phyclk_d18_mhz = 667, + .dtbclk_mhz = 600, + }, + { + .voltage = 1, + .dispclk_mhz = 739, + .dppclk_mhz = 739, + .phyclk_mhz = 810, + .phyclk_d18_mhz = 667, + .dtbclk_mhz = 600, + }, + { + .voltage = 2, + .dispclk_mhz = 960, + .dppclk_mhz = 960, + .phyclk_mhz = 810, + .phyclk_d18_mhz = 667, + .dtbclk_mhz = 600, + }, + { + .voltage = 3, + .dispclk_mhz = 1200, + .dppclk_mhz = 1200, + .phyclk_mhz = 810, + .phyclk_d18_mhz = 667, + .dtbclk_mhz = 600, + }, + { + .voltage = 4, + .dispclk_mhz = 1372, + .dppclk_mhz = 1372, + .phyclk_mhz = 810, + .phyclk_d18_mhz = 667, + .dtbclk_mhz = 600, + }, + }, .num_entries = 5, }, @@ -300,8 +341,8 @@ static struct wm_table lpddr5_wm_table = { } }; -static DpmClocks_315_t dummy_clocks; - +/* Temporary Place holder until we can get them from fuse */ +static DpmClocks_315_t dummy_clocks = { 0 }; static struct dcn315_watermarks dummy_wms = { 0 }; static void dcn315_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn315_watermarks *table) @@ -415,22 +456,6 @@ static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks) return max; } -static unsigned int find_clk_for_voltage( - const DpmClocks_315_t *clock_table, - const uint32_t clocks[], - unsigned int voltage) -{ - int i; - - for (i = 0; i < NUM_SOC_VOLTAGE_LEVELS; i++) { - if (clock_table->SocVoltage[i] == voltage) - return clocks[i]; - } - - ASSERT(0); - return 0; -} - static void dcn315_clk_mgr_helper_populate_bw_params( struct clk_mgr_internal *clk_mgr, struct integrated_info *bios_info, @@ -438,13 +463,9 @@ static void dcn315_clk_mgr_helper_populate_bw_params( { int i; struct clk_bw_params *bw_params = clk_mgr->base.bw_params; - uint32_t max_dispclk, max_dppclk, max_pstate, max_socclk, max_fclk = 0, min_pstate = 0; + uint32_t max_pstate = 0, max_fclk = 0, min_pstate = 0; struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1]; - max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled); - max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled); - max_socclk = find_max_clk_value(clock_table->SocClocks, clock_table->NumSocClkLevelsEnabled); - /* Find highest fclk pstate */ for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) { if (clock_table->DfPstateTable[i].FClk > max_fclk) { @@ -466,35 +487,44 @@ static void dcn315_clk_mgr_helper_populate_bw_params( } } + /* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */ + for (j = bw_params->clk_table.num_entries - 1; j > 0; j--) + if (bw_params->clk_table.entries[j].dcfclk_mhz <= clock_table->DcfClocks[i]) + break; + bw_params->clk_table.entries[i].phyclk_mhz = bw_params->clk_table.entries[j].phyclk_mhz; + bw_params->clk_table.entries[i].phyclk_d18_mhz = bw_params->clk_table.entries[j].phyclk_d18_mhz; + bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz; + + /* Now update clocks we do read */ bw_params->clk_table.entries[i].fclk_mhz = min_fclk; bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk; bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage; bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i]; bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i]; - bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; - bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; + bw_params->clk_table.entries[i].dispclk_mhz = clock_table->DispClocks[i]; + bw_params->clk_table.entries[i].dppclk_mhz = clock_table->DppClocks[i]; bw_params->clk_table.entries[i].wck_ratio = 1; }; /* Make sure to include at least one entry and highest pstate */ - if (max_pstate != min_pstate) { + if (max_pstate != min_pstate || i == 0) { bw_params->clk_table.entries[i].fclk_mhz = max_fclk; bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_pstate].MemClk; bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_pstate].Voltage; - bw_params->clk_table.entries[i].dcfclk_mhz = find_clk_for_voltage( - clock_table, clock_table->DcfClocks, clock_table->DfPstateTable[max_pstate].Voltage); - bw_params->clk_table.entries[i].socclk_mhz = find_clk_for_voltage( - clock_table, clock_table->SocClocks, clock_table->DfPstateTable[max_pstate].Voltage); - bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; - bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; + bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, NUM_DCFCLK_DPM_LEVELS); bw_params->clk_table.entries[i].wck_ratio = 1; i++; } - bw_params->clk_table.num_entries = i; + bw_params->clk_table.num_entries = i--; - /* Include highest socclk */ - if (bw_params->clk_table.entries[i-1].socclk_mhz < max_socclk) - bw_params->clk_table.entries[i-1].socclk_mhz = max_socclk; + /* Make sure all highest clocks are included*/ + bw_params->clk_table.entries[i].socclk_mhz = find_max_clk_value(clock_table->SocClocks, NUM_SOCCLK_DPM_LEVELS); + bw_params->clk_table.entries[i].dispclk_mhz = find_max_clk_value(clock_table->DispClocks, NUM_DISPCLK_DPM_LEVELS); + bw_params->clk_table.entries[i].dppclk_mhz = find_max_clk_value(clock_table->DppClocks, NUM_DPPCLK_DPM_LEVELS); + ASSERT(clock_table->DcfClocks[i] == find_max_clk_value(clock_table->DcfClocks, NUM_DCFCLK_DPM_LEVELS)); + bw_params->clk_table.entries[i].phyclk_mhz = def_max.phyclk_mhz; + bw_params->clk_table.entries[i].phyclk_d18_mhz = def_max.phyclk_d18_mhz; + bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz; /* Set any 0 clocks to max default setting. Not an issue for * power since we aren't doing switching in such case anyway @@ -513,9 +543,18 @@ static void dcn315_clk_mgr_helper_populate_bw_params( bw_params->clk_table.entries[i].dispclk_mhz = def_max.dispclk_mhz; if (!bw_params->clk_table.entries[i].dppclk_mhz) bw_params->clk_table.entries[i].dppclk_mhz = def_max.dppclk_mhz; + if (!bw_params->clk_table.entries[i].phyclk_mhz) + bw_params->clk_table.entries[i].phyclk_mhz = def_max.phyclk_mhz; + if (!bw_params->clk_table.entries[i].phyclk_d18_mhz) + bw_params->clk_table.entries[i].phyclk_d18_mhz = def_max.phyclk_d18_mhz; + if (!bw_params->clk_table.entries[i].dtbclk_mhz) + bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz; } + ASSERT(bw_params->clk_table.entries[i].dcfclk_mhz); bw_params->vram_type = bios_info->memory_type; bw_params->num_channels = bios_info->ma_channel_number; + if (!bw_params->num_channels) + bw_params->num_channels = 2; for (i = 0; i < WM_SET_COUNT; i++) { bw_params->wm_table.entries[i].wm_inst = i; @@ -539,6 +578,7 @@ static void dcn315_enable_pme_wa(struct clk_mgr *clk_mgr_base) static struct clk_mgr_funcs dcn315_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, .update_clocks = dcn315_update_clocks, .init_clocks = dcn31_init_clocks, .enable_pme_wa = dcn315_enable_pme_wa, @@ -615,9 +655,9 @@ void dcn315_clk_mgr_construct( clk_mgr->base.base.dprefclk_khz = 600000; clk_mgr->base.base.dprefclk_khz = dcn315_smu_get_dpref_clk(&clk_mgr->base); - clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; + clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; dce_clock_read_ss_info(&clk_mgr->base); - clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz); + clk_mgr->base.base.clks.ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz); clk_mgr->base.base.bw_params = &dcn315_bw_params; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c index 3121dd2d2a91..e4bb9c6193b5 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c @@ -122,7 +122,8 @@ static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) if (pipe->top_pipe || pipe->prev_odm_pipe) continue; - if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) { + if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL || + dc_is_virtual_signal(pipe->stream->signal))) { if (disable) pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); else @@ -570,6 +571,7 @@ static void dcn316_clk_mgr_helper_populate_bw_params( static struct clk_mgr_funcs dcn316_funcs = { .enable_pme_wa = dcn316_enable_pme_wa, .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, .update_clocks = dcn316_update_clocks, .init_clocks = dcn31_init_clocks, .are_clock_states_equal = dcn31_are_clock_states_equal, @@ -684,7 +686,7 @@ void dcn316_clk_mgr_construct( clk_mgr->base.base.dprefclk_khz = 600000; clk_mgr->base.base.dprefclk_khz = dcn316_smu_get_dpref_clk(&clk_mgr->base); - clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; + clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; dce_clock_read_ss_info(&clk_mgr->base); /*clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);*/ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c2fcd67bcc4d..f14449401188 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -829,14 +829,12 @@ static void dc_destruct(struct dc *dc) kfree(dc->bw_dceip); dc->bw_dceip = NULL; -#ifdef CONFIG_DRM_AMD_DC_DCN kfree(dc->dcn_soc); dc->dcn_soc = NULL; kfree(dc->dcn_ip); dc->dcn_ip = NULL; -#endif kfree(dc->vm_helper); dc->vm_helper = NULL; @@ -882,10 +880,8 @@ static bool dc_construct(struct dc *dc, struct dc_context *dc_ctx; struct bw_calcs_dceip *dc_dceip; struct bw_calcs_vbios *dc_vbios; -#ifdef CONFIG_DRM_AMD_DC_DCN struct dcn_soc_bounding_box *dcn_soc; struct dcn_ip_params *dcn_ip; -#endif dc->config = init_params->flags; @@ -913,7 +909,6 @@ static bool dc_construct(struct dc *dc, } dc->bw_vbios = dc_vbios; -#ifdef CONFIG_DRM_AMD_DC_DCN dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL); if (!dcn_soc) { dm_error("%s: failed to create dcn_soc\n", __func__); @@ -929,7 +924,6 @@ static bool dc_construct(struct dc *dc, } dc->dcn_ip = dcn_ip; -#endif if (!dc_construct_ctx(dc, init_params)) { dm_error("%s: failed to create ctx\n", __func__); @@ -1680,7 +1674,6 @@ static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context) return stream_mask; } -#if defined(CONFIG_DRM_AMD_DC_DCN) void dc_z10_restore(const struct dc *dc) { if (dc->hwss.z10_restore) @@ -1692,7 +1685,7 @@ void dc_z10_save_init(struct dc *dc) if (dc->hwss.z10_save_init) dc->hwss.z10_save_init(dc); } -#endif + /* * Applies given context to HW and copy it into current context. * It's up to the user to release the src context afterwards. @@ -1706,10 +1699,8 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c struct dc_stream_state *dc_streams[MAX_STREAMS] = {0}; struct dc_state *old_state; -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_restore(dc); dc_allow_idle_optimizations(dc, false); -#endif for (i = 0; i < context->stream_count; i++) dc_streams[i] = context->streams[i]; @@ -1868,7 +1859,6 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) return (result == DC_OK); } -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dc_acquire_release_mpc_3dlut( struct dc *dc, bool acquire, struct dc_stream_state *stream, @@ -1904,7 +1894,7 @@ bool dc_acquire_release_mpc_3dlut( } return ret; } -#endif + static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) { int i; @@ -1925,7 +1915,6 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) return false; } -#ifdef CONFIG_DRM_AMD_DC_DCN /* Perform updates here which need to be deferred until next vupdate * * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered @@ -1944,7 +1933,6 @@ static void process_deferred_updates(struct dc *dc) dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]); } } -#endif /* CONFIG_DRM_AMD_DC_DCN */ void dc_post_update_surfaces_to_stream(struct dc *dc) { @@ -1971,9 +1959,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]); } -#ifdef CONFIG_DRM_AMD_DC_DCN process_deferred_updates(dc); -#endif dc->hwss.optimize_bandwidth(dc, context); @@ -1987,9 +1973,7 @@ static void init_state(struct dc *dc, struct dc_state *context) * initialize and obtain IP and SOC the base DML instance from DC is * initially copied into every context */ -#ifdef CONFIG_DRM_AMD_DC_DCN memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); -#endif } struct dc_state *dc_create_state(struct dc *dc) @@ -2361,11 +2345,9 @@ static enum surface_update_type check_update_surfaces_for_stream( int i; enum surface_update_type overall_type = UPDATE_TYPE_FAST; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dc->idle_optimizations_allowed) overall_type = UPDATE_TYPE_FULL; -#endif if (stream_status == NULL || stream_status->plane_count != surface_count) overall_type = UPDATE_TYPE_FULL; @@ -2854,9 +2836,7 @@ static void commit_planes_for_stream(struct dc *dc, struct pipe_ctx *top_pipe_to_program = NULL; bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_restore(dc); -#endif if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { /* Optimize seamless boot flag keeps clocks and watermarks high until @@ -2874,10 +2854,8 @@ static void commit_planes_for_stream(struct dc *dc, } if (update_type == UPDATE_TYPE_FULL) { -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_allow_idle_optimizations(dc, false); -#endif if (get_seamless_boot_stream_count(context) == 0) dc->hwss.prepare_bandwidth(dc, context); @@ -2895,7 +2873,6 @@ static void commit_planes_for_stream(struct dc *dc, } } -#ifdef CONFIG_DRM_AMD_DC_DCN if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) { struct pipe_ctx *mpcc_pipe; struct pipe_ctx *odm_pipe; @@ -2904,7 +2881,6 @@ static void commit_planes_for_stream(struct dc *dc, for (odm_pipe = mpcc_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; } -#endif if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) if (top_pipe_to_program && @@ -2925,14 +2901,15 @@ static void commit_planes_for_stream(struct dc *dc, top_pipe_to_program->stream_res.tg); } - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) + if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { dc->hwss.interdependent_update_lock(dc, context, true); - else + } else { /* 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 */ dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); + } // Stream updates if (stream_update) @@ -2948,10 +2925,11 @@ static void commit_planes_for_stream(struct dc *dc, if (dc->hwss.program_front_end_for_ctx) dc->hwss.program_front_end_for_ctx(dc, context); - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) + if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { dc->hwss.interdependent_update_lock(dc, context, false); - else + } else { dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); + } dc->hwss.post_unlock_program_front_end(dc, context); return; } @@ -3014,7 +2992,6 @@ static void commit_planes_for_stream(struct dc *dc, } if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) { dc->hwss.program_front_end_for_ctx(dc, context); -#ifdef CONFIG_DRM_AMD_DC_DCN if (dc->debug.validate_dml_output) { for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i]; @@ -3028,7 +3005,6 @@ static void commit_planes_for_stream(struct dc *dc, &context->res_ctx.pipe_ctx[i].ttu_regs); } } -#endif } // Update Type FAST, Surface updates @@ -3078,10 +3054,11 @@ static void commit_planes_for_stream(struct dc *dc, } - if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) + if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { dc->hwss.interdependent_update_lock(dc, context, false); - else + } else { dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); + } if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { @@ -3319,9 +3296,8 @@ void dc_set_power_state( case DC_ACPI_CM_POWER_STATE_D0: dc_resource_state_construct(dc, dc->current_state); -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_restore(dc); -#endif + if (dc->ctx->dmub_srv) dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv); @@ -3583,8 +3559,6 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable) return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) - void dc_allow_idle_optimizations(struct dc *dc, bool allow) { if (dc->debug.disable_idle_power_optimizations) @@ -3740,7 +3714,6 @@ void dc_hardware_release(struct dc *dc) if (dc->hwss.hardware_release) dc->hwss.hardware_release(dc); } -#endif /* ***************************************************************************** @@ -3760,13 +3733,12 @@ void dc_hardware_release(struct dc *dc) */ bool dc_is_dmub_outbox_supported(struct dc *dc) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */ + /* DCN31 B0 USB4 DPIA needs dmub notifications for interrupts */ if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 && !dc->debug.dpia_debug.bits.disable_dpia) return true; -#endif + /* dmub aux needs dmub notifications to be enabled */ return dc->debug.enable_dmub_aux_for_legacy_ddc; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index 643762542e4d..72376075db0c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -345,7 +345,6 @@ void context_clock_trace( struct dc *dc, struct dc_state *context) { -#if defined(CONFIG_DRM_AMD_DC_DCN) DC_LOGGER_INIT(dc->ctx->logger); CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", @@ -363,7 +362,6 @@ void context_clock_trace( context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz, context->bw_ctx.bw.dcn.clk.fclk_khz, context->bw_ctx.bw.dcn.clk.socclk_khz); -#endif } /** 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 faab1460d0b5..a789ea8af27f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -33,6 +33,7 @@ #include "gpio_service_interface.h" #include "core_status.h" #include "dc_link_dp.h" +#include "dc_link_dpia.h" #include "dc_link_ddc.h" #include "link_hwss.h" #include "opp.h" @@ -240,7 +241,7 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type) /* Link may not have physical HPD pin. */ if (link->ep_type != DISPLAY_ENDPOINT_PHY) { - if (link->is_hpd_pending || !link->hpd_status) + if (link->is_hpd_pending || !dc_link_dpia_query_hpd_status(link)) *type = dc_connection_none; else *type = dc_connection_single; @@ -804,7 +805,6 @@ static bool wait_for_entering_dp_alt_mode(struct dc_link *link) static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link) { -#if defined(CONFIG_DRM_AMD_DC_DCN) /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock * reports DSC support. */ @@ -815,7 +815,6 @@ static void apply_dpia_mst_dsc_always_on_wa(struct dc_link *link) link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT && !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around) link->wa_flags.dpia_mst_dsc_always_on = true; -#endif } static void revert_dpia_mst_dsc_always_on_wa(struct dc_link *link) @@ -881,9 +880,7 @@ static bool should_prepare_phy_clocks_for_link_verification(const struct dc *dc, static void prepare_phy_clocks_for_destructive_link_verification(const struct dc *dc) { -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_restore(dc); -#endif clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); } @@ -1608,8 +1605,25 @@ static bool dc_link_construct_legacy(struct dc_link *link, if (link->hpd_gpio) { if (!link->dc->config.allow_edp_hotplug_detection) link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; - link->irq_source_hpd_rx = - dal_irq_get_rx_source(link->hpd_gpio); + + switch (link->dc->config.allow_edp_hotplug_detection) { + case 1: // only the 1st eDP handles hotplug + if (link->link_index == 0) + link->irq_source_hpd_rx = + dal_irq_get_rx_source(link->hpd_gpio); + else + link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; + break; + case 2: // only the 2nd eDP handles hotplug + if (link->link_index == 1) + link->irq_source_hpd_rx = + dal_irq_get_rx_source(link->hpd_gpio); + else + link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; + break; + default: + break; + } } break; @@ -3100,10 +3114,8 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active if (allow_active && link->psr_settings.psr_allow_active != *allow_active) { link->psr_settings.psr_allow_active = *allow_active; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (!link->psr_settings.psr_allow_active) dc_z10_restore(dc); -#endif if (psr != NULL && link->psr_settings.psr_feature_enabled) { psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst); @@ -3317,9 +3329,12 @@ bool dc_link_setup_psr(struct dc_link *link, */ psr_context->frame_delay = 0; - if (psr) + if (psr) { link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, link, psr_context, panel_inst); + link->psr_settings.psr_power_opt = 0; + link->psr_settings.psr_allow_active = 0; + } else link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context); @@ -3543,7 +3558,8 @@ static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx, } /* slot X.Y for SST payload allocate */ - if (allocate) { + if (allocate && dp_get_link_encoding_format(&link->cur_link_settings) == + DP_128b_132b_ENCODING) { avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link); dc_log_vcp_x_y(link, avg_time_slots_per_mtp); @@ -3966,8 +3982,12 @@ static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) if (is_dp_128b_132b_signal(pipe_ctx)) config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst; - /* dio output index */ - config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; + /* dio output index is dpia index for DPIA endpoint & dcio index by default */ + if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) + config.dio_output_idx = pipe_ctx->stream->link->link_id.enum_id - ENUM_ID_1; + else + config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; + /* phy index */ config.phy_idx = resource_transmitter_to_phy_idx( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index 1d4863763df9..2b09310965bc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -543,15 +543,9 @@ bool dal_ddc_service_query_ddc_data( uint32_t payloads_num = write_payloads + read_payloads; - - if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE) - return false; - if (!payloads_num) return false; - /*TODO: len of payload data for i2c and aux is uint8!!!!, - * but we want to read 256 over i2c!!!!*/ if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) { struct aux_payload payload; 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 c5f5d25035d2..cbc47aecd00f 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 @@ -114,8 +114,8 @@ static const struct dc_link_settings fail_safe_link_settings = { static bool decide_fallback_link_setting( struct dc_link *link, - struct dc_link_settings initial_link_settings, - struct dc_link_settings *current_link_setting, + struct dc_link_settings *max, + struct dc_link_settings *cur, enum link_training_result training_result); static void maximize_lane_settings(const struct link_training_settings *lt_settings, struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); @@ -793,7 +793,7 @@ bool dp_is_interlane_aligned(union lane_align_status_updated align_status) void dp_hw_to_dpcd_lane_settings( const struct link_training_settings *lt_settings, const struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]) + union dpcd_training_lane dpcd_lane_settings[]) { uint8_t lane = 0; @@ -823,7 +823,7 @@ void dp_decide_lane_settings( const struct link_training_settings *lt_settings, const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]) + union dpcd_training_lane dpcd_lane_settings[]) { uint32_t lane; @@ -2783,31 +2783,37 @@ bool perform_link_training_with_retries( struct dc_link *link = stream->link; enum dp_panel_mode panel_mode = dp_get_panel_mode(link); enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0; - struct dc_link_settings current_setting = *link_setting; + struct dc_link_settings cur_link_settings = *link_setting; + struct dc_link_settings max_link_settings = *link_setting; const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); int fail_count = 0; + bool is_link_bw_low = false; /* link bandwidth < stream bandwidth */ + bool is_link_bw_min = /* RBR x 1 */ + (cur_link_settings.link_rate <= LINK_RATE_LOW) && + (cur_link_settings.lane_count <= LANE_COUNT_ONE); dp_trace_commit_lt_init(link); - - if (dp_get_link_encoding_format(¤t_setting) == DP_8b_10b_ENCODING) + if (dp_get_link_encoding_format(&cur_link_settings) == DP_8b_10b_ENCODING) /* We need to do this before the link training to ensure the idle * pattern in SST mode will be sent right after the link training */ link_hwss->setup_stream_encoder(pipe_ctx); dp_trace_set_lt_start_timestamp(link, false); - for (j = 0; j < attempts; ++j) { + j = 0; + while (j < attempts && fail_count < (attempts * 10)) { - DC_LOG_HW_LINK_TRAINING("%s: Beginning link training attempt %u of %d\n", - __func__, (unsigned int)j + 1, attempts); + DC_LOG_HW_LINK_TRAINING("%s: Beginning link training attempt %u of %d @ rate(%d) x lane(%d)\n", + __func__, (unsigned int)j + 1, attempts, cur_link_settings.link_rate, + cur_link_settings.lane_count); dp_enable_link_phy( link, &pipe_ctx->link_res, signal, pipe_ctx->clock_source->id, - ¤t_setting); + &cur_link_settings); if (stream->sink_patches.dppowerup_delay > 0) { int delay_dp_power_up_in_ms = stream->sink_patches.dppowerup_delay; @@ -2832,30 +2838,30 @@ bool perform_link_training_with_retries( dp_set_panel_mode(link, panel_mode); if (link->aux_access_disabled) { - dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, ¤t_setting); + dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &cur_link_settings); return true; } else { /** @todo Consolidate USB4 DP and DPx.x training. */ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { status = dc_link_dpia_perform_link_training(link, &pipe_ctx->link_res, - ¤t_setting, + &cur_link_settings, skip_video_pattern); /* Transmit idle pattern once training successful. */ - if (status == LINK_TRAINING_SUCCESS) + if (status == LINK_TRAINING_SUCCESS && !is_link_bw_low) dp_set_hw_test_pattern(link, &pipe_ctx->link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); } else { status = dc_link_dp_perform_link_training(link, &pipe_ctx->link_res, - ¤t_setting, + &cur_link_settings, skip_video_pattern); } dp_trace_lt_total_count_increment(link, false); dp_trace_lt_result_update(link, status, false); dp_trace_set_lt_end_timestamp(link, false); - if (status == LINK_TRAINING_SUCCESS) + if (status == LINK_TRAINING_SUCCESS && !is_link_bw_low) return true; } @@ -2866,8 +2872,9 @@ bool perform_link_training_with_retries( if (j == (attempts - 1) && link->ep_type == DISPLAY_ENDPOINT_PHY) break; - DC_LOG_WARNING("%s: Link training attempt %u of %d failed\n", - __func__, (unsigned int)j + 1, attempts); + DC_LOG_WARNING("%s: Link training attempt %u of %d failed @ rate(%d) x lane(%d)\n", + __func__, (unsigned int)j + 1, attempts, cur_link_settings.link_rate, + cur_link_settings.lane_count); dp_disable_link_phy(link, &pipe_ctx->link_res, signal); @@ -2876,27 +2883,45 @@ bool perform_link_training_with_retries( enum dc_connection_type type = dc_connection_none; dc_link_detect_sink(link, &type); - if (type == dc_connection_none) + if (type == dc_connection_none) { + DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__); break; - } else if (do_fallback) { + } + } + + /* Try to train again at original settings if: + * - not falling back between training attempts; + * - aborted previous attempt due to reasons other than sink unplug; + * - successfully trained but at a link rate lower than that required by stream; + * - reached minimum link bandwidth. + */ + if (!do_fallback || (status == LINK_TRAINING_ABORT) || + (status == LINK_TRAINING_SUCCESS && is_link_bw_low) || + is_link_bw_min) { + j++; + cur_link_settings = *link_setting; + delay_between_attempts += LINK_TRAINING_RETRY_DELAY; + is_link_bw_low = false; + is_link_bw_min = (cur_link_settings.link_rate <= LINK_RATE_LOW) && + (cur_link_settings.lane_count <= LANE_COUNT_ONE); + + } else if (do_fallback) { /* Try training at lower link bandwidth if doing fallback. */ uint32_t req_bw; uint32_t link_bw; - decide_fallback_link_setting(link, *link_setting, ¤t_setting, status); + decide_fallback_link_setting(link, &max_link_settings, + &cur_link_settings, status); /* Fail link training if reduced link bandwidth no longer meets * stream requirements. */ req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); - link_bw = dc_link_bandwidth_kbps(link, ¤t_setting); + link_bw = dc_link_bandwidth_kbps(link, &cur_link_settings); if (req_bw > link_bw) break; } msleep(delay_between_attempts); - - delay_between_attempts += LINK_TRAINING_RETRY_DELAY; } - return false; } @@ -3280,7 +3305,7 @@ static bool dp_verify_link_cap( int *fail_count) { struct dc_link_settings cur_link_settings = {0}; - struct dc_link_settings initial_link_settings = *known_limit_link_setting; + struct dc_link_settings max_link_settings = *known_limit_link_setting; bool success = false; bool skip_video_pattern; enum clock_source_id dp_cs_id = get_clock_source_id(link); @@ -3289,7 +3314,7 @@ static bool dp_verify_link_cap( struct link_resource link_res; memset(&irq_data, 0, sizeof(irq_data)); - cur_link_settings = initial_link_settings; + cur_link_settings = max_link_settings; /* Grant extended timeout request */ if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) { @@ -3332,7 +3357,7 @@ static bool dp_verify_link_cap( dp_trace_lt_result_update(link, status, true); dp_disable_link_phy(link, &link_res, link->connector_signal); } while (!success && decide_fallback_link_setting(link, - initial_link_settings, &cur_link_settings, status)); + &max_link_settings, &cur_link_settings, status)); link->verified_link_cap = success ? cur_link_settings : fail_safe_link_settings; @@ -3567,16 +3592,19 @@ static bool decide_fallback_link_setting_max_bw_policy( */ static bool decide_fallback_link_setting( struct dc_link *link, - struct dc_link_settings initial_link_settings, - struct dc_link_settings *current_link_setting, + struct dc_link_settings *max, + struct dc_link_settings *cur, enum link_training_result training_result) { - if (!current_link_setting) + if (!cur) return false; - if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING || + if (!max) + return false; + + if (dp_get_link_encoding_format(max) == DP_128b_132b_ENCODING || link->dc->debug.force_dp2_lt_fallback_method) - return decide_fallback_link_setting_max_bw_policy(link, &initial_link_settings, - current_link_setting, training_result); + return decide_fallback_link_setting_max_bw_policy(link, max, cur, + training_result); switch (training_result) { case LINK_TRAINING_CR_FAIL_LANE0: @@ -3584,28 +3612,18 @@ static bool decide_fallback_link_setting( case LINK_TRAINING_CR_FAIL_LANE23: case LINK_TRAINING_LQA_FAIL: { - if (!reached_minimum_link_rate - (current_link_setting->link_rate)) { - current_link_setting->link_rate = - reduce_link_rate( - current_link_setting->link_rate); - } else if (!reached_minimum_lane_count - (current_link_setting->lane_count)) { - current_link_setting->link_rate = - initial_link_settings.link_rate; + if (!reached_minimum_link_rate(cur->link_rate)) { + cur->link_rate = reduce_link_rate(cur->link_rate); + } else if (!reached_minimum_lane_count(cur->lane_count)) { + cur->link_rate = max->link_rate; if (training_result == LINK_TRAINING_CR_FAIL_LANE0) return false; else if (training_result == LINK_TRAINING_CR_FAIL_LANE1) - current_link_setting->lane_count = - LANE_COUNT_ONE; - else if (training_result == - LINK_TRAINING_CR_FAIL_LANE23) - current_link_setting->lane_count = - LANE_COUNT_TWO; + cur->lane_count = LANE_COUNT_ONE; + else if (training_result == LINK_TRAINING_CR_FAIL_LANE23) + cur->lane_count = LANE_COUNT_TWO; else - current_link_setting->lane_count = - reduce_lane_count( - current_link_setting->lane_count); + cur->lane_count = reduce_lane_count(cur->lane_count); } else { return false; } @@ -3613,17 +3631,17 @@ static bool decide_fallback_link_setting( } case LINK_TRAINING_EQ_FAIL_EQ: { - if (!reached_minimum_lane_count - (current_link_setting->lane_count)) { - current_link_setting->lane_count = - reduce_lane_count( - current_link_setting->lane_count); - } else if (!reached_minimum_link_rate - (current_link_setting->link_rate)) { - current_link_setting->link_rate = - reduce_link_rate( - current_link_setting->link_rate); - current_link_setting->lane_count = initial_link_settings.lane_count; + if (!reached_minimum_lane_count(cur->lane_count)) { + cur->lane_count = reduce_lane_count(cur->lane_count); + } else if (!reached_minimum_link_rate(cur->link_rate)) { + cur->link_rate = reduce_link_rate(cur->link_rate); + /* Reduce max link rate to avoid potential infinite loop. + * Needed so that any subsequent CR_FAIL fallback can't + * re-set the link rate higher than the link rate from + * the latest EQ_FAIL fallback. + */ + max->link_rate = cur->link_rate; + cur->lane_count = max->lane_count; } else { return false; } @@ -3631,12 +3649,15 @@ static bool decide_fallback_link_setting( } case LINK_TRAINING_EQ_FAIL_CR: { - if (!reached_minimum_link_rate - (current_link_setting->link_rate)) { - current_link_setting->link_rate = - reduce_link_rate( - current_link_setting->link_rate); - current_link_setting->lane_count = initial_link_settings.lane_count; + if (!reached_minimum_link_rate(cur->link_rate)) { + cur->link_rate = reduce_link_rate(cur->link_rate); + /* Reduce max link rate to avoid potential infinite loop. + * Needed so that any subsequent CR_FAIL fallback can't + * re-set the link rate higher than the link rate from + * the latest EQ_FAIL fallback. + */ + max->link_rate = cur->link_rate; + cur->lane_count = max->lane_count; } else { return false; } @@ -4464,7 +4485,7 @@ static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video &dpcd_pattern_type.value, sizeof(dpcd_pattern_type)); - channel_count = dpcd_test_mode.bits.channel_count + 1; + channel_count = min(dpcd_test_mode.bits.channel_count + 1, AUDIO_CHANNELS_COUNT); // read pattern periods for requested channels when sawTooth pattern is requested if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH || @@ -4576,6 +4597,7 @@ void dc_link_dp_handle_link_loss(struct dc_link *link) { int i; struct pipe_ctx *pipe_ctx; + struct dc_link_settings prev_link_settings = link->preferred_link_setting; for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; @@ -4586,6 +4608,10 @@ void dc_link_dp_handle_link_loss(struct dc_link *link) if (pipe_ctx == NULL || pipe_ctx->stream == NULL) return; + /* toggle stream state with the preference for current link settings */ + dc_link_set_preferred_training_settings((struct dc *)link->dc, + &link->cur_link_settings, NULL, link, true); + for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && @@ -4601,6 +4627,10 @@ void dc_link_dp_handle_link_loss(struct dc_link *link) core_link_enable_stream(link->dc->current_state, pipe_ctx); } } + + /* restore previous link settings preference */ + dc_link_set_preferred_training_settings((struct dc *)link->dc, + &prev_link_settings, NULL, link, true); } bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, @@ -5124,6 +5154,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) else link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; } + #if defined(CONFIG_DRM_AMD_DC_DCN) /* Check DP tunnel LTTPR mode debug option. */ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && @@ -5140,11 +5171,6 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV, lttpr_dpcd_data, sizeof(lttpr_dpcd_data)); - if (status != DC_OK) { - DC_LOG_DP2("%s: Read LTTPR caps data failed.\n", __func__); - link->lttpr_mode = LTTPR_MODE_NON_LTTPR; - return false; - } link->dpcd_caps.lttpr_caps.revision.raw = lttpr_dpcd_data[DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV - @@ -5169,18 +5195,16 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) link->dpcd_caps.lttpr_caps.max_ext_timeout = lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; - link->dpcd_caps.lttpr_caps.main_link_channel_coding.raw = lttpr_dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw = - lttpr_dpcd_data[DP_PHY_REPEATER_128b_132b_RATES - + lttpr_dpcd_data[DP_PHY_REPEATER_128B132B_RATES - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */ is_lttpr_present = (link->dpcd_caps.lttpr_caps.max_lane_count > 0 && - link->dpcd_caps.lttpr_caps.phy_repeater_cnt < 0xff && link->dpcd_caps.lttpr_caps.max_lane_count <= 4 && link->dpcd_caps.lttpr_caps.revision.raw >= 0x14); if (is_lttpr_present) { @@ -5586,9 +5610,7 @@ static bool retrieve_link_cap(struct dc_link *link) * only if required. */ if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && -#if defined(CONFIG_DRM_AMD_DC_DCN) !link->dc->debug.dpia_debug.bits.disable_force_tbt3_work_around && -#endif link->dpcd_caps.is_branch_dev && link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_10 && @@ -5822,6 +5844,10 @@ void detect_edp_sink_caps(struct dc_link *link) core_link_read_dpcd(link, DP_PSR_SUPPORT, &link->dpcd_caps.psr_info.psr_version, sizeof(link->dpcd_caps.psr_info.psr_version)); + if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8) + core_link_read_dpcd(link, DP_FORCE_PSRSU_CAPABILITY, + &link->dpcd_caps.psr_info.force_psrsu_cap, + sizeof(link->dpcd_caps.psr_info.force_psrsu_cap)); core_link_read_dpcd(link, DP_PSR_CAPS, &link->dpcd_caps.psr_info.psr_dpcd_caps.raw, sizeof(link->dpcd_caps.psr_info.psr_dpcd_caps.raw)); @@ -7565,6 +7591,7 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_u DC_LOG_DSC(" "); dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]); + memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps)); if (dc_is_dp_signal(stream->signal)) { DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id); if (is_dp_128b_132b_signal(pipe_ctx)) @@ -7582,6 +7609,7 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_u } } else { /* disable DSC PPS in stream encoder */ + memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps)); if (dc_is_dp_signal(stream->signal)) { if (is_dp_128b_132b_signal(pipe_ctx)) pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c index 0e95bc5df4e7..1b7a8774b0c9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c @@ -34,6 +34,7 @@ #include "dm_helpers.h" #include "dmub/inc/dmub_cmd.h" #include "inc/link_dpcd.h" +#include "dc_dmub_srv.h" #define DC_LOGGER \ link->ctx->logger @@ -69,6 +70,24 @@ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link) return status; } +bool dc_link_dpia_query_hpd_status(struct dc_link *link) +{ + union dmub_rb_cmd cmd = {0}; + struct dc_dmub_srv *dmub_srv = link->ctx->dmub_srv; + bool is_hpd_high = false; + + /* prepare QUERY_HPD command */ + cmd.query_hpd.header.type = DMUB_CMD__QUERY_HPD_STATE; + cmd.query_hpd.data.instance = link->link_id.enum_id - ENUM_ID_1; + cmd.query_hpd.data.ch_type = AUX_CHANNEL_DPIA; + + /* Return HPD status reported by DMUB if query successfully executed. */ + if (dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd) && cmd.query_hpd.data.status == AUX_RET_SUCCESS) + is_hpd_high = cmd.query_hpd.data.result; + + return is_hpd_high; +} + /* Configure link as prescribed in link_setting; set LTTPR mode; and * Initialize link training settings. * Abort link training if sink unplug detected. @@ -547,11 +566,9 @@ static uint32_t dpia_get_eq_aux_rd_interval(const struct dc_link *link, dp_translate_training_aux_read_interval( link->dpcd_caps.lttpr_caps.aux_rd_interval[hop - 1]); -#if defined(CONFIG_DRM_AMD_DC_DCN) /* Check debug option for extending aux read interval. */ if (link->dc->debug.dpia_debug.bits.extend_aux_rd_interval) wait_time_microsec = DPIA_DEBUG_EXTENDED_AUX_RD_INTERVAL_US; -#endif return wait_time_microsec; } 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 f292303b75a5..6774dd8bb53e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -56,7 +56,6 @@ #include "dce110/dce110_resource.h" #include "dce112/dce112_resource.h" #include "dce120/dce120_resource.h" -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "dcn10/dcn10_resource.h" #include "dcn20/dcn20_resource.h" #include "dcn21/dcn21_resource.h" @@ -68,7 +67,6 @@ #include "dcn31/dcn31_resource.h" #include "dcn315/dcn315_resource.h" #include "dcn316/dcn316_resource.h" -#endif #define DC_LOGGER_INIT(logger) @@ -124,7 +122,6 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) else dc_version = DCE_VERSION_12_0; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) case FAMILY_RV: dc_version = DCN_VERSION_1_0; if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) @@ -165,7 +162,6 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) if (ASICREV_IS_GC_10_3_7(asic_id.hw_internal_rev)) dc_version = DCN_VERSION_3_16; break; -#endif default: dc_version = DCE_VERSION_UNKNOWN; @@ -397,7 +393,6 @@ bool resource_construct( } } -#if defined(CONFIG_DRM_AMD_DC_DCN) for (i = 0; i < caps->num_mpc_3dlut; i++) { pool->mpc_lut[i] = dc_create_3dlut_func(); if (pool->mpc_lut[i] == NULL) @@ -406,7 +401,7 @@ bool resource_construct( if (pool->mpc_shaper[i] == NULL) DC_ERR("DC: failed to create MPC shaper!\n"); } -#endif + dc->caps.dynamic_audio = false; if (pool->audio_count < pool->stream_enc_count) { dc->caps.dynamic_audio = true; @@ -1369,7 +1364,6 @@ static struct pipe_ctx *acquire_free_pipe_for_head( return pool->funcs->acquire_idle_pipe_for_layer(context, pool, head_pipe->stream); } -#if defined(CONFIG_DRM_AMD_DC_DCN) static int acquire_first_split_pipe( struct resource_context *res_ctx, const struct resource_pool *pool, @@ -1404,7 +1398,6 @@ static int acquire_first_split_pipe( } return -1; } -#endif bool dc_add_plane_to_context( const struct dc *dc, @@ -1447,13 +1440,12 @@ bool dc_add_plane_to_context( while (head_pipe) { free_pipe = acquire_free_pipe_for_head(context, pool, head_pipe); - #if defined(CONFIG_DRM_AMD_DC_DCN) if (!free_pipe) { int pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); if (pipe_idx >= 0) free_pipe = &context->res_ctx.pipe_ctx[pipe_idx]; } - #endif + if (!free_pipe) { dc_plane_state_release(plane_state); return false; @@ -2150,12 +2142,18 @@ static int acquire_resource_from_hw_enabled_state( if (!res_ctx->pipe_ctx[tg_inst].stream) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[tg_inst]; + pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst]; id_src[0] = tg_inst; if (pipe_ctx->stream_res.tg->funcs->get_optc_source) pipe_ctx->stream_res.tg->funcs->get_optc_source(pipe_ctx->stream_res.tg, &numPipes, &id_src[0], &id_src[1]); + if (id_src[0] == 0xf && id_src[1] == 0xf) { + id_src[0] = tg_inst; + numPipes = 1; + } + for (i = 0; i < numPipes; i++) { //Check if src id invalid if (id_src[i] == 0xf) @@ -2253,10 +2251,8 @@ enum dc_status resource_map_pool_resources( /* acquire new resources */ pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream); -#ifdef CONFIG_DRM_AMD_DC_DCN if (pipe_idx < 0) pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream); -#endif if (pipe_idx < 0 || context->res_ctx.pipe_ctx[pipe_idx].stream_res.tg == NULL) return DC_NO_CONTROLLER_RESOURCE; @@ -2319,14 +2315,10 @@ enum dc_status resource_map_pool_resources( /* Add ABM to the resource if on EDP */ if (pipe_ctx->stream && dc_is_embedded_signal(pipe_ctx->stream->signal)) { -#if defined(CONFIG_DRM_AMD_DC_DCN) if (pool->abm) pipe_ctx->stream_res.abm = pool->abm; else pipe_ctx->stream_res.abm = pool->multiple_abms[pipe_ctx->stream_res.tg->inst]; -#else - pipe_ctx->stream_res.abm = pool->abm; -#endif } for (i = 0; i < context->stream_count; i++) @@ -2447,7 +2439,6 @@ enum dc_status dc_validate_global_state( if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate)) result = DC_FAIL_BANDWIDTH_VALIDATE; -#if defined(CONFIG_DRM_AMD_DC_DCN) /* * Only update link encoder to stream assignment after bandwidth validation passed. * TODO: Split out assignment and validation. @@ -2455,7 +2446,6 @@ enum dc_status dc_validate_global_state( if (result == DC_OK && dc->res_pool->funcs->link_encs_assign && fast_validate == false) dc->res_pool->funcs->link_encs_assign( dc, new_ctx, new_ctx->streams, new_ctx->stream_count); -#endif return result; } @@ -3183,10 +3173,8 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format) case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: -#if defined(CONFIG_DRM_AMD_DC_DCN) case SURFACE_PIXEL_FORMAT_GRPH_RGBE: case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: -#endif return 32; case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: @@ -3339,7 +3327,6 @@ uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter tr /* TODO - get transmitter to phy idx mapping from DMUB */ uint8_t phy_idx = transmitter - TRANSMITTER_UNIPHY_A; -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dc->ctx->dce_version == DCN_VERSION_3_1 && dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { switch (transmitter) { @@ -3363,7 +3350,7 @@ uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter tr break; } } -#endif + return phy_idx; } 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 c4e871f358ab..de8b214132a2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -314,9 +314,7 @@ bool dc_stream_set_cursor_attributes( const struct dc_cursor_attributes *attributes) { struct dc *dc; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool reset_idle_optimizations = false; -#endif if (NULL == stream) { dm_error("DC: dc_stream is NULL!\n"); @@ -335,7 +333,6 @@ bool dc_stream_set_cursor_attributes( dc = stream->ctx->dc; stream->cursor_attributes = *attributes; -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_restore(dc); /* disable idle optimizations while updating cursor */ if (dc->idle_optimizations_allowed) { @@ -343,15 +340,12 @@ bool dc_stream_set_cursor_attributes( reset_idle_optimizations = true; } -#endif program_cursor_attributes(dc, stream, attributes); -#if defined(CONFIG_DRM_AMD_DC_DCN) /* re-enable idle optimizations if necessary */ if (reset_idle_optimizations) dc_allow_idle_optimizations(dc, true); -#endif return true; } @@ -396,9 +390,7 @@ bool dc_stream_set_cursor_position( const struct dc_cursor_position *position) { struct dc *dc; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool reset_idle_optimizations = false; -#endif if (NULL == stream) { dm_error("DC: dc_stream is NULL!\n"); @@ -411,7 +403,6 @@ bool dc_stream_set_cursor_position( } dc = stream->ctx->dc; -#if defined(CONFIG_DRM_AMD_DC_DCN) dc_z10_restore(dc); /* disable idle optimizations if enabling cursor */ @@ -420,16 +411,13 @@ bool dc_stream_set_cursor_position( reset_idle_optimizations = true; } -#endif stream->cursor_position = *position; program_cursor_position(dc, stream, position); -#if defined(CONFIG_DRM_AMD_DC_DCN) /* re-enable idle optimizations if necessary */ if (reset_idle_optimizations) dc_allow_idle_optimizations(dc, true); -#endif return true; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index e6b9c6a71841..5bc6ff2fa73e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -61,6 +61,8 @@ static void dc_plane_construct(struct dc_context *ctx, struct dc_plane_state *pl plane_state->blend_tf->type = TF_TYPE_BYPASS; } + plane_state->pre_multiplied_alpha = true; + } static void dc_plane_destruct(struct dc_plane_state *plane_state) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 2f0c436dae4c..817028d3c4a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -47,7 +47,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.181" +#define DC_VER "3.2.187" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -222,7 +222,6 @@ struct dc_dcc_setting { unsigned int max_compressed_blk_size; unsigned int max_uncompressed_blk_size; bool independent_64b_blks; -#if defined(CONFIG_DRM_AMD_DC_DCN) //These bitfields to be used starting with DCN struct { uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN (the worst compression case) @@ -230,7 +229,6 @@ struct dc_dcc_setting { uint32_t dcc_256_128_128 : 1; //available starting with DCN uint32_t dcc_256_256_unconstrained : 1; //available in ASICs before DCN (the best compression case) } dcc_controls; -#endif }; struct dc_surface_dcc_cap { @@ -331,10 +329,8 @@ struct dc_config { bool disable_dmcu; bool enable_4to1MPC; bool enable_windowed_mpo_odm; - bool allow_edp_hotplug_detection; -#if defined(CONFIG_DRM_AMD_DC_DCN) + uint32_t allow_edp_hotplug_detection; bool clamp_min_dcfclk; -#endif uint64_t vblank_alignment_dto_params; uint8_t vblank_alignment_max_frame_time_diff; bool is_asymmetric_memory; @@ -359,6 +355,12 @@ enum dc_psr_power_opts { psr_power_opt_ds_disable_allow = 0x100, }; +enum dml_hostvm_override_opts { + DML_HOSTVM_NO_OVERRIDE = 0x0, + DML_HOSTVM_OVERRIDE_FALSE = 0x1, + DML_HOSTVM_OVERRIDE_TRUE = 0x2, +}; + enum dcc_option { DCC_ENABLE = 0, DCC_DISABLE = 1, @@ -389,14 +391,12 @@ enum dcn_pwr_state { DCN_PWR_STATE_LOW_POWER = 3, }; -#if defined(CONFIG_DRM_AMD_DC_DCN) enum dcn_zstate_support_state { DCN_ZSTATE_SUPPORT_UNKNOWN, DCN_ZSTATE_SUPPORT_ALLOW, DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY, DCN_ZSTATE_SUPPORT_DISALLOW, }; -#endif /* * For any clocks that may differ per pipe * only the max is stored in this structure @@ -414,11 +414,9 @@ struct dc_clocks { int phyclk_khz; int dramclk_khz; bool p_state_change_support; -#if defined(CONFIG_DRM_AMD_DC_DCN) enum dcn_zstate_support_state zstate_support; bool dtbclk_en; - int dtbclk_khz; -#endif + int ref_dtbclk_khz; enum dcn_pwr_state pwr_state; /* * Elements below are not compared for the purposes of @@ -648,9 +646,7 @@ struct dc_debug_options { bool disable_pplib_clock_request; bool disable_clock_gate; bool disable_mem_low_power; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool pstate_enabled; -#endif bool disable_dmcu; bool disable_psr; bool force_abm_enable; @@ -668,20 +664,16 @@ struct dc_debug_options { bool remove_disconnect_edp; unsigned int force_odm_combine; //bit vector based on otg inst unsigned int seamless_boot_odm_combine; -#if defined(CONFIG_DRM_AMD_DC_DCN) unsigned int force_odm_combine_4to1; //bit vector based on otg inst bool disable_z9_mpc; -#endif unsigned int force_fclk_khz; bool enable_tri_buf; bool dmub_offload_enabled; bool dmcub_emulation; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool disable_idle_power_optimizations; unsigned int mall_size_override; unsigned int mall_additional_timer_percent; bool mall_error_as_fatal; -#endif bool dmub_command_table; /* for testing only */ struct dc_bw_validation_profile bw_val_profile; bool disable_fec; @@ -690,9 +682,7 @@ struct dc_debug_options { * watermarks are not affected. */ unsigned int force_min_dcfclk_mhz; -#if defined(CONFIG_DRM_AMD_DC_DCN) int dwb_fi_phase; -#endif bool disable_timing_sync; bool cm_in_bypass; int force_clock_mode;/*every mode change.*/ @@ -724,15 +714,16 @@ struct dc_debug_options { enum det_size crb_alloc_policy; int crb_alloc_policy_min_disp_count; bool disable_z10; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool enable_z9_disable_interface; bool enable_sw_cntl_psr; union dpia_debug_options dpia_debug; -#endif bool apply_vendor_specific_lttpr_wa; bool extended_blank_optimization; union aux_wake_wa_options aux_wake_wa; + /* uses value at boot and disables switch */ + bool disable_dtb_ref_clk_switch; uint8_t psr_power_use_phy_fsm; + enum dml_hostvm_override_opts dml_hostvm_override; }; struct gpu_info_soc_bounding_box_v1_0; @@ -761,11 +752,9 @@ struct dc { /* Inputs into BW and WM calculations. */ struct bw_calcs_dceip *bw_dceip; struct bw_calcs_vbios *bw_vbios; -#ifdef CONFIG_DRM_AMD_DC_DCN struct dcn_soc_bounding_box *dcn_soc; struct dcn_ip_params *dcn_ip; struct display_mode_lib dml; -#endif /* HW functions */ struct hw_sequencer_funcs hwss; @@ -774,12 +763,8 @@ struct dc { /* Require to optimize clocks and bandwidth for added/removed planes */ bool optimized_required; bool wm_optimized_required; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool idle_optimizations_allowed; -#endif -#if defined(CONFIG_DRM_AMD_DC_DCN) bool enable_c20_dtm_b0; -#endif /* Require to maintain clocks and bandwidth for UEFI enabled HW */ @@ -829,9 +814,7 @@ struct dc_init_data { uint64_t log_mask; struct dpcd_vendor_signature vendor_signature; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool force_smu_not_present; -#endif }; struct dc_callback_init { @@ -1024,15 +1007,14 @@ struct dc_plane_state { struct dc_transfer_func *in_shaper_func; struct dc_transfer_func *blend_tf; -#if defined(CONFIG_DRM_AMD_DC_DCN) struct dc_transfer_func *gamcor_tf; -#endif enum surface_pixel_format format; enum dc_rotation_angle rotation; enum plane_stereo_format stereo_format; bool is_tiling_rotated; bool per_pixel_alpha; + bool pre_multiplied_alpha; bool global_alpha; int global_alpha_value; bool visible; @@ -1067,6 +1049,7 @@ struct dc_plane_info { bool horizontal_mirror; bool visible; bool per_pixel_alpha; + bool pre_multiplied_alpha; bool global_alpha; int global_alpha_value; bool input_csc_enabled; @@ -1123,18 +1106,6 @@ struct dc_transfer_func *dc_create_transfer_func(void); struct dc_3dlut *dc_create_3dlut_func(void); void dc_3dlut_func_release(struct dc_3dlut *lut); void dc_3dlut_func_retain(struct dc_3dlut *lut); -/* - * This structure holds a surface address. There could be multiple addresses - * in cases such as Stereo 3D, Planar YUV, etc. Other per-flip attributes such - * as frame durations and DCC format can also be set. - */ -struct dc_flip_addrs { - struct dc_plane_address address; - unsigned int flip_timestamp_in_us; - bool flip_immediate; - /* TODO: add flip duration for FreeSync */ - bool triplebuffer_flips; -}; void dc_post_update_surfaces_to_stream( struct dc *dc); @@ -1175,13 +1146,11 @@ void dc_resource_state_construct( const struct dc *dc, struct dc_state *dst_ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dc_acquire_release_mpc_3dlut( struct dc *dc, bool acquire, struct dc_stream_state *stream, struct dc_3dlut **lut, struct dc_transfer_func **shaper); -#endif void dc_resource_state_copy_construct( const struct dc_state *src_ctx, @@ -1312,10 +1281,8 @@ struct hdcp_caps { #include "dc_link.h" -#if defined(CONFIG_DRM_AMD_DC_DCN) uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); -#endif /******************************************************************************* * Sink Interfaces - A sink corresponds to a display output device ******************************************************************************/ @@ -1439,7 +1406,6 @@ bool dc_is_dmcu_initialized(struct dc *dc); enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane, struct dc_cursor_attributes *cursor_attr); @@ -1464,13 +1430,9 @@ void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable); /* cleanup on driver unload */ void dc_hardware_release(struct dc *dc); -#endif - bool dc_set_psr_allow_active(struct dc *dc, bool enable); -#if defined(CONFIG_DRM_AMD_DC_DCN) void dc_z10_restore(const struct dc *dc); void dc_z10_save_init(struct dc *dc); -#endif bool dc_is_dmub_outbox_supported(struct dc *dc); bool dc_enable_dmub_notifications(struct dc *dc); 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 c964f598755a..aa7e3a07191d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -201,8 +201,9 @@ enum surface_pixel_format { SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb, SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr, SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb, + SURFACE_PIXEL_FORMAT_SUBSAMPLE_END, + SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010 = SURFACE_PIXEL_FORMAT_SUBSAMPLE_END, - SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010, SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102, SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888, SURFACE_PIXEL_FORMAT_INVALID @@ -235,6 +236,22 @@ enum pixel_format { PIXEL_FORMAT_UNKNOWN }; +/* + * This structure holds a surface address. There could be multiple addresses + * in cases such as Stereo 3D, Planar YUV, etc. Other per-flip attributes such + * as frame durations and DCC format can also be set. + */ +#define DC_MAX_DIRTY_RECTS 3 +struct dc_flip_addrs { + struct dc_plane_address address; + unsigned int flip_timestamp_in_us; + bool flip_immediate; + /* TODO: add flip duration for FreeSync */ + bool triplebuffer_flips; + unsigned int dirty_rect_count; + struct rect dirty_rects[DC_MAX_DIRTY_RECTS]; +}; + enum tile_split_values { DC_DISPLAY_MICRO_TILING = 0x0, DC_THIN_MICRO_TILING = 0x1, diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 580420c3eedc..58941f4defb3 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -162,7 +162,7 @@ struct dc_stream_state { struct dc_info_packet vrr_infopacket; struct dc_info_packet vsc_infopacket; struct dc_info_packet vsp_infopacket; - + uint8_t dsc_packed_pps[128]; struct rect src; /* composition area */ struct rect dst; /* stream addressable area */ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c index 29e20d92b0bb..9e39cd7b203e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c @@ -87,7 +87,8 @@ static void release_engine( engine->ddc = NULL; - REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1); + REG_UPDATE_2(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1, + AUX_SW_USE_AUX_REG_REQ, 0); } #define SW_CAN_ACCESS_AUX 1 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 760653e2b607..845aa8a1027d 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 @@ -918,7 +918,6 @@ static bool dce112_program_pix_clk( struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source); struct bp_pixel_clock_parameters bp_pc_params = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN) 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_100hz = 7000000; @@ -932,7 +931,6 @@ static bool dce112_program_pix_clk( REG_UPDATE(PIXEL_RATE_CNTL[inst], DP_DTO0_ENABLE, 1); return true; } -#endif /* First disable SS * ATOMBIOS will enable by default SS on PLL for DP, * do not disable it here @@ -971,7 +969,6 @@ static bool dce112_program_pix_clk( return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) static bool dcn31_program_pix_clk( struct clock_source *clock_source, struct pixel_clk_params *pix_clk_params, @@ -1062,7 +1059,6 @@ static bool dcn31_program_pix_clk( return true; } -#endif static bool dce110_clock_source_power_down( struct clock_source *clk_src) @@ -1105,9 +1101,12 @@ static bool get_pixel_clk_frequency_100hz( * not be programmed equal to DPREFCLK */ modulo_hz = REG_READ(MODULO[inst]); - *pixel_clk_khz = div_u64((uint64_t)clock_hz* - clock_source->ctx->dc->clk_mgr->dprefclk_khz*10, - modulo_hz); + if (modulo_hz) + *pixel_clk_khz = div_u64((uint64_t)clock_hz* + clock_source->ctx->dc->clk_mgr->dprefclk_khz*10, + modulo_hz); + else + *pixel_clk_khz = 0; } else { /* NOTE: There is agreement with VBIOS here that MODULO is * programmed equal to DPREFCLK, in which case PHASE will be @@ -1121,7 +1120,6 @@ static bool get_pixel_clk_frequency_100hz( return false; } -#if defined(CONFIG_DRM_AMD_DC_DCN) /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { // /1.001 rates @@ -1171,7 +1169,6 @@ const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( return NULL; } -#endif static bool dcn20_program_pix_clk( struct clock_source *clock_source, @@ -1218,7 +1215,6 @@ static const struct clock_source_funcs dcn20_clk_src_funcs = { .override_dp_pix_clk = dcn20_override_dp_pix_clk }; -#if defined(CONFIG_DRM_AMD_DC_DCN) static bool dcn3_program_pix_clk( struct clock_source *clock_source, struct pixel_clk_params *pix_clk_params, @@ -1304,7 +1300,7 @@ static const struct clock_source_funcs dcn31_clk_src_funcs = { .get_pix_clk_dividers = dcn3_get_pix_clk_dividers, .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz }; -#endif + /*****************************************/ /* Constructor */ /*****************************************/ @@ -1690,7 +1686,6 @@ bool dcn20_clk_src_construct( return ret; } -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dcn3_clk_src_construct( struct dce110_clk_src *clk_src, struct dc_context *ctx, @@ -1706,9 +1701,7 @@ bool dcn3_clk_src_construct( return ret; } -#endif -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dcn31_clk_src_construct( struct dce110_clk_src *clk_src, struct dc_context *ctx, @@ -1724,9 +1717,7 @@ bool dcn31_clk_src_construct( return ret; } -#endif -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dcn301_clk_src_construct( struct dce110_clk_src *clk_src, struct dc_context *ctx, @@ -1742,4 +1733,3 @@ bool dcn301_clk_src_construct( return ret; } -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h index 069de7649c8c..9eec3524335f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h @@ -100,7 +100,6 @@ SRII(PIXEL_RATE_CNTL, OTG, 2),\ SRII(PIXEL_RATE_CNTL, OTG, 3) -#if defined(CONFIG_DRM_AMD_DC_DCN) #define CS_COMMON_REG_LIST_DCN3_0(index, pllid) \ SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ SRII(PHASE, DP_DTO, 0),\ @@ -130,9 +129,7 @@ SRII(PIXEL_RATE_CNTL, OTG, 1),\ SRII(PIXEL_RATE_CNTL, OTG, 2),\ SRII(PIXEL_RATE_CNTL, OTG, 3) -#endif -#if defined(CONFIG_DRM_AMD_DC_DCN) #define CS_COMMON_REG_LIST_DCN3_02(index, pllid) \ SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ SRII(PHASE, DP_DTO, 0),\ @@ -160,15 +157,13 @@ SRII(PIXEL_RATE_CNTL, OTG, 0),\ SRII(PIXEL_RATE_CNTL, OTG, 1) -#endif + #define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\ CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\ CS_SF(DP_DTO0_MODULO, DP_DTO0_MODULO, mask_sh),\ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\ CS_SF(OTG0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh) -#if defined(CONFIG_DRM_AMD_DC_DCN) - #define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \ SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ SRII(PHASE, DP_DTO, 0),\ @@ -190,7 +185,6 @@ CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\ CS_SF(OTG0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh) -#endif #define CS_REG_FIELD_LIST(type) \ type PLL_REF_DIV_SRC; \ @@ -274,7 +268,6 @@ bool dcn20_clk_src_construct( const struct dce110_clk_src_shift *cs_shift, const struct dce110_clk_src_mask *cs_mask); -#if defined(CONFIG_DRM_AMD_DC_DCN) bool dcn3_clk_src_construct( struct dce110_clk_src *clk_src, struct dc_context *ctx, @@ -301,7 +294,6 @@ bool dcn31_clk_src_construct( const struct dce110_clk_src_regs *regs, const struct dce110_clk_src_shift *cs_shift, const struct dce110_clk_src_mask *cs_mask); -#endif /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ struct pixel_rate_range_table_entry { @@ -312,10 +304,8 @@ struct pixel_rate_range_table_entry { unsigned short div_factor; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) extern const struct pixel_rate_range_table_entry video_optimized_pixel_rates[]; const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( unsigned int pixel_rate_khz); -#endif #endif 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 8cd841320ded..7183ac5780a4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -70,9 +70,7 @@ //Register access policy version #define mmMP0_SMN_C2PMSG_91 0x1609B -#if defined(CONFIG_DRM_AMD_DC_DCN) static const uint32_t abm_gain_stepsize = 0x0060; -#endif static bool dce_dmcu_init(struct dmcu *dmcu) { @@ -333,7 +331,6 @@ static void dce_get_psr_wait_loop( return; } -#if defined(CONFIG_DRM_AMD_DC_DCN) static void dcn10_get_dmcu_version(struct dmcu *dmcu) { struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); @@ -930,7 +927,6 @@ static bool dcn10_recv_edid_cea_ack(struct dmcu *dmcu, int *offset) return false; } -#endif //(CONFIG_DRM_AMD_DC_DCN) #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) static void dcn10_forward_crc_window(struct dmcu *dmcu, @@ -1021,7 +1017,6 @@ static const struct dmcu_funcs dce_funcs = { .is_dmcu_initialized = dce_is_dmcu_initialized }; -#if defined(CONFIG_DRM_AMD_DC_DCN) static const struct dmcu_funcs dcn10_funcs = { .dmcu_init = dcn10_dmcu_init, .load_iram = dcn10_dmcu_load_iram, @@ -1065,7 +1060,6 @@ static const struct dmcu_funcs dcn21_funcs = { .lock_phy = dcn20_lock_phy, .unlock_phy = dcn20_unlock_phy }; -#endif static void dce_dmcu_construct( struct dce_dmcu *dmcu_dce, @@ -1085,7 +1079,6 @@ static void dce_dmcu_construct( dmcu_dce->dmcu_mask = dmcu_mask; } -#if defined(CONFIG_DRM_AMD_DC_DCN) static void dcn21_dmcu_construct( struct dce_dmcu *dmcu_dce, struct dc_context *ctx, @@ -1103,7 +1096,6 @@ static void dcn21_dmcu_construct( dmcu_dce->base.psp_version = psp_version; } } -#endif struct dmcu *dce_dmcu_create( struct dc_context *ctx, @@ -1126,7 +1118,6 @@ struct dmcu *dce_dmcu_create( return &dmcu_dce->base; } -#if defined(CONFIG_DRM_AMD_DC_DCN) struct dmcu *dcn10_dmcu_create( struct dc_context *ctx, const struct dce_dmcu_registers *regs, @@ -1189,7 +1180,6 @@ struct dmcu *dcn21_dmcu_create( return &dmcu_dce->base; } -#endif void dce_dmcu_destroy(struct dmcu **dmcu) { 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 779bc92a2968..a8c92b517df1 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 @@ -136,7 +136,7 @@ static void dce110_update_generic_info_packet( AFMT_GENERIC0_UPDATE, (packet_index == 0), AFMT_GENERIC2_UPDATE, (packet_index == 2)); } -#if defined(CONFIG_DRM_AMD_DC_DCN) + if (REG(AFMT_VBI_PACKET_CONTROL1)) { switch (packet_index) { case 0: @@ -175,7 +175,6 @@ static void dce110_update_generic_info_packet( break; } } -#endif } static void dce110_update_hdmi_info_packet( @@ -230,7 +229,6 @@ static void dce110_update_hdmi_info_packet( HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; -#if defined(CONFIG_DRM_AMD_DC_DCN) case 4: if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, @@ -259,7 +257,6 @@ static void dce110_update_hdmi_info_packet( HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; -#endif default: /* invalid HW packet index */ DC_LOG_WARNING( @@ -277,7 +274,6 @@ static void dce110_stream_encoder_dp_set_stream_attribute( bool use_vsc_sdp_for_colorimetry, uint32_t enable_sdp_splitting) { -#if defined(CONFIG_DRM_AMD_DC_DCN) uint32_t h_active_start; uint32_t v_active_start; uint32_t misc0 = 0; @@ -288,7 +284,6 @@ static void dce110_stream_encoder_dp_set_stream_attribute( uint8_t colorimetry_bpc; uint8_t dynamic_range_rgb = 0; /*full range*/ uint8_t dynamic_range_ycbcr = 1; /*bt709*/ -#endif struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); struct dc_crtc_timing hw_crtc_timing = *crtc_timing; @@ -329,10 +324,8 @@ static void dce110_stream_encoder_dp_set_stream_attribute( if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN) REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1); -#if defined(CONFIG_DRM_AMD_DC_DCN) if (enc110->se_mask->DP_VID_N_MUL) REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1); -#endif break; default: REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING, @@ -340,10 +333,8 @@ static void dce110_stream_encoder_dp_set_stream_attribute( break; } -#if defined(CONFIG_DRM_AMD_DC_DCN) if (REG(DP_MSA_MISC)) misc1 = REG_READ(DP_MSA_MISC); -#endif /* set color depth */ @@ -374,7 +365,6 @@ static void dce110_stream_encoder_dp_set_stream_attribute( /* set dynamic range and YCbCr range */ -#if defined(CONFIG_DRM_AMD_DC_DCN) switch (hw_crtc_timing.display_color_depth) { case COLOR_DEPTH_666: colorimetry_bpc = 0; @@ -454,7 +444,6 @@ static void dce110_stream_encoder_dp_set_stream_attribute( DP_DYN_RANGE, dynamic_range_rgb, DP_YCBCR_RANGE, dynamic_range_ycbcr); -#if defined(CONFIG_DRM_AMD_DC_DCN) if (REG(DP_MSA_COLORIMETRY)) REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0); @@ -468,7 +457,6 @@ static void dce110_stream_encoder_dp_set_stream_attribute( REG_SET_2(DP_MSA_TIMING_PARAM1, 0, DP_MSA_HTOTAL, hw_crtc_timing.h_total, DP_MSA_VTOTAL, hw_crtc_timing.v_total); -#endif /* calcuate from vesa timing parameters * h_active_start related to leading edge of sync @@ -489,7 +477,6 @@ static void dce110_stream_encoder_dp_set_stream_attribute( hw_crtc_timing.v_front_porch; -#if defined(CONFIG_DRM_AMD_DC_DCN) /* start at begining of left border */ if (REG(DP_MSA_TIMING_PARAM2)) REG_SET_2(DP_MSA_TIMING_PARAM2, 0, @@ -514,9 +501,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute( hw_crtc_timing.h_addressable + hw_crtc_timing.h_border_right, DP_MSA_VHEIGHT, hw_crtc_timing.v_border_top + hw_crtc_timing.v_addressable + hw_crtc_timing.v_border_bottom); -#endif } -#endif } static void dce110_stream_encoder_set_stream_attribute_helper( @@ -787,7 +772,6 @@ static void dce110_stream_encoder_update_hdmi_info_packets( dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd); } -#if defined(CONFIG_DRM_AMD_DC_DCN) if (enc110->se_mask->HDMI_DB_DISABLE) { /* for bring up, disable dp double TODO */ if (REG(HDMI_DB_CONTROL)) @@ -799,7 +783,6 @@ static void dce110_stream_encoder_update_hdmi_info_packets( dce110_update_hdmi_info_packet(enc110, 3, &info_frame->spd); dce110_update_hdmi_info_packet(enc110, 4, &info_frame->hdrsmd); } -#endif } static void dce110_stream_encoder_stop_hdmi_info_packets( @@ -825,7 +808,6 @@ static void dce110_stream_encoder_stop_hdmi_info_packets( HDMI_GENERIC1_LINE, 0, HDMI_GENERIC1_SEND, 0); -#if defined(CONFIG_DRM_AMD_DC_DCN) /* stop generic packets 2 & 3 on HDMI */ if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0, @@ -844,7 +826,6 @@ static void dce110_stream_encoder_stop_hdmi_info_packets( HDMI_GENERIC1_CONT, 0, HDMI_GENERIC1_LINE, 0, HDMI_GENERIC1_SEND, 0); -#endif } static void dce110_stream_encoder_update_dp_info_packets( diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 312c68172689..1d4f0c45b536 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -231,7 +231,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_ dc_dmub_srv_wait_idle(dc->dmub_srv); } -/** +/* * Set PSR power optimization flags. */ static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst) 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 9fc1ba12ec19..7eff7811769d 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 @@ -1365,11 +1365,9 @@ static void program_scaler(const struct dc *dc, { struct tg_color color = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN) /* TOFPGA */ if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) return; -#endif if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) get_surface_visual_confirm_color(pipe_ctx, &color); 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 e02ac75afbf7..e3a62873c0e7 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 @@ -2550,12 +2550,21 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) blnd_cfg.overlap_only = false; blnd_cfg.global_gain = 0xff; - if (per_pixel_alpha && pipe_ctx->plane_state->global_alpha) { - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN; - blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value; - } else if (per_pixel_alpha) { - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; + if (per_pixel_alpha) { + /* DCN1.0 has output CM before MPC which seems to screw with + * pre-multiplied alpha. + */ + blnd_cfg.pre_multiplied_alpha = (is_rgb_cspace( + pipe_ctx->stream->output_color_space) + && pipe_ctx->plane_state->pre_multiplied_alpha); + if (pipe_ctx->plane_state->global_alpha) { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN; + blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value; + } else { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; + } } else { + blnd_cfg.pre_multiplied_alpha = false; blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; } @@ -2564,14 +2573,6 @@ void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) else blnd_cfg.global_alpha = 0xff; - /* DCN1.0 has output CM before MPC which seems to screw with - * pre-multiplied alpha. - */ - blnd_cfg.pre_multiplied_alpha = is_rgb_cspace( - pipe_ctx->stream->output_color_space) - && per_pixel_alpha; - - /* * TODO: remove hack * Note: currently there is a bug in init_hw such that diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c index b0c08ee6bc2c..7608187751c8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c @@ -25,6 +25,7 @@ #include <linux/delay.h> +#include "dm_services.h" #include "dc_bios_types.h" #include "dcn10_stream_encoder.h" #include "reg_helper.h" diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h index 687d7e4bf7ca..293595a33982 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h @@ -92,6 +92,8 @@ SRI(DP_VID_STREAM_CNTL, DP, id), \ SRI(DP_VID_TIMING, DP, id), \ SRI(DP_SEC_AUD_N, DP, id), \ + SRI(DP_SEC_AUD_N_READBACK, DP, id), \ + SRI(DP_SEC_AUD_M_READBACK, DP, id), \ SRI(DP_SEC_TIMESTAMP, DP, id), \ SRI(DIG_CLOCK_PATTERN, DIG, id) @@ -140,6 +142,8 @@ struct dcn10_stream_enc_registers { uint32_t DP_VID_STREAM_CNTL; uint32_t DP_VID_TIMING; uint32_t DP_SEC_AUD_N; + uint32_t DP_SEC_AUD_N_READBACK; + uint32_t DP_SEC_AUD_M_READBACK; uint32_t DP_SEC_TIMESTAMP; uint32_t HDMI_CONTROL; uint32_t HDMI_GC; @@ -256,6 +260,8 @@ struct dcn10_stream_enc_registers { SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_6, mask_sh),\ SE_SF(DIG0_AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_7, mask_sh),\ SE_SF(DP0_DP_SEC_AUD_N, DP_SEC_AUD_N, mask_sh),\ + SE_SF(DP0_DP_SEC_AUD_N_READBACK, DP_SEC_AUD_N_READBACK, mask_sh),\ + SE_SF(DP0_DP_SEC_AUD_M_READBACK, DP_SEC_AUD_M_READBACK, mask_sh),\ SE_SF(DP0_DP_SEC_TIMESTAMP, DP_SEC_TIMESTAMP_MODE, mask_sh),\ SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ASP_ENABLE, mask_sh),\ SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ATP_ENABLE, mask_sh),\ @@ -473,6 +479,8 @@ struct dcn10_stream_enc_registers { type AFMT_60958_CS_CHANNEL_NUMBER_6;\ type AFMT_60958_CS_CHANNEL_NUMBER_7;\ type DP_SEC_AUD_N;\ + type DP_SEC_AUD_N_READBACK;\ + type DP_SEC_AUD_M_READBACK;\ type DP_SEC_TIMESTAMP_MODE;\ type DP_SEC_ASP_ENABLE;\ type DP_SEC_ATP_ENABLE;\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c index 6f24ceab97ad..136a9dc062bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c @@ -47,6 +47,7 @@ static void dsc2_set_config(struct display_stream_compressor *dsc, const struct static bool dsc2_get_packed_pps(struct display_stream_compressor *dsc, const struct dsc_config *dsc_cfg, uint8_t *dsc_packed_pps); static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe); static void dsc2_disable(struct display_stream_compressor *dsc); +static void dsc2_disconnect(struct display_stream_compressor *dsc); const struct dsc_funcs dcn20_dsc_funcs = { .dsc_get_enc_caps = dsc2_get_enc_caps, @@ -56,6 +57,7 @@ const struct dsc_funcs dcn20_dsc_funcs = { .dsc_get_packed_pps = dsc2_get_packed_pps, .dsc_enable = dsc2_enable, .dsc_disable = dsc2_disable, + .dsc_disconnect = dsc2_disconnect, }; /* Macro definitios for REG_SET macros*/ @@ -278,6 +280,15 @@ static void dsc2_disable(struct display_stream_compressor *dsc) DSC_CLOCK_EN, 0); } +static void dsc2_disconnect(struct display_stream_compressor *dsc) +{ + struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc); + + DC_LOG_DSC("disconnect DSC %d", dsc->inst); + + REG_UPDATE(DSCRM_DSC_FORWARD_CONFIG, + DSCRM_DSC_FORWARD_EN, 0); +} /* This module's internal functions */ static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_config *pps) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index b627c41713cc..ec6aa8d8b251 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1593,7 +1593,6 @@ static void dcn20_program_pipe( pipe_ctx->pipe_dlg_param.vupdate_offset, pipe_ctx->pipe_dlg_param.vupdate_width); - pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); pipe_ctx->stream_res.tg->funcs->set_vtg_params( @@ -1774,7 +1773,6 @@ void dcn20_post_unlock_program_front_end( */ for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - if (pipe->plane_state && !pipe->top_pipe && pipe->update_flags.bits.enable) { struct hubp *hubp = pipe->plane_res.hubp; int j = 0; @@ -2347,12 +2345,16 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) blnd_cfg.overlap_only = false; blnd_cfg.global_gain = 0xff; - if (per_pixel_alpha && pipe_ctx->plane_state->global_alpha) { - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN; - blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value; - } else if (per_pixel_alpha) { - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; + if (per_pixel_alpha) { + blnd_cfg.pre_multiplied_alpha = pipe_ctx->plane_state->pre_multiplied_alpha; + if (pipe_ctx->plane_state->global_alpha) { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN; + blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value; + } else { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; + } } else { + blnd_cfg.pre_multiplied_alpha = false; blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; } @@ -2366,7 +2368,7 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) blnd_cfg.top_gain = 0x1f000; blnd_cfg.bottom_inside_gain = 0x1f000; blnd_cfg.bottom_outside_gain = 0x1f000; - blnd_cfg.pre_multiplied_alpha = per_pixel_alpha; + if (pipe_ctx->plane_state->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA) blnd_cfg.pre_multiplied_alpha = false; diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c index fe22530242d2..05b3fba9ccce 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hwseq.c @@ -95,8 +95,6 @@ static void gpu_addr_to_uma(struct dce_hwseq *hwseq, } else if (hwseq->fb_offset.quad_part <= addr->quad_part && addr->quad_part <= hwseq->uma_top.quad_part) { is_in_uma = true; - } else if (addr->quad_part == 0) { - is_in_uma = false; } else { is_in_uma = false; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.h index e2c264ecb20f..42140e73c3b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.h @@ -95,6 +95,8 @@ SRI(DP_VID_STREAM_CNTL, DP, id), \ SRI(DP_VID_TIMING, DP, id), \ SRI(DP_SEC_AUD_N, DP, id), \ + SRI(DP_SEC_AUD_N_READBACK, DP, id), \ + SRI(DP_SEC_AUD_M_READBACK, DP, id), \ SRI(DP_SEC_TIMESTAMP, DP, id), \ SRI(DP_DSC_CNTL, DP, id), \ SRI(DP_DSC_BYTES_PER_PIXEL, DP, id), \ @@ -157,6 +159,8 @@ SE_SF(DIG0_HDMI_ACR_48_0, HDMI_ACR_CTS_48, mask_sh),\ SE_SF(DIG0_HDMI_ACR_48_1, HDMI_ACR_N_48, mask_sh),\ SE_SF(DP0_DP_SEC_AUD_N, DP_SEC_AUD_N, mask_sh),\ + SE_SF(DP0_DP_SEC_AUD_N_READBACK, DP_SEC_AUD_N_READBACK, mask_sh),\ + SE_SF(DP0_DP_SEC_AUD_M_READBACK, DP_SEC_AUD_M_READBACK, mask_sh),\ SE_SF(DP0_DP_SEC_TIMESTAMP, DP_SEC_TIMESTAMP_MODE, mask_sh),\ SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ASP_ENABLE, mask_sh),\ SE_SF(DP0_DP_SEC_CNTL, DP_SEC_ATP_ENABLE, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h index b7dc78624963..34b9cedbd012 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h @@ -99,11 +99,6 @@ SRII(MPCC_OGAM_CONTROL, MPCC_OGAM, inst),\ SRII(MPCC_OGAM_LUT_CONTROL, MPCC_OGAM, inst) -/* - SRII(MPCC_OGAM_LUT_RAM_CONTROL, MPCC_OGAM, inst),\ - SRII(MPCC_OGAM_MODE, MPCC_OGAM, inst) -*/ - #define MPC_OUT_MUX_REG_LIST_DCN3_0(inst) \ MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst),\ SRII(CSC_MODE, MPC_OUT, inst),\ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index f5e8916601d3..b604fb26f288 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -28,6 +28,8 @@ #include "dc.h" #include "dcn_calc_math.h" +#include "dml/dcn30/dcn30_fpu.h" + #define REG(reg)\ optc1->tg_regs->reg @@ -184,6 +186,14 @@ void optc3_set_dsc_config(struct timing_generator *optc, } +void optc3_set_vrr_m_const(struct timing_generator *optc, + double vtotal_avg) +{ + DC_FP_START(); + optc3_fpu_set_vrr_m_const(optc, vtotal_avg); + DC_FP_END(); +} + void optc3_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h index 736e63bc80c2..97f11ef6e9f0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h @@ -344,5 +344,5 @@ void optc3_set_timing_db_mode(struct timing_generator *optc, bool enable); void optc3_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing); void optc3_tg_init(struct timing_generator *optc); - +void optc3_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, int vtotal_max); #endif /* __DC_OPTC_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 336b2ce6a636..1c1a67c4cec1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -84,6 +84,7 @@ #include "dce/dce_aux.h" #include "dce/dce_i2c.h" +#include "dml/dcn30/dcn30_fpu.h" #include "dml/dcn30/display_mode_vba_30.h" #include "vm_helper.h" #include "dcn20/dcn20_vmid.h" @@ -91,137 +92,6 @@ #define DC_LOGGER_INIT(logger) -struct _vcs_dpi_ip_params_st dcn3_0_ip = { - .use_min_dcfclk = 0, - .clamp_min_dcfclk = 0, - .odm_capable = 1, - .gpuvm_enable = 0, - .hostvm_enable = 0, - .gpuvm_max_page_table_levels = 4, - .hostvm_max_page_table_levels = 4, - .hostvm_cached_page_table_levels = 0, - .pte_group_size_bytes = 2048, - .num_dsc = 6, - .rob_buffer_size_kbytes = 184, - .det_buffer_size_kbytes = 184, - .dpte_buffer_size_in_pte_reqs_luma = 84, - .pde_proc_buffer_size_64k_reqs = 48, - .dpp_output_buffer_pixels = 2560, - .opp_output_buffer_lines = 1, - .pixel_chunk_size_kbytes = 8, - .pte_enable = 1, - .max_page_table_levels = 2, - .pte_chunk_size_kbytes = 2, // ? - .meta_chunk_size_kbytes = 2, - .writeback_chunk_size_kbytes = 8, - .line_buffer_size_bits = 789504, - .is_line_buffer_bpp_fixed = 0, // ? - .line_buffer_fixed_bpp = 0, // ? - .dcc_supported = true, - .writeback_interface_buffer_size_kbytes = 90, - .writeback_line_buffer_buffer_size = 0, - .max_line_buffer_lines = 12, - .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 - .writeback_chroma_buffer_size_kbytes = 8, - .writeback_chroma_line_buffer_width_pixels = 4, - .writeback_max_hscl_ratio = 1, - .writeback_max_vscl_ratio = 1, - .writeback_min_hscl_ratio = 1, - .writeback_min_vscl_ratio = 1, - .writeback_max_hscl_taps = 1, - .writeback_max_vscl_taps = 1, - .writeback_line_buffer_luma_buffer_size = 0, - .writeback_line_buffer_chroma_buffer_size = 14643, - .cursor_buffer_size = 8, - .cursor_chunk_size = 2, - .max_num_otg = 6, - .max_num_dpp = 6, - .max_num_wb = 1, - .max_dchub_pscl_bw_pix_per_clk = 4, - .max_pscl_lb_bw_pix_per_clk = 2, - .max_lb_vscl_bw_pix_per_clk = 4, - .max_vscl_hscl_bw_pix_per_clk = 4, - .max_hscl_ratio = 6, - .max_vscl_ratio = 6, - .hscl_mults = 4, - .vscl_mults = 4, - .max_hscl_taps = 8, - .max_vscl_taps = 8, - .dispclk_ramp_margin_percent = 1, - .underscan_factor = 1.11, - .min_vblank_lines = 32, - .dppclk_delay_subtotal = 46, - .dynamic_metadata_vm_enabled = true, - .dppclk_delay_scl_lb_only = 16, - .dppclk_delay_scl = 50, - .dppclk_delay_cnvc_formatter = 27, - .dppclk_delay_cnvc_cursor = 6, - .dispclk_delay_subtotal = 119, - .dcfclk_cstate_latency = 5.2, // SRExitTime - .max_inter_dcn_tile_repeaters = 8, - .odm_combine_4to1_supported = true, - - .xfc_supported = false, - .xfc_fill_bw_overhead_percent = 10.0, - .xfc_fill_constant_bytes = 0, - .gfx7_compat_tiling_supported = 0, - .number_of_cursors = 1, -}; - -struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = { - .clock_limits = { - { - .state = 0, - .dispclk_mhz = 562.0, - .dppclk_mhz = 300.0, - .phyclk_mhz = 300.0, - .phyclk_d18_mhz = 667.0, - .dscclk_mhz = 405.6, - }, - }, - .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ - .num_states = 1, - .sr_exit_time_us = 15.5, - .sr_enter_plus_exit_time_us = 20, - .urgent_latency_us = 4.0, - .urgent_latency_pixel_data_only_us = 4.0, - .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, - .urgent_latency_vm_data_only_us = 4.0, - .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, - .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, - .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, - .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, - .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, - .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, - .max_avg_sdp_bw_use_normal_percent = 60.0, - .max_avg_dram_bw_use_normal_percent = 40.0, - .writeback_latency_us = 12.0, - .max_request_size_bytes = 256, - .fabric_datapath_to_dcn_data_return_bytes = 64, - .dcn_downspread_percent = 0.5, - .downspread_percent = 0.38, - .dram_page_open_time_ns = 50.0, - .dram_rw_turnaround_time_ns = 17.5, - .dram_return_buffer_per_channel_bytes = 8192, - .round_trip_ping_latency_dcfclk_cycles = 191, - .urgent_out_of_order_return_per_channel_bytes = 4096, - .channel_interleave_bytes = 256, - .num_banks = 8, - .gpuvm_min_page_size_bytes = 4096, - .hostvm_min_page_size_bytes = 4096, - .dram_clock_change_latency_us = 404, - .dummy_pstate_latency_us = 5, - .writeback_dram_clock_change_latency_us = 23.0, - .return_bus_width_bytes = 64, - .dispclk_dppclk_vco_speed_mhz = 3650, - .xfc_bus_transport_time_us = 20, // ? - .xfc_xbuf_latency_tolerance_us = 4, // ? - .use_urgent_burst_bw = 1, // ? - .do_urgent_latency_adjustment = true, - .urgent_latency_adjustment_fabric_clock_component_us = 1.0, - .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, -}; - enum dcn30_clk_src_array_id { DCN30_CLK_SRC_PLL0, DCN30_CLK_SRC_PLL1, @@ -1480,90 +1350,9 @@ int dcn30_populate_dml_pipes_from_context( void dcn30_populate_dml_writeback_from_context( struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) { - int pipe_cnt, i, j; - double max_calc_writeback_dispclk; - double writeback_dispclk; - struct writeback_st dout_wb; - - for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { - struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream; - - if (!stream) - continue; - max_calc_writeback_dispclk = 0; - - /* Set writeback information */ - pipes[pipe_cnt].dout.wb_enable = 0; - pipes[pipe_cnt].dout.num_active_wb = 0; - for (j = 0; j < stream->num_wb_info; j++) { - struct dc_writeback_info *wb_info = &stream->writeback_info[j]; - - if (wb_info->wb_enabled && wb_info->writeback_source_plane && - (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) { - pipes[pipe_cnt].dout.wb_enable = 1; - pipes[pipe_cnt].dout.num_active_wb++; - dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ? - wb_info->dwb_params.cnv_params.crop_height : - wb_info->dwb_params.cnv_params.src_height; - dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ? - wb_info->dwb_params.cnv_params.crop_width : - wb_info->dwb_params.cnv_params.src_width; - dout_wb.wb_dst_width = wb_info->dwb_params.dest_width; - dout_wb.wb_dst_height = wb_info->dwb_params.dest_height; - - /* For IP that doesn't support WB scaling, set h/v taps to 1 to avoid DML validation failure */ - if (dc->dml.ip.writeback_max_hscl_taps > 1) { - dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps; - dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps; - } else { - dout_wb.wb_htaps_luma = 1; - dout_wb.wb_vtaps_luma = 1; - } - dout_wb.wb_htaps_chroma = 0; - dout_wb.wb_vtaps_chroma = 0; - dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ? - (double)wb_info->dwb_params.cnv_params.crop_width / - (double)wb_info->dwb_params.dest_width : - (double)wb_info->dwb_params.cnv_params.src_width / - (double)wb_info->dwb_params.dest_width; - dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ? - (double)wb_info->dwb_params.cnv_params.crop_height / - (double)wb_info->dwb_params.dest_height : - (double)wb_info->dwb_params.cnv_params.src_height / - (double)wb_info->dwb_params.dest_height; - if (wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_ARGB || - wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_RGBA) - dout_wb.wb_pixel_format = dm_444_64; - else - dout_wb.wb_pixel_format = dm_444_32; - - /* Workaround for cases where multiple writebacks are connected to same plane - * In which case, need to compute worst case and set the associated writeback parameters - * This workaround is necessary due to DML computation assuming only 1 set of writeback - * parameters per pipe - */ - writeback_dispclk = dml30_CalculateWriteBackDISPCLK( - dout_wb.wb_pixel_format, - pipes[pipe_cnt].pipe.dest.pixel_rate_mhz, - dout_wb.wb_hratio, - dout_wb.wb_vratio, - dout_wb.wb_htaps_luma, - dout_wb.wb_vtaps_luma, - dout_wb.wb_src_width, - dout_wb.wb_dst_width, - pipes[pipe_cnt].pipe.dest.htotal, - dc->current_state->bw_ctx.dml.ip.writeback_line_buffer_buffer_size); - - if (writeback_dispclk > max_calc_writeback_dispclk) { - max_calc_writeback_dispclk = writeback_dispclk; - pipes[pipe_cnt].dout.wb = dout_wb; - } - } - } - - pipe_cnt++; - } - + DC_FP_START(); + dcn30_fpu_populate_dml_writeback_from_context(dc, res_ctx, pipes); + DC_FP_END(); } unsigned int dcn30_calc_max_scaled_time( @@ -1598,7 +1387,7 @@ void dcn30_set_mcif_arb_params( enum mmhubbub_wbif_mode wbif_mode; struct display_mode_lib *dml = &context->bw_ctx.dml; struct mcif_arb_params *wb_arb_params; - int i, j, k, dwb_pipe; + int i, j, dwb_pipe; /* Writeback MCIF_WB arbitration parameters */ dwb_pipe = 0; @@ -1622,17 +1411,15 @@ void dcn30_set_mcif_arb_params( else wbif_mode = PACKED_444; - for (k = 0; k < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); k++) { - wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(dml, pipes, pipe_cnt) * 1000; - wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(dml, pipes, pipe_cnt) * 1000; - } + DC_FP_START(); + dcn30_fpu_set_mcif_arb_params(wb_arb_params, dml, pipes, pipe_cnt, j); + DC_FP_END(); wb_arb_params->time_per_pixel = (1000000 << 6) / context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; /* time_per_pixel should be in u6.6 format */ wb_arb_params->slice_lines = 32; wb_arb_params->arbitration_slice = 2; /* irrelevant since there is no YUV output */ wb_arb_params->max_scaled_time = dcn30_calc_max_scaled_time(wb_arb_params->time_per_pixel, wbif_mode, wb_arb_params->cli_watermark[0]); /* assume 4 watermark sets have the same value */ - wb_arb_params->dram_speed_change_duration = dml->vba.WritebackAllowDRAMClockChangeEndPosition[j] * pipes[0].clks_cfg.refclk_mhz; /* num_clock_cycles = us * MHz */ dwb_pipe++; @@ -2111,178 +1898,11 @@ validate_out: return out; } -/* - * This must be noinline to ensure anything that deals with FP registers - * is contained within this call; previously our compiling with hard-float - * would result in fp instructions being emitted outside of the boundaries - * of the DC_FP_START/END macros, which makes sense as the compiler has no - * idea about what is wrapped and what is not - * - * This is largely just a workaround to avoid breakage introduced with 5.6, - * ideally all fp-using code should be moved into its own file, only that - * should be compiled with hard-float, and all code exported from there - * should be strictly wrapped with DC_FP_START/END - */ -static noinline void dcn30_calculate_wm_and_dlg_fp( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int pipe_cnt, - int vlevel) +void dcn30_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) { - int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; - int i, pipe_idx; - double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb]; - bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported; - - if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) - dcfclk = context->bw_ctx.dml.soc.min_dcfclk; - - pipes[0].clks_cfg.voltage = vlevel; - pipes[0].clks_cfg.dcfclk_mhz = dcfclk; - pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz; - - /* Set B: - * DCFCLK: 1GHz or min required above 1GHz - * FCLK/UCLK: Max - */ - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) { - if (vlevel == 0) { - pipes[0].clks_cfg.voltage = 1; - pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz; - } - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us; - } - context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - - pipes[0].clks_cfg.voltage = vlevel; - pipes[0].clks_cfg.dcfclk_mhz = dcfclk; - - /* Set D: - * DCFCLK: Min Required - * FCLK(proportional to UCLK): 1GHz or Max - * MALL stutter, sr_enter_exit = 4, sr_exit = 2us - */ - /* - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us; - } - context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - */ - - /* Set C: - * DCFCLK: Min Required - * FCLK(proportional to UCLK): 1GHz or Max - * pstate latency overridden to 5us - */ - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) { - unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; - unsigned int min_dram_speed_mts_margin = 160; - - if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_unsupported) - min_dram_speed_mts = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz * 16; - - /* find largest table entry that is lower than dram speed, but lower than DPM0 still uses DPM0 */ - for (i = 3; i > 0; i--) - if (min_dram_speed_mts + min_dram_speed_mts_margin > dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts) - break; - - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us; - } - - context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - - if (!pstate_en) { - /* The only difference between A and C is p-state latency, if p-state is not supported we want to - * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark - */ - context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0; - } else { - /* Set A: - * DCFCLK: Min Required - * FCLK(proportional to UCLK): 1GHz or Max - * - * Set A calculated last so that following calculations are based on Set A - */ - dc->res_pool->funcs->update_soc_for_wm_a(dc, context); - context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; - } - - context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod; - - /* Make set D = set A until set D is enabled */ - context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; - - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - if (!context->res_ctx.pipe_ctx[i].stream) - continue; - - pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); - pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - - if (dc->config.forced_clocks) { - pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; - pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; - } - if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) - pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; - if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) - pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; - - pipe_idx++; - } - DC_FP_START(); - dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); + dcn30_fpu_update_soc_for_wm_a(dc, context); DC_FP_END(); - - if (!pstate_en) - /* Restore full p-state latency */ - context->bw_ctx.dml.soc.dram_clock_change_latency_us = - dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; -} - -void dcn30_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) -{ - if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) { - context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; - context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us; - context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us; - } } void dcn30_calculate_wm_and_dlg( @@ -2292,7 +1912,7 @@ void dcn30_calculate_wm_and_dlg( int vlevel) { DC_FP_START(); - dcn30_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel); + dcn30_fpu_calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); DC_FP_END(); } @@ -2351,40 +1971,6 @@ validate_out: return out; } -/* - * This must be noinline to ensure anything that deals with FP registers - * is contained within this call; previously our compiling with hard-float - * would result in fp instructions being emitted outside of the boundaries - * of the DC_FP_START/END macros, which makes sense as the compiler has no - * idea about what is wrapped and what is not - * - * This is largely just a workaround to avoid breakage introduced with 5.6, - * ideally all fp-using code should be moved into its own file, only that - * should be compiled with hard-float, and all code exported from there - * should be strictly wrapped with DC_FP_START/END - */ -static noinline void dcn30_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, - unsigned int *optimal_dcfclk, - unsigned int *optimal_fclk) -{ - double bw_from_dram, bw_from_dram1, bw_from_dram2; - - bw_from_dram1 = uclk_mts * dcn3_0_soc.num_chans * - dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_dram_bw_use_normal_percent / 100); - bw_from_dram2 = uclk_mts * dcn3_0_soc.num_chans * - dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100); - - bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2; - - if (optimal_fclk) - *optimal_fclk = bw_from_dram / - (dcn3_0_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100)); - - if (optimal_dcfclk) - *optimal_dcfclk = bw_from_dram / - (dcn3_0_soc.return_bus_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100)); -} - void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) { unsigned int i, j; @@ -2399,47 +1985,43 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params unsigned int num_dcfclk_sta_targets = 4; unsigned int num_uclk_states; + struct dc_bounding_box_max_clk dcn30_bb_max_clk; + + memset(&dcn30_bb_max_clk, 0, sizeof(dcn30_bb_max_clk)); + if (dc->ctx->dc_bios->vram_info.num_chans) dcn3_0_soc.num_chans = dc->ctx->dc_bios->vram_info.num_chans; - if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) - dcn3_0_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; - - dcn3_0_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; - dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; + DC_FP_START(); + dcn30_fpu_update_dram_channel_width_bytes(dc); + DC_FP_END(); if (bw_params->clk_table.entries[0].memclk_mhz) { - int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0; for (i = 0; i < MAX_NUM_DPM_LVL; i++) { - if (bw_params->clk_table.entries[i].dcfclk_mhz > max_dcfclk_mhz) - max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz; - if (bw_params->clk_table.entries[i].dispclk_mhz > max_dispclk_mhz) - max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz; - if (bw_params->clk_table.entries[i].dppclk_mhz > max_dppclk_mhz) - max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz; - if (bw_params->clk_table.entries[i].phyclk_mhz > max_phyclk_mhz) - max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz; + if (bw_params->clk_table.entries[i].dcfclk_mhz > dcn30_bb_max_clk.max_dcfclk_mhz) + dcn30_bb_max_clk.max_dcfclk_mhz = bw_params->clk_table.entries[i].dcfclk_mhz; + if (bw_params->clk_table.entries[i].dispclk_mhz > dcn30_bb_max_clk.max_dispclk_mhz) + dcn30_bb_max_clk.max_dispclk_mhz = bw_params->clk_table.entries[i].dispclk_mhz; + if (bw_params->clk_table.entries[i].dppclk_mhz > dcn30_bb_max_clk.max_dppclk_mhz) + dcn30_bb_max_clk.max_dppclk_mhz = bw_params->clk_table.entries[i].dppclk_mhz; + if (bw_params->clk_table.entries[i].phyclk_mhz > dcn30_bb_max_clk.max_phyclk_mhz) + dcn30_bb_max_clk.max_phyclk_mhz = bw_params->clk_table.entries[i].phyclk_mhz; } - if (!max_dcfclk_mhz) - max_dcfclk_mhz = dcn3_0_soc.clock_limits[0].dcfclk_mhz; - if (!max_dispclk_mhz) - max_dispclk_mhz = dcn3_0_soc.clock_limits[0].dispclk_mhz; - if (!max_dppclk_mhz) - max_dppclk_mhz = dcn3_0_soc.clock_limits[0].dppclk_mhz; - if (!max_phyclk_mhz) - max_phyclk_mhz = dcn3_0_soc.clock_limits[0].phyclk_mhz; + DC_FP_START(); + dcn30_fpu_update_max_clk(&dcn30_bb_max_clk); + DC_FP_END(); - if (max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { + if (dcn30_bb_max_clk.max_dcfclk_mhz > dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { // If max DCFCLK is greater than the max DCFCLK STA target, insert into the DCFCLK STA target array - dcfclk_sta_targets[num_dcfclk_sta_targets] = max_dcfclk_mhz; + dcfclk_sta_targets[num_dcfclk_sta_targets] = dcn30_bb_max_clk.max_dcfclk_mhz; num_dcfclk_sta_targets++; - } else if (max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { + } else if (dcn30_bb_max_clk.max_dcfclk_mhz < dcfclk_sta_targets[num_dcfclk_sta_targets-1]) { // If max DCFCLK is less than the max DCFCLK STA target, cap values and remove duplicates for (i = 0; i < num_dcfclk_sta_targets; i++) { - if (dcfclk_sta_targets[i] > max_dcfclk_mhz) { - dcfclk_sta_targets[i] = max_dcfclk_mhz; + if (dcfclk_sta_targets[i] > dcn30_bb_max_clk.max_dcfclk_mhz) { + dcfclk_sta_targets[i] = dcn30_bb_max_clk.max_dcfclk_mhz; break; } } @@ -2452,7 +2034,7 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params // Calculate optimal dcfclk for each uclk for (i = 0; i < num_uclk_states; i++) { DC_FP_START(); - dcn30_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, + dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, &optimal_dcfclk_for_uclk[i], NULL); DC_FP_END(); if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { @@ -2479,7 +2061,7 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params dcfclk_mhz[num_states] = dcfclk_sta_targets[i]; dram_speed_mts[num_states++] = optimal_uclk_for_dcfclk_sta_targets[i++]; } else { - if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) { + if (j < num_uclk_states && optimal_dcfclk_for_uclk[j] <= dcn30_bb_max_clk.max_dcfclk_mhz) { dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j]; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; } else { @@ -2494,33 +2076,15 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params } while (j < num_uclk_states && num_states < DC__VOLTAGE_STATES && - optimal_dcfclk_for_uclk[j] <= max_dcfclk_mhz) { + optimal_dcfclk_for_uclk[j] <= dcn30_bb_max_clk.max_dcfclk_mhz) { dcfclk_mhz[num_states] = optimal_dcfclk_for_uclk[j]; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; } dcn3_0_soc.num_states = num_states; - for (i = 0; i < dcn3_0_soc.num_states; i++) { - dcn3_0_soc.clock_limits[i].state = i; - dcn3_0_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i]; - dcn3_0_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i]; - dcn3_0_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i]; - - /* Fill all states with max values of all other clocks */ - dcn3_0_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; - dcn3_0_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; - dcn3_0_soc.clock_limits[i].phyclk_mhz = max_phyclk_mhz; - dcn3_0_soc.clock_limits[i].dtbclk_mhz = dcn3_0_soc.clock_limits[0].dtbclk_mhz; - /* These clocks cannot come from bw_params, always fill from dcn3_0_soc[1] */ - /* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */ - dcn3_0_soc.clock_limits[i].phyclk_d18_mhz = dcn3_0_soc.clock_limits[0].phyclk_d18_mhz; - dcn3_0_soc.clock_limits[i].socclk_mhz = dcn3_0_soc.clock_limits[0].socclk_mhz; - dcn3_0_soc.clock_limits[i].dscclk_mhz = dcn3_0_soc.clock_limits[0].dscclk_mhz; - } - /* re-init DML with updated bb */ - dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30); - if (dc->current_state) - dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30); + DC_FP_START(); + dcn30_fpu_update_bw_bounding_box(dc, bw_params, &dcn30_bb_max_clk, dcfclk_mhz, dram_speed_mts); + DC_FP_END(); } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h index b92e4cc0232f..3330a1026fa5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h @@ -35,6 +35,9 @@ struct dc; struct resource_pool; struct _vcs_dpi_display_pipe_params_st; +extern struct _vcs_dpi_ip_params_st dcn3_0_ip; +extern struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc; + struct dcn30_resource_pool { struct resource_pool base; }; @@ -96,4 +99,6 @@ enum dc_status dcn30_add_stream_to_ctx( void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params); +void dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(struct dc *dc, struct dc_state *context); + #endif /* _DCN30_RESOURCE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index 4daf8931aa7c..a5df74110284 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -81,6 +81,8 @@ #include "dce/dce_aux.h" #include "dce/dce_i2c.h" +#include "dml/dcn30/dcn30_fpu.h" + #include "dml/dcn30/display_mode_vba_30.h" #include "dml/dcn301/dcn301_fpu.h" #include "vm_helper.h" diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index f0938653bb88..f537888f4fa6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -43,6 +43,8 @@ #include "dcn20/dcn20_dsc.h" #include "dcn20/dcn20_resource.h" +#include "dml/dcn30/dcn30_fpu.h" + #include "dcn10/dcn10_resource.h" #include "dce/dce_abm.h" diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index 4fcbc0502808..76f863eb86ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -25,6 +25,8 @@ #include "dcn20/dcn20_dsc.h" #include "dcn20/dcn20_resource.h" +#include "dml/dcn30/dcn30_fpu.h" + #include "dcn10/dcn10_resource.h" #include "dc_link_ddc.h" diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 287a1066b547..bbc58d167c63 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -513,12 +513,10 @@ void dccg31_set_physymclk( /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ static void dccg31_set_dtbclk_dto( struct dccg *dccg, - int dtbclk_inst, - int req_dtbclk_khz, - int num_odm_segments, - const struct dc_crtc_timing *timing) + struct dtbclk_dto_params *params) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + int req_dtbclk_khz = params->pixclk_khz; uint32_t dtbdto_div; /* Mode DTBDTO Rate DTBCLK_DTO<x>_DIV Register @@ -529,57 +527,53 @@ static void dccg31_set_dtbclk_dto( * DSC native 4:2:2 pixel rate/2 4 * Other modes pixel rate 8 */ - if (num_odm_segments == 4) { + if (params->num_odm_segments == 4) { dtbdto_div = 2; - req_dtbclk_khz = req_dtbclk_khz / 4; - } else if ((num_odm_segments == 2) || - (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || - (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 - && !timing->dsc_cfg.ycbcr422_simple)) { + req_dtbclk_khz = params->pixclk_khz / 4; + } else if ((params->num_odm_segments == 2) || + (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || + (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 + && !params->timing->dsc_cfg.ycbcr422_simple)) { dtbdto_div = 4; - req_dtbclk_khz = req_dtbclk_khz / 2; + req_dtbclk_khz = params->pixclk_khz / 2; } else dtbdto_div = 8; - if (dccg->ref_dtbclk_khz && req_dtbclk_khz) { + if (params->ref_dtbclk_khz && req_dtbclk_khz) { uint32_t modulo, phase; // phase / modulo = dtbclk / dtbclk ref - modulo = dccg->ref_dtbclk_khz * 1000; - phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1), - dccg->ref_dtbclk_khz); + modulo = params->ref_dtbclk_khz * 1000; + phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1), + params->ref_dtbclk_khz); - REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div); + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); - REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo); - REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase); + REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo); + REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase); - REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLK_DTO_ENABLE[dtbclk_inst], 1); + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 1); - REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1, + REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1, 1, 100); /* The recommended programming sequence to enable DTBCLK DTO to generate * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should * be set only after DTO is enabled */ - REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - PIPE_DTO_SRC_SEL[dtbclk_inst], 1); - - dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz; + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + PIPE_DTO_SRC_SEL[params->otg_inst], 1); } else { - REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLK_DTO_ENABLE[dtbclk_inst], 0, - PIPE_DTO_SRC_SEL[dtbclk_inst], 0, - DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div); + REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 0, + PIPE_DTO_SRC_SEL[params->otg_inst], 0, + DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); - REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0); - REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0); - - dccg->dtbclk_khz[dtbclk_inst] = 0; + REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); + REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); } } @@ -606,16 +600,12 @@ void dccg31_set_audio_dtbclk_dto( REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, 4); // 04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK - - dccg->audio_dtbclk_khz = req_audio_dtbclk_khz; } else { REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0); REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0); REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, 3); // 03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO - - dccg->audio_dtbclk_khz = 0; } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c index d94fd1010deb..8b12b4111c88 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c @@ -230,9 +230,7 @@ static void enc31_hw_init(struct link_encoder *enc) AUX_RX_PHASE_DETECT_LEN, [21,20] = 0x3 default is 3 AUX_RX_DETECTION_THRESHOLD [30:28] = 1 */ - AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); - - AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a); + // dmub will read AUX_DPHY_RX_CONTROL0/AUX_DPHY_TX_CONTROL from vbios table in dp_aux_init //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; // Set AUX_TX_REF_DIV Divider to generate 2 MHz reference from refclk diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index 5b3f0c2dfb55..3d9f07d4770b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -36,6 +36,8 @@ #include "dcn20/dcn20_resource.h" #include "dcn30/dcn30_resource.h" +#include "dml/dcn30/dcn30_fpu.h" + #include "dcn10/dcn10_ipp.h" #include "dcn30/dcn30_hubbub.h" #include "dcn31/dcn31_hubbub.h" @@ -890,6 +892,7 @@ static const struct dc_debug_options debug_defaults_drv = { .enable_sw_cntl_psr = true, .apply_vendor_specific_lttpr_wa = true, .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/ + .dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE, }; static const struct dc_debug_options debug_defaults_diags = { @@ -1247,12 +1250,6 @@ static struct stream_encoder *dcn31_stream_encoder_create( return NULL; } - if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && - ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { - if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD)) - eng_id = eng_id + 3; // For B0 only. C->F, D->G. - } - dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id], @@ -1666,7 +1663,6 @@ int dcn31_populate_dml_pipes_from_context( * intermittently experienced depending on peak b/w requirements. */ pipes[pipe_cnt].pipe.src.immediate_flip = true; - pipes[pipe_cnt].pipe.src.unbounded_req_mode = false; pipes[pipe_cnt].pipe.src.gpuvm = true; pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0; @@ -1675,6 +1671,13 @@ int dcn31_populate_dml_pipes_from_context( pipes[pipe_cnt].pipe.src.dcc_rate = 3; pipes[pipe_cnt].dout.dsc_input_bpc = 0; + if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE) + pipes[pipe_cnt].pipe.src.hostvm = dc->res_pool->hubbub->riommu_active; + else if (dc->debug.dml_hostvm_override == DML_HOSTVM_OVERRIDE_FALSE) + pipes[pipe_cnt].pipe.src.hostvm = false; + else if (dc->debug.dml_hostvm_override == DML_HOSTVM_OVERRIDE_TRUE) + pipes[pipe_cnt].pipe.src.hostvm = true; + if (pipes[pipe_cnt].dout.dsc_enable) { switch (timing->display_color_depth) { case COLOR_DEPTH_888: @@ -1735,6 +1738,27 @@ void dcn31_calculate_wm_and_dlg( DC_FP_END(); } +void +dcn31_populate_dml_writeback_from_context(struct dc *dc, + struct resource_context *res_ctx, + display_e2e_pipe_params_st *pipes) +{ + DC_FP_START(); + dcn30_populate_dml_writeback_from_context(dc, res_ctx, pipes); + DC_FP_END(); +} + +void +dcn31_set_mcif_arb_params(struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt) +{ + DC_FP_START(); + dcn30_set_mcif_arb_params(dc, context, pipes, pipe_cnt); + DC_FP_END(); +} + bool dcn31_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate) @@ -1808,8 +1832,8 @@ static struct resource_funcs dcn31_res_pool_funcs = { .add_stream_to_ctx = dcn30_add_stream_to_ctx, .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, - .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, - .set_mcif_arb_params = dcn30_set_mcif_arb_params, + .populate_dml_writeback_from_context = dcn31_populate_dml_writeback_from_context, + .set_mcif_arb_params = dcn31_set_mcif_arb_params, .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h index 1ce6509c1ed1..393458015d6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h @@ -50,6 +50,15 @@ int dcn31_populate_dml_pipes_from_context( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, bool fast_validate); +void +dcn31_populate_dml_writeback_from_context(struct dc *dc, + struct resource_context *res_ctx, + display_e2e_pipe_params_st *pipes); +void +dcn31_set_mcif_arb_params(struct dc *dc, + struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt); void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context); struct resource_pool *dcn31_create_resource_pool( diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c index e6f9312e3a48..2b42af030b33 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c @@ -1726,8 +1726,8 @@ static struct resource_funcs dcn315_res_pool_funcs = { .add_stream_to_ctx = dcn30_add_stream_to_ctx, .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, - .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, - .set_mcif_arb_params = dcn30_set_mcif_arb_params, + .populate_dml_writeback_from_context = dcn31_populate_dml_writeback_from_context, + .set_mcif_arb_params = dcn31_set_mcif_arb_params, .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c index d5c195749a81..ef16260b7f3f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c @@ -1728,8 +1728,8 @@ static struct resource_funcs dcn316_res_pool_funcs = { .add_stream_to_ctx = dcn30_add_stream_to_ctx, .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, - .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, - .set_mcif_arb_params = dcn30_set_mcif_arb_params, + .populate_dml_writeback_from_context = dcn31_populate_dml_writeback_from_context, + .set_mcif_arb_params = dcn31_set_mcif_arb_params, .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, .acquire_post_bldn_3dlut = dcn30_acquire_post_bldn_3dlut, .release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut, diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 31109db02e93..fb6a2d7b6470 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -160,9 +160,7 @@ void dm_set_dcn_clocks( struct dc_context *ctx, struct dc_clocks *clks); -#if defined(CONFIG_DRM_AMD_DC_DCN) void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable); -#endif void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz); diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index ee911452c048..a64b88ca01a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -71,6 +71,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(fram CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag) CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_ccflags) @@ -113,7 +114,7 @@ DML += dcn20/dcn20_fpu.o DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o -DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o +DML += dcn30/dcn30_fpu.o dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o DML += dcn31/dcn31_fpu.o DML += dcn301/dcn301_fpu.o diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c new file mode 100644 index 000000000000..574676a0711a --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c @@ -0,0 +1,617 @@ +/* + * Copyright 2020-2021 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 "resource.h" +#include "clk_mgr.h" +#include "reg_helper.h" +#include "dcn_calc_math.h" +#include "dcn20/dcn20_resource.h" +#include "dcn30/dcn30_resource.h" + + +#include "display_mode_vba_30.h" +#include "dcn30_fpu.h" + +#define REG(reg)\ + optc1->tg_regs->reg + +#define CTX \ + optc1->base.ctx + +#undef FN +#define FN(reg_name, field_name) \ + optc1->tg_shift->field_name, optc1->tg_mask->field_name + + +struct _vcs_dpi_ip_params_st dcn3_0_ip = { + .use_min_dcfclk = 0, + .clamp_min_dcfclk = 0, + .odm_capable = 1, + .gpuvm_enable = 0, + .hostvm_enable = 0, + .gpuvm_max_page_table_levels = 4, + .hostvm_max_page_table_levels = 4, + .hostvm_cached_page_table_levels = 0, + .pte_group_size_bytes = 2048, + .num_dsc = 6, + .rob_buffer_size_kbytes = 184, + .det_buffer_size_kbytes = 184, + .dpte_buffer_size_in_pte_reqs_luma = 84, + .pde_proc_buffer_size_64k_reqs = 48, + .dpp_output_buffer_pixels = 2560, + .opp_output_buffer_lines = 1, + .pixel_chunk_size_kbytes = 8, + .pte_enable = 1, + .max_page_table_levels = 2, + .pte_chunk_size_kbytes = 2, // ? + .meta_chunk_size_kbytes = 2, + .writeback_chunk_size_kbytes = 8, + .line_buffer_size_bits = 789504, + .is_line_buffer_bpp_fixed = 0, // ? + .line_buffer_fixed_bpp = 0, // ? + .dcc_supported = true, + .writeback_interface_buffer_size_kbytes = 90, + .writeback_line_buffer_buffer_size = 0, + .max_line_buffer_lines = 12, + .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 + .writeback_chroma_buffer_size_kbytes = 8, + .writeback_chroma_line_buffer_width_pixels = 4, + .writeback_max_hscl_ratio = 1, + .writeback_max_vscl_ratio = 1, + .writeback_min_hscl_ratio = 1, + .writeback_min_vscl_ratio = 1, + .writeback_max_hscl_taps = 1, + .writeback_max_vscl_taps = 1, + .writeback_line_buffer_luma_buffer_size = 0, + .writeback_line_buffer_chroma_buffer_size = 14643, + .cursor_buffer_size = 8, + .cursor_chunk_size = 2, + .max_num_otg = 6, + .max_num_dpp = 6, + .max_num_wb = 1, + .max_dchub_pscl_bw_pix_per_clk = 4, + .max_pscl_lb_bw_pix_per_clk = 2, + .max_lb_vscl_bw_pix_per_clk = 4, + .max_vscl_hscl_bw_pix_per_clk = 4, + .max_hscl_ratio = 6, + .max_vscl_ratio = 6, + .hscl_mults = 4, + .vscl_mults = 4, + .max_hscl_taps = 8, + .max_vscl_taps = 8, + .dispclk_ramp_margin_percent = 1, + .underscan_factor = 1.11, + .min_vblank_lines = 32, + .dppclk_delay_subtotal = 46, + .dynamic_metadata_vm_enabled = true, + .dppclk_delay_scl_lb_only = 16, + .dppclk_delay_scl = 50, + .dppclk_delay_cnvc_formatter = 27, + .dppclk_delay_cnvc_cursor = 6, + .dispclk_delay_subtotal = 119, + .dcfclk_cstate_latency = 5.2, // SRExitTime + .max_inter_dcn_tile_repeaters = 8, + .max_num_hdmi_frl_outputs = 1, + .odm_combine_4to1_supported = true, + + .xfc_supported = false, + .xfc_fill_bw_overhead_percent = 10.0, + .xfc_fill_constant_bytes = 0, + .gfx7_compat_tiling_supported = 0, + .number_of_cursors = 1, +}; + +struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = { + .clock_limits = { + { + .state = 0, + .dispclk_mhz = 562.0, + .dppclk_mhz = 300.0, + .phyclk_mhz = 300.0, + .phyclk_d18_mhz = 667.0, + .dscclk_mhz = 405.6, + }, + }, + + .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ + .num_states = 1, + .sr_exit_time_us = 15.5, + .sr_enter_plus_exit_time_us = 20, + .urgent_latency_us = 4.0, + .urgent_latency_pixel_data_only_us = 4.0, + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, + .urgent_latency_vm_data_only_us = 4.0, + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, + .max_avg_sdp_bw_use_normal_percent = 60.0, + .max_avg_dram_bw_use_normal_percent = 40.0, + .writeback_latency_us = 12.0, + .max_request_size_bytes = 256, + .fabric_datapath_to_dcn_data_return_bytes = 64, + .dcn_downspread_percent = 0.5, + .downspread_percent = 0.38, + .dram_page_open_time_ns = 50.0, + .dram_rw_turnaround_time_ns = 17.5, + .dram_return_buffer_per_channel_bytes = 8192, + .round_trip_ping_latency_dcfclk_cycles = 191, + .urgent_out_of_order_return_per_channel_bytes = 4096, + .channel_interleave_bytes = 256, + .num_banks = 8, + .gpuvm_min_page_size_bytes = 4096, + .hostvm_min_page_size_bytes = 4096, + .dram_clock_change_latency_us = 404, + .dummy_pstate_latency_us = 5, + .writeback_dram_clock_change_latency_us = 23.0, + .return_bus_width_bytes = 64, + .dispclk_dppclk_vco_speed_mhz = 3650, + .xfc_bus_transport_time_us = 20, // ? + .xfc_xbuf_latency_tolerance_us = 4, // ? + .use_urgent_burst_bw = 1, // ? + .do_urgent_latency_adjustment = true, + .urgent_latency_adjustment_fabric_clock_component_us = 1.0, + .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, +}; + + +void optc3_fpu_set_vrr_m_const(struct timing_generator *optc, + double vtotal_avg) +{ +struct optc *optc1 = DCN10TG_FROM_TG(optc); + double vtotal_min, vtotal_max; + double ratio, modulo, phase; + uint32_t vblank_start; + uint32_t v_total_mask_value = 0; + + dc_assert_fp_enabled(); + + /* Compute VTOTAL_MIN and VTOTAL_MAX, so that + * VOTAL_MAX - VTOTAL_MIN = 1 + */ + v_total_mask_value = 16; + vtotal_min = dcn_bw_floor(vtotal_avg); + vtotal_max = dcn_bw_ceil(vtotal_avg); + + /* Check that bottom VBLANK is at least 2 lines tall when running with + * VTOTAL_MIN. Note that VTOTAL registers are defined as 'total number + * of lines in a frame - 1'. + */ + REG_GET(OTG_V_BLANK_START_END, OTG_V_BLANK_START, + &vblank_start); + ASSERT(vtotal_min >= vblank_start + 1); + + /* Special case where the average frame rate can be achieved + * without using the DTO + */ + if (vtotal_min == vtotal_max) { + REG_SET(OTG_V_TOTAL, 0, OTG_V_TOTAL, (uint32_t)vtotal_min); + + optc->funcs->set_vtotal_min_max(optc, 0, 0); + REG_SET(OTG_M_CONST_DTO0, 0, OTG_M_CONST_DTO_PHASE, 0); + REG_SET(OTG_M_CONST_DTO1, 0, OTG_M_CONST_DTO_MODULO, 0); + REG_UPDATE_3(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MIN_SEL, 0, + OTG_V_TOTAL_MAX_SEL, 0, + OTG_SET_V_TOTAL_MIN_MASK_EN, 0); + return; + } + + ratio = vtotal_max - vtotal_avg; + modulo = 65536.0 * 65536.0 - 1.0; /* 2^32 - 1 */ + phase = ratio * modulo; + + /* Special cases where the DTO phase gets rounded to 0 or + * to DTO modulo + */ + if (phase <= 0 || phase >= modulo) { + REG_SET(OTG_V_TOTAL, 0, OTG_V_TOTAL, + phase <= 0 ? + (uint32_t)vtotal_max : (uint32_t)vtotal_min); + REG_SET(OTG_V_TOTAL_MIN, 0, OTG_V_TOTAL_MIN, 0); + REG_SET(OTG_V_TOTAL_MAX, 0, OTG_V_TOTAL_MAX, 0); + REG_SET(OTG_M_CONST_DTO0, 0, OTG_M_CONST_DTO_PHASE, 0); + REG_SET(OTG_M_CONST_DTO1, 0, OTG_M_CONST_DTO_MODULO, 0); + REG_UPDATE_3(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MIN_SEL, 0, + OTG_V_TOTAL_MAX_SEL, 0, + OTG_SET_V_TOTAL_MIN_MASK_EN, 0); + return; + } + REG_UPDATE_6(OTG_V_TOTAL_CONTROL, + OTG_V_TOTAL_MIN_SEL, 1, + OTG_V_TOTAL_MAX_SEL, 1, + OTG_SET_V_TOTAL_MIN_MASK_EN, 1, + OTG_SET_V_TOTAL_MIN_MASK, v_total_mask_value, + OTG_VTOTAL_MID_REPLACING_MIN_EN, 0, + OTG_VTOTAL_MID_REPLACING_MAX_EN, 0); + REG_SET(OTG_V_TOTAL, 0, OTG_V_TOTAL, (uint32_t)vtotal_min); + optc->funcs->set_vtotal_min_max(optc, vtotal_min, vtotal_max); + REG_SET(OTG_M_CONST_DTO0, 0, OTG_M_CONST_DTO_PHASE, (uint32_t)phase); + REG_SET(OTG_M_CONST_DTO1, 0, OTG_M_CONST_DTO_MODULO, (uint32_t)modulo); +} + +void dcn30_fpu_populate_dml_writeback_from_context( + struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) +{ + int pipe_cnt, i, j; + double max_calc_writeback_dispclk; + double writeback_dispclk; + struct writeback_st dout_wb; + + dc_assert_fp_enabled(); + + for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { + struct dc_stream_state *stream = res_ctx->pipe_ctx[i].stream; + + if (!stream) + continue; + max_calc_writeback_dispclk = 0; + + /* Set writeback information */ + pipes[pipe_cnt].dout.wb_enable = 0; + pipes[pipe_cnt].dout.num_active_wb = 0; + for (j = 0; j < stream->num_wb_info; j++) { + struct dc_writeback_info *wb_info = &stream->writeback_info[j]; + + if (wb_info->wb_enabled && wb_info->writeback_source_plane && + (wb_info->writeback_source_plane == res_ctx->pipe_ctx[i].plane_state)) { + pipes[pipe_cnt].dout.wb_enable = 1; + pipes[pipe_cnt].dout.num_active_wb++; + dout_wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_en ? + wb_info->dwb_params.cnv_params.crop_height : + wb_info->dwb_params.cnv_params.src_height; + dout_wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_en ? + wb_info->dwb_params.cnv_params.crop_width : + wb_info->dwb_params.cnv_params.src_width; + dout_wb.wb_dst_width = wb_info->dwb_params.dest_width; + dout_wb.wb_dst_height = wb_info->dwb_params.dest_height; + + /* For IP that doesn't support WB scaling, set h/v taps to 1 to avoid DML validation failure */ + if (dc->dml.ip.writeback_max_hscl_taps > 1) { + dout_wb.wb_htaps_luma = wb_info->dwb_params.scaler_taps.h_taps; + dout_wb.wb_vtaps_luma = wb_info->dwb_params.scaler_taps.v_taps; + } else { + dout_wb.wb_htaps_luma = 1; + dout_wb.wb_vtaps_luma = 1; + } + dout_wb.wb_htaps_chroma = 0; + dout_wb.wb_vtaps_chroma = 0; + dout_wb.wb_hratio = wb_info->dwb_params.cnv_params.crop_en ? + (double)wb_info->dwb_params.cnv_params.crop_width / + (double)wb_info->dwb_params.dest_width : + (double)wb_info->dwb_params.cnv_params.src_width / + (double)wb_info->dwb_params.dest_width; + dout_wb.wb_vratio = wb_info->dwb_params.cnv_params.crop_en ? + (double)wb_info->dwb_params.cnv_params.crop_height / + (double)wb_info->dwb_params.dest_height : + (double)wb_info->dwb_params.cnv_params.src_height / + (double)wb_info->dwb_params.dest_height; + if (wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_ARGB || + wb_info->dwb_params.cnv_params.fc_out_format == DWB_OUT_FORMAT_64BPP_RGBA) + dout_wb.wb_pixel_format = dm_444_64; + else + dout_wb.wb_pixel_format = dm_444_32; + + /* Workaround for cases where multiple writebacks are connected to same plane + * In which case, need to compute worst case and set the associated writeback parameters + * This workaround is necessary due to DML computation assuming only 1 set of writeback + * parameters per pipe + */ + writeback_dispclk = dml30_CalculateWriteBackDISPCLK( + dout_wb.wb_pixel_format, + pipes[pipe_cnt].pipe.dest.pixel_rate_mhz, + dout_wb.wb_hratio, + dout_wb.wb_vratio, + dout_wb.wb_htaps_luma, + dout_wb.wb_vtaps_luma, + dout_wb.wb_src_width, + dout_wb.wb_dst_width, + pipes[pipe_cnt].pipe.dest.htotal, + dc->current_state->bw_ctx.dml.ip.writeback_line_buffer_buffer_size); + + if (writeback_dispclk > max_calc_writeback_dispclk) { + max_calc_writeback_dispclk = writeback_dispclk; + pipes[pipe_cnt].dout.wb = dout_wb; + } + } + } + + pipe_cnt++; + } +} + +void dcn30_fpu_set_mcif_arb_params(struct mcif_arb_params *wb_arb_params, + struct display_mode_lib *dml, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int cur_pipe) +{ + int i; + + dc_assert_fp_enabled(); + + for (i = 0; i < sizeof(wb_arb_params->cli_watermark)/sizeof(wb_arb_params->cli_watermark[0]); i++) { + wb_arb_params->cli_watermark[i] = get_wm_writeback_urgent(dml, pipes, pipe_cnt) * 1000; + wb_arb_params->pstate_watermark[i] = get_wm_writeback_dram_clock_change(dml, pipes, pipe_cnt) * 1000; + } + + wb_arb_params->dram_speed_change_duration = dml->vba.WritebackAllowDRAMClockChangeEndPosition[cur_pipe] * pipes[0].clks_cfg.refclk_mhz; /* num_clock_cycles = us * MHz */ +} + +void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) +{ + +dc_assert_fp_enabled(); + +if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) { + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us; + context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us; + } +} + +void dcn30_fpu_calculate_wm_and_dlg( + struct dc *dc, struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int vlevel) +{ +int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; + int i, pipe_idx; + double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb]; + bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported; + +dc_assert_fp_enabled(); + + if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) + dcfclk = context->bw_ctx.dml.soc.min_dcfclk; + + pipes[0].clks_cfg.voltage = vlevel; + pipes[0].clks_cfg.dcfclk_mhz = dcfclk; + pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz; + + /* Set B: + * DCFCLK: 1GHz or min required above 1GHz + * FCLK/UCLK: Max + */ + if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].valid) { + if (vlevel == 0) { + pipes[0].clks_cfg.voltage = 1; + pipes[0].clks_cfg.dcfclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dcfclk_mhz; + } + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us; + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us; + context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us; + } + context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.b.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + + pipes[0].clks_cfg.voltage = vlevel; + pipes[0].clks_cfg.dcfclk_mhz = dcfclk; + + /* Set D: + * DCFCLK: Min Required + * FCLK(proportional to UCLK): 1GHz or Max + * MALL stutter, sr_enter_exit = 4, sr_exit = 2us + */ + /* + if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.pstate_latency_us; + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_enter_plus_exit_time_us; + context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].dml_input.sr_exit_time_us; + } + context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.d.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + */ + + /* Set C: + * DCFCLK: Min Required + * FCLK(proportional to UCLK): 1GHz or Max + * pstate latency overridden to 5us + */ + if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) { + unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; + unsigned int min_dram_speed_mts_margin = 160; + + if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] == dm_dram_clock_change_unsupported) + min_dram_speed_mts = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz * 16; + + /* find largest table entry that is lower than dram speed, but lower than DPM0 still uses DPM0 */ + for (i = 3; i > 0; i--) + if (min_dram_speed_mts + min_dram_speed_mts_margin > dc->clk_mgr->bw_params->dummy_pstate_table[i].dram_speed_mts) + break; + + context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->dummy_pstate_table[i].dummy_pstate_latency_us; + + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us; + context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us; + } + + context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.c.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + + if (!pstate_en) { + /* The only difference between A and C is p-state latency, if p-state is not supported we want to + * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark + */ + context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 0; + } else { + /* Set A: + * DCFCLK: Min Required + * FCLK(proportional to UCLK): 1GHz or Max + * + * Set A calculated last so that following calculations are based on Set A + */ + dc->res_pool->funcs->update_soc_for_wm_a(dc, context); + context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = get_wm_memory_trip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + context->bw_ctx.bw.dcn.watermarks.a.urgent_latency_ns = get_urgent_latency(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; + } + + context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod; + + /* Make set D = set A until set D is enabled */ + context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; + + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + if (!context->res_ctx.pipe_ctx[i].stream) + continue; + + pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); + pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); + + if (dc->config.forced_clocks) { + pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; + pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; + } + if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) + pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; + if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) + pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; + + pipe_idx++; + } + + DC_FP_START(); + dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); + DC_FP_END(); + + if (!pstate_en) + /* Restore full p-state latency */ + context->bw_ctx.dml.soc.dram_clock_change_latency_us = + dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; + +} + +void dcn30_fpu_update_dram_channel_width_bytes(struct dc *dc) +{ + dc_assert_fp_enabled(); + + if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) + dcn3_0_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; +} + +void dcn30_fpu_update_max_clk(struct dc_bounding_box_max_clk *dcn30_bb_max_clk) +{ + dc_assert_fp_enabled(); + + if (!dcn30_bb_max_clk->max_dcfclk_mhz) + dcn30_bb_max_clk->max_dcfclk_mhz = dcn3_0_soc.clock_limits[0].dcfclk_mhz; + if (!dcn30_bb_max_clk->max_dispclk_mhz) + dcn30_bb_max_clk->max_dispclk_mhz = dcn3_0_soc.clock_limits[0].dispclk_mhz; + if (!dcn30_bb_max_clk->max_dppclk_mhz) + dcn30_bb_max_clk->max_dppclk_mhz = dcn3_0_soc.clock_limits[0].dppclk_mhz; + if (!dcn30_bb_max_clk->max_phyclk_mhz) + dcn30_bb_max_clk->max_phyclk_mhz = dcn3_0_soc.clock_limits[0].phyclk_mhz; +} + +void dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, + unsigned int *optimal_dcfclk, + unsigned int *optimal_fclk) +{ + double bw_from_dram, bw_from_dram1, bw_from_dram2; + + dc_assert_fp_enabled(); + + bw_from_dram1 = uclk_mts * dcn3_0_soc.num_chans * + dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_dram_bw_use_normal_percent / 100); + bw_from_dram2 = uclk_mts * dcn3_0_soc.num_chans * + dcn3_0_soc.dram_channel_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100); + + bw_from_dram = (bw_from_dram1 < bw_from_dram2) ? bw_from_dram1 : bw_from_dram2; + + if (optimal_fclk) + *optimal_fclk = bw_from_dram / + (dcn3_0_soc.fabric_datapath_to_dcn_data_return_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100)); + + if (optimal_dcfclk) + *optimal_dcfclk = bw_from_dram / + (dcn3_0_soc.return_bus_width_bytes * (dcn3_0_soc.max_avg_sdp_bw_use_normal_percent / 100)); +} + +void dcn30_fpu_update_bw_bounding_box(struct dc *dc, + struct clk_bw_params *bw_params, + struct dc_bounding_box_max_clk *dcn30_bb_max_clk, + unsigned int *dcfclk_mhz, + unsigned int *dram_speed_mts) +{ + unsigned int i; + + dc_assert_fp_enabled(); + + dcn3_0_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; + dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; + + for (i = 0; i < dcn3_0_soc.num_states; i++) { + dcn3_0_soc.clock_limits[i].state = i; + dcn3_0_soc.clock_limits[i].dcfclk_mhz = dcfclk_mhz[i]; + dcn3_0_soc.clock_limits[i].fabricclk_mhz = dcfclk_mhz[i]; + dcn3_0_soc.clock_limits[i].dram_speed_mts = dram_speed_mts[i]; + + /* Fill all states with max values of all other clocks */ + dcn3_0_soc.clock_limits[i].dispclk_mhz = dcn30_bb_max_clk->max_dispclk_mhz; + dcn3_0_soc.clock_limits[i].dppclk_mhz = dcn30_bb_max_clk->max_dppclk_mhz; + dcn3_0_soc.clock_limits[i].phyclk_mhz = dcn30_bb_max_clk->max_phyclk_mhz; + dcn3_0_soc.clock_limits[i].dtbclk_mhz = dcn3_0_soc.clock_limits[0].dtbclk_mhz; + /* These clocks cannot come from bw_params, always fill from dcn3_0_soc[1] */ + /* FCLK, PHYCLK_D18, SOCCLK, DSCCLK */ + dcn3_0_soc.clock_limits[i].phyclk_d18_mhz = dcn3_0_soc.clock_limits[0].phyclk_d18_mhz; + dcn3_0_soc.clock_limits[i].socclk_mhz = dcn3_0_soc.clock_limits[0].socclk_mhz; + dcn3_0_soc.clock_limits[i].dscclk_mhz = dcn3_0_soc.clock_limits[0].dscclk_mhz; + } + /* re-init DML with updated bb */ + dml_init_instance(&dc->dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30); + if (dc->current_state) + dml_init_instance(&dc->current_state->bw_ctx.dml, &dcn3_0_soc, &dcn3_0_ip, DML_PROJECT_DCN30); + +} + + diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h new file mode 100644 index 000000000000..dedfe7b5f173 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h @@ -0,0 +1,67 @@ +/* + * Copyright 2020-2021 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 __DCN30_FPU_H__ +#define __DCN30_FPU_H__ + +#include "core_types.h" +#include "dcn20/dcn20_optc.h" + +void optc3_fpu_set_vrr_m_const(struct timing_generator *optc, + double vtotal_avg); + +void dcn30_fpu_populate_dml_writeback_from_context( + struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes); + +void dcn30_fpu_set_mcif_arb_params(struct mcif_arb_params *wb_arb_params, + struct display_mode_lib *dml, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int cur_pipe); + +void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context); + +void dcn30_fpu_calculate_wm_and_dlg( + struct dc *dc, struct dc_state *context, + display_e2e_pipe_params_st *pipes, + int pipe_cnt, + int vlevel); + +void dcn30_fpu_update_dram_channel_width_bytes(struct dc *dc); + +void dcn30_fpu_update_max_clk(struct dc_bounding_box_max_clk *dcn30_bb_max_clk); + +void dcn30_fpu_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, + unsigned int *optimal_dcfclk, + unsigned int *optimal_fclk); + +void dcn30_fpu_update_bw_bounding_box(struct dc *dc, + struct clk_bw_params *bw_params, + struct dc_bounding_box_max_clk *dcn30_bb_max_clk, + unsigned int *dcfclk_mhz, + unsigned int *dram_speed_mts); + + +#endif /* __DCN30_FPU_H__*/ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c index a0a2e125c9c8..54db2eca9e6b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c @@ -260,55 +260,6 @@ struct _vcs_dpi_ip_params_st dcn3_15_ip = { }; struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = { - /*TODO: correct dispclk/dppclk voltage level determination*/ - .clock_limits = { - { - .state = 0, - .dispclk_mhz = 1372.0, - .dppclk_mhz = 1372.0, - .phyclk_mhz = 810.0, - .phyclk_d18_mhz = 667.0, - .dscclk_mhz = 417.0, - .dtbclk_mhz = 600.0, - }, - { - .state = 1, - .dispclk_mhz = 1372.0, - .dppclk_mhz = 1372.0, - .phyclk_mhz = 810.0, - .phyclk_d18_mhz = 667.0, - .dscclk_mhz = 417.0, - .dtbclk_mhz = 600.0, - }, - { - .state = 2, - .dispclk_mhz = 1372.0, - .dppclk_mhz = 1372.0, - .phyclk_mhz = 810.0, - .phyclk_d18_mhz = 667.0, - .dscclk_mhz = 417.0, - .dtbclk_mhz = 600.0, - }, - { - .state = 3, - .dispclk_mhz = 1372.0, - .dppclk_mhz = 1372.0, - .phyclk_mhz = 810.0, - .phyclk_d18_mhz = 667.0, - .dscclk_mhz = 417.0, - .dtbclk_mhz = 600.0, - }, - { - .state = 4, - .dispclk_mhz = 1372.0, - .dppclk_mhz = 1372.0, - .phyclk_mhz = 810.0, - .phyclk_d18_mhz = 667.0, - .dscclk_mhz = 417.0, - .dtbclk_mhz = 600.0, - }, - }, - .num_states = 5, .sr_exit_time_us = 9.0, .sr_enter_plus_exit_time_us = 11.0, .sr_exit_z8_time_us = 50.0, @@ -696,80 +647,50 @@ void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) { struct clk_limit_table *clk_table = &bw_params->clk_table; - struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; - unsigned int i, closest_clk_lvl; - int max_dispclk_mhz = 0, max_dppclk_mhz = 0; - int j; + int i, max_dispclk_mhz = 0, max_dppclk_mhz = 0; dc_assert_fp_enabled(); - // Default clock levels are used for diags, which may lead to overclocking. - if (!IS_DIAG_DC(dc->ctx->dce_environment)) { - - dcn3_15_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator; - dcn3_15_ip.max_num_dpp = dc->res_pool->pipe_count; - dcn3_15_soc.num_chans = bw_params->num_channels; + dcn3_15_ip.max_num_otg = dc->res_pool->res_cap->num_timing_generator; + dcn3_15_ip.max_num_dpp = dc->res_pool->pipe_count; + dcn3_15_soc.num_chans = bw_params->num_channels; - ASSERT(clk_table->num_entries); + ASSERT(clk_table->num_entries); - /* Prepass to find max clocks independent of voltage level. */ - for (i = 0; i < clk_table->num_entries; ++i) { - if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) - max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; - if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) - max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; - } + /* Setup soc to always use max dispclk/dppclk to avoid odm-to-lower-voltage */ + for (i = 0; i < clk_table->num_entries; ++i) { + if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) + max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; + if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) + max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; + } - for (i = 0; i < clk_table->num_entries; i++) { - /* loop backwards*/ - for (closest_clk_lvl = 0, j = dcn3_15_soc.num_states - 1; j >= 0; j--) { - if ((unsigned int) dcn3_15_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { - closest_clk_lvl = j; - break; - } - } - if (clk_table->num_entries == 1) { - /*smu gives one DPM level, let's take the highest one*/ - closest_clk_lvl = dcn3_15_soc.num_states - 1; - } + for (i = 0; i < clk_table->num_entries; i++) { + dcn3_15_soc.clock_limits[i].state = i; - clock_limits[i].state = i; + /* Clocks dependent on voltage level. */ + dcn3_15_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + dcn3_15_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + dcn3_15_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; + dcn3_15_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio; - /* Clocks dependent on voltage level. */ - clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; - if (clk_table->num_entries == 1 && - clock_limits[i].dcfclk_mhz < dcn3_15_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) { - /*SMU fix not released yet*/ - clock_limits[i].dcfclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].dcfclk_mhz; - } - clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; - clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; - clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2 * clk_table->entries[i].wck_ratio; - - /* Clocks independent of voltage level. */ - clock_limits[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : - dcn3_15_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - - clock_limits[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : - dcn3_15_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + /* These aren't actually read from smu, but rather set in clk_mgr defaults */ + dcn3_15_soc.clock_limits[i].dtbclk_mhz = clk_table->entries[i].dtbclk_mhz; + dcn3_15_soc.clock_limits[i].phyclk_d18_mhz = clk_table->entries[i].phyclk_d18_mhz; + dcn3_15_soc.clock_limits[i].phyclk_mhz = clk_table->entries[i].phyclk_mhz; - clock_limits[i].dram_bw_per_chan_gbps = dcn3_15_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; - clock_limits[i].dscclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].dscclk_mhz; - clock_limits[i].dtbclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; - clock_limits[i].phyclk_d18_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; - clock_limits[i].phyclk_mhz = dcn3_15_soc.clock_limits[closest_clk_lvl].phyclk_mhz; - } - for (i = 0; i < clk_table->num_entries; i++) - dcn3_15_soc.clock_limits[i] = clock_limits[i]; - if (clk_table->num_entries) { - dcn3_15_soc.num_states = clk_table->num_entries; - } + /* Clocks independent of voltage level. */ + dcn3_15_soc.clock_limits[i].dispclk_mhz = max_dispclk_mhz; + dcn3_15_soc.clock_limits[i].dppclk_mhz = max_dppclk_mhz; + dcn3_15_soc.clock_limits[i].dscclk_mhz = max_dispclk_mhz / 3.0; } + dcn3_15_soc.num_states = clk_table->num_entries; - if (max_dispclk_mhz) { - dcn3_15_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; - dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; - } + + /* Set vco to max_dispclk * 2 to make sure the highest dispclk is always available for dml calcs, + * no impact outside of dml validation + */ + dcn3_15_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2; if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN31); diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c index 789f7562cdc7..d2273674e872 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c @@ -1284,10 +1284,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { if (!context->res_ctx.pipe_ctx[i].stream) continue; -#if defined (CONFIG_DRM_AMD_DC_DP2_0) if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) return true; -#endif } return false; } diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile index d1c2ec58676d..0f4a22be8c40 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile +++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile @@ -73,7 +73,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCE120) ############################################################################### # DCN 1x ############################################################################### -ifdef CONFIG_DRM_AMD_DC_DCN GPIO_DCN10 = hw_translate_dcn10.o hw_factory_dcn10.o AMD_DAL_GPIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn10/,$(GPIO_DCN10)) @@ -114,7 +113,7 @@ GPIO_DCN315 = hw_translate_dcn315.o hw_factory_dcn315.o AMD_DAL_GPIO_DCN315 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn315/,$(GPIO_DCN315)) AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN315) -endif + ############################################################################### # Diagnostics on FPGA ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c index 3b7df1ac26be..687d4f128480 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.c @@ -22,7 +22,6 @@ * Authors: AMD * */ -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "dm_services.h" #include "include/gpio_types.h" #include "../hw_factory.h" @@ -266,4 +265,3 @@ void dal_hw_factory_dcn30_init(struct hw_factory *factory) factory->funcs = &funcs; } -#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.h b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.h index 131e742b050a..e491af845b83 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_factory_dcn30.h @@ -22,7 +22,6 @@ * Authors: AMD * */ -#if defined(CONFIG_DRM_AMD_DC_DCN) #ifndef __DAL_HW_FACTORY_DCN30_H__ #define __DAL_HW_FACTORY_DCN30_H__ @@ -30,4 +29,3 @@ void dal_hw_factory_dcn30_init(struct hw_factory *factory); #endif /* __DAL_HW_FACTORY_DCN30_H__ */ -#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c index 6b6b7c7bd12f..3169c567475f 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c @@ -26,7 +26,6 @@ /* * Pre-requisites: headers required by header of this unit */ -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "hw_translate_dcn30.h" #include "dm_services.h" @@ -384,4 +383,3 @@ void dal_hw_translate_dcn30_init(struct hw_translate *tr) tr->funcs = &funcs; } -#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.h b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.h index ed55410b7a4e..511a0dd49140 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.h @@ -22,7 +22,6 @@ * Authors: AMD * */ -#if defined(CONFIG_DRM_AMD_DC_DCN) #ifndef __DAL_HW_TRANSLATE_DCN30_H__ #define __DAL_HW_TRANSLATE_DCN30_H__ @@ -32,4 +31,3 @@ struct hw_translate; void dal_hw_translate_dcn30_init(struct hw_translate *tr); #endif /* __DAL_HW_TRANSLATE_DCN30_H__ */ -#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index 5c00ffde3996..ef4f69612097 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -48,13 +48,11 @@ #include "dce80/hw_factory_dce80.h" #include "dce110/hw_factory_dce110.h" #include "dce120/hw_factory_dce120.h" -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "dcn10/hw_factory_dcn10.h" #include "dcn20/hw_factory_dcn20.h" #include "dcn21/hw_factory_dcn21.h" #include "dcn30/hw_factory_dcn30.h" #include "dcn315/hw_factory_dcn315.h" -#endif #include "diagnostics/hw_factory_diag.h" @@ -98,7 +96,6 @@ bool dal_hw_factory_init( case DCE_VERSION_12_1: dal_hw_factory_dce120_init(factory); return true; -#if defined(CONFIG_DRM_AMD_DC_DCN) case DCN_VERSION_1_0: case DCN_VERSION_1_01: dal_hw_factory_dcn10_init(factory); @@ -121,7 +118,6 @@ bool dal_hw_factory_init( case DCN_VERSION_3_15: dal_hw_factory_dcn315_init(factory); return true; -#endif default: ASSERT_CRITICAL(false); return false; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index 7a39cbc01f63..1db4f1414d7e 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c @@ -46,13 +46,11 @@ #include "dce80/hw_translate_dce80.h" #include "dce110/hw_translate_dce110.h" #include "dce120/hw_translate_dce120.h" -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "dcn10/hw_translate_dcn10.h" #include "dcn20/hw_translate_dcn20.h" #include "dcn21/hw_translate_dcn21.h" #include "dcn30/hw_translate_dcn30.h" #include "dcn315/hw_translate_dcn315.h" -#endif #include "diagnostics/hw_translate_diag.h" @@ -93,7 +91,6 @@ bool dal_hw_translate_init( case DCE_VERSION_12_1: dal_hw_translate_dce120_init(translate); return true; -#if defined(CONFIG_DRM_AMD_DC_DCN) case DCN_VERSION_1_0: case DCN_VERSION_1_01: dal_hw_translate_dcn10_init(translate); @@ -116,7 +113,6 @@ bool dal_hw_translate_init( case DCN_VERSION_3_15: dal_hw_translate_dcn315_init(translate); return true; -#endif default: BREAK_TO_DEBUGGER(); 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 951c9b60917d..555d4d9e1454 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -33,9 +33,7 @@ #include "dc_bios_types.h" #include "mem_input.h" #include "hubp.h" -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "mpc.h" -#endif #include "dwb.h" #include "mcif_wb.h" #include "panel_cntl.h" @@ -181,7 +179,6 @@ struct resource_funcs { void (*update_bw_bounding_box)( struct dc *dc, struct clk_bw_params *bw_params); -#if defined(CONFIG_DRM_AMD_DC_DCN) bool (*acquire_post_bldn_3dlut)( struct resource_context *res_ctx, const struct resource_pool *pool, @@ -194,7 +191,7 @@ struct resource_funcs { const struct resource_pool *pool, struct dc_3dlut **lut, struct dc_transfer_func **shaper); -#endif + enum dc_status (*add_dsc_to_stream_resource)( struct dc *dc, struct dc_state *state, struct dc_stream_state *stream); @@ -254,10 +251,9 @@ struct resource_pool { struct hpo_dp_stream_encoder *hpo_dp_stream_enc[MAX_HPO_DP2_ENCODERS]; unsigned int hpo_dp_link_enc_count; struct hpo_dp_link_encoder *hpo_dp_link_enc[MAX_HPO_DP2_LINK_ENCODERS]; -#if defined(CONFIG_DRM_AMD_DC_DCN) struct dc_3dlut *mpc_lut[MAX_PIPES]; struct dc_transfer_func *mpc_shaper[MAX_PIPES]; -#endif + struct { unsigned int xtalin_clock_inKhz; unsigned int dccg_ref_clock_inKhz; @@ -286,9 +282,7 @@ struct resource_pool { struct dmcu *dmcu; struct dmub_psr *psr; -#if defined(CONFIG_DRM_AMD_DC_DCN) struct abm *multiple_abms[MAX_PIPES]; -#endif const struct resource_funcs *funcs; const struct resource_caps *res_cap; @@ -380,7 +374,6 @@ struct pipe_ctx { struct pipe_ctx *next_odm_pipe; struct pipe_ctx *prev_odm_pipe; -#ifdef CONFIG_DRM_AMD_DC_DCN struct _vcs_dpi_display_dlg_regs_st dlg_regs; struct _vcs_dpi_display_ttu_regs_st ttu_regs; struct _vcs_dpi_display_rq_regs_st rq_regs; @@ -390,7 +383,7 @@ struct pipe_ctx { struct _vcs_dpi_display_e2e_pipe_params_st dml_input; int det_buffer_size_kb; bool unbounded_req; -#endif + union pipe_update_flags update_flags; struct dwbc *dwbc; struct mcif_wb *mcif_wb; @@ -419,9 +412,7 @@ struct resource_context { bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS]; unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS]; int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS]; -#if defined(CONFIG_DRM_AMD_DC_DCN) bool is_mpc_3dlut_acquired[MAX_PIPES]; -#endif }; struct dce_bw_output { @@ -484,9 +475,7 @@ struct dc_state { /* Note: these are big structures, do *not* put on stack! */ struct dm_pp_display_configuration pp_display_cfg; -#ifdef CONFIG_DRM_AMD_DC_DCN struct dcn_bw_internal_vars dcn_bw_vars; -#endif struct clk_mgr *clk_mgr; @@ -497,4 +486,11 @@ struct dc_state { } perf_params; }; +struct dc_bounding_box_max_clk { + int max_dcfclk_mhz; + int max_dispclk_mhz; + int max_dppclk_mhz; + int max_phyclk_mhz; +}; + #endif /* _CORE_TYPES_H_ */ 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 44f167d2584f..a3c1e9c56d8b 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 @@ -148,12 +148,12 @@ bool dp_is_max_vs_reached( void dp_hw_to_dpcd_lane_settings( const struct link_training_settings *lt_settings, const struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]); + union dpcd_training_lane dpcd_lane_settings[]); void dp_decide_lane_settings( const struct link_training_settings *lt_settings, const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]); + union dpcd_training_lane dpcd_lane_settings[]); uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval); diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h index 74dafd0f9d3d..39c1d1d07357 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dpia.h @@ -87,6 +87,11 @@ union dpia_set_config_data { */ enum dc_status dpcd_get_tunneling_device_data(struct dc_link *link); +/* Query hot plug status of USB4 DP tunnel. + * Returns true if HPD high. + */ +bool dc_link_dpia_query_hpd_status(struct dc_link *link); + /* Train DP tunneling link for USB4 DPIA display endpoint. * DPIA equivalent of dc_link_dp_perfrorm_link_training. * Aborts link training upon detection of sink unplug. diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index c920c4b6077d..b5570aa8e39d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -91,6 +91,7 @@ struct clk_limit_table_entry { unsigned int dispclk_mhz; unsigned int dppclk_mhz; unsigned int phyclk_mhz; + unsigned int phyclk_d18_mhz; unsigned int wck_ratio; }; @@ -236,6 +237,7 @@ struct clk_mgr_funcs { bool safe_to_lower); int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr); + int (*get_dtb_ref_clk_frequency)(struct clk_mgr *clk_mgr); void (*set_low_power_state)(struct clk_mgr *clk_mgr); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index b2fa4de47734..c7021915bac8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -60,8 +60,17 @@ struct dccg { const struct dccg_funcs *funcs; int pipe_dppclk_khz[MAX_PIPES]; int ref_dppclk; - int dtbclk_khz[MAX_PIPES]; - int audio_dtbclk_khz; + //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ + //int audio_dtbclk_khz;/* TODO needs to be removed */ + int ref_dtbclk_khz;/* TODO needs to be removed */ +}; + +struct dtbclk_dto_params { + const struct dc_crtc_timing *timing; + int otg_inst; + int pixclk_khz; + int req_audio_dtbclk_khz; + int num_odm_segments; int ref_dtbclk_khz; }; @@ -111,10 +120,7 @@ struct dccg_funcs { void (*set_dtbclk_dto)( struct dccg *dccg, - int dtbclk_inst, - int req_dtbclk_khz, - int num_odm_segments, - const struct dc_crtc_timing *timing); + struct dtbclk_dto_params *dto_params); void (*set_audio_dtbclk_dto)( struct dccg *dccg, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h index 346f0ba73e86..d7b8d586b523 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h @@ -104,6 +104,7 @@ struct dsc_funcs { uint8_t *dsc_packed_pps); void (*dsc_enable)(struct display_stream_compressor *dsc, int opp_pipe); void (*dsc_disable)(struct display_stream_compressor *dsc); + void (*dsc_disconnect)(struct display_stream_compressor *dsc); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile index f305d4c9a122..5f49048dde47 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/Makefile +++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile @@ -71,7 +71,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCE12) ############################################################################### # DCN 1x ############################################################################### -ifdef CONFIG_DRM_AMD_DC_DCN IRQ_DCN1 = irq_service_dcn10.o AMD_DAL_IRQ_DCN1 = $(addprefix $(AMDDALPATH)/dc/irq/dcn10/,$(IRQ_DCN1)) @@ -136,7 +135,7 @@ IRQ_DCN31 = irq_service_dcn31.o AMD_DAL_IRQ_DCN31= $(addprefix $(AMDDALPATH)/dc/irq/dcn31/,$(IRQ_DCN31)) AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN31) -endif + ############################################################################### # DCN 315 ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c index ac0c6a62d17b..146cd1819912 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c @@ -22,8 +22,6 @@ * */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - #include "dm_services.h" #include "include/logger_interface.h" @@ -450,4 +448,3 @@ struct irq_service *dal_irq_service_dcn30_create( return irq_service; } -#endif diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.h b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.h index 080e21239688..c6c7b184d3c1 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.h +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.h @@ -23,8 +23,6 @@ * */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - #ifndef __DAL_IRQ_SERVICE_DCN30_H__ #define __DAL_IRQ_SERVICE_DCN30_H__ @@ -34,4 +32,3 @@ struct irq_service *dal_irq_service_dcn30_create( struct irq_service_init_data *init_data); #endif /* __DAL_IRQ_SERVICE_DCN30_H__ */ -#endif diff --git a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c index a2a4fbeb83f8..cb38d4c527d4 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/irq_service.c +++ b/drivers/gpu/drm/amd/display/dc/irq/irq_service.c @@ -37,13 +37,8 @@ #endif #include "dce80/irq_service_dce80.h" - #include "dce120/irq_service_dce120.h" - - -#if defined(CONFIG_DRM_AMD_DC_DCN) #include "dcn10/irq_service_dcn10.h" -#endif #include "reg_helper.h" #include "irq_service.h" diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c index 87972dc8443d..ea6cf8bfce30 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c @@ -27,6 +27,7 @@ #include "core_types.h" #include "dccg.h" #include "dc_link_dp.h" +#include "clk_mgr.h" static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) { @@ -106,14 +107,18 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc; struct dccg *dccg = dc->res_pool->dccg; struct timing_generator *tg = pipe_ctx->stream_res.tg; - int odm_segment_count = get_odm_segment_count(pipe_ctx); + struct dtbclk_dto_params dto_params = {0}; enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link); + dto_params.otg_inst = tg->inst; + dto_params.pixclk_khz = pipe_ctx->stream->phy_pix_clk; + dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); + dto_params.timing = &pipe_ctx->stream->timing; + dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); + dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst); dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk); - dccg->funcs->set_dtbclk_dto(dccg, tg->inst, pipe_ctx->stream->phy_pix_clk, - odm_segment_count, - &pipe_ctx->stream->timing); + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); stream_enc->funcs->enable_stream(stream_enc); stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst); } @@ -124,9 +129,13 @@ static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; struct dccg *dccg = dc->res_pool->dccg; struct timing_generator *tg = pipe_ctx->stream_res.tg; + struct dtbclk_dto_params dto_params = {0}; + + dto_params.otg_inst = tg->inst; + dto_params.timing = &pipe_ctx->stream->timing; stream_enc->funcs->disable(stream_enc); - dccg->funcs->set_dtbclk_dto(dccg, tg->inst, 0, 0, &pipe_ctx->stream->timing); + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst); dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst); } diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index 56757a286a03..f5cb8932bd5c 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -243,6 +243,7 @@ struct dmub_srv_hw_params { bool power_optimization; bool dpia_supported; bool disable_dpia; + bool usb4_cm_version; }; /** diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 05c8d91ad4ab..385c28238beb 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -350,8 +350,9 @@ union dmub_fw_boot_options { uint32_t power_optimization: 1; uint32_t diag_env: 1; /* 1 if diagnostic environment */ uint32_t gpint_scratch8: 1; /* 1 if GPINT is in scratch8*/ + uint32_t usb4_cm_version: 1; /**< 1 CM support */ - uint32_t reserved : 18; /**< reserved */ + uint32_t reserved : 17; /**< reserved */ } bits; /**< boot bits */ uint32_t all; /**< 32-bit access to bits */ }; @@ -654,6 +655,10 @@ enum dmub_cmd_type { */ DMUB_CMD_GET_USBC_CABLE_ID = 81, /** + * Command type used to query HPD state. + */ + DMUB_CMD__QUERY_HPD_STATE = 82, + /** * Command type used for all VBIOS interface commands. */ DMUB_CMD__VBIOS = 128, @@ -1352,6 +1357,30 @@ struct dmub_rb_cmd_dp_set_config_reply { struct set_config_reply_control_data set_config_reply_control; }; +/** + * Data passed from driver to FW in a DMUB_CMD__QUERY_HPD_STATE command. + */ +struct dmub_cmd_hpd_state_query_data { + uint8_t instance; /**< HPD instance or DPIA instance */ + uint8_t result; /**< For returning HPD state */ + enum aux_channel_type ch_type; /**< enum aux_channel_type */ + enum aux_return_code_type status; /**< for returning the status of command */ +}; + +/** + * Definition of a DMUB_CMD__QUERY_HPD_STATE command. + */ +struct dmub_rb_cmd_query_hpd_state { + /** + * Command header. + */ + struct dmub_cmd_header header; + /** + * Data passed from driver to FW in a DMUB_CMD__QUERY_HPD_STATE command. + */ + struct dmub_cmd_hpd_state_query_data data; +}; + /* * Command IDs should be treated as stable ABI. * Do not reuse or modify IDs. @@ -2756,6 +2785,11 @@ union dmub_rb_cmd { * Definition of a DMUB_CMD_GET_USBC_CABLE_ID command. */ struct dmub_rb_cmd_get_usbc_cable_id cable_id; + + /** + * Definition of a DMUB_CMD__QUERY_HPD_STATE command. + */ + struct dmub_rb_cmd_query_hpd_state query_hpd; }; /** diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index 82c651535628..c7bd7e216710 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -84,7 +84,7 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) { union dmub_gpint_data_register cmd; const uint32_t timeout = 100; - uint32_t in_reset, scratch, i; + uint32_t in_reset, scratch, i, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -115,6 +115,13 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) udelay(1); } + for (i = 0; i < timeout; ++i) { + REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode); + if (pwait_mode & (1 << 0)) + break; + + udelay(1); + } /* Force reset in case we timed out, DMCUB is likely hung. */ } @@ -125,6 +132,8 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) REG_WRITE(DMCUB_INBOX1_WPTR, 0); REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); REG_WRITE(DMCUB_OUTBOX1_WPTR, 0); + REG_WRITE(DMCUB_OUTBOX0_RPTR, 0); + REG_WRITE(DMCUB_OUTBOX0_WPTR, 0); REG_WRITE(DMCUB_SCRATCH0, 0); /* Clear the GPINT command manually so we don't send anything during boot. */ @@ -340,6 +349,7 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu boot_options.bits.z10_disable = params->disable_z10; boot_options.bits.dpia_supported = params->dpia_supported; boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1; + boot_options.bits.usb4_cm_version = params->usb4_cm_version; boot_options.bits.power_optimization = params->power_optimization; boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h index 59ddc81b5a0e..f6db6f89d45d 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h @@ -151,7 +151,8 @@ struct dmub_srv; DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \ DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \ DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \ - DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) + DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) \ + DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS) struct dmub_srv_dcn31_reg_offset { #define DMUB_SR(reg) uint32_t reg; diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h index f883d87791fe..20a3d4e23f66 100644 --- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h +++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h @@ -39,6 +39,8 @@ #define DP_BRANCH_HW_REV_20 0x20 #define DP_DEVICE_ID_38EC11 0x38EC11 +#define DP_FORCE_PSRSU_CAPABILITY 0x40F + enum ddc_result { DDC_RESULT_UNKNOWN = 0, DDC_RESULT_SUCESSFULL, @@ -125,6 +127,8 @@ struct av_sync_data { static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0}; static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0}; +static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u"; + /*MST Dock*/ static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA"; |