summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
diff options
context:
space:
mode:
authorNikola Cornij <nikola.cornij@amd.com>2019-04-02 12:40:22 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-06-22 09:34:10 -0500
commitc9ae6e1691cd1dcd5f7f76050b5eca16bc82445e (patch)
tree0da915b62075e91af7ec0cb94c3d4626fd81c4e1 /drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
parent0d7bd17c6e7146df6de8c37b3fbc91dbaa138014 (diff)
drm/amd/display: Acquire DSC HW resource only if required by stream
[why] There are ASICs that have fewer DSC engines than pipes, which makes DSC a resource that should be used only if required. [how] Acquire DSC HW resource if required by stream and release when not required anymore. Signed-off-by: Nikola Cornij <nikola.cornij@amd.com> Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Acked-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c139
1 files changed, 78 insertions, 61 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index d2642cc52c85..2d6f9c4de893 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -1230,94 +1230,79 @@ enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
-static struct display_stream_compressor *acquire_dsc(struct resource_context *res_ctx,
- const struct resource_pool *pool)
+static void acquire_dsc(struct resource_context *res_ctx,
+ const struct resource_pool *pool,
+ struct display_stream_compressor **dsc)
{
int i;
- struct display_stream_compressor *dsc = NULL;
+
+ ASSERT(*dsc == NULL);
+ *dsc = NULL;
/* Find first free DSC */
for (i = 0; i < pool->res_cap->num_dsc; i++)
if (!res_ctx->is_dsc_acquired[i]) {
- dsc = pool->dscs[i];
+ *dsc = pool->dscs[i];
res_ctx->is_dsc_acquired[i] = true;
break;
}
-
- return dsc;
}
static void release_dsc(struct resource_context *res_ctx,
const struct resource_pool *pool,
- const struct display_stream_compressor *dsc)
+ struct display_stream_compressor **dsc)
{
int i;
for (i = 0; i < pool->res_cap->num_dsc; i++)
- if (pool->dscs[i] == dsc) {
+ if (pool->dscs[i] == *dsc) {
res_ctx->is_dsc_acquired[i] = false;
+ *dsc = NULL;
break;
}
}
#endif
-enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
-{
- enum dc_status result = DC_ERROR_UNEXPECTED;
-
- result = resource_map_pool_resources(dc, new_ctx, dc_stream);
-
- if (result == DC_OK)
- result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
- /* Get a DSC if required and available */
- if (result == DC_OK) {
- int i;
- const struct resource_pool *pool = dc->res_pool;
- bool is_add_dsc = true;
+enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc,
+ struct dc_state *dc_ctx,
+ struct dc_stream_state *dc_stream)
+{
+ enum dc_status result = DC_OK;
+ int i;
+ const struct resource_pool *pool = dc->res_pool;
- for (i = 0; i < dc->res_pool->pipe_count; i++) {
- struct pipe_ctx *pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
+ /* Get a DSC if required and available */
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe_ctx = &dc_ctx->res_ctx.pipe_ctx[i];
- if (pipe_ctx->stream != dc_stream)
- continue;
+ if (pipe_ctx->stream != dc_stream)
+ continue;
- if (IS_DIAG_DC(dc->ctx->dce_environment) ||
- dc->res_pool->res_cap->num_dsc == 1) {
- // Diags build can also run on platforms that have fewer DSCs than pipes.
- // In that case, add DSC only if needed by timing.
- is_add_dsc = (dc_stream->timing.flags.DSC == 1);
- }
- if (is_add_dsc) {
- pipe_ctx->stream_res.dsc = acquire_dsc(&new_ctx->res_ctx, pool);
-
- /* The number of DSCs can be less than the number of pipes */
- if (!pipe_ctx->stream_res.dsc) {
- dm_output_to_console("No DSCs available\n");
- result = DC_NO_DSC_RESOURCE;
- }
- }
+ acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc);
- break;
+ /* The number of DSCs can be less than the number of pipes */
+ if (!pipe_ctx->stream_res.dsc) {
+ dm_output_to_console("No DSCs available\n");
+ result = DC_NO_DSC_RESOURCE;
}
- }
-#endif
- if (result == DC_OK)
- result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream);
+ break;
+ }
return result;
}
-enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
+enum dc_status dcn20_remove_dsc_from_stream_resource(struct dc *dc,
+ struct dc_state *new_ctx,
+ struct dc_stream_state *dc_stream)
{
struct pipe_ctx *pipe_ctx = NULL;
int i;
- /* Remove DSC */
for (i = 0; i < MAX_PIPES; i++) {
if (new_ctx->res_ctx.pipe_ctx[i].stream == dc_stream && !new_ctx->res_ctx.pipe_ctx[i].top_pipe) {
pipe_ctx = &new_ctx->res_ctx.pipe_ctx[i];
@@ -1328,21 +1313,51 @@ enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_
if (!pipe_ctx)
return DC_ERROR_UNEXPECTED;
-#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
if (pipe_ctx->stream_res.dsc) {
struct pipe_ctx *odm_pipe = dc_res_get_odm_bottom_pipe(pipe_ctx);
- release_dsc(&new_ctx->res_ctx, dc->res_pool, pipe_ctx->stream_res.dsc);
- pipe_ctx->stream_res.dsc = NULL;
- if (odm_pipe) {
- release_dsc(&new_ctx->res_ctx, dc->res_pool, odm_pipe->stream_res.dsc);
- odm_pipe->stream_res.dsc = NULL;
- }
+ release_dsc(&new_ctx->res_ctx, dc->res_pool, &pipe_ctx->stream_res.dsc);
+ if (odm_pipe)
+ release_dsc(&new_ctx->res_ctx, dc->res_pool, &odm_pipe->stream_res.dsc);
}
-#endif
return DC_OK;
}
+#endif
+
+
+enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
+{
+ enum dc_status result = DC_ERROR_UNEXPECTED;
+
+ result = resource_map_pool_resources(dc, new_ctx, dc_stream);
+
+ if (result == DC_OK)
+ result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
+
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+ /* Get a DSC if required and available */
+ if (result == DC_OK && dc_stream->timing.flags.DSC)
+ result = dcn20_add_dsc_to_stream_resource(dc, new_ctx, dc_stream);
+#endif
+
+ if (result == DC_OK)
+ result = dcn20_build_mapped_resource(dc, new_ctx, dc_stream);
+
+ return result;
+}
+
+
+enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream)
+{
+ enum dc_status result = DC_OK;
+
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+ result = dcn20_remove_dsc_from_stream_resource(dc, new_ctx, dc_stream);
+#endif
+
+ return result;
+}
static void swizzle_to_dml_params(
@@ -1439,8 +1454,6 @@ static bool dcn20_split_stream_for_combine(
secondary_pipe->top_pipe = primary_pipe;
if (is_odm_combine) {
- bool is_add_dsc = true;
-
if (primary_pipe->plane_state) {
/* HACTIVE halved for odm combine */
sd->h_active /= 2;
@@ -1477,8 +1490,8 @@ static bool dcn20_split_stream_for_combine(
}
secondary_pipe->stream_res.opp = pool->opps[secondary_pipe->pipe_idx];
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
- if (is_add_dsc) {
- secondary_pipe->stream_res.dsc = acquire_dsc(res_ctx, pool);
+ if (secondary_pipe->stream->timing.flags.DSC == 1) {
+ acquire_dsc(res_ctx, pool, &secondary_pipe->stream_res.dsc);
ASSERT(secondary_pipe->stream_res.dsc);
if (secondary_pipe->stream_res.dsc == NULL)
return false;
@@ -1952,7 +1965,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
hsplit_pipe->bottom_pipe = NULL;
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
if (hsplit_pipe->stream_res.dsc && hsplit_pipe->stream_res.dsc != pipe->stream_res.dsc)
- release_dsc(&context->res_ctx, dc->res_pool, hsplit_pipe->stream_res.dsc);
+ release_dsc(&context->res_ctx, dc->res_pool, &hsplit_pipe->stream_res.dsc);
#endif
/* Clear plane_res and stream_res */
memset(&hsplit_pipe->plane_res, 0, sizeof(hsplit_pipe->plane_res));
@@ -2364,7 +2377,11 @@ static struct resource_funcs dcn20_res_pool_funcs = {
.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
.populate_dml_writeback_from_context = dcn20_populate_dml_writeback_from_context,
.get_default_swizzle_mode = dcn20_get_default_swizzle_mode,
- .set_mcif_arb_params = dcn20_set_mcif_arb_params
+ .set_mcif_arb_params = dcn20_set_mcif_arb_params,
+#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
+ .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
+ .remove_dsc_from_stream_resource = dcn20_remove_dsc_from_stream_resource
+#endif
};
struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx)