drm/amd/display: Copy stream updates onto streams
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tue, 14 May 2019 13:19:01 +0000 (09:19 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 11 Jun 2019 17:49:15 +0000 (12:49 -0500)
[Why]
Almost every function in DC that works with stream state expects that
the current state on the stream is the one that it should be writing
out. These functions are typically triggered by specifying a particular
stream update - but the actual contents of the stream update itself
are ignored, leaving it to the DM to actually update the stream state
itself.

The problem with doing this in DM is a matter of timing. On Linux
most of this is incorrectly done in atomic check, when we actually want
it to be done during atomic commit tail while access to DC is locked.

To give an example, a commit requesting to modify color management
state for DM could come in, be rejected, but still have modified
the actual system state for the stream since it's shared memory. The
next time color management gets programmed it'll use the rejected
color management info - which might not even still be around if it's
a custom transfer function.

So a reasonable place to perform this is within DC itself and this is
the model that's currently in use for surface updates. DC can even
compare the current system state to the incoming surface update to
determine update level, something that can't currnetly be done with the
framework for stream updates.

[How]
Duplicate the framework used for surface updates for stream updates
as well. Copy all the updates after checking the update type.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@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.c

index 0bff546d3727db6dd5db15e8a6fe40689196283c..45b542b5d9204751a3b0d00b94c6eb3df1754f66 100644 (file)
@@ -1607,6 +1607,73 @@ static void copy_surface_update_to_plane(
                        *srf_update->coeff_reduction_factor;
 }
 
+static void copy_stream_update_to_stream(struct dc *dc,
+                                        struct dc_state *context,
+                                        struct dc_stream_state *stream,
+                                        const struct dc_stream_update *update)
+{
+       if (update == NULL || stream == NULL)
+               return;
+
+       if (update->src.height && update->src.width)
+               stream->src = update->src;
+
+       if (update->dst.height && update->dst.width)
+               stream->dst = update->dst;
+
+       if (update->out_transfer_func &&
+           stream->out_transfer_func != update->out_transfer_func) {
+               stream->out_transfer_func->sdr_ref_white_level =
+                       update->out_transfer_func->sdr_ref_white_level;
+               stream->out_transfer_func->tf = update->out_transfer_func->tf;
+               stream->out_transfer_func->type =
+                       update->out_transfer_func->type;
+               memcpy(&stream->out_transfer_func->tf_pts,
+                      &update->out_transfer_func->tf_pts,
+                      sizeof(struct dc_transfer_func_distributed_points));
+       }
+
+       if (update->hdr_static_metadata)
+               stream->hdr_static_metadata = *update->hdr_static_metadata;
+
+       if (update->abm_level)
+               stream->abm_level = *update->abm_level;
+
+       if (update->periodic_interrupt0)
+               stream->periodic_interrupt0 = *update->periodic_interrupt0;
+
+       if (update->periodic_interrupt1)
+               stream->periodic_interrupt1 = *update->periodic_interrupt1;
+
+       if (update->gamut_remap)
+               stream->gamut_remap_matrix = *update->gamut_remap;
+
+       /* Note: this being updated after mode set is currently not a use case
+        * however if it arises OCSC would need to be reprogrammed at the
+        * minimum
+        */
+       if (update->output_color_space)
+               stream->output_color_space = *update->output_color_space;
+
+       if (update->output_csc_transform)
+               stream->csc_color_matrix = *update->output_csc_transform;
+
+       if (update->vrr_infopacket)
+               stream->vrr_infopacket = *update->vrr_infopacket;
+
+       if (update->dpms_off)
+               stream->dpms_off = *update->dpms_off;
+
+       if (update->vsc_infopacket)
+               stream->vsc_infopacket = *update->vsc_infopacket;
+
+       if (update->vsp_infopacket)
+               stream->vsp_infopacket = *update->vsp_infopacket;
+
+       if (update->dither_option)
+               stream->dither_option = *update->dither_option;
+}
+
 static void commit_planes_do_stream_update(struct dc *dc,
                struct dc_stream_state *stream,
                struct dc_stream_update *stream_update,
@@ -1857,6 +1924,8 @@ void dc_commit_updates_for_stream(struct dc *dc,
                }
        }
 
+       copy_stream_update_to_stream(dc, context, stream, stream_update);
+
        commit_planes_for_stream(
                                dc,
                                srf_updates,