diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c7415772e280..4887d0611001 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -584,6 +584,28 @@ void dc_link_set_test_pattern(struct dc_link *link, cust_pattern_size); } +uint32_t dc_link_bandwidth_kbps( + const struct dc_link *link, + const struct dc_link_settings *link_setting) +{ + uint32_t link_bw_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ; /* bytes per sec */ + + link_bw_kbps *= 8; /* 8 bits per byte*/ + link_bw_kbps *= link_setting->lane_count; + + return link_bw_kbps; + +} + +const struct dc_link_settings *dc_link_get_verified_link_cap( + const struct dc_link *link) +{ + if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN && + link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) + return &link->preferred_link_setting; + return &link->verified_link_cap; +} + static void destruct(struct dc *dc) { dc_release_state(dc->current_state); @@ -632,6 +654,8 @@ static bool construct(struct dc *dc, #endif enum dce_version dc_version = DCE_VERSION_UNKNOWN; + dc->config = init_params->flags; + memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides)); dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL); @@ -681,13 +705,6 @@ static bool construct(struct dc *dc, dc_ctx->dc_stream_id_count = 0; dc->ctx = dc_ctx; - dc->current_state = dc_create_state(); - - if (!dc->current_state) { - dm_error("%s: failed to create validate ctx\n", __func__); - goto fail; - } - /* Create logger */ dc_ctx->dce_environment = init_params->dce_environment; @@ -739,6 +756,18 @@ static bool construct(struct dc *dc, if (!dc->res_pool) goto fail; + /* Creation of current_state must occur after dc->dml + * is initialized in dc_create_resource_pool because + * on creation it copies the contents of dc->dml + */ + + dc->current_state = dc_create_state(dc); + + if (!dc->current_state) { + dm_error("%s: failed to create validate ctx\n", __func__); + goto fail; + } + dc_resource_state_construct(dc, dc->current_state); if (!create_links(dc, init_params->num_virtual_links)) @@ -755,7 +784,7 @@ fail: static void disable_dangling_plane(struct dc *dc, struct dc_state *context) { int i, j; - struct dc_state *dangling_context = dc_create_state(); + struct dc_state *dangling_context = dc_create_state(dc); struct dc_state *current_ctx; if (dangling_context == NULL) @@ -820,8 +849,6 @@ struct dc *dc_create(const struct dc_init_data *init_params) if (dc->res_pool->dmcu != NULL) dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version; - dc->config = init_params->flags; - dc->build_id = DC_BUILD_ID; DC_LOG_DC("Display Core initialized\n"); @@ -1213,18 +1240,60 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) return true; } -struct dc_state *dc_create_state(void) +struct dc_state *dc_create_state(struct dc *dc) { struct dc_state *context = kzalloc(sizeof(struct dc_state), GFP_KERNEL); if (!context) return NULL; + /* Each context must have their own instance of VBA and in order to + * initialize and obtain IP and SOC the base DML instance from DC is + * initially copied into every context + */ +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 + memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); +#endif kref_init(&context->refcount); + return context; } +struct dc_state *dc_copy_state(struct dc_state *src_ctx) +{ + int i, j; + struct dc_state *new_ctx = kzalloc(sizeof(struct dc_state), + GFP_KERNEL); + + if (!new_ctx) + return NULL; + + memcpy(new_ctx, src_ctx, sizeof(struct dc_state)); + + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i]; + + if (cur_pipe->top_pipe) + cur_pipe->top_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx]; + + if (cur_pipe->bottom_pipe) + cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx]; + + } + + for (i = 0; i < new_ctx->stream_count; i++) { + dc_stream_retain(new_ctx->streams[i]); + for (j = 0; j < new_ctx->stream_status[i].plane_count; j++) + dc_plane_state_retain( + new_ctx->stream_status[i].plane_states[j]); + } + + kref_init(&new_ctx->refcount); + + return new_ctx; +} + void dc_retain_state(struct dc_state *context) { kref_get(&context->refcount); @@ -1824,7 +1893,7 @@ void dc_commit_updates_for_stream(struct dc *dc, if (update_type >= UPDATE_TYPE_FULL) { /* initialize scratch memory for building context */ - context = dc_create_state(); + context = dc_create_state(dc); if (context == NULL) { DC_ERROR("Failed to allocate new validate context!\n"); return; @@ -2109,13 +2178,13 @@ void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) { - info->displayClock = (unsigned int)state->bw.dcn.clk.dispclk_khz; - info->engineClock = (unsigned int)state->bw.dcn.clk.dcfclk_khz; - info->memoryClock = (unsigned int)state->bw.dcn.clk.dramclk_khz; - info->maxSupportedDppClock = (unsigned int)state->bw.dcn.clk.max_supported_dppclk_khz; - info->dppClock = (unsigned int)state->bw.dcn.clk.dppclk_khz; - info->socClock = (unsigned int)state->bw.dcn.clk.socclk_khz; - info->dcfClockDeepSleep = (unsigned int)state->bw.dcn.clk.dcfclk_deep_sleep_khz; - info->fClock = (unsigned int)state->bw.dcn.clk.fclk_khz; - info->phyClock = (unsigned int)state->bw.dcn.clk.phyclk_khz; + info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; + info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz; + info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz; + info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz; + info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz; + info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz; + info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz; + info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz; + info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz; } |