drm/amd/display: Expose send immediate sdp message interface
authorLeo (Hanghong) Ma <hanghong.ma@amd.com>
Tue, 16 Apr 2019 15:07:22 +0000 (11:07 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 24 May 2019 17:20:50 +0000 (12:20 -0500)
[Why]
To send sdp message immediately from a single slot.

[How]
Modify the generic SDP message interface, and use GSP4 to send immediate
sdp message.

Signed-off-by: Leo (Hanghong) Ma <hanghong.ma@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h

index 47b99458d319adc2c4a0aee056d5b3fad6839635..58ce7a6b914ca0a71f4fdf1e192de46cdf6bcf59 100644 (file)
@@ -2446,21 +2446,6 @@ static void set_spd_info_packet(
        *info_packet = stream->vrr_infopacket;
 }
 
-static void set_dp_sdp_info_packet(
-               struct dc_info_packet *info_packet,
-               struct dc_stream_state *stream)
-{
-       /* SPD info packet for custom sdp message */
-
-       /* Return if false. If true,
-        * set the corresponding bit in the info packet
-        */
-       if (!stream->dpsdp_infopacket.valid)
-               return;
-
-       *info_packet = stream->dpsdp_infopacket;
-}
-
 static void set_hdr_static_info_packet(
                struct dc_info_packet *info_packet,
                struct dc_stream_state *stream)
@@ -2557,7 +2542,6 @@ void resource_build_info_frame(struct pipe_ctx *pipe_ctx)
        info->spd.valid = false;
        info->hdrsmd.valid = false;
        info->vsc.valid = false;
-       info->dpsdp.valid = false;
 
        signal = pipe_ctx->stream->signal;
 
@@ -2577,8 +2561,6 @@ void resource_build_info_frame(struct pipe_ctx *pipe_ctx)
                set_spd_info_packet(&info->spd, pipe_ctx->stream);
 
                set_hdr_static_info_packet(&info->hdrsmd, pipe_ctx->stream);
-
-               set_dp_sdp_info_packet(&info->dpsdp, pipe_ctx->stream);
        }
 
        patch_gamut_packet_checksum(&info->gamut);
index a79f608b2f798edf0932e372bd8fab29959fe64f..b723ffc8ea253fd9e89ac7376f8218e13e664f60 100644 (file)
@@ -371,42 +371,12 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream)
        return 0;
 }
 
-static void build_dp_sdp_info_frame(struct pipe_ctx *pipe_ctx,
-               const uint8_t  *custom_sdp_message,
-               unsigned int sdp_message_size)
-{
-       uint8_t i;
-       struct encoder_info_frame *info = &pipe_ctx->stream_res.encoder_info_frame;
-
-       /* set valid info */
-       info->dpsdp.valid = true;
-
-       /* set sdp message header */
-       info->dpsdp.hb0 = custom_sdp_message[0]; /* package id */
-       info->dpsdp.hb1 = custom_sdp_message[1]; /* package type */
-       info->dpsdp.hb2 = custom_sdp_message[2]; /* package specific byte 0 any data */
-       info->dpsdp.hb3 = custom_sdp_message[3]; /* package specific byte 0 any data */
-
-       /* set sdp message data */
-       for (i = 0; i < 32; i++)
-               info->dpsdp.sb[i] = (custom_sdp_message[i+4]);
-
-}
-
-static void invalid_dp_sdp_info_frame(struct pipe_ctx *pipe_ctx)
-{
-       struct encoder_info_frame *info = &pipe_ctx->stream_res.encoder_info_frame;
-
-       /* in-valid info */
-       info->dpsdp.valid = false;
-}
-
 bool dc_stream_send_dp_sdp(const struct dc_stream_state *stream,
                const uint8_t *custom_sdp_message,
                unsigned int sdp_message_size)
 {
        int i;
-       struct dc  *core_dc;
+       struct dc  *dc;
        struct resource_context *res_ctx;
 
        if (stream == NULL) {
@@ -414,8 +384,8 @@ bool dc_stream_send_dp_sdp(const struct dc_stream_state *stream,
                return false;
        }
 
-       core_dc = stream->ctx->dc;
-       res_ctx = &core_dc->current_state->res_ctx;
+       dc = stream->ctx->dc;
+       res_ctx = &dc->current_state->res_ctx;
 
        for (i = 0; i < MAX_PIPES; i++) {
                struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
@@ -423,11 +393,14 @@ bool dc_stream_send_dp_sdp(const struct dc_stream_state *stream,
                if (pipe_ctx->stream != stream)
                        continue;
 
-               build_dp_sdp_info_frame(pipe_ctx, custom_sdp_message, sdp_message_size);
-
-               core_dc->hwss.update_info_frame(pipe_ctx);
+               if (dc->hwss.send_immediate_sdp_message != NULL)
+                       dc->hwss.send_immediate_sdp_message(pipe_ctx,
+                                                               custom_sdp_message,
+                                                               sdp_message_size);
+               else
+                       DC_LOG_WARNING("%s:send_immediate_sdp_message not implemented on this ASIC\n",
+                       __func__);
 
-               invalid_dp_sdp_info_frame(pipe_ctx);
        }
 
        return true;
index 723b2ddf9aa548c94f351df1e63dcfab77c17983..c2b60b1e1a25d90e6d3dc35902fc299c2cb9dcc8 100644 (file)
@@ -2957,6 +2957,18 @@ static void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx,
        }
 }
 
+static void dcn10_send_immediate_sdp_message(struct pipe_ctx *pipe_ctx,
+                               const uint8_t *custom_sdp_message,
+                               unsigned int sdp_message_size)
+{
+       if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+               pipe_ctx->stream_res.stream_enc->funcs->send_immediate_sdp_message(
+                               pipe_ctx->stream_res.stream_enc,
+                               custom_sdp_message,
+                               sdp_message_size);
+       }
+}
+
 static const struct hw_sequencer_funcs dcn10_funcs = {
        .program_gamut_remap = program_gamut_remap,
        .init_hw = dcn10_init_hw,
@@ -2976,6 +2988,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
        .enable_timing_synchronization = dcn10_enable_timing_synchronization,
        .enable_per_frame_crtc_position_reset = dcn10_enable_per_frame_crtc_position_reset,
        .update_info_frame = dce110_update_info_frame,
+       .send_immediate_sdp_message = dcn10_send_immediate_sdp_message,
        .enable_stream = dce110_enable_stream,
        .disable_stream = dce110_disable_stream,
        .unblank_stream = dcn10_unblank_stream,
index c259c51dff9a8714e3a6ff78919c5fa0eba85068..ba71b5224e7fa43b0b95c6b87c615dea3dd4ea8c 100644 (file)
@@ -727,11 +727,9 @@ void enc1_stream_encoder_update_dp_info_packets(
                                3,  /* packetIndex */
                                &info_frame->hdrsmd);
 
-       if (info_frame->dpsdp.valid)
-               enc1_update_generic_info_packet(
-                               enc1,
-                               4,/* packetIndex */
-                               &info_frame->dpsdp);
+       /* packetIndex 4 is used for send immediate sdp message, and please
+        * use other packetIndex (such as 5,6) for other info packet
+        */
 
        /* enable/disable transmission of packet(s).
         * If enabled, packet transmission begins on the next frame
@@ -739,7 +737,101 @@ void enc1_stream_encoder_update_dp_info_packets(
        REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid);
        REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, info_frame->spd.valid);
        REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, info_frame->hdrsmd.valid);
-       REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP4_ENABLE, info_frame->dpsdp.valid);
+
+
+       /* This bit is the master enable bit.
+        * When enabling secondary stream engine,
+        * this master bit must also be set.
+        * This register shared with audio info frame.
+        * Therefore we need to enable master bit
+        * if at least on of the fields is not 0
+        */
+       value = REG_READ(DP_SEC_CNTL);
+       if (value)
+               REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);
+}
+
+void enc1_stream_encoder_send_immediate_sdp_message(
+       struct stream_encoder *enc,
+       const uint8_t *custom_sdp_message,
+       unsigned int sdp_message_size)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+       uint32_t value = 0;
+
+       /* TODOFPGA Figure out a proper number for max_retries polling for lock
+        * use 50 for now.
+        */
+       uint32_t max_retries = 50;
+
+       /* check if GSP4 is transmitted */
+       REG_WAIT(DP_SEC_CNTL2, DP_SEC_GSP4_SEND_PENDING,
+               0, 10, max_retries);
+
+       /* disable GSP4 transmitting */
+       REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP4_SEND, 0);
+
+       /* transmit GSP4 at the earliest time in a frame */
+       REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP4_SEND_ANY_LINE, 1);
+
+       /*we need turn on clock before programming AFMT block*/
+       REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);
+
+       /* check if HW reading GSP memory */
+       REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,
+                       0, 10, max_retries);
+
+       /* HW does is not reading GSP memory not reading too long ->
+        * something wrong. clear GPS memory access and notify?
+        * hw SW is writing to GSP memory
+        */
+       REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);
+
+       /* use generic packet 4 for immediate sdp message */
+       REG_UPDATE(AFMT_VBI_PACKET_CONTROL,
+                       AFMT_GENERIC_INDEX, 4);
+
+       /* write generic packet header
+        * (4th byte is for GENERIC0 only)
+        */
+       REG_SET_4(AFMT_GENERIC_HDR, 0,
+                       AFMT_GENERIC_HB0, custom_sdp_message[0],
+                       AFMT_GENERIC_HB1, custom_sdp_message[1],
+                       AFMT_GENERIC_HB2, custom_sdp_message[2],
+                       AFMT_GENERIC_HB3, custom_sdp_message[3]);
+
+       /* write generic packet contents
+        * (we never use last 4 bytes)
+        * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers
+        */
+       {
+               const uint32_t *content =
+                       (const uint32_t *) &custom_sdp_message[4];
+
+               REG_WRITE(AFMT_GENERIC_0, *content++);
+               REG_WRITE(AFMT_GENERIC_1, *content++);
+               REG_WRITE(AFMT_GENERIC_2, *content++);
+               REG_WRITE(AFMT_GENERIC_3, *content++);
+               REG_WRITE(AFMT_GENERIC_4, *content++);
+               REG_WRITE(AFMT_GENERIC_5, *content++);
+               REG_WRITE(AFMT_GENERIC_6, *content++);
+               REG_WRITE(AFMT_GENERIC_7, *content);
+       }
+
+       /* check whether GENERIC4 registers double buffer update in immediate mode
+        * is pending
+        */
+       REG_WAIT(AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_IMMEDIATE_UPDATE_PENDING,
+                       0, 10, max_retries);
+
+       /* atomically update double-buffered GENERIC4 registers in immediate mode
+        * (update immediately)
+        */
+       REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+                       AFMT_GENERIC4_IMMEDIATE_UPDATE, 1);
+
+       /* enable GSP4 transmitting */
+       REG_UPDATE(DP_SEC_CNTL2, DP_SEC_GSP4_SEND, 1);
 
        /* This bit is the master enable bit.
         * When enabling secondary stream engine,
@@ -1463,6 +1555,8 @@ static const struct stream_encoder_funcs dcn10_str_enc_funcs = {
                enc1_stream_encoder_stop_hdmi_info_packets,
        .update_dp_info_packets =
                enc1_stream_encoder_update_dp_info_packets,
+       .send_immediate_sdp_message =
+               enc1_stream_encoder_send_immediate_sdp_message,
        .stop_dp_info_packets =
                enc1_stream_encoder_stop_dp_info_packets,
        .dp_blank =
index e654c2f559711833408f0f6466a6f76b66687065..a292b106a8b1591fe9547a5c85ab921e37fbef95 100644 (file)
@@ -81,6 +81,7 @@
        SRI(DP_MSE_RATE_UPDATE, DP, id), \
        SRI(DP_PIXEL_FORMAT, DP, id), \
        SRI(DP_SEC_CNTL, DP, id), \
+       SRI(DP_SEC_CNTL2, DP, id), \
        SRI(DP_STEER_FIFO, DP, id), \
        SRI(DP_VID_M, DP, id), \
        SRI(DP_VID_N, DP, id), \
@@ -118,10 +119,12 @@ struct dcn10_stream_enc_registers {
        uint32_t AFMT_60958_1;
        uint32_t AFMT_60958_2;
        uint32_t DIG_FE_CNTL;
+       uint32_t DIG_FE_CNTL2;
        uint32_t DP_MSE_RATE_CNTL;
        uint32_t DP_MSE_RATE_UPDATE;
        uint32_t DP_PIXEL_FORMAT;
        uint32_t DP_SEC_CNTL;
+       uint32_t DP_SEC_CNTL2;
        uint32_t DP_STEER_FIFO;
        uint32_t DP_VID_M;
        uint32_t DP_VID_N;
@@ -191,6 +194,10 @@ struct dcn10_stream_enc_registers {
        SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, mask_sh),\
        SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, mask_sh),\
        SE_SF(DP0_DP_SEC_CNTL, DP_SEC_MPG_ENABLE, mask_sh),\
+       SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND, mask_sh),\
+       SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND_PENDING, mask_sh),\
+       SE_SF(DP0_DP_SEC_CNTL4, DP_SEC_GSP4_LINE_NUM, mask_sh),\
+       SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP4_SEND_ANY_LINE, mask_sh),\
        SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, mask_sh),\
        SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, mask_sh),\
        SE_SF(DP0_DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, mask_sh),\
@@ -245,6 +252,7 @@ struct dcn10_stream_enc_registers {
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE_PENDING, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE_PENDING, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE_PENDING, mask_sh),\
+       SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_IMMEDIATE_UPDATE_PENDING, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE_PENDING, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE_PENDING, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE_PENDING, mask_sh),\
@@ -253,6 +261,7 @@ struct dcn10_stream_enc_registers {
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE, mask_sh),\
+       SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_IMMEDIATE_UPDATE, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE, mask_sh),\
        SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, mask_sh),\
@@ -260,6 +269,7 @@ struct dcn10_stream_enc_registers {
        SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP5_ENABLE, mask_sh),\
        SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP6_ENABLE, mask_sh),\
        SE_SF(DP0_DP_SEC_CNTL, DP_SEC_GSP7_ENABLE, mask_sh),\
+       SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP7_PPS, mask_sh),\
        SE_SF(DP0_DP_SEC_CNTL2, DP_SEC_GSP7_SEND, mask_sh),\
        SE_SF(DP0_DP_DB_CNTL, DP_DB_DISABLE, mask_sh),\
        SE_SF(DP0_DP_MSA_COLORIMETRY, DP_MSA_MISC0, mask_sh),\
@@ -304,6 +314,7 @@ struct dcn10_stream_enc_registers {
        type AFMT_GENERIC2_FRAME_UPDATE_PENDING;\
        type AFMT_GENERIC3_FRAME_UPDATE_PENDING;\
        type AFMT_GENERIC4_FRAME_UPDATE_PENDING;\
+       type AFMT_GENERIC4_IMMEDIATE_UPDATE_PENDING;\
        type AFMT_GENERIC5_FRAME_UPDATE_PENDING;\
        type AFMT_GENERIC6_FRAME_UPDATE_PENDING;\
        type AFMT_GENERIC7_FRAME_UPDATE_PENDING;\
@@ -312,6 +323,7 @@ struct dcn10_stream_enc_registers {
        type AFMT_GENERIC2_FRAME_UPDATE;\
        type AFMT_GENERIC3_FRAME_UPDATE;\
        type AFMT_GENERIC4_FRAME_UPDATE;\
+       type AFMT_GENERIC4_IMMEDIATE_UPDATE;\
        type AFMT_GENERIC5_FRAME_UPDATE;\
        type AFMT_GENERIC6_FRAME_UPDATE;\
        type AFMT_GENERIC7_FRAME_UPDATE;\
@@ -366,7 +378,12 @@ struct dcn10_stream_enc_registers {
        type DP_SEC_GSP5_ENABLE;\
        type DP_SEC_GSP6_ENABLE;\
        type DP_SEC_GSP7_ENABLE;\
+       type DP_SEC_GSP7_PPS;\
        type DP_SEC_GSP7_SEND;\
+       type DP_SEC_GSP4_SEND;\
+       type DP_SEC_GSP4_SEND_PENDING;\
+       type DP_SEC_GSP4_LINE_NUM;\
+       type DP_SEC_GSP4_SEND_ANY_LINE;\
        type DP_SEC_MPG_ENABLE;\
        type DP_VID_STREAM_DIS_DEFER;\
        type DP_VID_STREAM_ENABLE;\
@@ -484,6 +501,11 @@ void enc1_stream_encoder_update_dp_info_packets(
        struct stream_encoder *enc,
        const struct encoder_info_frame *info_frame);
 
+void enc1_stream_encoder_send_immediate_sdp_message(
+       struct stream_encoder *enc,
+       const uint8_t *custom_sdp_message,
+                               unsigned int sdp_message_size);
+
 void enc1_stream_encoder_stop_dp_info_packets(
        struct stream_encoder *enc);
 
index 49854eb73d1d6ac5a501ee017400d904dfa665e6..537563888f87feaa9f0ed930c375839de0b79752 100644 (file)
@@ -63,8 +63,6 @@ struct encoder_info_frame {
        struct dc_info_packet vsc;
        /* HDR Static MetaData */
        struct dc_info_packet hdrsmd;
-       /* custom sdp message */
-       struct dc_info_packet dpsdp;
 };
 
 struct encoder_unblank_param {
@@ -123,6 +121,11 @@ struct stream_encoder_funcs {
                struct stream_encoder *enc,
                const struct encoder_info_frame *info_frame);
 
+       void (*send_immediate_sdp_message)(
+                               struct stream_encoder *enc,
+                               const uint8_t *custom_sdp_message,
+                               unsigned int sdp_message_size);
+
        void (*stop_dp_info_packets)(
                struct stream_encoder *enc);
 
index 33905468e2b9f8ba06b7d27d8dbe3fa196b987fb..eb1c12ed026aeafcb45ad8d9c505a0e9a7da2c42 100644 (file)
@@ -158,6 +158,11 @@ struct hw_sequencer_funcs {
 
        void (*update_info_frame)(struct pipe_ctx *pipe_ctx);
 
+       void (*send_immediate_sdp_message)(
+                               struct pipe_ctx *pipe_ctx,
+                               const uint8_t *custom_sdp_message,
+                               unsigned int sdp_message_size);
+
        void (*enable_stream)(struct pipe_ctx *pipe_ctx);
 
        void (*disable_stream)(struct pipe_ctx *pipe_ctx,