]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Disable FRL and add module param to enable it
authorFangzhi Zuo <Jerry.Zuo@amd.com>
Wed, 13 May 2026 21:02:03 +0000 (17:02 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Jun 2026 17:45:01 +0000 (13:45 -0400)
FRL links don't yet support VRR. If we enable it by default
users will see a functional regression when connected to an FRL
capable display as the driver will now default to FRL and not
allow VRR.

VRR support will come soon, so instead of making an elaborate
TMDS fallback mechanism simply default FRL to disabled, but
provide a dcfeaturemask of 0x400 to enable it if anyone wants
to already try it out.

Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/include/amd_shared.h

index d9f909b86f8f724d4ca58b81658148069a70b24f..04e440521f67a331d55fcab0a089507e9fc89822 100644 (file)
@@ -2090,6 +2090,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
        if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP2_0)
                init_data.flags.allow_lttpr_non_transparent_mode.bits.DP2_0 = true;
 
+       if (amdgpu_dc_feature_mask & DC_FRL_MASK)
+               init_data.flags.enable_frl = true;
+
        init_data.flags.seamless_boot_edp_requested = false;
 
        if (amdgpu_device_seamless_boot_supported(adev)) {
index d0cad3bfe697b96b2dc0c879dca94c65a3c6c451..dd199e0b79226546d58d4099c23d84b274645f8c 100644 (file)
@@ -1116,7 +1116,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 void amdgpu_dm_update_connector_after_detect(
                struct amdgpu_dm_connector *aconnector);
 
-void populate_hdmi_info_from_connector(struct drm_hdmi_info *info,
+void populate_hdmi_info_from_connector(bool enable_frl, struct drm_hdmi_info *info,
                                      struct dc_edid_caps *edid_caps);
 
 extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs;
index d79158e53db6a3be4570afafbff2f1b7db169c0b..b9a3e842626e16f114df530bd477d4ea0a907273 100644 (file)
@@ -179,7 +179,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
        edid_caps->edid_hdmi = connector->display_info.is_hdmi;
 
        if (edid_caps->edid_hdmi) {
-               populate_hdmi_info_from_connector(&connector->display_info.hdmi, edid_caps);
+               populate_hdmi_info_from_connector(link->dc->config.enable_frl, &connector->display_info.hdmi, edid_caps);
                drm_dbg_driver(connector->dev, "%s: HDMI_FRL [%s] max_frl_rate %d\n", __func__, connector->name, edid_caps->max_frl_rate);
                if (edid_caps->frl_dsc_support)
                        drm_dbg_driver(connector->dev, "%s: HDMI_FRL_DSC [%s] frl_dsc_10bpc %d, frl_dsc_12bpc %d, frl_dsc_all_bpp %d, frl_dsc_native_420 %d, frl_dsc_max_slices %d, frl_dsc_max_frl_rate %d, frl_dsc_total_chunk_kbytes %d\n",
@@ -1124,21 +1124,23 @@ static uint8_t get_dsc_max_slices(uint8_t max_slices, int clk_per_slice)
        return dsc_max_slices;
 }
 
-void populate_hdmi_info_from_connector(struct drm_hdmi_info *hdmi, struct dc_edid_caps *edid_caps)
+void populate_hdmi_info_from_connector(bool enable_frl, struct drm_hdmi_info *hdmi, struct dc_edid_caps *edid_caps)
 {
        edid_caps->scdc_present = hdmi->scdc.supported;
-       edid_caps->max_frl_rate = get_max_frl_rate(hdmi->max_lanes, hdmi->max_frl_rate_per_lane);
-       edid_caps->frl_dsc_support = hdmi->dsc_cap.v_1p2;
-       if (edid_caps->frl_dsc_support) {
-               if (hdmi->dsc_cap.bpc_supported == 10)
-                       edid_caps->frl_dsc_10bpc = true;
-               else if (hdmi->dsc_cap.bpc_supported == 12)
-                       edid_caps->frl_dsc_12bpc = true;
-               edid_caps->frl_dsc_all_bpp = hdmi->dsc_cap.all_bpp;
-               edid_caps->frl_dsc_native_420 = hdmi->dsc_cap.native_420;
-               edid_caps->frl_dsc_max_slices = get_dsc_max_slices(hdmi->dsc_cap.max_slices, hdmi->dsc_cap.clk_per_slice);
-               edid_caps->frl_dsc_max_frl_rate = get_max_frl_rate(hdmi->dsc_cap.max_lanes, hdmi->dsc_cap.max_frl_rate_per_lane);
-               edid_caps->frl_dsc_total_chunk_kbytes = hdmi->dsc_cap.total_chunk_kbytes;
+       if (enable_frl) {
+               edid_caps->max_frl_rate = get_max_frl_rate(hdmi->max_lanes, hdmi->max_frl_rate_per_lane);
+               edid_caps->frl_dsc_support = hdmi->dsc_cap.v_1p2;
+               if (edid_caps->frl_dsc_support) {
+                       if (hdmi->dsc_cap.bpc_supported == 10)
+                               edid_caps->frl_dsc_10bpc = true;
+                       else if (hdmi->dsc_cap.bpc_supported == 12)
+                               edid_caps->frl_dsc_12bpc = true;
+                       edid_caps->frl_dsc_all_bpp = hdmi->dsc_cap.all_bpp;
+                       edid_caps->frl_dsc_native_420 = hdmi->dsc_cap.native_420;
+                       edid_caps->frl_dsc_max_slices = get_dsc_max_slices(hdmi->dsc_cap.max_slices, hdmi->dsc_cap.clk_per_slice);
+                       edid_caps->frl_dsc_max_frl_rate = get_max_frl_rate(hdmi->dsc_cap.max_lanes, hdmi->dsc_cap.max_frl_rate_per_lane);
+                       edid_caps->frl_dsc_total_chunk_kbytes = hdmi->dsc_cap.total_chunk_kbytes;
+               }
        }
 }
 
index 21816738a7422cebcfe57c3ff979d91d5f908187..c6db021a61b0c19ce11ad19941d50fa1776c30ad 100644 (file)
@@ -589,6 +589,7 @@ struct dc_config {
        int smart_mux_version;
        bool ignore_dpref_ss;
        bool enable_mipi_converter_optimization;
+       bool enable_frl;
        bool force_hdmi21_frl_enc_enable;
        bool skip_frl_pretraining;
        bool use_default_clock_table;
index ac2d3701e2bdcc3c657df5369c56d59e8111001c..3fd38323a88ba7a70baa92bf7695784b40d1253c 100644 (file)
@@ -286,6 +286,10 @@ enum DC_FEATURE_MASK {
         * @DC_REPLAY_MASK: (0x200) disabled by default for DCN < 3.1.4
         */
        DC_REPLAY_MASK = (1 << 9),
+       /**
+        * @DC_FRL_MASK: (0x400) disabled by default
+        */
+       DC_FRL_MASK = (1 << 10),
 };
 
 /**