diff options
author | Dave Airlie <airlied@redhat.com> | 2025-03-10 08:19:25 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2025-03-10 09:04:52 +1000 |
commit | 236f475d29f8e585a72fb6fac7f8bb4dc4b162b7 (patch) | |
tree | a5b2d1e4bbb4a8f808aa351f386c432e6cb2102a /drivers/gpu/drm/amd/display | |
parent | d65a27f95f6ab236b1a788d9bc463d24a8b2aebe (diff) | |
parent | cf6d949a409e09539477d32dbe7c954e4852e744 (diff) | |
download | linux-236f475d29f8e585a72fb6fac7f8bb4dc4b162b7.tar.gz linux-236f475d29f8e585a72fb6fac7f8bb4dc4b162b7.tar.bz2 linux-236f475d29f8e585a72fb6fac7f8bb4dc4b162b7.zip |
Merge tag 'amd-drm-next-6.15-2025-03-07' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amdgpu:
- Fix spelling typos
- RAS updates
- VCN 5.0.1 updates
- SubVP fixes
- DCN 4.0.1 fixes
- MSO DPCD fixes
- DIO encoder refactor
- PCON fixes
- Misc cleanups
- DMCUB fixes
- USB4 DP fixes
- DM cleanups
- Backlight cleanups and fixes
- Support platform backlight curves
- Misc code cleanups
- SMU 14 fixes
- JPEG 4.0.3 reset updates
- SR-IOV fixes
- SVM fixes
- GC 12 DCC fixes
- DC DCE 6.x fix
- Hiberation fix
amdkfd:
- Fix possible NULL pointer in queue validation
- Remove unnecessary CP domain validation
- SDMA queue reset support
- Add per process flags
radeon:
- Fix spelling typos
- RS400 hyperZ fix
UAPI:
- Add KFD per process flags for setting precision
Proposed user space: https://github.com/ROCm/ROCR-Runtime/commit/2a64fa5e06e80e0af36df4ce0c76ae52eeec0a9d
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250307211051.1880472-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/display')
97 files changed, 1493 insertions, 1354 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 16e4eb474eec..6a54f1cfa125 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -321,7 +321,7 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, return 0; } -static bool dm_is_idle(void *handle) +static bool dm_is_idle(struct amdgpu_ip_block *ip_block) { /* XXX todo */ return true; @@ -1625,75 +1625,130 @@ static bool dm_should_disable_stutter(struct pci_dev *pdev) return false; } -static const struct dmi_system_id hpd_disconnect_quirk_table[] = { +struct amdgpu_dm_quirks { + bool aux_hpd_discon; + bool support_edp0_on_dp1; +}; + +static struct amdgpu_dm_quirks quirk_entries = { + .aux_hpd_discon = false, + .support_edp0_on_dp1 = false +}; + +static int edp0_on_dp1_callback(const struct dmi_system_id *id) +{ + quirk_entries.support_edp0_on_dp1 = true; + return 0; +} + +static int aux_hpd_discon_callback(const struct dmi_system_id *id) +{ + quirk_entries.aux_hpd_discon = true; + return 0; +} + +static const struct dmi_system_id dmi_quirk_table[] = { { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3660"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3260"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"), }, }, { + .callback = aux_hpd_discon_callback, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"), }, }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite mt645 G8 Mobile Thin Client"), + }, + }, + { + .callback = edp0_on_dp1_callback, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 665 16 inch G11 Notebook PC"), + }, + }, {} /* TODO: refactor this from a fixed table to a dynamic option */ }; -static void retrieve_dmi_info(struct amdgpu_display_manager *dm) +static void retrieve_dmi_info(struct amdgpu_display_manager *dm, struct dc_init_data *init_data) { - const struct dmi_system_id *dmi_id; + int dmi_id; + struct drm_device *dev = dm->ddev; dm->aux_hpd_discon_quirk = false; + init_data->flags.support_edp0_on_dp1 = false; + + dmi_id = dmi_check_system(dmi_quirk_table); - dmi_id = dmi_first_match(hpd_disconnect_quirk_table); - if (dmi_id) { + if (!dmi_id) + return; + + if (quirk_entries.aux_hpd_discon) { dm->aux_hpd_discon_quirk = true; - DRM_INFO("aux_hpd_discon_quirk attached\n"); + drm_info(dev, "aux_hpd_discon_quirk attached\n"); + } + if (quirk_entries.support_edp0_on_dp1) { + init_data->flags.support_edp0_on_dp1 = true; + drm_info(dev, "aux_hpd_discon_quirk attached\n"); } } @@ -2002,7 +2057,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0)) init_data.num_virtual_links = 1; - retrieve_dmi_info(&adev->dm); + retrieve_dmi_info(&adev->dm, &init_data); if (adev->dm.bb_from_dmub) init_data.bb_from_dmub = adev->dm.bb_from_dmub; @@ -3031,10 +3086,11 @@ static void dm_gpureset_toggle_interrupts(struct amdgpu_device *adev, } +DEFINE_FREE(state_release, struct dc_state *, if (_T) dc_state_release(_T)) + static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) { - struct dc_state *context = NULL; - enum dc_status res = DC_ERROR_UNEXPECTED; + struct dc_state *context __free(state_release) = NULL; int i; struct dc_stream_state *del_streams[MAX_PIPES]; int del_streams_count = 0; @@ -3044,7 +3100,7 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) context = dc_state_create_current_copy(dc); if (context == NULL) - goto context_alloc_fail; + return DC_ERROR_UNEXPECTED; /* First remove from context all streams */ for (i = 0; i < context->stream_count; i++) { @@ -3055,25 +3111,20 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) /* Remove all planes for removed streams and then remove the streams */ for (i = 0; i < del_streams_count; i++) { - if (!dc_state_rem_all_planes_for_stream(dc, del_streams[i], context)) { - res = DC_FAIL_DETACH_SURFACES; - goto fail; - } + enum dc_status res; + + if (!dc_state_rem_all_planes_for_stream(dc, del_streams[i], context)) + return DC_FAIL_DETACH_SURFACES; res = dc_state_remove_stream(dc, context, del_streams[i]); if (res != DC_OK) - goto fail; + return res; } params.streams = context->streams; params.stream_count = context->stream_count; - res = dc_commit_streams(dc, ¶ms); - -fail: - dc_state_release(context); -context_alloc_fail: - return res; + return dc_commit_streams(dc, ¶ms); } static void hpd_rx_irq_work_suspend(struct amdgpu_display_manager *dm) @@ -3090,9 +3141,10 @@ static int dm_suspend(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; struct amdgpu_display_manager *dm = &adev->dm; - int ret = 0; if (amdgpu_in_reset(adev)) { + enum dc_status res; + mutex_lock(&dm->dc_lock); dc_allow_idle_optimizations(adev->dm.dc, false); @@ -3102,13 +3154,17 @@ static int dm_suspend(struct amdgpu_ip_block *ip_block) if (dm->cached_dc_state) dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); - amdgpu_dm_commit_zero_streams(dm->dc); + res = amdgpu_dm_commit_zero_streams(dm->dc); + if (res != DC_OK) { + drm_err(adev_to_drm(adev), "Failed to commit zero streams: %d\n", res); + return -EINVAL; + } amdgpu_dm_irq_suspend(adev); hpd_rx_irq_work_suspend(dm); - return ret; + return 0; } WARN_ON(adev->dm.cached_state); @@ -3245,14 +3301,14 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, struct dc_scaling_info scaling_infos[MAX_SURFACES]; struct dc_flip_addrs flip_addrs[MAX_SURFACES]; struct dc_stream_update stream_update; - } *bundle; + } *bundle __free(kfree); int k, m; bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); if (!bundle) { drm_err(dm->ddev, "Failed to allocate update bundle\n"); - goto cleanup; + return; } for (k = 0; k < dc_state->stream_count; k++) { @@ -3272,9 +3328,24 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, &bundle->stream_update, bundle->surface_updates); } +} -cleanup: - kfree(bundle); +static void apply_delay_after_dpcd_poweroff(struct amdgpu_device *adev, + struct dc_sink *sink) +{ + struct dc_panel_patch *ppatch = NULL; + + if (!sink) + return; + + ppatch = &sink->edid_caps.panel_patch; + if (ppatch->wait_after_dpcd_poweroff_ms) { + msleep(ppatch->wait_after_dpcd_poweroff_ms); + drm_dbg_driver(adev_to_drm(adev), + "%s: adding a %ds delay as w/a for panel\n", + __func__, + ppatch->wait_after_dpcd_poweroff_ms / 1000); + } } static int dm_resume(struct amdgpu_ip_block *ip_block) @@ -3323,7 +3394,7 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) r = dm_dmub_hw_init(adev); if (r) - DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); + drm_err(adev_to_drm(adev), "DMUB interface failed to initialize: status=%d\n", r); dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0); dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0); @@ -3363,6 +3434,11 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) return 0; } + + /* leave display off for S4 sequence */ + if (adev->in_s4) + return 0; + /* Recreate dc_state - DC invalidates it when setting power state to S3. */ dc_state_release(dm_state->context); dm_state->context = dc_state_create(dm->dc, NULL); @@ -3398,6 +3474,7 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) /* Do detection*/ drm_connector_list_iter_begin(ddev, &iter); drm_for_each_connector_iter(connector, &iter) { + bool ret; if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) continue; @@ -3414,17 +3491,20 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) if (aconnector->mst_root) continue; - mutex_lock(&aconnector->hpd_lock); + guard(mutex)(&aconnector->hpd_lock); if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type)) - DRM_ERROR("KMS: Failed to detect connector\n"); + drm_err(adev_to_drm(adev), "KMS: Failed to detect connector\n"); if (aconnector->base.force && new_connection_type == dc_connection_none) { emulated_link_detect(aconnector->dc_link); } else { - mutex_lock(&dm->dc_lock); + guard(mutex)(&dm->dc_lock); dc_exit_ips_for_hw_access(dm->dc); - dc_link_detect(aconnector->dc_link, DETECT_REASON_RESUMEFROMS3S4); - mutex_unlock(&dm->dc_lock); + ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_RESUMEFROMS3S4); + if (ret) { + /* w/a delay for certain panels */ + apply_delay_after_dpcd_poweroff(adev, aconnector->dc_sink); + } } if (aconnector->fake_enable && aconnector->dc_link->local_sink) @@ -3434,7 +3514,6 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) dc_sink_release(aconnector->dc_sink); aconnector->dc_sink = NULL; amdgpu_dm_update_connector_after_detect(aconnector); - mutex_unlock(&aconnector->hpd_lock); } drm_connector_list_iter_end(&iter); @@ -3603,12 +3682,14 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) caps->min_input_signal = min_input_signal_override; } +DEFINE_FREE(sink_release, struct dc_sink *, if (_T) dc_sink_release(_T)) + void amdgpu_dm_update_connector_after_detect( struct amdgpu_dm_connector *aconnector) { struct drm_connector *connector = &aconnector->base; + struct dc_sink *sink __free(sink_release) = NULL; struct drm_device *dev = connector->dev; - struct dc_sink *sink; /* MST handled by drm_mst framework */ if (aconnector->mst_mgr.mst_state == true) @@ -3630,7 +3711,7 @@ void amdgpu_dm_update_connector_after_detect( * For S3 resume with headless use eml_sink to fake stream * because on resume connector->sink is set to NULL */ - mutex_lock(&dev->mode_config.mutex); + guard(mutex)(&dev->mode_config.mutex); if (sink) { if (aconnector->dc_sink) { @@ -3655,10 +3736,6 @@ void amdgpu_dm_update_connector_after_detect( } } - mutex_unlock(&dev->mode_config.mutex); - - if (sink) - dc_sink_release(sink); return; } @@ -3666,10 +3743,8 @@ void amdgpu_dm_update_connector_after_detect( * TODO: temporary guard to look for proper fix * if this sink is MST sink, we should not do anything */ - if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - dc_sink_release(sink); + if (sink && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) return; - } if (aconnector->dc_sink == sink) { /* @@ -3678,15 +3753,13 @@ void amdgpu_dm_update_connector_after_detect( */ drm_dbg_kms(dev, "DCHPD: connector_id=%d: dc_sink didn't change.\n", aconnector->connector_id); - if (sink) - dc_sink_release(sink); return; } drm_dbg_kms(dev, "DCHPD: connector_id=%d: Old sink=%p New sink=%p\n", aconnector->connector_id, aconnector->dc_sink, sink); - mutex_lock(&dev->mode_config.mutex); + guard(mutex)(&dev->mode_config.mutex); /* * 1. Update status of the drm connector @@ -3748,12 +3821,7 @@ void amdgpu_dm_update_connector_after_detect( connector->state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; } - mutex_unlock(&dev->mode_config.mutex); - update_subconnector_property(aconnector); - - if (sink) - dc_sink_release(sink); } static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) @@ -3773,7 +3841,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) * In case of failure or MST no need to update connector status or notify the OS * since (for MST case) MST does this in its own context. */ - mutex_lock(&aconnector->hpd_lock); + guard(mutex)(&aconnector->hpd_lock); if (adev->dm.hdcp_workqueue) { hdcp_reset_display(adev->dm.hdcp_workqueue, aconnector->dc_link->link_index); @@ -3785,7 +3853,7 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) aconnector->timing_changed = false; if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type)) - DRM_ERROR("KMS: Failed to detect connector\n"); + drm_err(adev_to_drm(adev), "KMS: Failed to detect connector\n"); if (aconnector->base.force && new_connection_type == dc_connection_none) { emulated_link_detect(aconnector->dc_link); @@ -3797,11 +3865,13 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) drm_kms_helper_connector_hotplug_event(connector); } else { - mutex_lock(&adev->dm.dc_lock); - dc_exit_ips_for_hw_access(dc); - ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); - mutex_unlock(&adev->dm.dc_lock); + scoped_guard(mutex, &adev->dm.dc_lock) { + dc_exit_ips_for_hw_access(dc); + ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); + } if (ret) { + /* w/a delay for certain panels */ + apply_delay_after_dpcd_poweroff(adev, aconnector->dc_sink); amdgpu_dm_update_connector_after_detect(aconnector); drm_modeset_lock_all(dev); @@ -3812,8 +3882,6 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) drm_kms_helper_connector_hotplug_event(connector); } } - mutex_unlock(&aconnector->hpd_lock); - } static void handle_hpd_irq(void *param) @@ -4653,48 +4721,40 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm, int bl_idx) { -#if defined(CONFIG_ACPI) - struct amdgpu_dm_backlight_caps caps; + struct amdgpu_dm_backlight_caps *caps = &dm->backlight_caps[bl_idx]; - memset(&caps, 0, sizeof(caps)); - - if (dm->backlight_caps[bl_idx].caps_valid) + if (caps->caps_valid) return; - amdgpu_acpi_get_backlight_caps(&caps); +#if defined(CONFIG_ACPI) + amdgpu_acpi_get_backlight_caps(caps); /* validate the firmware value is sane */ - if (caps.caps_valid) { - int spread = caps.max_input_signal - caps.min_input_signal; + if (caps->caps_valid) { + int spread = caps->max_input_signal - caps->min_input_signal; - if (caps.max_input_signal > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || - caps.min_input_signal < 0 || + if (caps->max_input_signal > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || + caps->min_input_signal < 0 || spread > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || spread < AMDGPU_DM_MIN_SPREAD) { DRM_DEBUG_KMS("DM: Invalid backlight caps: min=%d, max=%d\n", - caps.min_input_signal, caps.max_input_signal); - caps.caps_valid = false; + caps->min_input_signal, caps->max_input_signal); + caps->caps_valid = false; } } - if (caps.caps_valid) { - dm->backlight_caps[bl_idx].caps_valid = true; - if (caps.aux_support) - return; - dm->backlight_caps[bl_idx].min_input_signal = caps.min_input_signal; - dm->backlight_caps[bl_idx].max_input_signal = caps.max_input_signal; - } else { - dm->backlight_caps[bl_idx].min_input_signal = - AMDGPU_DM_DEFAULT_MIN_BACKLIGHT; - dm->backlight_caps[bl_idx].max_input_signal = - AMDGPU_DM_DEFAULT_MAX_BACKLIGHT; + if (!caps->caps_valid) { + caps->min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT; + caps->max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT; + caps->caps_valid = true; } #else - if (dm->backlight_caps[bl_idx].aux_support) + if (caps->aux_support) return; - dm->backlight_caps[bl_idx].min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT; - dm->backlight_caps[bl_idx].max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT; + caps->min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT; + caps->max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT; + caps->caps_valid = true; #endif } @@ -4720,10 +4780,38 @@ static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *c uint32_t brightness) { unsigned int min, max; + u8 prev_signal = 0, prev_lum = 0; if (!get_brightness_range(caps, &min, &max)) return brightness; + for (int i = 0; i < caps->data_points; i++) { + u8 signal, lum; + + if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE) + break; + + signal = caps->luminance_data[i].input_signal; + lum = caps->luminance_data[i].luminance; + + /* + * brightness == signal: luminance is percent numerator + * brightness < signal: interpolate between previous and current luminance numerator + * brightness > signal: find next data point + */ + if (brightness < signal) + lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) * + (brightness - prev_signal), + signal - prev_signal); + else if (brightness > signal) { + prev_signal = signal; + prev_lum = lum; + continue; + } + brightness = DIV_ROUND_CLOSEST(lum * brightness, 101); + break; + } + // Rescale 0..255 to min..max return min + DIV_ROUND_CLOSEST((max - min) * brightness, AMDGPU_MAX_BL_LEVEL); @@ -4748,19 +4836,19 @@ static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm, int bl_idx, u32 user_brightness) { - struct amdgpu_dm_backlight_caps caps; + struct amdgpu_dm_backlight_caps *caps; struct dc_link *link; u32 brightness; bool rc, reallow_idle = false; amdgpu_dm_update_backlight_caps(dm, bl_idx); - caps = dm->backlight_caps[bl_idx]; + caps = &dm->backlight_caps[bl_idx]; dm->brightness[bl_idx] = user_brightness; /* update scratch register */ if (bl_idx == 0) amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]); - brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]); + brightness = convert_brightness_from_user(caps, dm->brightness[bl_idx]); link = (struct dc_link *)dm->backlight_link[bl_idx]; /* Change brightness based on AUX property */ @@ -4770,7 +4858,7 @@ static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm, reallow_idle = true; } - if (caps.aux_support) { + if (caps->aux_support) { rc = dc_link_set_backlight_level_nits(link, true, brightness, AUX_BL_DEFAULT_TRANSITION_TIME_MS); if (!rc) @@ -4887,6 +4975,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) } else props.brightness = AMDGPU_MAX_BL_LEVEL; + if (caps.data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) + drm_info(drm, "Using custom brightness curve\n"); props.max_brightness = AMDGPU_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW; @@ -7295,8 +7385,14 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector) struct dc_link *dc_link = aconnector->dc_link; struct dc_sink *dc_em_sink = aconnector->dc_em_sink; const struct drm_edid *drm_edid; + struct i2c_adapter *ddc; + + if (dc_link && dc_link->aux_mode) + ddc = &aconnector->dm_dp_aux.aux.ddc; + else + ddc = &aconnector->i2c->base; - drm_edid = drm_edid_read(connector); + drm_edid = drm_edid_read_ddc(connector, ddc); drm_edid_connector_update(connector, drm_edid); if (!drm_edid) { DRM_ERROR("No EDID found on connector: %s.\n", connector->name); @@ -7341,14 +7437,21 @@ static int get_modes(struct drm_connector *connector) static void create_eml_sink(struct amdgpu_dm_connector *aconnector) { struct drm_connector *connector = &aconnector->base; + struct dc_link *dc_link = aconnector->dc_link; struct dc_sink_init_data init_params = { .link = aconnector->dc_link, .sink_signal = SIGNAL_TYPE_VIRTUAL }; const struct drm_edid *drm_edid; const struct edid *edid; + struct i2c_adapter *ddc; + + if (dc_link && dc_link->aux_mode) + ddc = &aconnector->dm_dp_aux.aux.ddc; + else + ddc = &aconnector->i2c->base; - drm_edid = drm_edid_read(connector); + drm_edid = drm_edid_read_ddc(connector, ddc); drm_edid_connector_update(connector, drm_edid); if (!drm_edid) { DRM_ERROR("No EDID found on connector: %s.\n", connector->name); @@ -12655,3 +12758,10 @@ bool dm_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count, { return dc_dmub_srv_cmd_run_list(ctx->dmub_srv, count, cmd, wait_type); } + +void dm_acpi_process_phy_transition_interlock( + const struct dc_context *ctx, + struct dm_process_phy_transition_init_params process_phy_transition_init_params) +{ + // Not yet implemented +} 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 acead14ab45d..385faaca6e26 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -151,6 +151,18 @@ struct idle_workqueue { bool running; }; +#define MAX_LUMINANCE_DATA_POINTS 99 + +/** + * struct amdgpu_dm_luminance_data - Custom luminance data + * @luminance: Luminance in percent + * @input_signal: Input signal in range 0-255 + */ +struct amdgpu_dm_luminance_data { + u8 luminance; + u8 input_signal; +} __packed; + /** * struct amdgpu_dm_backlight_caps - Information about backlight * @@ -195,6 +207,14 @@ struct amdgpu_dm_backlight_caps { * @dc_level: the default brightness if booted on DC */ u8 dc_level; + /** + * @data_points: the number of custom luminance data points + */ + u8 data_points; + /** + * @luminance_data: custom luminance data + */ + struct amdgpu_dm_luminance_data luminance_data[MAX_LUMINANCE_DATA_POINTS]; }; /** 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 fbd80d8545a8..2cd35392e2da 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 @@ -55,16 +55,21 @@ static u32 edid_extract_panel_id(struct edid *edid) (u32)EDID_PRODUCT_ID(edid); } -static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps) +static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct dc_edid_caps *edid_caps) { uint32_t panel_id = edid_extract_panel_id(edid); switch (panel_id) { + /* Workaround for monitors that need a delay after detecting the link */ + case drm_edid_encode_panel_id('G', 'B', 'T', 0x3215): + drm_dbg_driver(dev, "Add 10s delay for link detection for panel id %X\n", panel_id); + edid_caps->panel_patch.wait_after_dpcd_poweroff_ms = 10000; + break; /* Workaround for some monitors which does not work well with FAMS */ case drm_edid_encode_panel_id('S', 'A', 'M', 0x0E5E): case drm_edid_encode_panel_id('S', 'A', 'M', 0x7053): case drm_edid_encode_panel_id('S', 'A', 'M', 0x71AC): - DRM_DEBUG_DRIVER("Disabling FAMS on monitor with panel id %X\n", panel_id); + drm_dbg_driver(dev, "Disabling FAMS on monitor with panel id %X\n", panel_id); edid_caps->panel_patch.disable_fams = true; break; /* Workaround for some monitors that do not clear DPCD 0x317 if FreeSync is unsupported */ @@ -73,11 +78,11 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps) case drm_edid_encode_panel_id('B', 'O', 'E', 0x092A): case drm_edid_encode_panel_id('L', 'G', 'D', 0x06D1): case drm_edid_encode_panel_id('M', 'S', 'F', 0x1003): - DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); + drm_dbg_driver(dev, "Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); edid_caps->panel_patch.remove_sink_ext_caps = true; break; case drm_edid_encode_panel_id('S', 'D', 'C', 0x4154): - DRM_DEBUG_DRIVER("Disabling VSC on monitor with panel id %X\n", panel_id); + drm_dbg_driver(dev, "Disabling VSC on monitor with panel id %X\n", panel_id); edid_caps->panel_patch.disable_colorimetry = true; break; default: @@ -101,6 +106,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps( { struct amdgpu_dm_connector *aconnector = link->priv; struct drm_connector *connector = &aconnector->base; + struct drm_device *dev = connector->dev; struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL; struct cea_sad *sads; int sad_count = -1; @@ -130,7 +136,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps( edid_caps->edid_hdmi = connector->display_info.is_hdmi; - apply_edid_quirks(edid_buf, edid_caps); + apply_edid_quirks(dev, edid_buf, edid_caps); sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) 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 3390f0d8420a..2b63cbab0e87 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 @@ -473,7 +473,7 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev) unregister_all_irq_handlers(adev); } -int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) +void amdgpu_dm_irq_suspend(struct amdgpu_device *adev) { int src; struct list_head *hnd_list_h; @@ -511,10 +511,9 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) } DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - return 0; } -int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) +void amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) { int src; struct list_head *hnd_list_h, *hnd_list_l; @@ -522,7 +521,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) DM_IRQ_TABLE_LOCK(adev, irq_table_flags); - DRM_DEBUG_KMS("DM_IRQ: early resume\n"); + drm_dbg(adev_to_drm(adev), "DM_IRQ: early resume\n"); /* re-enable short pulse interrupts HW interrupt */ for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) { @@ -533,11 +532,9 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev) } DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - - return 0; } -int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) +void amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) { int src; struct list_head *hnd_list_h, *hnd_list_l; @@ -545,7 +542,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) DM_IRQ_TABLE_LOCK(adev, irq_table_flags); - DRM_DEBUG_KMS("DM_IRQ: resume\n"); + drm_dbg(adev_to_drm(adev), "DM_IRQ: resume\n"); /** * Renable HW interrupt for HPD and only since FLIP and VBLANK @@ -559,7 +556,6 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) } DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - return 0; } /* @@ -894,6 +890,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) struct drm_device *dev = adev_to_drm(adev); struct drm_connector *connector; struct drm_connector_list_iter iter; + int i; drm_connector_list_iter_begin(dev, &iter); drm_for_each_connector_iter(connector, &iter) { @@ -920,6 +917,12 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) } } drm_connector_list_iter_end(&iter); + + /* Update reference counts for HPDs */ + for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) { + if (amdgpu_irq_get(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1)) + drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n", i); + } } /** @@ -935,6 +938,7 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) struct drm_device *dev = adev_to_drm(adev); struct drm_connector *connector; struct drm_connector_list_iter iter; + int i; drm_connector_list_iter_begin(dev, &iter); drm_for_each_connector_iter(connector, &iter) { @@ -960,4 +964,10 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev) } } drm_connector_list_iter_end(&iter); + + /* Update reference counts for HPDs */ + for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) { + if (amdgpu_irq_put(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1)) + drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n", i); + } } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h index 2349238a626b..ba17c23b2706 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h @@ -90,14 +90,14 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev); * amdgpu_dm_irq_suspend - disable ASIC interrupt during suspend. * */ -int amdgpu_dm_irq_suspend(struct amdgpu_device *adev); +void amdgpu_dm_irq_suspend(struct amdgpu_device *adev); /** * amdgpu_dm_irq_resume_early - enable HPDRX ASIC interrupts during resume. * amdgpu_dm_irq_resume - enable ASIC interrupt during resume. * */ -int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev); -int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev); +void amdgpu_dm_irq_resume_early(struct amdgpu_device *adev); +void amdgpu_dm_irq_resume_late(struct amdgpu_device *adev); #endif /* __AMDGPU_DM_IRQ_H__ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 056b17198956..7ceedf626d23 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 @@ -1632,6 +1632,9 @@ int pre_validate_dsc(struct drm_atomic_state *state, connector = amdgpu_dm_find_first_crtc_matching_connector(state, state->crtcs[ind].ptr); + if (!connector) + continue; + drm_new_conn_state = drm_atomic_get_new_connector_state(state, connector); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index fcb0e900a38a..0090e08d5057 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -277,8 +277,11 @@ static int amdgpu_dm_plane_validate_dcc(struct amdgpu_device *adev, if (!dcc->enable) return 0; - if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || - !dc->cap_funcs.get_dcc_compression_cap) + if (adev->family < AMDGPU_FAMILY_GC_12_0_0 && + format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return -EINVAL; + + if (!dc->cap_funcs.get_dcc_compression_cap) return -EINVAL; input.format = format; 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 104f03868266..e140b7a04d72 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 @@ -30,23 +30,6 @@ #include "amdgpu_dm.h" #include "modules/power/power_helpers.h" -static bool is_specific_oled_panel(struct dc_link *link) -{ - if (!link->dpcd_sink_ext_caps.bits.oled) - return false; - - /* Disable PSR-SU for some OLED panels to avoid glitches */ - if (link->dpcd_caps.sink_dev_id == 0xBA4159) { - uint8_t sink_dev_id_str1[] = {'4', '0', 'C', 'U', '1'}; - - if (!memcmp(link->dpcd_caps.sink_dev_id_str, sink_dev_id_str1, - sizeof(sink_dev_id_str1))) - return true; - } - - return false; -} - static bool link_supports_psrsu(struct dc_link *link) { struct dc *dc = link->ctx->dc; @@ -57,9 +40,6 @@ static bool link_supports_psrsu(struct dc_link *link) if (dc->ctx->dce_version < DCN_VERSION_3_1) return false; - if (is_specific_oled_panel(link)) - return false; - if (!is_psr_su_specific_panel(link)) return false; @@ -74,7 +54,8 @@ static bool link_supports_psrsu(struct dc_link *link) if (amdgpu_dc_debug_mask & DC_DISABLE_PSR_SU) return false; - return dc_dmub_check_min_version(dc->ctx->dmub_srv->dmub); + /* Temporarily disable PSR-SU to avoid glitches */ + return false; } /* diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index 7d18f372ce7a..2c645dffec18 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -101,7 +101,6 @@ static void init_dig_encoder_control(struct bios_parser *bp) bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5; break; default: - dm_output_to_console("Don't have dig_encoder_control for v%d\n", version); bp->cmd_tbl.dig_encoder_control = encoder_control_fallback; break; } @@ -210,6 +209,7 @@ static enum bp_result encoder_control_fallback( ****************************************************************************** *****************************************************************************/ + static enum bp_result transmitter_control_v1_6( struct bios_parser *bp, struct bp_transmitter_control *cntl); @@ -238,7 +238,6 @@ static void init_transmitter_control(struct bios_parser *bp) bp->cmd_tbl.transmitter_control = transmitter_control_v1_7; break; default: - dm_output_to_console("Don't have transmitter_control for v%d\n", crev); bp->cmd_tbl.transmitter_control = transmitter_control_fallback; break; } @@ -325,6 +324,21 @@ static void transmitter_control_dmcub_v1_7( dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); } +static struct dc_link *get_link_by_phy_id(struct dc *p_dc, uint32_t phy_id) +{ + struct dc_link *link = NULL; + + // Get Transition Bitmask from dc_link structure associated with PHY + for (uint8_t link_id = 0; link_id < MAX_LINKS; link_id++) { + if (phy_id == p_dc->links[link_id]->link_enc->transmitter) { + link = p_dc->links[link_id]; + break; + } + } + + return link; +} + static enum bp_result transmitter_control_v1_7( struct bios_parser *bp, struct bp_transmitter_control *cntl) @@ -363,7 +377,37 @@ static enum bp_result transmitter_control_v1_7( if (bp->base.ctx->dc->ctx->dmub_srv && bp->base.ctx->dc->debug.dmub_command_table) { + struct dm_process_phy_transition_init_params process_phy_transition_init_params = {0}; + struct dc_link *link = get_link_by_phy_id(bp->base.ctx->dc, dig_v1_7.phyid); + bool is_phy_transition_interlock_allowed = false; + uint8_t action = dig_v1_7.action; + + if (link) { + if (link->phy_transition_bitmask && + (action == TRANSMITTER_CONTROL_ENABLE || action == TRANSMITTER_CONTROL_DISABLE)) { + is_phy_transition_interlock_allowed = true; + + // Prepare input parameters for processing ACPI retimers + process_phy_transition_init_params.action = action; + process_phy_transition_init_params.display_port_lanes_count = cntl->lanes_number; + process_phy_transition_init_params.phy_id = dig_v1_7.phyid; + process_phy_transition_init_params.signal = cntl->signal; + process_phy_transition_init_params.sym_clock_10khz = dig_v1_7.symclk_units.symclk_10khz; + process_phy_transition_init_params.display_port_link_rate = link->cur_link_settings.link_rate; + process_phy_transition_init_params.transition_bitmask = link->phy_transition_bitmask; + } + } + + // Handle PRE_OFF_TO_ON: Process ACPI PHY Transition Interlock + if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_ENABLE) + dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params); + transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7); + + // Handle POST_ON_TO_OFF: Process ACPI PHY Transition Interlock + if (is_phy_transition_interlock_allowed && action == TRANSMITTER_CONTROL_DISABLE) + dm_acpi_process_phy_transition_interlock(bp->base.ctx, process_phy_transition_init_params); + return BP_RESULT_OK; } @@ -408,8 +452,6 @@ static void init_set_pixel_clock(struct bios_parser *bp) bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; break; default: - dm_output_to_console("Don't have set_pixel_clock for v%d\n", - BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)); bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback; break; } @@ -554,7 +596,6 @@ static void init_set_crtc_timing(struct bios_parser *bp) set_crtc_using_dtd_timing_v3; break; default: - dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version); bp->cmd_tbl.set_crtc_timing = NULL; break; } @@ -671,8 +712,6 @@ static void init_enable_crtc(struct bios_parser *bp) bp->cmd_tbl.enable_crtc = enable_crtc_v1; break; default: - dm_output_to_console("Don't have enable_crtc for v%d\n", - BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)); bp->cmd_tbl.enable_crtc = NULL; break; } @@ -864,8 +903,6 @@ static void init_set_dce_clock(struct bios_parser *bp) bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; break; default: - dm_output_to_console("Don't have set_dce_clock for v%d\n", - BIOS_CMD_TABLE_PARA_REVISION(setdceclock)); bp->cmd_tbl.set_dce_clock = NULL; break; } @@ -1046,3 +1083,4 @@ void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) init_enable_lvtma_control(bp); } + diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c index e317a3615147..91bc8a06e2cf 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.c @@ -293,3 +293,107 @@ uint8_t dal_cmd_table_helper_encoder_id_to_atom( return ENCODER_OBJECT_ID_NONE; } } + +uint8_t phy_id_to_atom(enum transmitter t) +{ + uint8_t atom_phy_id; + + switch (t) { + case TRANSMITTER_UNIPHY_A: + atom_phy_id = ATOM_PHY_ID_UNIPHYA; + break; + case TRANSMITTER_UNIPHY_B: + atom_phy_id = ATOM_PHY_ID_UNIPHYB; + break; + case TRANSMITTER_UNIPHY_C: + atom_phy_id = ATOM_PHY_ID_UNIPHYC; + break; + case TRANSMITTER_UNIPHY_D: + atom_phy_id = ATOM_PHY_ID_UNIPHYD; + break; + case TRANSMITTER_UNIPHY_E: + atom_phy_id = ATOM_PHY_ID_UNIPHYE; + break; + case TRANSMITTER_UNIPHY_F: + atom_phy_id = ATOM_PHY_ID_UNIPHYF; + break; + case TRANSMITTER_UNIPHY_G: + atom_phy_id = ATOM_PHY_ID_UNIPHYG; + break; + default: + atom_phy_id = ATOM_PHY_ID_UNIPHYA; + break; + } + return atom_phy_id; +} + +uint8_t clock_source_id_to_atom_phy_clk_src_id( + enum clock_source_id id) +{ + uint8_t atom_phy_clk_src_id = 0; + + switch (id) { + case CLOCK_SOURCE_ID_PLL0: + atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; + break; + case CLOCK_SOURCE_ID_PLL1: + atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; + break; + case CLOCK_SOURCE_ID_PLL2: + atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; + break; + case CLOCK_SOURCE_ID_EXTERNAL: + atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; + break; + default: + atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; + break; + } + + return atom_phy_clk_src_id >> 2; +} + +bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) +{ + bool result = false; + + if (atom_engine_id != NULL) + switch (id) { + case ENGINE_ID_DIGA: + *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DIGB: + *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DIGC: + *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DIGD: + *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DIGE: + *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DIGF: + *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DIGG: + *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; + result = true; + break; + case ENGINE_ID_DACA: + *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; + result = true; + break; + default: + break; + } + + return result; +} diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h index dfd30aaf4032..547700e119a6 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper.h @@ -59,4 +59,12 @@ uint8_t dal_cmd_table_helper_transmitter_bp_to_atom( uint8_t dal_cmd_table_helper_encoder_id_to_atom( enum encoder_id id); + +uint8_t phy_id_to_atom(enum transmitter t); + +uint8_t clock_source_id_to_atom_phy_clk_src_id( + enum clock_source_id id); + +bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id); + #endif 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 bad4e4711b4f..268e2414b34f 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 @@ -88,8 +88,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2( return true; default: - /* Unsupported DCE */ - BREAK_TO_DEBUGGER(); + *h = dal_cmd_tbl_helper_dce112_get_table2(); return false; } } diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce110/command_table_helper_dce110.c b/drivers/gpu/drm/amd/display/dc/bios/dce110/command_table_helper_dce110.c index 11bf247bb180..3099128223df 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/dce110/command_table_helper_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/bios/dce110/command_table_helper_dce110.c @@ -31,39 +31,6 @@ #include "../command_table_helper.h" -static uint8_t phy_id_to_atom(enum transmitter t) -{ - uint8_t atom_phy_id; - - switch (t) { - case TRANSMITTER_UNIPHY_A: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - case TRANSMITTER_UNIPHY_B: - atom_phy_id = ATOM_PHY_ID_UNIPHYB; - break; - case TRANSMITTER_UNIPHY_C: - atom_phy_id = ATOM_PHY_ID_UNIPHYC; - break; - case TRANSMITTER_UNIPHY_D: - atom_phy_id = ATOM_PHY_ID_UNIPHYD; - break; - case TRANSMITTER_UNIPHY_E: - atom_phy_id = ATOM_PHY_ID_UNIPHYE; - break; - case TRANSMITTER_UNIPHY_F: - atom_phy_id = ATOM_PHY_ID_UNIPHYF; - break; - case TRANSMITTER_UNIPHY_G: - atom_phy_id = ATOM_PHY_ID_UNIPHYG; - break; - default: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - } - return atom_phy_id; -} - static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) { uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; @@ -94,32 +61,6 @@ static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) return atom_dig_mode; } -static uint8_t clock_source_id_to_atom_phy_clk_src_id( - enum clock_source_id id) -{ - uint8_t atom_phy_clk_src_id = 0; - - switch (id) { - case CLOCK_SOURCE_ID_PLL0: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; - break; - case CLOCK_SOURCE_ID_PLL1: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - case CLOCK_SOURCE_ID_PLL2: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; - break; - case CLOCK_SOURCE_ID_EXTERNAL: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; - break; - default: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - } - - return atom_phy_clk_src_id >> 2; -} - static uint8_t hpd_sel_to_atom(enum hpd_source_id id) { uint8_t atom_hpd_sel = 0; @@ -207,51 +148,6 @@ static bool clock_source_id_to_atom( return result; } -static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) -{ - bool result = false; - - if (atom_engine_id != NULL) - switch (id) { - case ENGINE_ID_DIGA: - *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGB: - *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGC: - *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGD: - *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGE: - *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGF: - *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGG: - *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DACA: - *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; - result = true; - break; - default: - break; - } - - return result; -} - static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) { uint8_t atom_action = 0; diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c index 755b6e33140a..349f0e5d5856 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c +++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c @@ -29,40 +29,9 @@ #include "include/bios_parser_types.h" -#include "../command_table_helper2.h" - -static uint8_t phy_id_to_atom(enum transmitter t) -{ - uint8_t atom_phy_id; +#include "../command_table_helper.h" - switch (t) { - case TRANSMITTER_UNIPHY_A: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - case TRANSMITTER_UNIPHY_B: - atom_phy_id = ATOM_PHY_ID_UNIPHYB; - break; - case TRANSMITTER_UNIPHY_C: - atom_phy_id = ATOM_PHY_ID_UNIPHYC; - break; - case TRANSMITTER_UNIPHY_D: - atom_phy_id = ATOM_PHY_ID_UNIPHYD; - break; - case TRANSMITTER_UNIPHY_E: - atom_phy_id = ATOM_PHY_ID_UNIPHYE; - break; - case TRANSMITTER_UNIPHY_F: - atom_phy_id = ATOM_PHY_ID_UNIPHYF; - break; - case TRANSMITTER_UNIPHY_G: - atom_phy_id = ATOM_PHY_ID_UNIPHYG; - break; - default: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - } - return atom_phy_id; -} +#include "../command_table_helper2.h" static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) { @@ -91,32 +60,6 @@ static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) return atom_dig_mode; } -static uint8_t clock_source_id_to_atom_phy_clk_src_id( - enum clock_source_id id) -{ - uint8_t atom_phy_clk_src_id = 0; - - switch (id) { - case CLOCK_SOURCE_ID_PLL0: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; - break; - case CLOCK_SOURCE_ID_PLL1: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - case CLOCK_SOURCE_ID_PLL2: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; - break; - case CLOCK_SOURCE_ID_EXTERNAL: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; - break; - default: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - } - - return atom_phy_clk_src_id >> 2; -} - static uint8_t hpd_sel_to_atom(enum hpd_source_id id) { uint8_t atom_hpd_sel = 0; @@ -209,51 +152,6 @@ static bool clock_source_id_to_atom( return result; } -static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) -{ - bool result = false; - - if (atom_engine_id != NULL) - switch (id) { - case ENGINE_ID_DIGA: - *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGB: - *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGC: - *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGD: - *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGE: - *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGF: - *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGG: - *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DACA: - *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; - result = true; - break; - default: - break; - } - - return result; -} - static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) { uint8_t atom_action = 0; diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c index 06b4f7fa4a50..1a5fefcde8af 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c +++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper_dce112.c @@ -31,39 +31,6 @@ #include "../command_table_helper.h" -static uint8_t phy_id_to_atom(enum transmitter t) -{ - uint8_t atom_phy_id; - - switch (t) { - case TRANSMITTER_UNIPHY_A: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - case TRANSMITTER_UNIPHY_B: - atom_phy_id = ATOM_PHY_ID_UNIPHYB; - break; - case TRANSMITTER_UNIPHY_C: - atom_phy_id = ATOM_PHY_ID_UNIPHYC; - break; - case TRANSMITTER_UNIPHY_D: - atom_phy_id = ATOM_PHY_ID_UNIPHYD; - break; - case TRANSMITTER_UNIPHY_E: - atom_phy_id = ATOM_PHY_ID_UNIPHYE; - break; - case TRANSMITTER_UNIPHY_F: - atom_phy_id = ATOM_PHY_ID_UNIPHYF; - break; - case TRANSMITTER_UNIPHY_G: - atom_phy_id = ATOM_PHY_ID_UNIPHYG; - break; - default: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - } - return atom_phy_id; -} - static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) { uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP; @@ -91,32 +58,6 @@ static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) return atom_dig_mode; } -static uint8_t clock_source_id_to_atom_phy_clk_src_id( - enum clock_source_id id) -{ - uint8_t atom_phy_clk_src_id = 0; - - switch (id) { - case CLOCK_SOURCE_ID_PLL0: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; - break; - case CLOCK_SOURCE_ID_PLL1: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - case CLOCK_SOURCE_ID_PLL2: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; - break; - case CLOCK_SOURCE_ID_EXTERNAL: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; - break; - default: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - } - - return atom_phy_clk_src_id >> 2; -} - static uint8_t hpd_sel_to_atom(enum hpd_source_id id) { uint8_t atom_hpd_sel = 0; @@ -209,51 +150,6 @@ static bool clock_source_id_to_atom( return result; } -static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) -{ - bool result = false; - - if (atom_engine_id != NULL) - switch (id) { - case ENGINE_ID_DIGA: - *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGB: - *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGC: - *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGD: - *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGE: - *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGF: - *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGG: - *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DACA: - *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; - result = true; - break; - default: - break; - } - - return result; -} - static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) { uint8_t atom_action = 0; diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce60/command_table_helper_dce60.c b/drivers/gpu/drm/amd/display/dc/bios/dce60/command_table_helper_dce60.c index 710221b4f5c5..01ccc803040c 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/dce60/command_table_helper_dce60.c +++ b/drivers/gpu/drm/amd/display/dc/bios/dce60/command_table_helper_dce60.c @@ -58,51 +58,6 @@ static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) return atom_action; } -static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) -{ - bool result = false; - - if (atom_engine_id != NULL) - switch (id) { - case ENGINE_ID_DIGA: - *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGB: - *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGC: - *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGD: - *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGE: - *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGF: - *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGG: - *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DACA: - *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; - result = true; - break; - default: - break; - } - - return result; -} - static bool clock_source_id_to_atom( enum clock_source_id id, uint32_t *atom_pll_id) @@ -149,32 +104,6 @@ static bool clock_source_id_to_atom( return result; } -static uint8_t clock_source_id_to_atom_phy_clk_src_id( - enum clock_source_id id) -{ - uint8_t atom_phy_clk_src_id = 0; - - switch (id) { - case CLOCK_SOURCE_ID_PLL0: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; - break; - case CLOCK_SOURCE_ID_PLL1: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - case CLOCK_SOURCE_ID_PLL2: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; - break; - case CLOCK_SOURCE_ID_EXTERNAL: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; - break; - default: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - } - - return atom_phy_clk_src_id >> 2; -} - static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) { uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; @@ -270,39 +199,6 @@ static uint8_t dig_encoder_sel_to_atom(enum engine_id id) return atom_dig_encoder_sel; } -static uint8_t phy_id_to_atom(enum transmitter t) -{ - uint8_t atom_phy_id; - - switch (t) { - case TRANSMITTER_UNIPHY_A: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - case TRANSMITTER_UNIPHY_B: - atom_phy_id = ATOM_PHY_ID_UNIPHYB; - break; - case TRANSMITTER_UNIPHY_C: - atom_phy_id = ATOM_PHY_ID_UNIPHYC; - break; - case TRANSMITTER_UNIPHY_D: - atom_phy_id = ATOM_PHY_ID_UNIPHYD; - break; - case TRANSMITTER_UNIPHY_E: - atom_phy_id = ATOM_PHY_ID_UNIPHYE; - break; - case TRANSMITTER_UNIPHY_F: - atom_phy_id = ATOM_PHY_ID_UNIPHYF; - break; - case TRANSMITTER_UNIPHY_G: - atom_phy_id = ATOM_PHY_ID_UNIPHYG; - break; - default: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - } - return atom_phy_id; -} - static uint8_t disp_power_gating_action_to_atom( enum bp_pipe_control_action action) { diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce80/command_table_helper_dce80.c b/drivers/gpu/drm/amd/display/dc/bios/dce80/command_table_helper_dce80.c index 8b30b558cf1f..2ec5264536c7 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/dce80/command_table_helper_dce80.c +++ b/drivers/gpu/drm/amd/display/dc/bios/dce80/command_table_helper_dce80.c @@ -58,51 +58,6 @@ static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) return atom_action; } -static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) -{ - bool result = false; - - if (atom_engine_id != NULL) - switch (id) { - case ENGINE_ID_DIGA: - *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGB: - *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGC: - *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGD: - *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGE: - *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGF: - *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DIGG: - *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; - result = true; - break; - case ENGINE_ID_DACA: - *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; - result = true; - break; - default: - break; - } - - return result; -} - static bool clock_source_id_to_atom( enum clock_source_id id, uint32_t *atom_pll_id) @@ -149,32 +104,6 @@ static bool clock_source_id_to_atom( return result; } -static uint8_t clock_source_id_to_atom_phy_clk_src_id( - enum clock_source_id id) -{ - uint8_t atom_phy_clk_src_id = 0; - - switch (id) { - case CLOCK_SOURCE_ID_PLL0: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; - break; - case CLOCK_SOURCE_ID_PLL1: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - case CLOCK_SOURCE_ID_PLL2: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; - break; - case CLOCK_SOURCE_ID_EXTERNAL: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; - break; - default: - atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; - break; - } - - return atom_phy_clk_src_id >> 2; -} - static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) { uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; @@ -270,39 +199,6 @@ static uint8_t dig_encoder_sel_to_atom(enum engine_id id) return atom_dig_encoder_sel; } -static uint8_t phy_id_to_atom(enum transmitter t) -{ - uint8_t atom_phy_id; - - switch (t) { - case TRANSMITTER_UNIPHY_A: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - case TRANSMITTER_UNIPHY_B: - atom_phy_id = ATOM_PHY_ID_UNIPHYB; - break; - case TRANSMITTER_UNIPHY_C: - atom_phy_id = ATOM_PHY_ID_UNIPHYC; - break; - case TRANSMITTER_UNIPHY_D: - atom_phy_id = ATOM_PHY_ID_UNIPHYD; - break; - case TRANSMITTER_UNIPHY_E: - atom_phy_id = ATOM_PHY_ID_UNIPHYE; - break; - case TRANSMITTER_UNIPHY_F: - atom_phy_id = ATOM_PHY_ID_UNIPHYF; - break; - case TRANSMITTER_UNIPHY_G: - atom_phy_id = ATOM_PHY_ID_UNIPHYG; - break; - default: - atom_phy_id = ATOM_PHY_ID_UNIPHYA; - break; - } - return atom_phy_id; -} - static uint8_t disp_power_gating_action_to_atom( enum bp_pipe_control_action action) { diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c index df29d28d89c9..af722519a1fa 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -201,16 +201,26 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state * struct pipe_ctx *pipe = safe_to_lower ? &context->res_ctx.pipe_ctx[i] : &dc->current_state->res_ctx.pipe_ctx[i]; + struct link_encoder *new_pipe_link_enc = new_pipe->link_res.dio_link_enc; + struct link_encoder *pipe_link_enc = pipe->link_res.dio_link_enc; bool stream_changed_otg_dig_on = false; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; + + if (!dc->config.unify_link_enc_assignment) { + if (new_pipe->stream) + new_pipe_link_enc = new_pipe->stream->link_enc; + if (pipe->stream) + pipe_link_enc = pipe->stream->link_enc; + } + stream_changed_otg_dig_on = old_pipe->stream && new_pipe->stream && old_pipe->stream != new_pipe->stream && old_pipe->stream_res.tg == new_pipe->stream_res.tg && - new_pipe->stream->link_enc && !new_pipe->stream->dpms_off && - new_pipe->stream->link_enc->funcs->is_dig_enabled && - new_pipe->stream->link_enc->funcs->is_dig_enabled( - new_pipe->stream->link_enc) && + new_pipe_link_enc && !new_pipe->stream->dpms_off && + new_pipe_link_enc->funcs->is_dig_enabled && + new_pipe_link_enc->funcs->is_dig_enabled( + new_pipe_link_enc) && new_pipe->stream_res.stream_enc && new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled && new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled(new_pipe->stream_res.stream_enc); @@ -226,7 +236,7 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state * if (!has_active_hpo && !dccg->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe) && (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) || - !pipe->stream->link_enc) && !stream_changed_otg_dig_on)) { + !pipe_link_enc) && !stream_changed_otg_dig_on)) { /* This w/a should not trigger when we have a dig active */ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 05ad7a9af4ff..e71ea21401f5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -905,7 +905,8 @@ void dc_stream_set_static_screen_params(struct dc *dc, static void dc_destruct(struct dc *dc) { // reset link encoder assignment table on destruct - if (dc->res_pool && dc->res_pool->funcs->link_encs_assign) + if (dc->res_pool && dc->res_pool->funcs->link_encs_assign && + !dc->config.unify_link_enc_assignment) link_enc_cfg_init(dc, dc->current_state); if (dc->current_state) { @@ -1201,6 +1202,8 @@ static void dc_update_visual_confirm_color(struct dc *dc, struct dc_state *conte get_surface_tile_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color)); else if (dc->debug.visual_confirm == VISUAL_CONFIRM_HW_CURSOR) get_cursor_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color)); + else if (dc->debug.visual_confirm == VISUAL_CONFIRM_DCC) + get_dcc_visual_confirm_color(dc, pipe_ctx, &(pipe_ctx->visual_confirm_color)); else { if (dc->ctx->dce_version < DCN_VERSION_2_0) color_space_to_black_color( @@ -3955,6 +3958,9 @@ static void commit_planes_for_stream(struct dc *dc, if (update_type == UPDATE_TYPE_FULL && dc->optimized_required) hwss_process_outstanding_hw_updates(dc, dc->current_state); + if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) + dc->res_pool->funcs->prepare_mcache_programming(dc, context); + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -4013,9 +4019,6 @@ static void commit_planes_for_stream(struct dc *dc, odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; } - if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) - dc->res_pool->funcs->prepare_mcache_programming(dc, context); - if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) if (top_pipe_to_program && top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { @@ -4937,7 +4940,8 @@ static bool full_update_required(struct dc *dc, stream_update->lut3d_func || stream_update->pending_test_pattern || stream_update->crtc_timing_adjust || - stream_update->scaler_sharpener_update)) + stream_update->scaler_sharpener_update || + stream_update->hw_cursor_req)) return true; if (stream) { 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 af1ea5792560..650e89825968 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -51,126 +51,6 @@ DC_LOG_BANDWIDTH_CALCS(__VA_ARGS__); \ } while (0) -void pre_surface_trace( - struct dc *dc, - const struct dc_plane_state *const *plane_states, - int surface_count) -{ - int i; - DC_LOGGER_INIT(dc->ctx->logger); - - for (i = 0; i < surface_count; i++) { - const struct dc_plane_state *plane_state = plane_states[i]; - - SURFACE_TRACE("Planes %d:\n", i); - - SURFACE_TRACE( - "plane_state->visible = %d;\n" - "plane_state->flip_immediate = %d;\n" - "plane_state->address.type = %d;\n" - "plane_state->address.grph.addr.quad_part = 0x%llX;\n" - "plane_state->address.grph.meta_addr.quad_part = 0x%llX;\n" - "plane_state->scaling_quality.h_taps = %d;\n" - "plane_state->scaling_quality.v_taps = %d;\n" - "plane_state->scaling_quality.h_taps_c = %d;\n" - "plane_state->scaling_quality.v_taps_c = %d;\n", - plane_state->visible, - plane_state->flip_immediate, - plane_state->address.type, - plane_state->address.grph.addr.quad_part, - plane_state->address.grph.meta_addr.quad_part, - plane_state->scaling_quality.h_taps, - plane_state->scaling_quality.v_taps, - plane_state->scaling_quality.h_taps_c, - plane_state->scaling_quality.v_taps_c); - - SURFACE_TRACE( - "plane_state->src_rect.x = %d;\n" - "plane_state->src_rect.y = %d;\n" - "plane_state->src_rect.width = %d;\n" - "plane_state->src_rect.height = %d;\n" - "plane_state->dst_rect.x = %d;\n" - "plane_state->dst_rect.y = %d;\n" - "plane_state->dst_rect.width = %d;\n" - "plane_state->dst_rect.height = %d;\n" - "plane_state->clip_rect.x = %d;\n" - "plane_state->clip_rect.y = %d;\n" - "plane_state->clip_rect.width = %d;\n" - "plane_state->clip_rect.height = %d;\n", - plane_state->src_rect.x, - plane_state->src_rect.y, - plane_state->src_rect.width, - plane_state->src_rect.height, - plane_state->dst_rect.x, - plane_state->dst_rect.y, - plane_state->dst_rect.width, - plane_state->dst_rect.height, - plane_state->clip_rect.x, - plane_state->clip_rect.y, - plane_state->clip_rect.width, - plane_state->clip_rect.height); - - SURFACE_TRACE( - "plane_state->plane_size.surface_size.x = %d;\n" - "plane_state->plane_size.surface_size.y = %d;\n" - "plane_state->plane_size.surface_size.width = %d;\n" - "plane_state->plane_size.surface_size.height = %d;\n" - "plane_state->plane_size.surface_pitch = %d;\n", - plane_state->plane_size.surface_size.x, - plane_state->plane_size.surface_size.y, - plane_state->plane_size.surface_size.width, - plane_state->plane_size.surface_size.height, - plane_state->plane_size.surface_pitch); - - - SURFACE_TRACE( - "plane_state->tiling_info.gfx8.num_banks = %d;\n" - "plane_state->tiling_info.gfx8.bank_width = %d;\n" - "plane_state->tiling_info.gfx8.bank_width_c = %d;\n" - "plane_state->tiling_info.gfx8.bank_height = %d;\n" - "plane_state->tiling_info.gfx8.bank_height_c = %d;\n" - "plane_state->tiling_info.gfx8.tile_aspect = %d;\n" - "plane_state->tiling_info.gfx8.tile_aspect_c = %d;\n" - "plane_state->tiling_info.gfx8.tile_split = %d;\n" - "plane_state->tiling_info.gfx8.tile_split_c = %d;\n" - "plane_state->tiling_info.gfx8.tile_mode = %d;\n" - "plane_state->tiling_info.gfx8.tile_mode_c = %d;\n", - plane_state->tiling_info.gfx8.num_banks, - plane_state->tiling_info.gfx8.bank_width, - plane_state->tiling_info.gfx8.bank_width_c, - plane_state->tiling_info.gfx8.bank_height, - plane_state->tiling_info.gfx8.bank_height_c, - plane_state->tiling_info.gfx8.tile_aspect, - plane_state->tiling_info.gfx8.tile_aspect_c, - plane_state->tiling_info.gfx8.tile_split, - plane_state->tiling_info.gfx8.tile_split_c, - plane_state->tiling_info.gfx8.tile_mode, - plane_state->tiling_info.gfx8.tile_mode_c); - - SURFACE_TRACE( - "plane_state->tiling_info.gfx8.pipe_config = %d;\n" - "plane_state->tiling_info.gfx8.array_mode = %d;\n" - "plane_state->color_space = %d;\n" - "plane_state->dcc.enable = %d;\n" - "plane_state->format = %d;\n" - "plane_state->rotation = %d;\n" - "plane_state->stereo_format = %d;\n", - plane_state->tiling_info.gfx8.pipe_config, - plane_state->tiling_info.gfx8.array_mode, - plane_state->color_space, - plane_state->dcc.enable, - plane_state->format, - plane_state->rotation, - plane_state->stereo_format); - - SURFACE_TRACE("plane_state->tiling_info.gfx9.swizzle = %d;\n", - plane_state->tiling_info.gfx9.swizzle); - - SURFACE_TRACE("\n"); - } - SURFACE_TRACE("\n"); -} - void update_surface_trace( struct dc *dc, const struct dc_surface_update *updates, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 6b514fd03f16..e0277728268a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -34,6 +34,7 @@ #include "dc_state_priv.h" #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) +#define MAX_NUM_MCACHE 8 /* used as index in array of black_color_format */ enum black_color_format { @@ -553,6 +554,53 @@ void get_cursor_visual_confirm_color( } } +void get_dcc_visual_confirm_color( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct tg_color *color) +{ + const uint32_t MCACHE_ID_UNASSIGNED = 0xF; + + if (!pipe_ctx->plane_state->dcc.enable) { + color->color_r_cr = 0; /* black - DCC disabled */ + color->color_g_y = 0; + color->color_b_cb = 0; + return; + } + + if (dc->ctx->dce_version < DCN_VERSION_4_01) { + color->color_r_cr = MAX_TG_COLOR_VALUE; /* red - DCC enabled */ + color->color_g_y = 0; + color->color_b_cb = 0; + return; + } + + uint32_t first_id = pipe_ctx->mcache_regs.main.p0.mcache_id_first; + uint32_t second_id = pipe_ctx->mcache_regs.main.p0.mcache_id_second; + + if (first_id != MCACHE_ID_UNASSIGNED && second_id != MCACHE_ID_UNASSIGNED && first_id != second_id) { + color->color_r_cr = MAX_TG_COLOR_VALUE/2; /* grey - 2 mcache */ + color->color_g_y = MAX_TG_COLOR_VALUE/2; + color->color_b_cb = MAX_TG_COLOR_VALUE/2; + } + + else if (first_id != MCACHE_ID_UNASSIGNED || second_id != MCACHE_ID_UNASSIGNED) { + const struct tg_color id_colors[MAX_NUM_MCACHE] = { + {0, MAX_TG_COLOR_VALUE, 0}, /* green */ + {0, 0, MAX_TG_COLOR_VALUE}, /* blue */ + {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */ + {MAX_TG_COLOR_VALUE, 0, MAX_TG_COLOR_VALUE}, /* magenta */ + {0, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* cyan */ + {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE}, /* white */ + {MAX_TG_COLOR_VALUE/2, 0, 0}, /* dark red */ + {0, MAX_TG_COLOR_VALUE/2, 0}, /* dark green */ + }; + + uint32_t assigned_id = (first_id != MCACHE_ID_UNASSIGNED) ? first_id : second_id; + *color = id_colors[assigned_id]; + } +} + void set_p_state_switch_method( struct dc *dc, struct dc_state *context, @@ -564,6 +612,7 @@ void set_p_state_switch_method( if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba) return; + pipe_ctx->p_state_type = P_STATE_UNKNOWN; if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] != dm_dram_clock_change_unsupported) { /* MCLK switching is supported */ 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 7eb91612b60d..ea404435c9b9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1472,7 +1472,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); /* Invalid input */ - if (!plane_state->dst_rect.width || + if (!plane_state || + !plane_state->dst_rect.width || !plane_state->dst_rect.height || !plane_state->src_rect.width || !plane_state->src_rect.height) { @@ -4925,7 +4926,10 @@ bool pipe_need_reprogram( return true; /* DIG link encoder resource assignment for stream changed. */ - if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) { + if (pipe_ctx_old->stream->ctx->dc->config.unify_link_enc_assignment) { + if (pipe_ctx_old->link_res.dio_link_enc != pipe_ctx->link_res.dio_link_enc) + return true; + } else if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) { bool need_reprogram = false; struct dc *dc = pipe_ctx_old->stream->ctx->dc; struct link_encoder *link_enc_prev = @@ -5191,7 +5195,7 @@ void get_audio_check(struct audio_info *aud_modes, } } -static struct link_encoder *get_temp_dio_link_enc( +struct link_encoder *get_temp_dio_link_enc( const struct resource_context *res_ctx, const struct resource_pool *const pool, const struct dc_link *link) 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 e8134c47fe0d..0478dd856d8c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -201,7 +201,8 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream) dc_stream_assign_stream_id(new_stream); /* If using dynamic encoder assignment, wait till stream committed to assign encoder. */ - if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign) + if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign && + !new_stream->ctx->dc->config.unify_link_enc_assignment) new_stream->link_enc = NULL; kref_init(&new_stream->refcount); diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5e96913bcab1..a62c4893e5ff 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -53,7 +53,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.321" +#define DC_VER "3.2.323" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC @@ -495,6 +495,7 @@ enum visual_confirm { VISUAL_CONFIRM_FAMS2 = 19, VISUAL_CONFIRM_HW_CURSOR = 20, VISUAL_CONFIRM_VABC = 21, + VISUAL_CONFIRM_DCC = 22, }; enum dc_psr_power_opts { @@ -1083,6 +1084,7 @@ struct dc_debug_options { unsigned int enable_oled_edp_power_up_opt; bool enable_hblank_borrow; bool force_subvp_df_throttle; + uint32_t acpi_transition_bitmasks[MAX_PIPES]; }; @@ -1806,6 +1808,7 @@ struct dc_link { struct dc_panel_config panel_config; struct phy_state phy_state; + uint32_t phy_transition_bitmask; // BW ALLOCATON USB4 ONLY struct dc_dpia_bw_alloc dpia_bw_alloc_config; bool skip_implict_edp_power_control; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index ae6e2d8552ac..1f4f11adc491 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -300,6 +300,19 @@ union lane_align_status_updated { uint8_t raw; }; +union link_service_irq_vector_esi0 { + struct { + uint8_t DP_LINK_RX_CAP_CHANGED:1; + uint8_t DP_LINK_STATUS_CHANGED:1; + uint8_t DP_LINK_STREAM_STATUS_CHANGED:1; + uint8_t DP_LINK_HDMI_LINK_STATUS_CHANGED:1; + uint8_t DP_LINK_CONNECTED_OFF_ENTRY_REQUESTED:1; + uint8_t DP_LINK_TUNNELING_IRQ:1; + uint8_t reserved:2; + } bits; + uint8_t raw; +}; + union lane_adjust { struct { uint8_t VOLTAGE_SWING_LANE:2; @@ -410,14 +423,6 @@ union dwnstream_port_caps_byte3_hdmi { uint8_t raw; }; -union hdmi_sink_encoded_link_bw_support { - struct { - uint8_t HDMI_SINK_ENCODED_LINK_BW_SUPPORT:3; - uint8_t RESERVED:5; - } bits; - uint8_t raw; -}; - union hdmi_encoded_link_bw { struct { uint8_t FRL_MODE:1; // Bit 0 @@ -470,8 +475,10 @@ union sink_status { uint8_t raw; }; -/*6-byte structure corresponding to 6 registers (200h-205h) -read during handling of HPD-IRQ*/ +/* 7-byte structure corresponding to 6 registers (200h-205h) + * and LINK_SERVICE_IRQ_ESI0 (2005h) for tunneling IRQ + * read during handling of HPD-IRQ + */ union hpd_irq_data { struct { union sink_count sink_cnt;/* 200h */ @@ -479,9 +486,10 @@ union hpd_irq_data { union lane_status lane01_status;/* 202h */ union lane_status lane23_status;/* 203h */ union lane_align_status_updated lane_status_updated;/* 204h */ - union sink_status sink_status; + union sink_status sink_status;/* 205h */ + union link_service_irq_vector_esi0 link_service_irq_esi0;/* 2005h */ } bytes; - uint8_t raw[6]; + uint8_t raw[7]; }; union down_stream_port_count { @@ -1128,6 +1136,8 @@ struct dc_lttpr_caps { union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates; union dp_alpm_lttpr_cap alpm; uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1]; + uint8_t lttpr_ieee_oui[3]; + uint8_t lttpr_device_id[6]; }; struct dc_dongle_dfp_cap_ext { @@ -1218,6 +1228,8 @@ struct dpcd_caps { struct replay_info pr_info; uint16_t edp_oled_emission_rate; union dp_receive_port0_cap receive_port0_cap; + /* Indicates the number of SST links supported by MSO (Multi-Stream Output) */ + uint8_t mso_cap_sst_links_supported; }; union dpcd_sink_ext_caps { @@ -1391,6 +1403,12 @@ struct dp_trace { #ifndef DP_BRANCH_VENDOR_SPECIFIC_START #define DP_BRANCH_VENDOR_SPECIFIC_START 0x50C #endif +#ifndef DP_LTTPR_IEEE_OUI +#define DP_LTTPR_IEEE_OUI 0xF003D +#endif +#ifndef DP_LTTPR_DEVICE_ID +#define DP_LTTPR_DEVICE_ID 0xF0040 +#endif /** USB4 DPCD BW Allocation Registers Chapter 10.7 **/ #ifndef DP_TUNNELING_CAPABILITIES #define DP_TUNNELING_CAPABILITIES 0xE000D /* 1.4a */ @@ -1428,4 +1446,20 @@ struct dp_trace { #ifndef REQUESTED_BW #define REQUESTED_BW 0xE0031 /* 1.4a */ #endif +# ifndef DP_TUNNELING_BW_ALLOC_BITS_MASK +# define DP_TUNNELING_BW_ALLOC_BITS_MASK (0x0F << 0) +# endif +# ifndef DP_TUNNELING_BW_REQUEST_FAILED +# define DP_TUNNELING_BW_REQUEST_FAILED (1 << 0) +# endif +# ifndef DP_TUNNELING_BW_REQUEST_SUCCEEDED +# define DP_TUNNELING_BW_REQUEST_SUCCEEDED (1 << 1) +# endif +# ifndef DP_TUNNELING_ESTIMATED_BW_CHANGED +# define DP_TUNNELING_ESTIMATED_BW_CHANGED (1 << 2) +# endif +# ifndef DP_TUNNELING_BW_ALLOC_CAP_CHANGED +# define DP_TUNNELING_BW_ALLOC_CAP_CHANGED (1 << 3) +# endif + #endif /* DC_DP_TYPES_H */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index e60898c2df01..acd3b373a18e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -181,6 +181,7 @@ struct dc_panel_patch { uint8_t blankstream_before_otg_off; bool oled_optimize_display_on; unsigned int force_mst_blocked_discovery; + unsigned int wait_after_dpcd_poweroff_ms; }; struct dc_edid_caps { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h index 160c299419b7..a9b88f5e0c04 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h @@ -379,53 +379,55 @@ struct dccg_mask { DCCG401_REG_FIELD_LIST(uint32_t) }; +#define DCCG_REG_VARIABLE_LIST \ + uint32_t DPPCLK_DTO_CTRL; \ + uint32_t DPPCLK_DTO_PARAM[6]; \ + uint32_t REFCLK_CNTL; \ + uint32_t DISPCLK_FREQ_CHANGE_CNTL; \ + uint32_t OTG_PIXEL_RATE_CNTL[MAX_PIPES]; \ + uint32_t HDMICHARCLK_CLOCK_CNTL[6]; \ + uint32_t PHYASYMCLK_CLOCK_CNTL; \ + uint32_t PHYBSYMCLK_CLOCK_CNTL; \ + uint32_t PHYCSYMCLK_CLOCK_CNTL; \ + uint32_t PHYDSYMCLK_CLOCK_CNTL; \ + uint32_t PHYESYMCLK_CLOCK_CNTL; \ + uint32_t DTBCLK_DTO_MODULO[MAX_PIPES]; \ + uint32_t DTBCLK_DTO_PHASE[MAX_PIPES]; \ + uint32_t DCCG_AUDIO_DTBCLK_DTO_MODULO; \ + uint32_t DCCG_AUDIO_DTBCLK_DTO_PHASE; \ + uint32_t DCCG_AUDIO_DTO_SOURCE; \ + uint32_t DPSTREAMCLK_CNTL; \ + uint32_t HDMISTREAMCLK_CNTL; \ + uint32_t SYMCLK32_SE_CNTL; \ + uint32_t SYMCLK32_LE_CNTL; \ + uint32_t DENTIST_DISPCLK_CNTL; \ + uint32_t DSCCLK_DTO_CTRL; \ + uint32_t DSCCLK0_DTO_PARAM; \ + uint32_t DSCCLK1_DTO_PARAM; \ + uint32_t DSCCLK2_DTO_PARAM; \ + uint32_t DSCCLK3_DTO_PARAM; \ + uint32_t DPSTREAMCLK_ROOT_GATE_DISABLE; \ + uint32_t DPSTREAMCLK_GATE_DISABLE; \ + uint32_t DCCG_GATE_DISABLE_CNTL; \ + uint32_t DCCG_GATE_DISABLE_CNTL2; \ + uint32_t DCCG_GATE_DISABLE_CNTL3; \ + uint32_t HDMISTREAMCLK0_DTO_PARAM; \ + uint32_t DCCG_GATE_DISABLE_CNTL4; \ + uint32_t OTG_PIXEL_RATE_DIV; \ + uint32_t DTBCLK_P_CNTL; \ + uint32_t DPPCLK_CTRL; \ + uint32_t DCCG_GATE_DISABLE_CNTL5; \ + uint32_t DCCG_GATE_DISABLE_CNTL6; \ + uint32_t DCCG_GLOBAL_FGCG_REP_CNTL; \ + uint32_t SYMCLKA_CLOCK_ENABLE; \ + uint32_t SYMCLKB_CLOCK_ENABLE; \ + uint32_t SYMCLKC_CLOCK_ENABLE; \ + uint32_t SYMCLKD_CLOCK_ENABLE; \ + uint32_t SYMCLKE_CLOCK_ENABLE; \ + uint32_t DP_DTO_MODULO[MAX_PIPES]; \ + uint32_t DP_DTO_PHASE[MAX_PIPES] struct dccg_registers { - uint32_t DPPCLK_DTO_CTRL; - uint32_t DPPCLK_DTO_PARAM[6]; - uint32_t REFCLK_CNTL; - uint32_t DISPCLK_FREQ_CHANGE_CNTL; - uint32_t OTG_PIXEL_RATE_CNTL[MAX_PIPES]; - uint32_t HDMICHARCLK_CLOCK_CNTL[6]; - uint32_t PHYASYMCLK_CLOCK_CNTL; - uint32_t PHYBSYMCLK_CLOCK_CNTL; - uint32_t PHYCSYMCLK_CLOCK_CNTL; - uint32_t PHYDSYMCLK_CLOCK_CNTL; - uint32_t PHYESYMCLK_CLOCK_CNTL; - uint32_t DTBCLK_DTO_MODULO[MAX_PIPES]; - uint32_t DTBCLK_DTO_PHASE[MAX_PIPES]; - uint32_t DCCG_AUDIO_DTBCLK_DTO_MODULO; - uint32_t DCCG_AUDIO_DTBCLK_DTO_PHASE; - uint32_t DCCG_AUDIO_DTO_SOURCE; - uint32_t DPSTREAMCLK_CNTL; - uint32_t HDMISTREAMCLK_CNTL; - uint32_t SYMCLK32_SE_CNTL; - uint32_t SYMCLK32_LE_CNTL; - uint32_t DENTIST_DISPCLK_CNTL; - uint32_t DSCCLK_DTO_CTRL; - uint32_t DSCCLK0_DTO_PARAM; - uint32_t DSCCLK1_DTO_PARAM; - uint32_t DSCCLK2_DTO_PARAM; - uint32_t DSCCLK3_DTO_PARAM; - uint32_t DPSTREAMCLK_ROOT_GATE_DISABLE; - uint32_t DPSTREAMCLK_GATE_DISABLE; - uint32_t DCCG_GATE_DISABLE_CNTL; - uint32_t DCCG_GATE_DISABLE_CNTL2; - uint32_t DCCG_GATE_DISABLE_CNTL3; - uint32_t HDMISTREAMCLK0_DTO_PARAM; - uint32_t DCCG_GATE_DISABLE_CNTL4; - uint32_t OTG_PIXEL_RATE_DIV; - uint32_t DTBCLK_P_CNTL; - uint32_t DPPCLK_CTRL; - uint32_t DCCG_GATE_DISABLE_CNTL5; - uint32_t DCCG_GATE_DISABLE_CNTL6; - uint32_t DCCG_GLOBAL_FGCG_REP_CNTL; - uint32_t SYMCLKA_CLOCK_ENABLE; - uint32_t SYMCLKB_CLOCK_ENABLE; - uint32_t SYMCLKC_CLOCK_ENABLE; - uint32_t SYMCLKD_CLOCK_ENABLE; - uint32_t SYMCLKE_CLOCK_ENABLE; - uint32_t DP_DTO_MODULO[MAX_PIPES]; - uint32_t DP_DTO_PHASE[MAX_PIPES]; + DCCG_REG_VARIABLE_LIST; }; struct dcn_dccg { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c index 332094ad2b05..ffd172231fdf 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c @@ -531,7 +531,7 @@ static void dccg401_enable_dpstreamclk(struct dccg *dccg, int otg_inst, int dp_h DPSTREAMCLK_ROOT_GATE_DISABLE, 1); } -static void dccg401_disable_dpstreamclk(struct dccg *dccg, int dp_hpo_inst) +void dccg401_disable_dpstreamclk(struct dccg *dccg, int dp_hpo_inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h index b9905c73e754..55e8718aad22 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h @@ -208,6 +208,8 @@ void dccg401_enable_symclk32_le( void dccg401_disable_symclk32_le( struct dccg *dccg, int hpo_le_inst); +void dccg401_disable_dpstreamclk(struct dccg *dccg, int dp_hpo_inst); +void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst); void dccg401_set_ref_dscclk(struct dccg *dccg, uint32_t dsc_inst); void dccg401_set_src_sel( @@ -228,14 +230,11 @@ void dccg401_set_dp_dto( const struct dp_dto_params *params); void dccg401_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst); void dccg401_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst); - void dccg401_set_dto_dscclk(struct dccg *dccg, uint32_t inst); void dccg401_set_dtbclk_p_src( struct dccg *dccg, enum streamclk_source src, uint32_t otg_inst); - - struct dccg *dccg401_create( struct dc_context *ctx, const struct dccg_registers *regs, diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c index e5fb0e8333e4..e691a1cf3356 100644 --- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c +++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c @@ -239,6 +239,7 @@ static const struct timing_generator_funcs dce60_tg_funcs = { dce60_timing_generator_enable_advanced_request, .configure_crc = dce60_configure_crc, .get_crc = dce110_get_crc, + .is_two_pixels_per_container = dce110_is_two_pixels_per_container, }; void dce60_timing_generator_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c index ea0c9a9d0bd6..9972911330b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c @@ -137,9 +137,9 @@ static const struct link_encoder_funcs dcn35_link_enc_funcs = { .hw_init = dcn35_link_encoder_init, .setup = dcn35_link_encoder_setup, .enable_tmds_output = dcn10_link_encoder_enable_tmds_output, - .enable_dp_output = dcn31_link_encoder_enable_dp_output, - .enable_dp_mst_output = dcn31_link_encoder_enable_dp_mst_output, - .disable_output = dcn31_link_encoder_disable_output, + .enable_dp_output = dcn35_link_encoder_enable_dp_output, + .enable_dp_mst_output = dcn35_link_encoder_enable_dp_mst_output, + .disable_output = dcn35_link_encoder_disable_output, .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings, .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern, .update_mst_stream_allocation_table = @@ -297,6 +297,50 @@ static void link_encoder_disable(struct dcn10_link_encoder *enc10) REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0); } +void dcn35_link_encoder_enable_dp_output( + struct link_encoder *enc, + const struct dc_link_settings *link_settings, + enum clock_source_id clock_source) +{ + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); + + if (!enc->ctx->dc->config.unify_link_enc_assignment) + dcn31_link_encoder_enable_dp_output(enc, link_settings, clock_source); + else { + DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine); + dcn20_link_encoder_enable_dp_output(enc, link_settings, clock_source); + } +} + +void dcn35_link_encoder_enable_dp_mst_output( + struct link_encoder *enc, + const struct dc_link_settings *link_settings, + enum clock_source_id clock_source) +{ + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); + + if (!enc->ctx->dc->config.unify_link_enc_assignment) + dcn31_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source); + else { + DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine); + dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source); + } +} + +void dcn35_link_encoder_disable_output( + struct link_encoder *enc, + enum signal_type signal) +{ + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); + + if (!enc->ctx->dc->config.unify_link_enc_assignment) + dcn31_link_encoder_disable_output(enc, signal); + else { + DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine); + dcn10_link_encoder_disable_output(enc, signal); + } +} + void dcn35_link_encoder_enable_dpia_output( struct link_encoder *enc, const struct dc_link_settings *link_settings, diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.h index f9d4221f4b43..5712e6553fab 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.h @@ -145,6 +145,29 @@ enum signal_type dcn35_get_dig_mode(struct link_encoder *enc); void dcn35_link_encoder_setup(struct link_encoder *enc, enum signal_type signal); /* + * Enable DP transmitter and its encoder. + */ +void dcn35_link_encoder_enable_dp_output( + struct link_encoder *enc, + const struct dc_link_settings *link_settings, + enum clock_source_id clock_source); + +/* + * Enable DP transmitter and its encoder in MST mode. + */ +void dcn35_link_encoder_enable_dp_mst_output( + struct link_encoder *enc, + const struct dc_link_settings *link_settings, + enum clock_source_id clock_source); + +/* + * Disable transmitter and its encoder. + */ +void dcn35_link_encoder_disable_output( + struct link_encoder *enc, + enum signal_type signal); + +/* * Enable DP transmitter and its encoder for dpia port. */ void dcn35_link_encoder_enable_dpia_output( diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c index 4bab180e1938..d5fa551dd3c9 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.c @@ -100,7 +100,7 @@ void enc401_stream_encoder_dvi_set_stream_attribute( } /* setup stream encoder in hdmi mode */ -static void enc401_stream_encoder_hdmi_set_stream_attribute( +void enc401_stream_encoder_hdmi_set_stream_attribute( struct stream_encoder *enc, struct dc_crtc_timing *crtc_timing, int actual_pix_clk_khz, diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h index 25cc8f72d8d3..d6b00cd246b1 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_stream_encoder.h @@ -232,4 +232,9 @@ void enc401_stream_encoder_map_to_link( uint32_t stream_enc_inst, uint32_t link_enc_inst); void enc401_read_state(struct stream_encoder *enc, struct enc_state *s); +void enc401_stream_encoder_hdmi_set_stream_attribute( + struct stream_encoder *enc, + struct dc_crtc_timing *crtc_timing, + int actual_pix_clk_khz, + bool enable_audio); #endif /* __DC_DIO_STREAM_ENCODER_DCN401_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dm_services.h b/drivers/gpu/drm/amd/display/dc/dm_services.h index f81e5a4e1d6d..7b9c22c45453 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services.h @@ -291,6 +291,13 @@ bool dm_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd, e bool dm_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count, union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type); /* + * ACPI Interfaces + */ +void dm_acpi_process_phy_transition_interlock( + const struct dc_context *ctx, + struct dm_process_phy_transition_init_params process_phy_transition_init_params); + +/* * Debug and verification hooks */ diff --git a/drivers/gpu/drm/amd/display/dc/dm_services_types.h b/drivers/gpu/drm/amd/display/dc/dm_services_types.h index facf269c4326..bf63da266a18 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_services_types.h +++ b/drivers/gpu/drm/amd/display/dc/dm_services_types.h @@ -275,4 +275,30 @@ enum dm_dmub_wait_type { DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY, }; +enum dm_acpi_transition_link_type { + hdmi_tmds, + hdmi_frl, + dp_8b_10b, + dp_128b_132b, + none +}; + +struct dm_process_phy_transition_init_params { + uint32_t phy_id; + uint8_t action; + uint32_t sym_clock_10khz; + enum signal_type signal; + enum dc_lane_count display_port_lanes_count; + enum dc_link_rate display_port_link_rate; + uint32_t transition_bitmask; + uint8_t hdmi_frl_num_lanes; +}; + +struct dm_process_phy_transition_input_params { + uint32_t phy_id; + uint32_t transition_id; + uint32_t phy_configuration; + uint32_t data_rate; +}; + #endif 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 index aac0a0ae2966..88789987bdbc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.c @@ -178,82 +178,6 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = { }; -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) { 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 index cab864095ce7..e3b6ad6a8784 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/dcn30_fpu.h @@ -29,9 +29,6 @@ #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); diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index cee1b351e105..f1fe49401bc0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -281,10 +281,10 @@ static void CalculateDynamicMetadataParameters( double DISPCLK, double DCFClkDeepSleep, double PixelClock, - long HTotal, - long VBlank, - long DynamicMetadataTransmittedBytes, - long DynamicMetadataLinesBeforeActiveRequired, + unsigned int HTotal, + unsigned int VBlank, + unsigned int DynamicMetadataTransmittedBytes, + int DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP, double *Tsetup, @@ -3265,8 +3265,8 @@ static double CalculateWriteBackDelay( static void CalculateDynamicMetadataParameters(int MaxInterDCNTileRepeaters, double DPPCLK, double DISPCLK, - double DCFClkDeepSleep, double PixelClock, long HTotal, long VBlank, long DynamicMetadataTransmittedBytes, - long DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP, + double DCFClkDeepSleep, double PixelClock, unsigned int HTotal, unsigned int VBlank, unsigned int DynamicMetadataTransmittedBytes, + int DynamicMetadataLinesBeforeActiveRequired, int InterlaceEnable, bool ProgressiveToInterlaceUnitInOPP, double *Tsetup, double *Tdmbf, double *Tdmec, double *Tdmsks) { double TotalRepeaterDelayTime = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 6f490d8d7038..56dda686e299 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -626,6 +626,7 @@ static bool dcn32_assign_subvp_pipe(struct dc *dc, * - Not TMZ surface */ if (pipe->plane_state && !pipe->top_pipe && !pipe->prev_odm_pipe && !dcn32_is_center_timing(pipe) && + !pipe->stream->hw_cursor_req && !(pipe->stream->timing.pix_clk_100hz / 10000 > DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ) && (!dcn32_is_psr_capable(pipe) || (context->stream_count == 1 && dc->caps.dmub_caps.subvp_psr)) && dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_NONE && diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c index 412e75eb4704..12ff65b6a7e5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c @@ -122,17 +122,6 @@ void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, const stru dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param) -{ - dml_print("DML_RQ_DLG_CALC: =====================================\n"); - dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); - dml_print("DML_RQ_DLG_CALC: <LUMA>\n"); - print__data_rq_dlg_params_st(mode_lib, &rq_dlg_param->rq_l); - dml_print("DML_RQ_DLG_CALC: <CHROMA>\n"); - print__data_rq_dlg_params_st(mode_lib, &rq_dlg_param->rq_c); - dml_print("DML_RQ_DLG_CALC: =====================================\n"); -} - void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h index ebcd717744e5..2bc64c4081dc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h @@ -35,7 +35,6 @@ void print__rq_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dp void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing); void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param); void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param); -void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param); void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param); void print__data_rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_regs_st *rq_regs); diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c index 3664980d1574..bb863c8c6b39 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4.c @@ -44,7 +44,7 @@ struct dml2_core_ip_params core_dcn4_ip_caps_base = { .dppclk_delay_scl_lb_only = 16, .dppclk_delay_cnvc_formatter = 28, .dppclk_delay_cnvc_cursor = 6, - .cursor_buffer_size = 42, + .cursor_buffer_size = 24, .cursor_chunk_size = 2, .dispclk_delay_subtotal = 125, .max_inter_dcn_tile_repeaters = 8, @@ -141,9 +141,8 @@ bool core_dcn4_initialize(struct dml2_core_initialize_in_out *in_out) core->clean_me_up.mode_lib.ip.subvp_fw_processing_delay_us = core_dcn4_ip_caps_base.subvp_pstate_allow_width_us; core->clean_me_up.mode_lib.ip.subvp_swath_height_margin_lines = core_dcn4_ip_caps_base.subvp_swath_height_margin_lines; } else { - memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn4_ip_caps_base, sizeof(struct dml2_core_ip_params)); + memcpy(&core->clean_me_up.mode_lib.ip, &core_dcn4_ip_caps_base, sizeof(struct dml2_core_ip_params)); patch_ip_params_with_ip_caps(&core->clean_me_up.mode_lib.ip, in_out->ip_caps); - core->clean_me_up.mode_lib.ip.imall_supported = false; } diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c index 78c93a502518..4c33d99ca7e8 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c @@ -5058,7 +5058,7 @@ static void CalculateExtraLatency( double HostVMInefficiencyFactorPrefetch, unsigned int HostVMMinPageSize, enum dml2_qos_param_type qos_type, - bool max_oustanding_when_urgent_expected, + bool max_outstanding_when_urgent_expected, unsigned int max_outstanding_requests, unsigned int request_size_bytes_luma[], unsigned int request_size_bytes_chroma[], @@ -5106,7 +5106,7 @@ static void CalculateExtraLatency( if (qos_type == dml2_qos_param_type_dcn4x) { *ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK; *ExtraLatency = *ExtraLatency_sr; - if (max_oustanding_when_urgent_expected) + if (max_outstanding_when_urgent_expected) *ExtraLatency = *ExtraLatency + (ROBBufferSizeInKByte * 1024 - max_outstanding_requests * max_request_size_bytes) / ReturnBW; } else { *ExtraLatency_sr = dchub_arb_to_ret_delay / DCFCLK + RoundTripPingLatencyCycles / FabricClock + ReorderingBytes / ReturnBW; @@ -5121,7 +5121,7 @@ static void CalculateExtraLatency( dml2_printf("DML::%s: qos_type=%u\n", __func__, qos_type); dml2_printf("DML::%s: hostvm_mode=%u\n", __func__, hostvm_mode); dml2_printf("DML::%s: Tex_trips=%u\n", __func__, Tex_trips); - dml2_printf("DML::%s: max_oustanding_when_urgent_expected=%u\n", __func__, max_oustanding_when_urgent_expected); + dml2_printf("DML::%s: max_outstanding_when_urgent_expected=%u\n", __func__, max_outstanding_when_urgent_expected); dml2_printf("DML::%s: FabricClock=%f\n", __func__, FabricClock); dml2_printf("DML::%s: DCFCLK=%f\n", __func__, DCFCLK); dml2_printf("DML::%s: ReturnBW=%f\n", __func__, ReturnBW); diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h index dfe54112a9c6..4e502f0a6d20 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_shared_types.h @@ -1571,7 +1571,7 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_param unsigned int *DSTYAfterScaler; bool UnboundedRequestEnabled; unsigned int CompressedBufferSizeInkByte; - bool max_oustanding_when_urgent_expected; + bool max_outstanding_when_urgent_expected; unsigned int max_outstanding_requests; unsigned int max_request_size_bytes; unsigned int *meta_row_height_l; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c index 1ed21c1b86a5..a966abd40788 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c @@ -532,26 +532,6 @@ static void calculate_odm_slices(const struct dc_stream_state *stream, unsigned odm_slice_end_x[odm_factor - 1] = stream->src.width - 1; } -static bool is_plane_in_odm_slice(const struct dc_plane_state *plane, unsigned int slice_index, unsigned int *odm_slice_end_x, unsigned int num_slices) -{ - unsigned int slice_start_x, slice_end_x; - - if (slice_index == 0) - slice_start_x = 0; - else - slice_start_x = odm_slice_end_x[slice_index - 1] + 1; - - slice_end_x = odm_slice_end_x[slice_index]; - - if (plane->clip_rect.x + plane->clip_rect.width < slice_start_x) - return false; - - if (plane->clip_rect.x > slice_end_x) - return false; - - return true; -} - static void add_odm_slice_to_odm_tree(struct dml2_context *ctx, struct dc_state *state, struct dc_pipe_mapping_scratch *scratch, @@ -791,12 +771,6 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state sort_pipes_for_splitting(&scratch->pipe_pool); for (odm_slice_index = 0; odm_slice_index < scratch->odm_info.odm_factor; odm_slice_index++) { - // We build the tree for one ODM slice at a time. - // Each ODM slice shares a common OPP - if (!is_plane_in_odm_slice(plane, odm_slice_index, scratch->odm_info.odm_slice_end_x, scratch->odm_info.odm_factor)) { - continue; - } - // Now we have a list of all pipes to be used for this plane/stream, now setup the tree. scratch->odm_info.next_higher_pipe_for_odm_slice[odm_slice_index] = add_plane_to_blend_tree(ctx, state, plane, diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c index f829d5ac7c8e..2061d43b92e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c @@ -557,6 +557,7 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, } if (dml2->v20.dml_core_ctx.project == dml_project_dcn35 || + dml2->v20.dml_core_ctx.project == dml_project_dcn36 || dml2->v20.dml_core_ctx.project == dml_project_dcn351) { int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0, max_phyclk_mhz = 0, max_dtbclk_mhz = 0, max_fclk_mhz = 0, max_uclk_mhz = 0, max_socclk_mhz = 0; diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c index 45584e2f5dfe..939ee0708bd2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -33,7 +33,6 @@ #include "dml2_dc_resource_mgmt.h" #include "dml21_wrapper.h" - static void initialize_dml2_ip_params(struct dml2_context *dml2, const struct dc *in_dc, struct ip_params_st *out) { if (dml2->config.use_native_soc_bb_construction) @@ -792,7 +791,7 @@ bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options // TODO : Temporarily add DCN_VERSION_3_2 for N-1 validation. Remove DCN_VERSION_3_2 after N-1 validation phase is complete. if ((in_dc->debug.using_dml21) && (in_dc->ctx->dce_version == DCN_VERSION_4_01 - )) + )) return dml21_create(in_dc, dml2, config); // Allocate Mode Lib Ctx diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c index 40acebd13e46..abf439e743f2 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c @@ -425,11 +425,6 @@ bool dpp3_get_optimal_number_of_taps( int min_taps_y, min_taps_c; enum lb_memory_config lb_config; - if (scl_data->viewport.width > scl_data->h_active && - dpp->ctx->dc->debug.max_downscale_src_width != 0 && - scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) - return false; - /* * Set default taps if none are provided * From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling @@ -467,6 +462,12 @@ bool dpp3_get_optimal_number_of_taps( else scl_data->taps.h_taps_c = in_taps->h_taps_c; + // Avoid null data in the scl data with this early return, proceed non-adaptive calcualtion first + if (scl_data->viewport.width > scl_data->h_active && + dpp->ctx->dc->debug.max_downscale_src_width != 0 && + scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) + return false; + /*Ensure we can support the requested number of vtaps*/ min_taps_y = dc_fixpt_ceil(scl_data->ratios.vert); min_taps_c = dc_fixpt_ceil(scl_data->ratios.vert_c); diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h index 4bc85aaf17da..ecaa976e1f52 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.h @@ -567,80 +567,82 @@ type ISHARP_NLDELTA_SCLIP_PIVOT_N; \ type ISHARP_NLDELTA_SCLIP_SLOPE_N +#define DPP_REG_VARIABLE_LIST_DCN401 \ + DPP_DCN3_REG_VARIABLE_LIST_COMMON; \ + uint32_t CURSOR0_FP_SCALE_BIAS_G_Y; \ + uint32_t CURSOR0_FP_SCALE_BIAS_RB_CRCB; \ + uint32_t CUR0_MATRIX_MODE; \ + uint32_t CUR0_MATRIX_C11_C12_A; \ + uint32_t CUR0_MATRIX_C13_C14_A; \ + uint32_t CUR0_MATRIX_C21_C22_A; \ + uint32_t CUR0_MATRIX_C23_C24_A; \ + uint32_t CUR0_MATRIX_C31_C32_A; \ + uint32_t CUR0_MATRIX_C33_C34_A; \ + uint32_t CUR0_MATRIX_C11_C12_B; \ + uint32_t CUR0_MATRIX_C13_C14_B; \ + uint32_t CUR0_MATRIX_C21_C22_B; \ + uint32_t CUR0_MATRIX_C23_C24_B; \ + uint32_t CUR0_MATRIX_C31_C32_B; \ + uint32_t CUR0_MATRIX_C33_C34_B; \ + uint32_t DSCL_SC_MODE; \ + uint32_t DSCL_EASF_H_MODE; \ + uint32_t DSCL_EASF_H_BF_CNTL; \ + uint32_t DSCL_EASF_H_RINGEST_EVENTAP_REDUCE; \ + uint32_t DSCL_EASF_H_RINGEST_EVENTAP_GAIN; \ + uint32_t DSCL_EASF_H_BF_FINAL_MAX_MIN; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG0; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG1; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG2; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG3; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG4; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG5; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG6; \ + uint32_t DSCL_EASF_H_BF1_PWL_SEG7; \ + uint32_t DSCL_EASF_H_BF3_PWL_SEG0; \ + uint32_t DSCL_EASF_H_BF3_PWL_SEG1; \ + uint32_t DSCL_EASF_H_BF3_PWL_SEG2; \ + uint32_t DSCL_EASF_H_BF3_PWL_SEG3; \ + uint32_t DSCL_EASF_H_BF3_PWL_SEG4; \ + uint32_t DSCL_EASF_H_BF3_PWL_SEG5; \ + uint32_t DSCL_EASF_V_MODE; \ + uint32_t DSCL_EASF_V_BF_CNTL; \ + uint32_t DSCL_EASF_V_RINGEST_3TAP_CNTL1; \ + uint32_t DSCL_EASF_V_RINGEST_3TAP_CNTL2; \ + uint32_t DSCL_EASF_V_RINGEST_3TAP_CNTL3; \ + uint32_t DSCL_EASF_V_RINGEST_EVENTAP_REDUCE; \ + uint32_t DSCL_EASF_V_RINGEST_EVENTAP_GAIN; \ + uint32_t DSCL_EASF_V_BF_FINAL_MAX_MIN; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG0; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG1; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG2; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG3; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG4; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG5; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG6; \ + uint32_t DSCL_EASF_V_BF1_PWL_SEG7; \ + uint32_t DSCL_EASF_V_BF3_PWL_SEG0; \ + uint32_t DSCL_EASF_V_BF3_PWL_SEG1; \ + uint32_t DSCL_EASF_V_BF3_PWL_SEG2; \ + uint32_t DSCL_EASF_V_BF3_PWL_SEG3; \ + uint32_t DSCL_EASF_V_BF3_PWL_SEG4; \ + uint32_t DSCL_EASF_V_BF3_PWL_SEG5; \ + uint32_t DSCL_SC_MATRIX_C0C1; \ + uint32_t DSCL_SC_MATRIX_C2C3; \ + uint32_t ISHARP_MODE; \ + uint32_t ISHARP_NOISEDET_THRESHOLD; \ + uint32_t ISHARP_NOISE_GAIN_PWL; \ + uint32_t ISHARP_LBA_PWL_SEG0; \ + uint32_t ISHARP_LBA_PWL_SEG1; \ + uint32_t ISHARP_LBA_PWL_SEG2; \ + uint32_t ISHARP_LBA_PWL_SEG3; \ + uint32_t ISHARP_LBA_PWL_SEG4; \ + uint32_t ISHARP_LBA_PWL_SEG5; \ + uint32_t ISHARP_DELTA_CTRL; \ + uint32_t ISHARP_DELTA_DATA; \ + uint32_t ISHARP_DELTA_INDEX; \ + uint32_t ISHARP_NLDELTA_SOFT_CLIP struct dcn401_dpp_registers { - DPP_DCN3_REG_VARIABLE_LIST_COMMON; - uint32_t CURSOR0_FP_SCALE_BIAS_G_Y; - uint32_t CURSOR0_FP_SCALE_BIAS_RB_CRCB; - uint32_t CUR0_MATRIX_MODE; - uint32_t CUR0_MATRIX_C11_C12_A; - uint32_t CUR0_MATRIX_C13_C14_A; - uint32_t CUR0_MATRIX_C21_C22_A; - uint32_t CUR0_MATRIX_C23_C24_A; - uint32_t CUR0_MATRIX_C31_C32_A; - uint32_t CUR0_MATRIX_C33_C34_A; - uint32_t CUR0_MATRIX_C11_C12_B; - uint32_t CUR0_MATRIX_C13_C14_B; - uint32_t CUR0_MATRIX_C21_C22_B; - uint32_t CUR0_MATRIX_C23_C24_B; - uint32_t CUR0_MATRIX_C31_C32_B; - uint32_t CUR0_MATRIX_C33_C34_B; - uint32_t DSCL_SC_MODE; - uint32_t DSCL_EASF_H_MODE; - uint32_t DSCL_EASF_H_BF_CNTL; - uint32_t DSCL_EASF_H_RINGEST_EVENTAP_REDUCE; - uint32_t DSCL_EASF_H_RINGEST_EVENTAP_GAIN; - uint32_t DSCL_EASF_H_BF_FINAL_MAX_MIN; - uint32_t DSCL_EASF_H_BF1_PWL_SEG0; - uint32_t DSCL_EASF_H_BF1_PWL_SEG1; - uint32_t DSCL_EASF_H_BF1_PWL_SEG2; - uint32_t DSCL_EASF_H_BF1_PWL_SEG3; - uint32_t DSCL_EASF_H_BF1_PWL_SEG4; - uint32_t DSCL_EASF_H_BF1_PWL_SEG5; - uint32_t DSCL_EASF_H_BF1_PWL_SEG6; - uint32_t DSCL_EASF_H_BF1_PWL_SEG7; - uint32_t DSCL_EASF_H_BF3_PWL_SEG0; - uint32_t DSCL_EASF_H_BF3_PWL_SEG1; - uint32_t DSCL_EASF_H_BF3_PWL_SEG2; - uint32_t DSCL_EASF_H_BF3_PWL_SEG3; - uint32_t DSCL_EASF_H_BF3_PWL_SEG4; - uint32_t DSCL_EASF_H_BF3_PWL_SEG5; - uint32_t DSCL_EASF_V_MODE; - uint32_t DSCL_EASF_V_BF_CNTL; - uint32_t DSCL_EASF_V_RINGEST_3TAP_CNTL1; - uint32_t DSCL_EASF_V_RINGEST_3TAP_CNTL2; - uint32_t DSCL_EASF_V_RINGEST_3TAP_CNTL3; - uint32_t DSCL_EASF_V_RINGEST_EVENTAP_REDUCE; - uint32_t DSCL_EASF_V_RINGEST_EVENTAP_GAIN; - uint32_t DSCL_EASF_V_BF_FINAL_MAX_MIN; - uint32_t DSCL_EASF_V_BF1_PWL_SEG0; - uint32_t DSCL_EASF_V_BF1_PWL_SEG1; - uint32_t DSCL_EASF_V_BF1_PWL_SEG2; - uint32_t DSCL_EASF_V_BF1_PWL_SEG3; - uint32_t DSCL_EASF_V_BF1_PWL_SEG4; - uint32_t DSCL_EASF_V_BF1_PWL_SEG5; - uint32_t DSCL_EASF_V_BF1_PWL_SEG6; - uint32_t DSCL_EASF_V_BF1_PWL_SEG7; - uint32_t DSCL_EASF_V_BF3_PWL_SEG0; - uint32_t DSCL_EASF_V_BF3_PWL_SEG1; - uint32_t DSCL_EASF_V_BF3_PWL_SEG2; - uint32_t DSCL_EASF_V_BF3_PWL_SEG3; - uint32_t DSCL_EASF_V_BF3_PWL_SEG4; - uint32_t DSCL_EASF_V_BF3_PWL_SEG5; - uint32_t DSCL_SC_MATRIX_C0C1; - uint32_t DSCL_SC_MATRIX_C2C3; - uint32_t ISHARP_MODE; - uint32_t ISHARP_NOISEDET_THRESHOLD; - uint32_t ISHARP_NOISE_GAIN_PWL; - uint32_t ISHARP_LBA_PWL_SEG0; - uint32_t ISHARP_LBA_PWL_SEG1; - uint32_t ISHARP_LBA_PWL_SEG2; - uint32_t ISHARP_LBA_PWL_SEG3; - uint32_t ISHARP_LBA_PWL_SEG4; - uint32_t ISHARP_LBA_PWL_SEG5; - uint32_t ISHARP_DELTA_CTRL; - uint32_t ISHARP_DELTA_DATA; - uint32_t ISHARP_DELTA_INDEX; - uint32_t ISHARP_NLDELTA_SOFT_CLIP; + DPP_REG_VARIABLE_LIST_DCN401; }; struct dcn401_dpp_shift { diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c index 03b4ac2f1991..0d2ae21abbdd 100644 --- a/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.c @@ -262,7 +262,7 @@ void dcn31_hpo_dp_link_enc_set_link_test_pattern( } } -static void fill_stream_allocation_row_info( +void dcn31_fill_stream_allocation_row_info( const struct link_mst_stream_allocation *stream_allocation, uint32_t *src, uint32_t *slots) @@ -296,7 +296,7 @@ void dcn31_hpo_dp_link_enc_update_stream_allocation_table( /* we should clean-up table each time */ if (table->stream_count >= 1) { - fill_stream_allocation_row_info( + dcn31_fill_stream_allocation_row_info( &table->stream_allocations[0], &src, &slots); @@ -310,7 +310,7 @@ void dcn31_hpo_dp_link_enc_update_stream_allocation_table( SAT_SLOT_COUNT, slots); if (table->stream_count >= 2) { - fill_stream_allocation_row_info( + dcn31_fill_stream_allocation_row_info( &table->stream_allocations[1], &src, &slots); @@ -324,7 +324,7 @@ void dcn31_hpo_dp_link_enc_update_stream_allocation_table( SAT_SLOT_COUNT, slots); if (table->stream_count >= 3) { - fill_stream_allocation_row_info( + dcn31_fill_stream_allocation_row_info( &table->stream_allocations[2], &src, &slots); @@ -338,7 +338,7 @@ void dcn31_hpo_dp_link_enc_update_stream_allocation_table( SAT_SLOT_COUNT, slots); if (table->stream_count >= 4) { - fill_stream_allocation_row_info( + dcn31_fill_stream_allocation_row_info( &table->stream_allocations[3], &src, &slots); diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h index 51f5781325e8..40859660e4dc 100644 --- a/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn31/dcn31_hpo_dp_link_encoder.h @@ -226,4 +226,10 @@ void dcn31_hpo_dp_link_enc_set_ffe( const struct dc_link_settings *link_settings, uint8_t ffe_preset); + +void dcn31_fill_stream_allocation_row_info( + const struct link_mst_stream_allocation *stream_allocation, + uint32_t *src, + uint32_t *slots); + #endif // __DAL_DCN31_HPO_LINK_ENCODER_H__ diff --git a/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h b/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h index 48ef3d29b370..bea4e1a8ff90 100644 --- a/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/hpo/dcn32/dcn32_hpo_dp_link_encoder.h @@ -62,4 +62,7 @@ void hpo_dp_link_encoder32_construct(struct dcn31_hpo_dp_link_encoder *enc31, const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift, const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask); +bool dcn32_hpo_dp_link_enc_is_in_alt_mode( + struct hpo_dp_link_encoder *enc); + #endif // __DAL_DCN32_HPO_DP_LINK_ENCODER_H__ diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h index 09049aa3c4f3..f66a38f43a09 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce/dce_hwseq.h @@ -1244,6 +1244,7 @@ struct dce_hwseq_registers { type DOMAIN24_PGFSM_PWR_STATUS; \ type DOMAIN25_PGFSM_PWR_STATUS; \ type DOMAIN_DESIRED_PWR_STATE; + struct dce_hwseq_shift { HWSEQ_REG_FIELD_LIST(uint8_t) HWSEQ_DCN_REG_FIELD_LIST(uint8_t) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c index 8280e3652171..9c9947fc5d44 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -1153,9 +1153,12 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) struct timing_generator *tg = pipe_ctx->stream_res.tg; struct dtbclk_dto_params dto_params = {0}; int dp_hpo_inst; - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; + if (!dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( pipe_ctx->stream_res.stream_enc); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index b158eb1045a1..a5a3e0823e21 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -3020,9 +3020,12 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) enum phyd32clk_clock_source phyd32clk; int dp_hpo_inst; - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; + if (!dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { dto_params.otg_inst = tg->inst; dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c index f698062f1e90..288e9dd9205d 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c @@ -621,7 +621,8 @@ void dcn31_reset_hw_ctx_wrap( } /* New dc_state in the process of being applied to hardware. */ - link_enc_cfg_set_transient_mode(dc, dc->current_state, context); + if (!dc->config.unify_link_enc_assignment) + link_enc_cfg_set_transient_mode(dc, dc->current_state, context); } void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable) diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index c4a37a95e812..39668d8cc13a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -927,9 +927,12 @@ void dcn401_enable_stream(struct pipe_ctx *pipe_ctx) int dp_hpo_inst = 0; unsigned int tmds_div = PIXEL_RATE_DIV_NA; unsigned int unused_div = PIXEL_RATE_DIV_NA; - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; + if (!dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + dcn401_enable_stream_calc(pipe_ctx, &dp_hpo_inst, &phyd32clk, &tmds_div, &early_control); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h index 599fa41fd75f..2b1a2a00648a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -517,6 +517,11 @@ void get_cursor_visual_confirm_color( struct pipe_ctx *pipe_ctx, struct tg_color *color); +void get_dcc_visual_confirm_color( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct tg_color *color); + void set_p_state_switch_method( struct dc *dc, struct dc_state *context, diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index 042e04f924a2..9458187b834d 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -647,4 +647,9 @@ void resource_init_common_dml2_callbacks(struct dc *dc, struct dml2_configuratio int resource_calculate_det_for_stream(struct dc_state *state, struct pipe_ctx *otg_master); bool resource_is_hpo_acquired(struct dc_state *context); + +struct link_encoder *get_temp_dio_link_enc( + const struct resource_context *res_ctx, + const struct resource_pool *const pool, + const struct dc_link *link); #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c index 06faa461067b..b68bcc9fca0a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c @@ -48,9 +48,16 @@ void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx, void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; + if (!pipe_ctx->stream->ctx->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + if (!link_enc) { + ASSERT(link_enc); + return; + } + link_enc->funcs->connect_dig_be_to_fe(link_enc, pipe_ctx->stream_res.stream_enc->id, true); if (dc_is_dp_signal(pipe_ctx->stream->signal)) @@ -71,9 +78,16 @@ void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx) void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; + if (!pipe_ctx->stream->ctx->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + if (!link_enc) { + ASSERT(link_enc); + return; + } + if (!stream_enc) return; @@ -142,7 +156,14 @@ void enable_dio_dp_link_output(struct dc_link *link, enum clock_source_id clock_source, const struct dc_link_settings *link_settings) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (!link_enc) { + ASSERT(link_enc); + return; + } if (dc_is_dp_sst_signal(signal)) link_enc->funcs->enable_dp_output( @@ -162,11 +183,16 @@ void disable_dio_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; - if (link_enc != NULL) - link_enc->funcs->disable_output(link_enc, signal); + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (!link_enc) { + ASSERT(link_enc); + return; + } + link_enc->funcs->disable_output(link_enc, signal); link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); } @@ -175,7 +201,14 @@ void set_dio_dp_link_test_pattern(struct dc_link *link, const struct link_resource *link_res, struct encoder_set_dp_phy_pattern_param *tp_params) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (!link_enc) { + ASSERT(link_enc); + return; + } link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params); link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); @@ -186,7 +219,14 @@ void set_dio_dp_lane_settings(struct dc_link *link, const struct dc_link_settings *link_settings, const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (!link_enc) { + ASSERT(link_enc); + return; + } link_enc->funcs->dp_set_lane_settings(link_enc, link_settings, lane_settings); } @@ -195,9 +235,15 @@ void update_dio_stream_allocation_table(struct dc_link *link, const struct link_resource *link_res, const struct link_mst_stream_allocation_table *table) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + if (!link_enc) { + ASSERT(link_enc); + return; + } - ASSERT(link_enc); link_enc->funcs->update_mst_stream_allocation_table(link_enc, table); } @@ -282,7 +328,10 @@ static const struct link_hwss dio_link_hwss = { bool can_use_dio_link_hwss(const struct dc_link *link, const struct link_resource *link_res) { - return link->link_enc != NULL; + if (!link->dc->config.unify_link_enc_assignment) + return link->link_enc != NULL; + else + return link_res->dio_link_enc != NULL; } /** diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c index a6d1d7641ab4..e1dff4e3f446 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c @@ -127,7 +127,10 @@ static void set_dio_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *lin const struct link_resource *link_res, struct encoder_set_dp_phy_pattern_param *tp_params) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); if (!set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override( link, link_res, tp_params, get_dio_link_hwss())) { diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c index 36adf95744fe..81bf3c5e1fdf 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c @@ -35,12 +35,15 @@ static void update_dpia_stream_allocation_table(struct dc_link *link, const struct link_resource *link_res, const struct link_mst_stream_allocation_table *table) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; static enum dc_status status; uint8_t mst_alloc_slots = 0, prev_mst_slots_in_use = 0xFF; int i; DC_LOGGER_INIT(link->ctx->logger); + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + for (i = 0; i < table->stream_count; i++) mst_alloc_slots += table->stream_allocations[i].slot_count; @@ -61,7 +64,10 @@ static void set_dio_dpia_link_test_pattern(struct dc_link *link, if (tp_params->dp_phy_pattern != DP_TEST_PATTERN_VIDEO_MODE) return; - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); if (!link_enc) return; @@ -83,31 +89,28 @@ static void enable_dpia_link_output(struct dc_link *link, enum clock_source_id clock_source, const struct dc_link_settings *link_settings) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + DC_LOGGER_INIT(link->ctx->logger); + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); if (link_enc != NULL) { - if (link->dc->config.enable_dpia_pre_training && link_enc->funcs->enable_dpia_output) { + if (link->dc->config.enable_dpia_pre_training || link->dc->config.unify_link_enc_assignment) { uint8_t fec_rdy = link->dc->link_srv->dp_should_enable_fec(link); uint8_t digmode = dc_is_dp_sst_signal(signal) ? DIG_SST_MODE : DIG_MST_MODE; - link_enc->funcs->enable_dpia_output( - link_enc, - link_settings, - link->ddc_hw_inst, - digmode, - fec_rdy); - } else { - if (dc_is_dp_sst_signal(signal)) - link_enc->funcs->enable_dp_output( + if (link_enc->funcs->enable_dpia_output) + link_enc->funcs->enable_dpia_output( link_enc, link_settings, - clock_source); + link->ddc_hw_inst, + digmode, + fec_rdy); else - link_enc->funcs->enable_dp_mst_output( - link_enc, - link_settings, - clock_source); - } + DC_LOG_ERROR("%s: link encoder does not support enable_dpia_output\n", __func__); + } else + enable_dio_dp_link_output(link, link_res, signal, clock_source, link_settings); } @@ -119,13 +122,20 @@ static void disable_dpia_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal) { - struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link); + struct link_encoder *link_enc = link_res->dio_link_enc; + DC_LOGGER_INIT(link->ctx->logger); + + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); if (link_enc != NULL) { - if (link->dc->config.enable_dpia_pre_training && link_enc->funcs->disable_dpia_output) { + if (link->dc->config.enable_dpia_pre_training || link->dc->config.unify_link_enc_assignment) { uint8_t digmode = dc_is_dp_sst_signal(signal) ? DIG_SST_MODE : DIG_MST_MODE; - link_enc->funcs->disable_dpia_output(link_enc, link->ddc_hw_inst, digmode); + if (link_enc->funcs->disable_dpia_output) + link_enc->funcs->disable_dpia_output(link_enc, link->ddc_hw_inst, digmode); + else + DC_LOG_ERROR("%s: link encoder does not support disable_dpia_output\n", __func__); } else link_enc->funcs->disable_output(link_enc, signal); } @@ -154,8 +164,10 @@ static const struct link_hwss dpia_link_hwss = { bool can_use_dpia_link_hwss(const struct dc_link *link, const struct link_resource *link_res) { - return link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign; + if (!link->dc->config.unify_link_enc_assignment) + return link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign; + else + return link->is_dig_mapping_flexible && link_res->dio_link_enc != NULL; } const struct link_hwss *get_dpia_link_hwss(void) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 550e1a098fa2..cc9191a5c9e6 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -816,7 +816,10 @@ static bool should_verify_link_capability_destructively(struct dc_link *link, { bool destrictive = false; struct dc_link_settings max_link_cap; - bool is_link_enc_unavailable = link->link_enc && + bool is_link_enc_unavailable = false; + + if (!link->dc->config.unify_link_enc_assignment) + is_link_enc_unavailable = link->link_enc && link->dc->res_pool->funcs->link_encs_assign && !link_enc_cfg_is_link_enc_avail( link->ctx->dc, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index ec7de9c01fab..321fd1785370 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -652,15 +652,15 @@ static void write_i2c_redriver_setting( static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) { struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp; - struct link_encoder *link_enc = NULL; + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct cp_psp_stream_config config = {0}; enum dp_panel_mode panel_mode = dp_get_panel_mode(pipe_ctx->stream->link); if (cp_psp == NULL || cp_psp->funcs.update_stream_config == NULL) return; - - link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); + if (!pipe_ctx->stream->ctx->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); ASSERT(link_enc); if (link_enc == NULL) return; @@ -1924,7 +1924,7 @@ static void disable_link_dp(struct dc_link *link, if (link_dp_get_encoding_format(&link_settings) == DP_8b_10b_ENCODING) { - dp_set_fec_enable(link, false); + dp_set_fec_enable(link, link_res, false); dp_set_fec_ready(link, link_res, false); } } @@ -2122,7 +2122,7 @@ static enum dc_status enable_link_dp(struct dc_state *state, fec_enable = true; if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) - dp_set_fec_enable(link, fec_enable); + dp_set_fec_enable(link, &pipe_ctx->link_res, fec_enable); // during mode set we do DP_SET_POWER off then on, aux writes are lost if (link->dpcd_sink_ext_caps.bits.oled == 1 || @@ -2461,7 +2461,7 @@ void link_set_dpms_on( struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->sink->link; enum dc_status status; - struct link_encoder *link_enc; + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO; struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); @@ -2486,7 +2486,8 @@ void link_set_dpms_on( } } - link_enc = link_enc_cfg_get_link_enc(link); + if (!dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); if (!dc_is_virtual_signal(pipe_ctx->stream->signal) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index e3e7fcb07f19..a77410122636 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -250,21 +250,21 @@ static uint32_t intersect_frl_link_bw_support( { uint32_t supported_bw_in_kbps = max_supported_frl_bw_in_kbps; - // HDMI_ENCODED_LINK_BW bits are only valid if HDMI Link Configuration bit is 1 (FRL mode) - if (hdmi_encoded_link_bw.bits.FRL_MODE) { - if (hdmi_encoded_link_bw.bits.BW_48Gbps) - supported_bw_in_kbps = 48000000; - else if (hdmi_encoded_link_bw.bits.BW_40Gbps) - supported_bw_in_kbps = 40000000; - else if (hdmi_encoded_link_bw.bits.BW_32Gbps) - supported_bw_in_kbps = 32000000; - else if (hdmi_encoded_link_bw.bits.BW_24Gbps) - supported_bw_in_kbps = 24000000; - else if (hdmi_encoded_link_bw.bits.BW_18Gbps) - supported_bw_in_kbps = 18000000; - else if (hdmi_encoded_link_bw.bits.BW_9Gbps) - supported_bw_in_kbps = 9000000; - } + /* Skip checking FRL_MODE bit, as certain PCON will clear + * it despite supporting the link BW indicated in the other bits. + */ + if (hdmi_encoded_link_bw.bits.BW_48Gbps) + supported_bw_in_kbps = 48000000; + else if (hdmi_encoded_link_bw.bits.BW_40Gbps) + supported_bw_in_kbps = 40000000; + else if (hdmi_encoded_link_bw.bits.BW_32Gbps) + supported_bw_in_kbps = 32000000; + else if (hdmi_encoded_link_bw.bits.BW_24Gbps) + supported_bw_in_kbps = 24000000; + else if (hdmi_encoded_link_bw.bits.BW_18Gbps) + supported_bw_in_kbps = 18000000; + else if (hdmi_encoded_link_bw.bits.BW_9Gbps) + supported_bw_in_kbps = 9000000; return supported_bw_in_kbps; } @@ -330,9 +330,12 @@ bool dp_is_fec_supported(const struct dc_link *link) /* TODO - use asic cap instead of link_enc->features * we no longer know which link enc to use for this link before commit */ - struct link_encoder *link_enc = NULL; + struct resource_context *res_ctx = &link->dc->current_state->res_ctx; + struct resource_pool *res_pool = link->dc->res_pool; + struct link_encoder *link_enc = get_temp_dio_link_enc(res_ctx, res_pool, link); - link_enc = link_enc_cfg_get_link_enc(link); + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); return (dc_is_dp_signal(link->connector_signal) && link_enc && @@ -1572,10 +1575,18 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link) /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */ is_lttpr_present = dp_is_lttpr_present(link); - if (is_lttpr_present) + DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present); + + if (is_lttpr_present) { CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: "); - DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present); + core_link_read_dpcd(link, DP_LTTPR_IEEE_OUI, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui)); + CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui), "LTTPR IEEE OUI: "); + + core_link_read_dpcd(link, DP_LTTPR_DEVICE_ID, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id)); + CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id), "LTTPR Device ID: "); + } + return status; } @@ -2089,18 +2100,32 @@ void detect_edp_sink_caps(struct dc_link *link) core_link_read_dpcd(link, DP_SINK_EMISSION_RATE, (uint8_t *)&link->dpcd_caps.edp_oled_emission_rate, sizeof(link->dpcd_caps.edp_oled_emission_rate)); + + /* + * Read Multi-SST (Single Stream Transport) capability + * for eDP version 1.4 or higher. + */ + if (link->dpcd_caps.dpcd_rev.raw >= DP_EDP_14) + core_link_read_dpcd( + link, + DP_EDP_MSO_LINK_CAPABILITIES, + (uint8_t *)&link->dpcd_caps.mso_cap_sst_links_supported, + sizeof(link->dpcd_caps.mso_cap_sst_links_supported)); } bool dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap) { - struct link_encoder *link_enc = NULL; + struct resource_context *res_ctx = &link->dc->current_state->res_ctx; + struct resource_pool *res_pool = link->dc->res_pool; + struct link_encoder *link_enc = get_temp_dio_link_enc(res_ctx, res_pool, link); if (!max_link_enc_cap) { DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__); return false; } - link_enc = link_enc_cfg_get_link_enc(link); + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); if (link_enc && link_enc->funcs->get_max_link_cap) { @@ -2128,10 +2153,13 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link) struct dc_link_settings max_link_cap = {0}; enum dc_link_rate lttpr_max_link_rate; enum dc_link_rate cable_max_link_rate; - struct link_encoder *link_enc = NULL; + struct resource_context *res_ctx = &link->dc->current_state->res_ctx; + struct resource_pool *res_pool = link->dc->res_pool; + struct link_encoder *link_enc = get_temp_dio_link_enc(res_ctx, res_pool, link); bool is_uhbr13_5_supported = true; - link_enc = link_enc_cfg_get_link_enc(link); + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); /* get max link encoder capability */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h index 8f0ce97f2362..0ce0af3ddbeb 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h @@ -67,6 +67,7 @@ bool dp_is_128b_132b_signal(struct pipe_ctx *pipe_ctx); /* Initialize output parameter lt_settings. */ void dp_decide_training_settings( struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_setting, struct link_training_settings *lt_settings); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c index 0f1c411523a2..a5541b8fc95b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -356,6 +356,32 @@ out: return ret; } +/* + * Handle DP BW allocation status register + * + * @link: pointer to the dc_link struct instance + * @status: content of DP tunneling status DPCD register + * + * return: none + */ +void link_dp_dpia_handle_bw_alloc_status(struct dc_link *link, uint8_t status) +{ + if (status & DP_TUNNELING_BW_REQUEST_SUCCEEDED) { + DC_LOG_DEBUG("%s: BW Allocation request succeeded on link(%d)", + __func__, link->link_index); + } else if (status & DP_TUNNELING_BW_REQUEST_FAILED) { + DC_LOG_DEBUG("%s: BW Allocation request failed on link(%d) allocated/estimated BW=%d", + __func__, link->link_index, link->dpia_bw_alloc_config.estimated_bw); + } else if (status & DP_TUNNELING_ESTIMATED_BW_CHANGED) { + DC_LOG_DEBUG("%s: Estimated BW changed on link(%d) new estimated BW=%d", + __func__, link->link_index, link->dpia_bw_alloc_config.estimated_bw); + } + + core_link_write_dpcd( + link, DP_TUNNELING_STATUS, + &status, sizeof(status)); +} + void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) { int bw_needed = 0; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h index 3b6d8494f9d5..1b240a2f6ce0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h @@ -108,4 +108,14 @@ bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed, const unsigned */ int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link); +/* + * Handle DP BW allocation status register + * + * @link: pointer to the dc_link struct instance + * @status: content of DP tunneling status register + * + * return: none + */ +void link_dp_dpia_handle_bw_alloc_status(struct dc_link *link, uint8_t status); + #endif /* DC_INC_LINK_DP_DPIA_BW_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index a08403c022ea..5be00e4ce10b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -37,6 +37,7 @@ #include "link/accessories/link_dp_trace.h" #include "link/link_dpms.h" #include "dm_helpers.h" +#include "link_dp_dpia_bw.h" #define DC_LOGGER \ link->ctx->logger @@ -286,6 +287,30 @@ void dp_handle_link_loss(struct dc_link *link) } } +static void dp_handle_tunneling_irq(struct dc_link *link) +{ + enum dc_status retval; + uint8_t tunneling_status = 0; + + retval = core_link_read_dpcd( + link, DP_TUNNELING_STATUS, + &tunneling_status, + sizeof(tunneling_status)); + + if (retval == DC_OK) { + DC_LOG_HW_HPD_IRQ("%s: Got DP tunneling status on link %d status=0x%x", + __func__, link->link_index, tunneling_status); + + if (tunneling_status & DP_TUNNELING_BW_ALLOC_BITS_MASK) + link_dp_dpia_handle_bw_alloc_status(link, tunneling_status); + } + + tunneling_status = DP_TUNNELING_IRQ; + core_link_write_dpcd( + link, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, + &tunneling_status, 1); +} + static void read_dpcd204h_on_irq_hpd(struct dc_link *link, union hpd_irq_data *irq_data) { enum dc_status retval; @@ -319,13 +344,19 @@ enum dc_status dp_read_hpd_rx_irq_data( * * For DP 1.4 we need to read those from 2002h range. */ - if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14) + if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14) { retval = core_link_read_dpcd( link, DP_SINK_COUNT, irq_data->raw, - sizeof(union hpd_irq_data)); - else { + DP_SINK_STATUS - DP_SINK_COUNT + 1); + + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { + retval = core_link_read_dpcd( + link, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, + &irq_data->bytes.link_service_irq_esi0.raw, 1); + } + } else { /* Read 14 bytes in a single read and then copy only the required fields. * This is more efficient than doing it in two separate AUX reads. */ @@ -346,6 +377,7 @@ enum dc_status dp_read_hpd_rx_irq_data( irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI]; irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI]; irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI]; + irq_data->bytes.link_service_irq_esi0.raw = tmp[DP_LINK_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI]; /* * This display doesn't have correct values in DPCD200Eh. @@ -488,6 +520,11 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, dp_trace_link_loss_increment(link); } + if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { + if (hpd_irq_dpcd_data.bytes.link_service_irq_esi0.bits.DP_LINK_TUNNELING_IRQ) + dp_handle_tunneling_irq(link); + } + if (link->type == dc_connection_sst_branch && hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT != link->dpcd_sink_count) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c index c27ffec5d84f..49521ac4b0e8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c @@ -142,11 +142,12 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource * if the sink supports it and leave it enabled on link. * If FEC is not supported, disable it. */ - struct link_encoder *link_enc = NULL; + struct link_encoder *link_enc = link_res->dio_link_enc; enum dc_status status = DC_OK; uint8_t fec_config = 0; - link_enc = link_enc_cfg_get_link_enc(link); + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); ASSERT(link_enc); if (link_enc->funcs->fec_set_ready == NULL) return DC_NOT_SUPPORTED; @@ -176,13 +177,14 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource return status; } -void dp_set_fec_enable(struct dc_link *link, bool enable) +void dp_set_fec_enable(struct dc_link *link, const struct link_resource *link_res, bool enable) { - struct link_encoder *link_enc = NULL; + struct link_encoder *link_enc = link_res->dio_link_enc; - link_enc = link_enc_cfg_get_link_enc(link); - ASSERT(link_enc); - if (link_enc->funcs->fec_set_enable == NULL) + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + + if (link_enc == NULL || link_enc->funcs == NULL || link_enc->funcs->fec_set_enable == NULL) return; if (enable && dp_should_enable_fec(link)) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h index 1eb0619d6710..ab1c1f8f1f8b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.h @@ -52,7 +52,8 @@ void dp_set_drive_settings( enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready); -void dp_set_fec_enable(struct dc_link *link, bool enable); +void dp_set_fec_enable(struct dc_link *link, + const struct link_resource *link_res, bool enable); void dpcd_write_rx_power_ctrl(struct dc_link *link, bool on); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index 751c18e592ea..613298d21d03 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -801,19 +801,23 @@ enum dc_dp_training_pattern decide_cr_training_pattern( } enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_settings) { - struct link_encoder *link_enc; + struct link_encoder *link_enc = link_res->dio_link_enc; struct encoder_feature_support *enc_caps; struct dpcd_caps *rx_caps = &link->dpcd_caps; enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_2; - link_enc = link_enc_cfg_get_link_enc(link); - ASSERT(link_enc); - enc_caps = &link_enc->features; - switch (link_dp_get_encoding_format(link_settings)) { case DP_8b_10b_ENCODING: + if (!link->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); + + if (!link_enc) + break; + + enc_caps = &link_enc->features; if (enc_caps->flags.bits.IS_TPS4_CAPABLE && rx_caps->max_down_spread.bits.TPS4_SUPPORTED) pattern = DP_TRAINING_PATTERN_SEQUENCE_4; @@ -886,13 +890,14 @@ void dp_decide_lane_settings( void dp_decide_training_settings( struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_settings, struct link_training_settings *lt_settings) { if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) - decide_8b_10b_training_settings(link, link_settings, lt_settings); + decide_8b_10b_training_settings(link, link_res, link_settings, lt_settings); else if (link_dp_get_encoding_format(link_settings) == DP_128b_132b_ENCODING) - decide_128b_132b_training_settings(link, link_settings, lt_settings); + decide_128b_132b_training_settings(link, link_res, link_settings, lt_settings); } @@ -1556,6 +1561,7 @@ enum link_training_result dp_perform_link_training( /* decide training settings */ dp_decide_training_settings( link, + link_res, link_settings, <_settings); @@ -1569,7 +1575,8 @@ enum link_training_result dp_perform_link_training( /* configure link prior to entering training mode */ dpcd_configure_lttpr_mode(link, <_settings); - dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready); + if (link_dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) + dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready); dpcd_configure_channel_coding(link, <_settings); /* enter training mode: diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h index 0b18aa35c33c..574b083e0936 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h @@ -104,6 +104,7 @@ void start_clock_recovery_pattern_early(struct dc_link *link, void dp_decide_training_settings( struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_settings, struct link_training_settings *lt_settings); @@ -117,6 +118,7 @@ enum dc_dp_training_pattern decide_cr_training_pattern( const struct dc_link_settings *link_settings); enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_settings); enum lttpr_mode dp_decide_lttpr_mode(struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.c index db87cfe37b5c..11565f187ac7 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.c @@ -204,6 +204,7 @@ enum link_training_result dp_perform_128b_132b_link_training( struct link_training_settings legacy_settings; decide_8b_10b_training_settings(link, + link_res, <_settings->link_settings, &legacy_settings); return dp_perform_8b_10b_link_training(link, link_res, &legacy_settings); @@ -227,6 +228,7 @@ enum link_training_result dp_perform_128b_132b_link_training( } void decide_128b_132b_training_settings(struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_settings, struct link_training_settings *lt_settings) { @@ -238,7 +240,7 @@ void decide_128b_132b_training_settings(struct dc_link *link, LINK_SPREAD_05_DOWNSPREAD_30KHZ; lt_settings->pattern_for_cr = decide_cr_training_pattern(link_settings); - lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_settings); + lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_res, link_settings); lt_settings->eq_pattern_time = 2500; lt_settings->eq_wait_time_limit = 400000; lt_settings->eq_loop_count_limit = 20; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.h index 2147f24efc8b..901a42edafa1 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_128b_132b.h @@ -34,6 +34,7 @@ enum link_training_result dp_perform_128b_132b_link_training( struct link_training_settings *lt_settings); void decide_128b_132b_training_settings(struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_settings, struct link_training_settings *lt_settings); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c index ae95ec48e572..34d2e097ca2e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c @@ -93,7 +93,8 @@ static uint32_t get_eq_training_aux_rd_interval( } void decide_8b_10b_training_settings( - struct dc_link *link, + struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_setting, struct link_training_settings *lt_settings) { @@ -115,7 +116,7 @@ void decide_8b_10b_training_settings( LINK_SPREAD_DISABLED : LINK_SPREAD_05_DOWNSPREAD_30KHZ; lt_settings->eq_pattern_time = get_eq_training_aux_rd_interval(link, link_setting); lt_settings->pattern_for_cr = decide_cr_training_pattern(link_setting); - lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting); + lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_res, link_setting); lt_settings->enhanced_framing = 1; lt_settings->should_set_fec_ready = true; lt_settings->disallow_per_lane_settings = true; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.h index d26de15ce954..ea0de701d83f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.h @@ -54,7 +54,8 @@ enum link_training_result perform_8b_10b_channel_equalization_sequence( enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link); void decide_8b_10b_training_settings( - struct dc_link *link, + struct dc_link *link, + const struct link_resource *link_res, const struct dc_link_settings *link_setting, struct link_training_settings *lt_settings); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c index 4c6b886a9da8..f99d26290bc0 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_auxless.c @@ -39,6 +39,7 @@ bool dp_perform_link_training_skip_aux( dp_decide_training_settings( link, + link_res, link_setting, <_settings); override_training_settings( diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index 39e4b7dc9588..603537ffd128 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -110,6 +110,7 @@ static enum link_training_result dpia_configure_link( dp_decide_training_settings( link, + link_res, link_setting, lt_settings); @@ -129,11 +130,14 @@ static enum link_training_result dpia_configure_link( if (status != DC_OK && link->is_hpd_pending) return LINK_TRAINING_ABORT; - if (link->preferred_training_settings.fec_enable != NULL) - fec_enable = *link->preferred_training_settings.fec_enable; - else - fec_enable = true; - status = dp_set_fec_ready(link, link_res, fec_enable); + if (link_dp_get_encoding_format(link_setting) == DP_8b_10b_ENCODING) { + if (link->preferred_training_settings.fec_enable != NULL) + fec_enable = *link->preferred_training_settings.fec_enable; + else + fec_enable = true; + status = dp_set_fec_ready(link, link_res, fec_enable); + } + if (status != DC_OK && link->is_hpd_pending) return LINK_TRAINING_ABORT; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c index ccf8096dde29..ce174ce5579c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c @@ -270,7 +270,8 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( rate = get_dpcd_link_rate(<_settings->link_settings); - if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) { + // Only perform toggle if FIXED_VS LTTPR reports no IEEE OUI + if (memcmp("\x0,\x0,\x0", &link->dpcd_caps.lttpr_caps.lttpr_ieee_oui[0], 3) == 0) { /* Vendor specific: Toggle link rate */ toggle_rate = (rate == 0x6) ? 0xA : 0x6; diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h index 9267cdf88e9a..ce6fbcf14d7a 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.h @@ -63,8 +63,7 @@ uint32_t MPC_MCM_SECOND_GAMUT_REMAP_C31_C32_B[MAX_MPCC]; \ uint32_t MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[MAX_MPCC]; \ uint32_t MPCC_MCM_3DLUT_FAST_LOAD_SELECT[MAX_MPCC]; \ - uint32_t MPCC_MCM_3DLUT_FAST_LOAD_STATUS[MAX_MPCC]; \ - uint32_t MPCC_CONTROL2[MAX_MPCC] + uint32_t MPCC_MCM_3DLUT_FAST_LOAD_STATUS[MAX_MPCC]; #define MPC_COMMON_MASK_SH_LIST_DCN4_01(mask_sh) \ MPC_COMMON_MASK_SH_LIST_DCN32(mask_sh), \ @@ -184,7 +183,7 @@ struct dcn401_mpc_mask { }; struct dcn401_mpc_registers { - MPC_REG_VARIABLE_LIST_DCN4_01; + MPC_REG_VARIABLE_LIST_DCN4_01 }; struct dcn401_mpc { @@ -236,7 +235,29 @@ void mpc401_get_gamut_remap( struct mpc *mpc, int mpcc_id, struct mpc_grph_gamut_adjustment *adjust); -void mpc401_update_3dlut_fast_load_select(struct mpc *mpc, int mpcc_id, int hubp_idx); -void mpc401_get_3dlut_fast_load_status(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow); + +void mpc401_update_3dlut_fast_load_select( + struct mpc *mpc, + int mpcc_id, + int hubp_idx); + +void mpc401_get_3dlut_fast_load_status( + struct mpc *mpc, + int mpcc_id, + uint32_t *done, + uint32_t *soft_underflow, + uint32_t *hard_underflow); + +void mpc401_update_3dlut_fast_load_select( + struct mpc *mpc, + int mpcc_id, + int hubp_idx); + +void mpc401_get_3dlut_fast_load_status( + struct mpc *mpc, + int mpcc_id, + uint32_t *done, + uint32_t *soft_underflow, + uint32_t *hard_underflow); #endif diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h index a6d4dbe82c13..8b2a8455eb56 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h @@ -104,120 +104,115 @@ SRI(OTG_MANUAL_FLOW_CONTROL, OTG, inst) +#define OPTC_REG_VARIABLE_LIST_DCN \ + uint32_t OTG_GLOBAL_CONTROL1; \ + uint32_t OTG_GLOBAL_CONTROL2; \ + uint32_t OTG_VERT_SYNC_CONTROL; \ + uint32_t OTG_MASTER_UPDATE_MODE; \ + uint32_t OTG_GSL_CONTROL; \ + uint32_t OTG_VSTARTUP_PARAM; \ + uint32_t OTG_VUPDATE_PARAM; \ + uint32_t OTG_VREADY_PARAM; \ + uint32_t OTG_BLANK_CONTROL; \ + uint32_t OTG_MASTER_UPDATE_LOCK; \ + uint32_t OTG_GLOBAL_CONTROL0; \ + uint32_t OTG_DOUBLE_BUFFER_CONTROL; \ + uint32_t OTG_H_TOTAL; \ + uint32_t OTG_H_BLANK_START_END; \ + uint32_t OTG_H_SYNC_A; \ + uint32_t OTG_H_SYNC_A_CNTL; \ + uint32_t OTG_H_TIMING_CNTL; \ + uint32_t OTG_V_TOTAL; \ + uint32_t OTG_V_BLANK_START_END; \ + uint32_t OTG_V_SYNC_A; \ + uint32_t OTG_V_SYNC_A_CNTL; \ + uint32_t OTG_INTERLACE_CONTROL; \ + uint32_t OTG_CONTROL; \ + uint32_t OTG_STEREO_CONTROL; \ + uint32_t OTG_3D_STRUCTURE_CONTROL; \ + uint32_t OTG_STEREO_STATUS; \ + uint32_t OTG_V_TOTAL_MAX; \ + uint32_t OTG_V_TOTAL_MID; \ + uint32_t OTG_V_TOTAL_MIN; \ + uint32_t OTG_V_TOTAL_CONTROL; \ + uint32_t OTG_V_COUNT_STOP_CONTROL; \ + uint32_t OTG_V_COUNT_STOP_CONTROL2; \ + uint32_t OTG_TRIGA_CNTL; \ + uint32_t OTG_TRIGA_MANUAL_TRIG; \ + uint32_t OTG_MANUAL_FLOW_CONTROL; \ + uint32_t OTG_FORCE_COUNT_NOW_CNTL; \ + uint32_t OTG_STATIC_SCREEN_CONTROL; \ + uint32_t OTG_STATUS_FRAME_COUNT; \ + uint32_t OTG_STATUS; \ + uint32_t OTG_STATUS_POSITION; \ + uint32_t OTG_NOM_VERT_POSITION; \ + uint32_t OTG_BLACK_COLOR; \ + uint32_t OTG_TEST_PATTERN_PARAMETERS; \ + uint32_t OTG_TEST_PATTERN_CONTROL; \ + uint32_t OTG_TEST_PATTERN_COLOR; \ + uint32_t OTG_CLOCK_CONTROL; \ + uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL; \ + uint32_t OTG_VERTICAL_INTERRUPT0_POSITION; \ + uint32_t OTG_VERTICAL_INTERRUPT1_CONTROL; \ + uint32_t OTG_VERTICAL_INTERRUPT1_POSITION; \ + uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL; \ + uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; \ + uint32_t OPTC_INPUT_CLOCK_CONTROL; \ + uint32_t OPTC_DATA_SOURCE_SELECT; \ + uint32_t OPTC_MEMORY_CONFIG; \ + uint32_t OPTC_INPUT_GLOBAL_CONTROL; \ + uint32_t CONTROL; \ + uint32_t OTG_GSL_WINDOW_X; \ + uint32_t OTG_GSL_WINDOW_Y; \ + uint32_t OTG_VUPDATE_KEEPOUT; \ + uint32_t OTG_CRC_CNTL; \ + uint32_t OTG_CRC_CNTL2; \ + uint32_t OTG_CRC0_DATA_RG; \ + uint32_t OTG_CRC0_DATA_B; \ + uint32_t OTG_CRC1_DATA_B; \ + uint32_t OTG_CRC2_DATA_B; \ + uint32_t OTG_CRC3_DATA_B; \ + uint32_t OTG_CRC1_DATA_RG; \ + uint32_t OTG_CRC2_DATA_RG; \ + uint32_t OTG_CRC3_DATA_RG; \ + uint32_t OTG_CRC0_WINDOWA_X_CONTROL; \ + uint32_t OTG_CRC0_WINDOWA_Y_CONTROL; \ + uint32_t OTG_CRC0_WINDOWB_X_CONTROL; \ + uint32_t OTG_CRC0_WINDOWB_Y_CONTROL; \ + uint32_t OTG_CRC1_WINDOWA_X_CONTROL; \ + uint32_t OTG_CRC1_WINDOWA_Y_CONTROL; \ + uint32_t OTG_CRC1_WINDOWB_X_CONTROL; \ + uint32_t OTG_CRC1_WINDOWB_Y_CONTROL; \ + uint32_t GSL_SOURCE_SELECT; \ + uint32_t DWB_SOURCE_SELECT; \ + uint32_t OTG_DSC_START_POSITION; \ + uint32_t OPTC_DATA_FORMAT_CONTROL; \ + uint32_t OPTC_BYTES_PER_PIXEL; \ + uint32_t OPTC_WIDTH_CONTROL; \ + uint32_t OTG_DRR_CONTROL; \ + uint32_t OTG_BLANK_DATA_COLOR; \ + uint32_t OTG_BLANK_DATA_COLOR_EXT; \ + uint32_t OTG_DRR_TRIGGER_WINDOW; \ + uint32_t OTG_M_CONST_DTO0; \ + uint32_t OTG_M_CONST_DTO1; \ + uint32_t OTG_DRR_V_TOTAL_CHANGE; \ + uint32_t OTG_GLOBAL_CONTROL4; \ + uint32_t OTG_CRC0_WINDOWA_X_CONTROL_READBACK; \ + uint32_t OTG_CRC0_WINDOWA_Y_CONTROL_READBACK; \ + uint32_t OTG_CRC0_WINDOWB_X_CONTROL_READBACK; \ + uint32_t OTG_CRC0_WINDOWB_Y_CONTROL_READBACK; \ + uint32_t OTG_CRC1_WINDOWA_X_CONTROL_READBACK; \ + uint32_t OTG_CRC1_WINDOWA_Y_CONTROL_READBACK; \ + uint32_t OTG_CRC1_WINDOWB_X_CONTROL_READBACK; \ + uint32_t OTG_CRC1_WINDOWB_Y_CONTROL_READBACK; \ + uint32_t OPTC_CLOCK_CONTROL; \ + uint32_t OPTC_WIDTH_CONTROL2; \ + uint32_t OTG_PSTATE_REGISTER; \ + uint32_t OTG_PIPE_UPDATE_STATUS; \ + uint32_t INTERRUPT_DEST + struct dcn_optc_registers { - uint32_t OTG_GLOBAL_CONTROL1; - uint32_t OTG_GLOBAL_CONTROL2; - uint32_t OTG_VERT_SYNC_CONTROL; - uint32_t OTG_MASTER_UPDATE_MODE; - uint32_t OTG_GSL_CONTROL; - uint32_t OTG_VSTARTUP_PARAM; - uint32_t OTG_VUPDATE_PARAM; - uint32_t OTG_VREADY_PARAM; - uint32_t OTG_BLANK_CONTROL; - uint32_t OTG_MASTER_UPDATE_LOCK; - uint32_t OTG_GLOBAL_CONTROL0; - uint32_t OTG_DOUBLE_BUFFER_CONTROL; - uint32_t OTG_H_TOTAL; - uint32_t OTG_H_BLANK_START_END; - uint32_t OTG_H_SYNC_A; - uint32_t OTG_H_SYNC_A_CNTL; - uint32_t OTG_H_TIMING_CNTL; - uint32_t OTG_V_TOTAL; - uint32_t OTG_V_BLANK_START_END; - uint32_t OTG_V_SYNC_A; - uint32_t OTG_V_SYNC_A_CNTL; - uint32_t OTG_INTERLACE_CONTROL; - uint32_t OTG_CONTROL; - uint32_t OTG_STEREO_CONTROL; - uint32_t OTG_3D_STRUCTURE_CONTROL; - uint32_t OTG_STEREO_STATUS; - uint32_t OTG_V_TOTAL_MAX; - uint32_t OTG_V_TOTAL_MID; - uint32_t OTG_V_TOTAL_MIN; - uint32_t OTG_V_TOTAL_CONTROL; - uint32_t OTG_V_COUNT_STOP_CONTROL; - uint32_t OTG_V_COUNT_STOP_CONTROL2; - uint32_t OTG_TRIGA_CNTL; - uint32_t OTG_TRIGA_MANUAL_TRIG; - uint32_t OTG_MANUAL_FLOW_CONTROL; - uint32_t OTG_FORCE_COUNT_NOW_CNTL; - uint32_t OTG_STATIC_SCREEN_CONTROL; - uint32_t OTG_STATUS_FRAME_COUNT; - uint32_t OTG_STATUS; - uint32_t OTG_STATUS_POSITION; - uint32_t OTG_NOM_VERT_POSITION; - uint32_t OTG_BLACK_COLOR; - uint32_t OTG_TEST_PATTERN_PARAMETERS; - uint32_t OTG_TEST_PATTERN_CONTROL; - uint32_t OTG_TEST_PATTERN_COLOR; - uint32_t OTG_CLOCK_CONTROL; - uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL; - uint32_t OTG_VERTICAL_INTERRUPT0_POSITION; - uint32_t OTG_VERTICAL_INTERRUPT1_CONTROL; - uint32_t OTG_VERTICAL_INTERRUPT1_POSITION; - uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL; - uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; - uint32_t OPTC_INPUT_CLOCK_CONTROL; - uint32_t OPTC_DATA_SOURCE_SELECT; - uint32_t OPTC_MEMORY_CONFIG; - uint32_t OPTC_INPUT_GLOBAL_CONTROL; - uint32_t CONTROL; - uint32_t OTG_GSL_WINDOW_X; - uint32_t OTG_GSL_WINDOW_Y; - uint32_t OTG_VUPDATE_KEEPOUT; - uint32_t OTG_CRC_CNTL; - uint32_t OTG_CRC_CNTL2; - uint32_t OTG_CRC0_DATA_RG; - uint32_t OTG_CRC1_DATA_RG; - uint32_t OTG_CRC2_DATA_RG; - uint32_t OTG_CRC3_DATA_RG; - uint32_t OTG_CRC0_DATA_B; - uint32_t OTG_CRC1_DATA_B; - uint32_t OTG_CRC2_DATA_B; - uint32_t OTG_CRC3_DATA_B; - uint32_t OTG_CRC0_DATA_R; - uint32_t OTG_CRC1_DATA_R; - uint32_t OTG_CRC2_DATA_R; - uint32_t OTG_CRC3_DATA_R; - uint32_t OTG_CRC0_DATA_G; - uint32_t OTG_CRC1_DATA_G; - uint32_t OTG_CRC2_DATA_G; - uint32_t OTG_CRC3_DATA_G; - uint32_t OTG_CRC0_WINDOWA_X_CONTROL; - uint32_t OTG_CRC0_WINDOWA_Y_CONTROL; - uint32_t OTG_CRC0_WINDOWB_X_CONTROL; - uint32_t OTG_CRC0_WINDOWB_Y_CONTROL; - uint32_t OTG_CRC1_WINDOWA_X_CONTROL; - uint32_t OTG_CRC1_WINDOWA_Y_CONTROL; - uint32_t OTG_CRC1_WINDOWB_X_CONTROL; - uint32_t OTG_CRC1_WINDOWB_Y_CONTROL; - uint32_t GSL_SOURCE_SELECT; - uint32_t DWB_SOURCE_SELECT; - uint32_t OTG_DSC_START_POSITION; - uint32_t OPTC_DATA_FORMAT_CONTROL; - uint32_t OPTC_BYTES_PER_PIXEL; - uint32_t OPTC_WIDTH_CONTROL; - uint32_t OTG_DRR_CONTROL; - uint32_t OTG_BLANK_DATA_COLOR; - uint32_t OTG_BLANK_DATA_COLOR_EXT; - uint32_t OTG_DRR_TRIGGER_WINDOW; - uint32_t OTG_M_CONST_DTO0; - uint32_t OTG_M_CONST_DTO1; - uint32_t OTG_DRR_V_TOTAL_CHANGE; - uint32_t OTG_GLOBAL_CONTROL4; - uint32_t OTG_CRC0_WINDOWA_X_CONTROL_READBACK; - uint32_t OTG_CRC0_WINDOWA_Y_CONTROL_READBACK; - uint32_t OTG_CRC0_WINDOWB_X_CONTROL_READBACK; - uint32_t OTG_CRC0_WINDOWB_Y_CONTROL_READBACK; - uint32_t OTG_CRC1_WINDOWA_X_CONTROL_READBACK; - uint32_t OTG_CRC1_WINDOWA_Y_CONTROL_READBACK; - uint32_t OTG_CRC1_WINDOWB_X_CONTROL_READBACK; - uint32_t OTG_CRC1_WINDOWB_Y_CONTROL_READBACK; - uint32_t OPTC_CLOCK_CONTROL; - uint32_t OPTC_WIDTH_CONTROL2; - uint32_t OTG_PSTATE_REGISTER; - uint32_t OTG_PIPE_UPDATE_STATUS; - uint32_t INTERRUPT_DEST; + OPTC_REG_VARIABLE_LIST_DCN; }; #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c index 5c6dc710e96c..e4eca3e32c1b 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c @@ -1220,7 +1220,7 @@ static void get_pixel_clock_parameters( struct pipe_ctx *odm_pipe; int opp_cnt = 1; struct dc_link *link = stream->link; - struct link_encoder *link_enc = NULL; + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct dc *dc = pipe_ctx->stream->ctx->dc; struct dce_hwseq *hws = dc->hwseq; @@ -1229,7 +1229,8 @@ static void get_pixel_clock_parameters( pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz; - link_enc = link_enc_cfg_get_link_enc(link); + if (!dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); if (link_enc) pixel_clk_params->encoder_object_id = link_enc->id; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c index 911bd60d4fbc..3c42ba8566cf 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c @@ -890,7 +890,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_z10 = true, .enable_legacy_fast_update = true, .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/ - .dml_hostvm_override = DML_HOSTVM_NO_OVERRIDE, + .dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE, .using_dml2 = false, }; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c index 4e842f29d4c4..7436dfbdf927 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c @@ -1666,12 +1666,13 @@ static void dcn401_build_pipe_pix_clk_params(struct pipe_ctx *pipe_ctx) { const struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; - struct link_encoder *link_enc = NULL; + struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; struct pixel_clk_params *pixel_clk_params = &pipe_ctx->stream_res.pix_clk_params; pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz; - link_enc = link_enc_cfg_get_link_enc(link); + if (!pipe_ctx->stream->ctx->dc->config.unify_link_enc_assignment) + link_enc = link_enc_cfg_get_link_enc(link); if (link_enc) pixel_clk_params->encoder_object_id = link_enc->id; diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c index 31495c9978b0..28348734d900 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c @@ -3,12 +3,11 @@ // Copyright 2024 Advanced Micro Devices, Inc. #include "dc_spl.h" -#include "dc_spl_scl_filters.h" #include "dc_spl_scl_easf_filters.h" #include "dc_spl_isharp_filters.h" #include "spl_debug.h" -#define IDENTITY_RATIO(ratio) (spl_fixpt_u2d19(ratio) == (1 << 19)) +#define IDENTITY_RATIO(ratio) (spl_fixpt_u3d19(ratio) == (1 << 19)) #define MIN_VIEWPORT_SIZE 12 static bool spl_is_yuv420(enum spl_pixel_format format) @@ -76,6 +75,21 @@ static struct spl_rect shift_rec(const struct spl_rect *rec_in, int x, int y) return rec_out; } +static void spl_opp_adjust_rect(struct spl_rect *rec, const struct spl_opp_adjust *adjust) +{ + if ((rec->x + adjust->x) >= 0) + rec->x += adjust->x; + + if ((rec->y + adjust->y) >= 0) + rec->y += adjust->y; + + if ((rec->width + adjust->width) >= 1) + rec->width += adjust->width; + + if ((rec->height + adjust->height) >= 1) + rec->height += adjust->height; +} + static struct spl_rect calculate_plane_rec_in_timing_active( struct spl_in *spl_in, const struct spl_rect *rec_in) @@ -723,13 +737,15 @@ static void spl_handle_3d_recout(struct spl_in *spl_in, struct spl_rect *recout) } } -static void spl_clamp_viewport(struct spl_rect *viewport) +static void spl_clamp_viewport(struct spl_rect *viewport, int min_viewport_size) { + if (min_viewport_size == 0) + min_viewport_size = MIN_VIEWPORT_SIZE; /* Clamp minimum viewport size */ - if (viewport->height < MIN_VIEWPORT_SIZE) - viewport->height = MIN_VIEWPORT_SIZE; - if (viewport->width < MIN_VIEWPORT_SIZE) - viewport->width = MIN_VIEWPORT_SIZE; + if (viewport->height < min_viewport_size) + viewport->height = min_viewport_size; + if (viewport->width < min_viewport_size) + viewport->width = min_viewport_size; } static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in, @@ -870,6 +886,8 @@ static bool spl_get_isharp_en(struct spl_in *spl_in, static void spl_get_taps_non_adaptive_scaler( struct spl_scratch *spl_scratch, const struct spl_taps *in_taps) { + bool check_max_downscale = false; + if (in_taps->h_taps == 0) { if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.horz) > 1) spl_scratch->scl_data.taps.h_taps = spl_min(2 * spl_fixpt_ceil( @@ -909,6 +927,23 @@ static void spl_get_taps_non_adaptive_scaler( else spl_scratch->scl_data.taps.h_taps_c = in_taps->h_taps_c; + + /* + * Max downscale supported is 6.0x. Add ASSERT to catch if go beyond that + */ + check_max_downscale = spl_fixpt_le(spl_scratch->scl_data.ratios.horz, + spl_fixpt_from_fraction(6, 1)); + SPL_ASSERT(check_max_downscale); + check_max_downscale = spl_fixpt_le(spl_scratch->scl_data.ratios.vert, + spl_fixpt_from_fraction(6, 1)); + SPL_ASSERT(check_max_downscale); + check_max_downscale = spl_fixpt_le(spl_scratch->scl_data.ratios.horz_c, + spl_fixpt_from_fraction(6, 1)); + SPL_ASSERT(check_max_downscale); + check_max_downscale = spl_fixpt_le(spl_scratch->scl_data.ratios.vert_c, + spl_fixpt_from_fraction(6, 1)); + SPL_ASSERT(check_max_downscale); + if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz)) spl_scratch->scl_data.taps.h_taps = 1; if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert)) @@ -927,8 +962,8 @@ static bool spl_get_optimal_number_of_taps( bool *enable_isharp) { int num_part_y, num_part_c; - int max_taps_y, max_taps_c; - int min_taps_y, min_taps_c; + unsigned int max_taps_y, max_taps_c; + unsigned int min_taps_y, min_taps_c; enum lb_memory_config lb_config; bool skip_easf = false; bool is_subsampled = spl_is_subsampled_format(spl_in->basic_in.format); @@ -990,12 +1025,18 @@ static bool spl_get_optimal_number_of_taps( lb_config, &num_part_y, &num_part_c); /* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */ if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) > 2) - max_taps_y = num_part_y - (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) - 2); + if ((spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) - 2) > num_part_y) + max_taps_y = 0; + else + max_taps_y = num_part_y - (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert) - 2); else max_taps_y = num_part_y; if (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) > 2) - max_taps_c = num_part_c - (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) - 2); + if ((spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) - 2) > num_part_c) + max_taps_c = 0; + else + max_taps_c = num_part_c - (spl_fixpt_ceil(spl_scratch->scl_data.ratios.vert_c) - 2); else max_taps_c = num_part_c; @@ -1764,6 +1805,8 @@ static bool spl_calculate_number_of_taps(struct spl_in *spl_in, struct spl_scrat spl_calculate_recout(spl_in, spl_scratch, spl_out); /* depends on pixel format */ spl_calculate_scaling_ratios(spl_in, spl_scratch, spl_out); + /* Adjust recout for opp if needed */ + spl_opp_adjust_rect(&spl_scratch->scl_data.recout, &spl_in->basic_in.opp_recout_adjust); /* depends on scaling ratios and recout, does not calculate offset yet */ spl_calculate_viewport_size(spl_in, spl_scratch); @@ -1775,7 +1818,7 @@ static bool spl_calculate_number_of_taps(struct spl_in *spl_in, struct spl_scrat } /* Calculate scaler parameters */ -bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) +bool SPL_NAMESPACE(spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)) { bool res = false; bool enable_easf_v = false; @@ -1800,7 +1843,7 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) // Handle 3d recout spl_handle_3d_recout(spl_in, &spl_scratch.scl_data.recout); // Clamp - spl_clamp_viewport(&spl_scratch.scl_data.viewport); + spl_clamp_viewport(&spl_scratch.scl_data.viewport, spl_in->min_viewport_size); // Save all calculated parameters in dscl_prog_data structure to program hw registers spl_set_dscl_prog_data(spl_in, &spl_scratch, spl_out, enable_easf_v, enable_easf_h, enable_isharp); @@ -1840,7 +1883,7 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out) } /* External interface to get number of taps only */ -bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out) +bool SPL_NAMESPACE(spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out)) { bool res = false; bool enable_easf_v = false; diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h index 02a2d6725ed5..145961803a92 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.h @@ -9,10 +9,22 @@ #define BLACK_OFFSET_RGB_Y 0x0 #define BLACK_OFFSET_CBCR 0x8000 +#ifndef SPL_PFX_ +#define SPL_PFX_ +#endif + +#define SPL_EXPAND2(a, b) a##b +#define SPL_EXPAND(a, b) SPL_EXPAND2(a, b) +#define SPL_NAMESPACE(symbol) SPL_EXPAND(SPL_PFX_, symbol) + +#ifdef __cplusplus +extern "C" { +#endif + /* SPL interfaces */ -bool spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out); +bool SPL_NAMESPACE(spl_calculate_scaler_params(struct spl_in *spl_in, struct spl_out *spl_out)); -bool spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out); +bool SPL_NAMESPACE(spl_get_number_of_taps(struct spl_in *spl_in, struct spl_out *spl_out)); #endif /* __DC_SPL_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h index 467af9dd90de..1c3949b24611 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h @@ -427,6 +427,14 @@ struct spl_out { // SPL inputs +// opp extra adjustment for rect +struct spl_opp_adjust { + int x; + int y; + int width; + int height; +}; + // Basic input information struct basic_in { enum spl_pixel_format format; // Pixel Format @@ -444,6 +452,7 @@ struct basic_in { } num_slices_recout_width; } num_h_slices_recout_width_align; int mpc_h_slice_index; // previous mpc_combine_v - split_idx + struct spl_opp_adjust opp_recout_adjust; // Inputs for adaptive scaler - TODO enum spl_transfer_func_type tf_type; /* Transfer function type */ enum spl_transfer_func_predefined tf_predefined_type; /* Transfer function predefined type */ @@ -484,7 +493,7 @@ struct spl_sharpness_range { }; struct adaptive_sharpness { bool enable; - int sharpness_level; + unsigned int sharpness_level; struct spl_sharpness_range sharpness_range; }; enum linear_light_scaling { // convert it in translation logic @@ -535,6 +544,7 @@ struct spl_in { bool is_hdr_on; int h_active; int v_active; + int min_viewport_size; int sdr_white_level_nits; enum sharpen_policy sharpen_policy; }; diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c index 131f1e3949d3..52d97918a3bd 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.c @@ -346,7 +346,7 @@ struct spl_fixed31_32 spl_fixpt_exp(struct spl_fixed31_32 arg) if (m > 0) return spl_fixpt_shl( spl_fixed31_32_exp_from_taylor_series(r), - (unsigned char)m); + (unsigned int)m); else return spl_fixpt_div_int( spl_fixed31_32_exp_from_taylor_series(r), diff --git a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h index ed2647f9a099..9f349ffe9148 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h +++ b/drivers/gpu/drm/amd/display/dc/sspl/spl_fixpt31_32.h @@ -189,7 +189,7 @@ static inline struct spl_fixed31_32 spl_fixpt_clamp( * @brief * result = arg << shift */ -static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned char shift) +static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, unsigned int shift) { SPL_ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) || ((arg.value < 0) && (arg.value >= ~(LLONG_MAX >> shift)))); @@ -203,7 +203,7 @@ static inline struct spl_fixed31_32 spl_fixpt_shl(struct spl_fixed31_32 arg, uns * @brief * result = arg >> shift */ -static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned char shift) +static inline struct spl_fixed31_32 spl_fixpt_shr(struct spl_fixed31_32 arg, unsigned int shift) { bool negative = arg.value < 0; 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 8cf89aed024b..f84bbc033e64 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -161,6 +161,13 @@ #endif /** + * OS/FW agnostic memcmp + */ +#ifndef dmub_memcmp +#define dmub_memcmp(lhs, rhs, bytes) memcmp((lhs), (rhs), (bytes)) +#endif + +/** * OS/FW agnostic udelay */ #ifndef dmub_udelay @@ -1460,6 +1467,11 @@ enum dmub_cmd_type { */ DMUB_CMD__PSP = 88, + /** + * Command type used for all Fused IO commands. + */ + DMUB_CMD__FUSED_IO = 89, + DMUB_CMD__VBIOS = 128, }; @@ -1491,6 +1503,10 @@ enum dmub_out_cmd_type { * Command type used for HPD redetect notification */ DMUB_OUT_CMD__HPD_SENSE_NOTIFY = 6, + /** + * Command type used for Fused IO notification + */ + DMUB_OUT_CMD__FUSED_IO = 7, }; /* DMUB_CMD__DPIA command sub-types. */ @@ -5325,6 +5341,63 @@ struct dmub_rb_cmd_get_usbc_cable_id { } data; }; +enum dmub_cmd_fused_io_sub_type { + DMUB_CMD__FUSED_IO_EXECUTE = 0, + DMUB_CMD__FUSED_IO_ABORT = 1, +}; + +enum dmub_cmd_fused_request_type { + FUSED_REQUEST_READ, + FUSED_REQUEST_WRITE, + FUSED_REQUEST_POLL, +}; + +enum dmub_cmd_fused_request_status { + FUSED_REQUEST_STATUS_SUCCESS, + FUSED_REQUEST_STATUS_BEGIN, + FUSED_REQUEST_STATUS_SUBMIT, + FUSED_REQUEST_STATUS_REPLY, + FUSED_REQUEST_STATUS_POLL, + FUSED_REQUEST_STATUS_ABORTED, + FUSED_REQUEST_STATUS_FAILED = 0x80, + FUSED_REQUEST_STATUS_INVALID, + FUSED_REQUEST_STATUS_BUSY, + FUSED_REQUEST_STATUS_TIMEOUT, + FUSED_REQUEST_STATUS_POLL_TIMEOUT, +}; + +struct dmub_cmd_fused_request { + uint8_t status; + uint8_t type : 2; + uint8_t _reserved0 : 3; + uint8_t poll_mask_msb : 3; // Number of MSB to zero out from last byte before comparing + uint8_t identifier; + uint8_t _reserved1; + uint32_t timeout_us; + union dmub_cmd_fused_request_location { + struct dmub_cmd_fused_request_location_i2c { + uint8_t is_aux : 1; // False + uint8_t ddc_line : 3; + uint8_t _reserved0 : 4; + uint8_t address; + uint8_t offset; + uint8_t length; + } i2c; + struct dmub_cmd_fused_request_location_aux { + uint32_t is_aux : 1; // True + uint32_t ddc_line : 3; + uint32_t address : 20; + uint32_t length : 8; // Automatically split into 16B transactions + } aux; + } u; + uint8_t buffer[0x30]; // Read: out, write: in, poll: expected +}; + +struct dmub_rb_cmd_fused_io { + struct dmub_cmd_header header; + struct dmub_cmd_fused_request request; +}; + /** * Command type of a DMUB_CMD__SECURE_DISPLAY command */ @@ -5738,6 +5811,8 @@ union dmub_rb_cmd { struct dmub_rb_cmd_fams2_drr_update fams2_drr_update; struct dmub_rb_cmd_fams2_flip fams2_flip; + + struct dmub_rb_cmd_fused_io fused_io; }; /** @@ -5768,6 +5843,7 @@ union dmub_rb_out_cmd { * HPD sense notification command. */ struct dmub_rb_cmd_hpd_sense_notify hpd_sense_notify; + struct dmub_rb_cmd_fused_io fused_io; }; #pragma pack(pop) 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 3d0bba602b53..9796077885c9 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -83,8 +83,8 @@ static inline void dmub_dcn31_translate_addr(const union dmub_addr *addr_in, 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, pwait_mode; + const uint32_t timeout = 100000; + uint32_t in_reset, is_enabled, scratch, i, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -108,7 +108,7 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) } for (i = 0; i < timeout; ++i) { - scratch = dmub->hw_funcs.get_gpint_response(dmub); + scratch = REG_READ(DMCUB_SCRATCH7); if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) break; @@ -125,9 +125,14 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) /* Force reset in case we timed out, DMCUB is likely hung. */ } - REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); - REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); - REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); + REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enabled); + + if (is_enabled) { + REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); + REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); + } + REG_WRITE(DMCUB_INBOX1_RPTR, 0); REG_WRITE(DMCUB_INBOX1_WPTR, 0); REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c index e5e77bd3c31e..01d013a12b94 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c @@ -88,7 +88,7 @@ static inline void dmub_dcn35_translate_addr(const union dmub_addr *addr_in, void dmub_dcn35_reset(struct dmub_srv *dmub) { union dmub_gpint_data_register cmd; - const uint32_t timeout = 100; + const uint32_t timeout = 100000; uint32_t in_reset, is_enabled, scratch, i, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -113,7 +113,7 @@ void dmub_dcn35_reset(struct dmub_srv *dmub) } for (i = 0; i < timeout; ++i) { - scratch = dmub->hw_funcs.get_gpint_response(dmub); + scratch = REG_READ(DMCUB_SCRATCH7); if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) break; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c index 39a8cb6d7523..e1c4fe1c6e3e 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.c @@ -63,8 +63,10 @@ static inline void dmub_dcn401_translate_addr(const union dmub_addr *addr_in, void dmub_dcn401_reset(struct dmub_srv *dmub) { union dmub_gpint_data_register cmd; - const uint32_t timeout = 30; - uint32_t in_reset, scratch, i; + const uint32_t timeout_us = 1 * 1000 * 1000; //1s + const uint32_t poll_delay_us = 1; //1us + uint32_t i = 0; + uint32_t in_reset, scratch, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -75,32 +77,35 @@ void dmub_dcn401_reset(struct dmub_srv *dmub) dmub->hw_funcs.set_gpint(dmub, cmd); - /** - * Timeout covers both the ACK and the wait - * for remaining work to finish. - * - * This is mostly bound by the PHY disable sequence. - * Each register check will be greater than 1us, so - * don't bother using udelay. - */ - - for (i = 0; i < timeout; ++i) { + for (i = 0; i < timeout_us; i++) { if (dmub->hw_funcs.is_gpint_acked(dmub, cmd)) break; + + udelay(poll_delay_us); } - for (i = 0; i < timeout; ++i) { + for (; i < timeout_us; i++) { scratch = dmub->hw_funcs.get_gpint_response(dmub); if (scratch == DMUB_GPINT__STOP_FW_RESPONSE) break; + + udelay(poll_delay_us); } - /* Force reset in case we timed out, DMCUB is likely hung. */ + for (; i < timeout_us; i++) { + REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode); + if (pwait_mode & (1 << 0)) + break; + + udelay(poll_delay_us); + } + } + + if (i >= timeout_us) { + /* timeout should never occur */ + BREAK_TO_DEBUGGER(); } - REG_UPDATE(DMCUB_CNTL2, DMCUB_SOFT_RESET, 1); - REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); - REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); REG_WRITE(DMCUB_INBOX1_RPTR, 0); REG_WRITE(DMCUB_INBOX1_WPTR, 0); REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); @@ -131,7 +136,10 @@ void dmub_dcn401_backdoor_load(struct dmub_srv *dmub, dmub_dcn401_get_fb_base_offset(dmub, &fb_base, &fb_offset); + /* reset and disable DMCUB and MMHUBBUB DMUIF */ REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); + REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); dmub_dcn401_translate_addr(&cw0->offset, fb_base, fb_offset, &offset); @@ -151,6 +159,7 @@ void dmub_dcn401_backdoor_load(struct dmub_srv *dmub, DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, DMCUB_REGION3_CW1_ENABLE, 1); + /* release DMCUB reset only to prevent premature execution */ REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID, 0x20); } @@ -161,7 +170,10 @@ void dmub_dcn401_backdoor_load_zfb_mode(struct dmub_srv *dmub, { union dmub_addr offset; + /* reset and disable DMCUB and MMHUBBUB DMUIF */ REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1); + REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1); + REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0); offset = cw0->offset; @@ -181,6 +193,7 @@ void dmub_dcn401_backdoor_load_zfb_mode(struct dmub_srv *dmub, DMCUB_REGION3_CW1_TOP_ADDRESS, cw1->region.top, DMCUB_REGION3_CW1_ENABLE, 1); + /* release DMCUB reset only to prevent premature execution */ REG_UPDATE_2(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 0, DMCUB_MEM_UNIT_ID, 0x20); } diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h index 4c8843b79695..31f95b27e227 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn401.h @@ -169,7 +169,8 @@ struct dmub_srv; DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_INBOX0_RSP_INT_EN) \ DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_ACK) \ DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_STAT) \ - DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_EN) + DMUB_SF(HOST_INTERRUPT_CSR, HOST_REG_OUTBOX0_RDY_INT_EN) \ + DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS) struct dmub_srv_dcn401_reg_offset { #define DMUB_SR(reg) uint32_t reg; diff --git a/drivers/gpu/drm/amd/display/include/logger_interface.h b/drivers/gpu/drm/amd/display/include/logger_interface.h index 058f882d5bdd..4c01514b926c 100644 --- a/drivers/gpu/drm/amd/display/include/logger_interface.h +++ b/drivers/gpu/drm/amd/display/include/logger_interface.h @@ -40,11 +40,6 @@ struct dc_state; * */ -void pre_surface_trace( - struct dc *dc, - const struct dc_plane_state *const *plane_states, - int surface_count); - void update_surface_trace( struct dc *dc, const struct dc_surface_update *updates, |