drm/amd/display: implement notify stream mask
authorEric Yang <Eric.Yang2@amd.com>
Fri, 21 Aug 2020 21:15:36 +0000 (17:15 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 15 Sep 2020 21:52:41 +0000 (17:52 -0400)
[Why]
Send stream active state info to DMUB

[How]
Implement GPINT to notify stream mask

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
drivers/gpu/drm/amd/display/dc/inc/core_types.h

index ce5303c..1190c58 100644 (file)
@@ -1246,6 +1246,19 @@ void dc_trigger_sync(struct dc *dc, struct dc_state *context)
        }
 }
 
+static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context)
+{
+       int i;
+       unsigned int stream_mask = 0;
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               if (context->res_ctx.pipe_ctx[i].stream)
+                       stream_mask |= 1 << i;
+       }
+
+       return stream_mask;
+}
+
 /*
  * Applies given context to HW and copy it into current context.
  * It's up to the user to release the src context afterwards.
@@ -1362,6 +1375,11 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
                dc->hwss.optimize_bandwidth(dc, context);
        }
 
+       context->stream_mask = get_stream_mask(dc, context);
+
+       if (context->stream_mask != dc->current_state->stream_mask)
+               dc_dmub_srv_notify_stream_mask(dc->ctx->dmub_srv, context->stream_mask);
+
        for (i = 0; i < context->stream_count; i++)
                context->streams[i]->mode_changed = false;
 
index eea2429..b987548 100644 (file)
@@ -132,3 +132,19 @@ void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv)
                /* Continue spinning so we don't hang the ASIC. */
        }
 }
+
+bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
+                                   unsigned int stream_mask)
+{
+       struct dmub_srv *dmub;
+       const uint32_t timeout = 30;
+
+       if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+               return false;
+
+       dmub = dc_dmub_srv->dmub;
+
+       return dmub_srv_send_gpint_command(
+                      dmub, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
+                      stream_mask, timeout) == DMUB_STATUS_OK;
+}
index a3a09cc..bb4ab61 100644 (file)
@@ -56,4 +56,6 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv);
 
 void dc_dmub_srv_wait_phy_init(struct dc_dmub_srv *dc_dmub_srv);
 
+bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
+                                   unsigned int stream_mask);
 #endif /* _DMUB_DC_SRV_H_ */
index 3ec1d9d..1daa563 100644 (file)
@@ -397,6 +397,7 @@ struct dc_state {
        struct dc_stream_state *streams[MAX_PIPES];
        struct dc_stream_status stream_status[MAX_PIPES];
        uint8_t stream_count;
+       uint8_t stream_mask;
 
        struct resource_context res_ctx;