diff options
author | Harry Wentland <harry.wentland@amd.com> | 2017-03-30 11:55:56 -0400 |
---|---|---|
committer | Harry Wentland <harry.wentland@amd.com> | 2017-04-19 20:57:52 -0400 |
commit | 64f569b5df205b1bb77bbca8b2b7e313e420915c (patch) | |
tree | a0a5b7b1ae92b789a24fbcbe0e4d78748014b72b | |
parent | 258e6a91fc6139f1de864606bbbc3bdf1d4bb5d9 (diff) |
drm/amd/display: Use validate_context from atomic_check in commitdc-drm-next-atomic-wip
With this we're now using the exact state that was validated in
atomic_check in atomic_commit.
Change-Id: Ia46a4f80e162934b71ce2aa59845b1bfac55c924
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 83 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 6 |
5 files changed, 76 insertions, 70 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c index aa4ee6b83438..d88e88c875a3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c @@ -2674,6 +2674,7 @@ void amdgpu_dm_atomic_commit_tail( new_stream = dm_state->set[j].stream; break; } + /* * this loop saves set mode crtcs * we needed to enable vblanks once all @@ -2691,16 +2692,30 @@ void amdgpu_dm_atomic_commit_tail( } case DM_COMMIT_ACTION_NOTHING: { - struct dm_connector_state *dm_state = NULL; + struct dm_connector_state *dm_conn_state = NULL; if (!aconnector) break; - dm_state = to_dm_connector_state(aconnector->base.state); + dm_conn_state = to_dm_connector_state(aconnector->base.state); + + /* TODO clean this stupid hack + * probably needs some cleanup in atomic_check first */ + for (j = 0; j < dm_state->set_count; j++) + if (dm_state->set[j].stream->priv == acrtc) { + if (acrtc->stream) + mod_freesync_remove_stream(adev->dm.freesync_module, + acrtc->stream); + acrtc->stream = dm_state->set[j].stream; + mod_freesync_add_stream(adev->dm.freesync_module, + acrtc->stream, + &aconnector->caps); + break; + } /* Scaling update */ update_stream_scaling_settings(&crtc->state->mode, - dm_state, acrtc->stream); + dm_conn_state, acrtc->stream); break; } @@ -2708,8 +2723,9 @@ void amdgpu_dm_atomic_commit_tail( case DM_COMMIT_ACTION_RESET: DRM_INFO("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc); /* i.e. reset mode */ - if (acrtc->stream) + if (acrtc->stream) { remove_stream(adev, acrtc); + } break; } /* switch() */ } /* for_each_crtc_in_state() */ @@ -2742,19 +2758,23 @@ void amdgpu_dm_atomic_commit_tail( } /* DC is optimized not to do anything if 'streams' didn't change. */ - WARN_ON(!dc_commit_validation_set(dm->dc, dm_state->set, - dm_state->set_count)); + WARN_ON(!dc_commit_context(dm->dc, dm_state->context)); + + /* update planes when needed */ + dc_commit_surfaces(state, dev, dm); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); - if (acrtc->stream != NULL) - acrtc->otg_inst = - dc_stream_get_status(acrtc->stream)->primary_otg_inst; - } + if (acrtc->stream != NULL) { + const struct dc_stream_status *status = dc_stream_get_status(acrtc->stream); - /* update planes when needed */ - dc_commit_surfaces(state, dev, dm); + if (!status) + DC_ERR("got no status for stream %p on acrtc%p\n", acrtc->stream, acrtc); + else + acrtc->otg_inst = status->primary_otg_inst; + } + } for (i = 0; i < new_crtcs_count; i++) { /* @@ -2970,6 +2990,7 @@ static uint32_t update_in_val_sets_stream( } else { /* update. relase old stream */ dc_stream_release(old_stream); + } return set_count; @@ -3137,6 +3158,7 @@ int amdgpu_dm_atomic_check(struct drm_device *dev, __func__, acrtc->base.base.id); break; } + new_stream->priv = acrtc; new_streams[new_stream_count] = new_stream; dm_state->set_count = update_in_val_sets_stream( diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index e5ec359b3830..2c86a6309074 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -792,18 +792,17 @@ static void program_timing_sync( } } -static bool set_changed( +static bool context_changed( struct core_dc *dc, - const struct dc_validation_set set[], - uint8_t set_count) + struct validate_context *context) { uint8_t i; - if (set_count != dc->current_context->stream_count) + if (context->stream_count != dc->current_context->stream_count) return true; for (i = 0; i < dc->current_context->stream_count; i++) { - if (&dc->current_context->streams[i]->public != set[i].stream) + if (&dc->current_context->streams[i]->public != &context->streams[i]->public) return true; } @@ -829,46 +828,36 @@ static bool streams_changed( } /* TODO operate on validation set (or something like it) */ -bool dc_commit_validation_set( - const struct dc *dc, - const struct dc_validation_set set[], - uint8_t set_count) +bool dc_commit_context(struct dc *dc, struct validate_context *context) { struct core_dc *core_dc = DC_TO_CORE(dc); struct dc_bios *dcb = core_dc->ctx->dc_bios; enum dc_status result = DC_ERROR_UNEXPECTED; - struct validate_context *context; int i, j, k; - /* TODO check validation set changed */ - if (false == set_changed(core_dc, set, set_count)) + if (!context) + dm_logger_write(core_dc->ctx->logger, LOG_ERROR, + "%s: dc_commit_context with no context!\n", + __func__); + + if (false == context_changed(core_dc, context)) return DC_OK; dm_logger_write(core_dc->ctx->logger, LOG_DC, "%s: %d streams\n", - __func__, set_count); + __func__, context->stream_count); - context = dm_alloc(sizeof(struct validate_context)); - if (context == NULL) - goto context_alloc_fail; + for (i = 0; i < context->stream_count; i++) { + const struct dc_stream *stream = &context->streams[i]->public; - /* TODO no need for validation. just rebuild context */ - /* TODO check context is created deterministically */ - result = core_dc->res_pool->funcs->validate_with_context(core_dc, set, set_count, context); - if (result != DC_OK) { - dm_logger_write(core_dc->ctx->logger, LOG_ERROR, - "%s: Context validation failed! dc_status:%d\n", - __func__, - result); - BREAK_TO_DEBUGGER(); - dc_resource_validate_ctx_destruct(context); - goto fail; + dc_stream_log(stream, + core_dc->ctx->logger, + LOG_DC); } if (!dcb->funcs->is_accelerated_mode(dcb)) core_dc->hwss.enable_accelerated_mode(core_dc); - if (result == DC_OK) - result = core_dc->hwss.apply_ctx_to_hw(core_dc, context); + result = core_dc->hwss.apply_ctx_to_hw(core_dc, context); program_timing_sync(core_dc, context); @@ -898,17 +887,8 @@ bool dc_commit_validation_set( context->streams[i]->public.timing.pix_clk_khz); } - dc_resource_validate_ctx_destruct(core_dc->current_context); - dm_free(core_dc->current_context); - - core_dc->current_context = context; - - return (result == DC_OK); - -fail: - dm_free(context); + dc_resource_validate_ctx_copy_construct(context, core_dc->current_context); -context_alloc_fail: return (result == DC_OK); } @@ -1028,24 +1008,27 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) dc_resource_validate_ctx_copy_construct(core_dc->current_context, context); post_surface_trace(dc); + for (i = 0; i < context->res_ctx.pool->pipe_count; i++) if (context->res_ctx.pipe_ctx[i].stream == NULL) { context->res_ctx.pipe_ctx[i].pipe_idx = i; core_dc->hwss.power_down_front_end( core_dc, &context->res_ctx.pipe_ctx[i]); } - if (!core_dc->res_pool->funcs->validate_bandwidth(core_dc, context)) { BREAK_TO_DEBUGGER(); + dc_resource_validate_ctx_destruct(context); + dm_free(context); return false; } core_dc->hwss.set_bandwidth(core_dc, context, true); - dc_resource_validate_ctx_copy_construct(context, core_dc->current_context); - - dc_resource_validate_ctx_destruct(context); - dm_free(context); + if (core_dc->current_context) { + dc_resource_validate_ctx_destruct(core_dc->current_context); + dm_free(core_dc->current_context); + } + core_dc->current_context = context; return true; } @@ -1494,8 +1477,10 @@ void dc_update_surfaces_and_stream(struct dc *dc, if (cur_pipe_ctx->surface == pipe_ctx->surface) is_new_pipe_surface = false; - if (is_new_pipe_surface || - srf_updates[i].in_transfer_func) + /* TODO find out why check is false */ + /* TODO with this still not programming some color stuff... panel is dark-ish */ + /*if (is_new_pipe_surface || + srf_updates[i].in_transfer_func)*/ core_dc->hwss.set_input_transfer_func( pipe_ctx, pipe_ctx->surface); @@ -1539,10 +1524,8 @@ void dc_update_surfaces_and_stream(struct dc *dc, return; fail: - if (core_dc->current_context != context) { - dc_resource_validate_ctx_destruct(context); - dm_free(context); - } + dc_resource_validate_ctx_destruct(context); + dm_free(context); } uint8_t dc_get_current_stream_count(const struct dc *dc) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 3dbd6c0885d8..454107b27db0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -164,9 +164,11 @@ const struct dc_stream_status *dc_stream_get_status( struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream); struct core_dc *dc = DC_TO_CORE(stream->ctx->dc); - for (i = 0; i < dc->current_context->stream_count; i++) - if (stream == dc->current_context->streams[i]) + for (i = 0; i < dc->current_context->stream_count; i++) { + if (stream == dc->current_context->streams[i]) { return &dc->current_context->stream_status[i]; + } + } return NULL; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index cc725c54f9f1..0863e44be550 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -544,10 +544,7 @@ void dc_resource_validate_ctx_destruct(struct validate_context *context); * Phy, Encoder, Timing Generator are programmed and enabled. * New streams are enabled with blank stream; no memory read. */ -bool dc_commit_validation_set( - const struct dc *dc, - const struct dc_validation_set set[], - uint8_t set_count); +bool dc_commit_context(struct dc *dc, struct validate_context *context); /* * Set up streams and links associated to drive sinks diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 2fbf6ddcf3be..1329106261a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2347,9 +2347,11 @@ static void dce110_program_front_end_for_pipe( pipe_ctx->xfm->funcs->transform_set_gamut_remap(pipe_ctx->xfm, &adjust); pipe_ctx->scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; - if (old_pipe && memcmp(&old_pipe->scl_data, + + /* TODO check why this skips scaler calll now */ + /*if (old_pipe && memcmp(&old_pipe->scl_data, &pipe_ctx->scl_data, - sizeof(struct scaler_data)) != 0) + sizeof(struct scaler_data)) != 0)*/ program_scaler(dc, pipe_ctx); mi->funcs->mem_input_program_surface_config( |