]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/display: Update HDCP and info_packet modules for FRL
authorHarry Wentland <harry.wentland@amd.com>
Fri, 24 Apr 2026 18:31:43 +0000 (14:31 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Jun 2026 17:44:49 +0000 (13:44 -0400)
The HDCP module has a minor update for FRL, and info_packet is
updated for ALLM.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@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/modules/hdcp/hdcp.c
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.h
drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h
drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c

index 94da226513c0aafc3b3b2e7ce6b88703971e6a2c..2aac1ce5b4e36846cc0d5204185bb410871d1aa2 100644 (file)
@@ -7620,7 +7620,7 @@ create_stream_for_sink(struct drm_connector *connector,
        update_stream_signal(stream, sink);
 
        if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-               mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket);
+               mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false);
 
        if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
            stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
index ca402ddcdacc821fb4dfabc2dcbdd7120e646866..fbab100c0e7ba20966993e998968b03b20a313e1 100644 (file)
@@ -66,6 +66,7 @@ static uint8_t is_cp_desired_hdcp1(struct mod_hdcp *hdcp)
 
        return is_auth_needed &&
                        !hdcp->connection.link.adjust.hdcp1.disable &&
+                       !is_frl_hdcp(hdcp) &&
                        !hdcp->connection.is_hdcp1_revoked;
 }
 
@@ -584,6 +585,7 @@ enum mod_hdcp_operation_mode mod_hdcp_signal_type_to_operation_mode(
        switch (signal) {
        case SIGNAL_TYPE_DVI_SINGLE_LINK:
        case SIGNAL_TYPE_HDMI_TYPE_A:
+       case SIGNAL_TYPE_HDMI_FRL:
                mode = MOD_HDCP_MODE_DEFAULT;
                break;
        case SIGNAL_TYPE_EDP:
index d07387a961dd90d909af5c2f84b2ddd1664b84b0..92c128ffe2ddc60eefda9b3d77e638783ac67545 100644 (file)
@@ -406,6 +406,12 @@ static inline uint8_t is_hdmi_dvi_sl_hdcp(struct mod_hdcp *hdcp)
        return (hdcp->connection.link.mode == MOD_HDCP_MODE_DEFAULT);
 }
 
+static inline uint8_t is_frl_hdcp(struct mod_hdcp *hdcp)
+{
+       return (hdcp->connection.link.mode == MOD_HDCP_MODE_DEFAULT &&
+                       hdcp->connection.link.hdmi.frl_enabled);
+}
+
 /* hdcp state helpers */
 static inline uint8_t current_state(struct mod_hdcp *hdcp)
 {
index 6b7db8ec9a53b2697f1d977cf1321de946ea58bd..d32df3b869f91f047329e77a77a16ccfed790abd 100644 (file)
@@ -200,6 +200,8 @@ static enum mod_hdcp_status add_display_to_topology_v3(
                        TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_3;
        dtm_cmd->dtm_in_message.topology_update_v3.encoder_type = TA_DTM_ENCODER_TYPE__DIG;
        dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
+       if (is_frl_hdcp(hdcp))
+               dtm_cmd->dtm_in_message.topology_update_v3.encoder_type = TA_DTM_ENCODER_TYPE__FRL;
        dtm_cmd->dtm_in_message.topology_update_v3.phy_id = link->phy_idx;
        dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational;
        dtm_cmd->dtm_in_message.topology_update_v3.dio_output_type = link->dp.usb4_enabled ?
index 7844ea91650bf397062a166d7feee700b1fece81..1f9ac8537d53112047df026c48b4fc8726e6d876 100644 (file)
@@ -84,6 +84,7 @@ struct ta_dtm_topology_update_input_v2 {
        uint32_t dig_fe;
        uint32_t dp_mst_vcid;
        uint32_t is_assr;
+       /*uint32_t is_frl;*/ /*todo*/
        uint32_t max_hdcp_supported_version;
 };
 
@@ -91,6 +92,7 @@ struct ta_dtm_topology_update_input_v2 {
 /* Security code will check real HW register values and these SW enum values */
 enum ta_dtm_encoder_type {
        TA_DTM_ENCODER_TYPE__INVALID    = 0,
+       TA_DTM_ENCODER_TYPE__FRL        = 0x20,
        TA_DTM_ENCODER_TYPE__DIG        = 0x10
 };
 
index 57916ed98c86e8397a6505d3150c386c9a78a396..c042fb1bf49c0bb44fc477fce311aad260359170 100644 (file)
@@ -90,6 +90,7 @@ struct mod_vrr_params_flip_interval {
 struct mod_vrr_params {
        bool supported;
        bool send_info_frame;
+       bool m_const_engaged; // this is used when m_const is set up in OPTC so no overriding happens from FreeSync Module
        enum mod_vrr_state state;
 
        uint32_t min_refresh_in_uhz;
@@ -98,6 +99,8 @@ struct mod_vrr_params {
        uint32_t min_duration_in_us;
        uint32_t fixed_refresh_in_uhz;
 
+       uint32_t m_const;
+
        struct dc_crtc_timing_adjust adjust;
 
        struct mod_vrr_params_fixed_refresh fixed;
index 83546722545891bb38a3fb2d554128f6cd3d05b9..d492a59e0939065938b6433f29afbaefcce5d6fd 100644 (file)
@@ -114,6 +114,7 @@ struct mod_hdcp_displayport {
 };
 
 struct mod_hdcp_hdmi {
+       uint8_t frl_enabled;
        uint8_t reserved;
 };
 enum mod_hdcp_operation_mode {
index 11b127eb13d841b9cb74a26b6d953891587b8d1c..eee8206bc531a8c621ac331755feedc8b6b9c4df 100644 (file)
@@ -46,7 +46,7 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
                enum color_transfer_func tf);
 
 void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
-               struct dc_info_packet *info_packet);
+               struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue);
 
 enum adaptive_sync_sdp_version {
        AS_SDP_VER_0 = 0x0,
index 55c7250f18d848ac2908f028b91383b6bd2394e2..fa05547c615ade7cbad519ced778e93589e196c0 100644 (file)
@@ -504,13 +504,16 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
  *  @info_packet: output structure where to store VSIF
  */
 void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
-               struct dc_info_packet *info_packet)
+               struct dc_info_packet *info_packet, int ALLMEnabled, int ALLMValue)
 {
                unsigned int length = 5;
                bool hdmi_vic_mode = false;
                uint8_t checksum = 0;
                uint32_t i = 0;
                enum dc_timing_3d_format format;
+               bool bALLM = (bool)ALLMEnabled;
+               bool bALLMVal = (bool)ALLMValue;
+               int CCBPC = 0;
 
                info_packet->valid = false;
                format = stream->timing.timing_3d_format;
@@ -523,47 +526,110 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
                                && format == TIMING_3D_FORMAT_NONE)
                        hdmi_vic_mode = true;
 
-               if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode)
+               if ((format == TIMING_3D_FORMAT_NONE) && !hdmi_vic_mode && !bALLM)
                        return;
 
-               info_packet->sb[1] = 0x03;
-               info_packet->sb[2] = 0x0C;
-               info_packet->sb[3] = 0x00;
-
-               if (format != TIMING_3D_FORMAT_NONE)
-                       info_packet->sb[4] = (2 << 5);
-
-               else if (hdmi_vic_mode)
-                       info_packet->sb[4] = (1 << 5);
-
-               switch (format) {
-               case TIMING_3D_FORMAT_HW_FRAME_PACKING:
-               case TIMING_3D_FORMAT_SW_FRAME_PACKING:
-                       info_packet->sb[5] = (0x0 << 4);
-                       break;
-
-               case TIMING_3D_FORMAT_SIDE_BY_SIDE:
-               case TIMING_3D_FORMAT_SBS_SW_PACKED:
-                       info_packet->sb[5] = (0x8 << 4);
-                       length = 6;
-                       break;
-
-               case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
-               case TIMING_3D_FORMAT_TB_SW_PACKED:
-                       info_packet->sb[5] = (0x6 << 4);
-                       break;
-
-               default:
-                       break;
+               if (!bALLM) {
+                       info_packet->sb[1] = 0x03;
+                       info_packet->sb[2] = 0x0C;
+                       info_packet->sb[3] = 0x00;
+
+                       if (format != TIMING_3D_FORMAT_NONE)
+                               info_packet->sb[4] = (2 << 5);
+                       else if (hdmi_vic_mode)
+                               info_packet->sb[4] = (1 << 5);
+
+                       switch (format) {
+                       case TIMING_3D_FORMAT_HW_FRAME_PACKING:
+                       case TIMING_3D_FORMAT_SW_FRAME_PACKING:
+                               info_packet->sb[5] = (0x0 << 4);
+                               break;
+
+                       case TIMING_3D_FORMAT_SIDE_BY_SIDE:
+                       case TIMING_3D_FORMAT_SBS_SW_PACKED:
+                               info_packet->sb[5] = (0x8 << 4);
+                               length = 6;
+                               break;
+
+                       case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
+                       case TIMING_3D_FORMAT_TB_SW_PACKED:
+                               info_packet->sb[5] = (0x6 << 4);
+                               break;
+
+                       default:
+                               break;
+                       }
+
+                       if (hdmi_vic_mode) {
+                               ASSERT(stream->timing.hdmi_vic <= 0xFF);
+                               info_packet->sb[5] = (uint8_t)stream->timing.hdmi_vic;
+                       }
+               } else {
+                       info_packet->sb[1] = 0xD8;
+                       info_packet->sb[2] = 0x5D;
+                       info_packet->sb[3] = 0xC4;
+                       info_packet->sb[4] = HF_VSIF_VERSION;
+
+                       if (format != TIMING_3D_FORMAT_NONE) {
+                               info_packet->sb[5] |= 0x01;
+                               length = 6;
+                               switch (format) {
+                               case TIMING_3D_FORMAT_HW_FRAME_PACKING:
+                               case TIMING_3D_FORMAT_SW_FRAME_PACKING:
+                                       info_packet->sb[6] = (0x0 << 4);
+                                       break;
+
+                               case TIMING_3D_FORMAT_SIDE_BY_SIDE:
+                               case TIMING_3D_FORMAT_SBS_SW_PACKED:
+                                       info_packet->sb[6] = (0x8 << 4);
+                                       break;
+
+                               case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
+                               case TIMING_3D_FORMAT_TB_SW_PACKED:
+                                       info_packet->sb[6] = (0x6 << 4);
+                                       break;
+
+                               default:
+                                       break;
+                               }
+                       }
+
+                       info_packet->sb[5] = (info_packet->sb[5] & ~0x02) | (bALLMVal << 1);
+
+                       switch (stream->timing.display_color_depth) {
+                       case COLOR_DEPTH_888:
+                               CCBPC = 1;
+                               break;
+                       case COLOR_DEPTH_101010:
+                               CCBPC = 3;
+                               break;
+                       case COLOR_DEPTH_121212:
+                               CCBPC = 5;
+                               break;
+                       case COLOR_DEPTH_161616:
+                               CCBPC = 9;
+                               break;
+
+                       case COLOR_DEPTH_UNDEFINED:
+                       case COLOR_DEPTH_666:
+#ifdef CONFIG_DRM_AMD_DC_DCN2_0
+                       case COLOR_DEPTH_999:
+                       case COLOR_DEPTH_111111:
+#endif
+                       case COLOR_DEPTH_141414:
+                       default:
+                               break;
+                       }
+
+                       info_packet->sb[5] = (uint8_t)((info_packet->sb[5] & ~0xF0) | (CCBPC << 4));
                }
 
-               if (hdmi_vic_mode)
-                       info_packet->sb[5] = stream->timing.hdmi_vic;
-
                info_packet->hb0 = HDMI_INFOFRAME_TYPE_VENDOR;
                info_packet->hb1 = 0x01;
                info_packet->hb2 = (uint8_t) (length);
 
+
+
                checksum += info_packet->hb0;
                checksum += info_packet->hb1;
                checksum += info_packet->hb2;