static enum dc_status build_mapped_resource( const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream) { struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; dce110_resource_build_pipe_hw_param(pipe_ctx); resource_build_info_frame(pipe_ctx); return DC_OK; }
static enum dc_status build_mapped_resource( const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream) { struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream); if (!pipe_ctx) return DC_ERROR_UNEXPECTED; if (!is_surface_pixel_format_supported(pipe_ctx, dc->res_pool->underlay_pipe_index)) return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED; dce110_resource_build_pipe_hw_param(pipe_ctx); /* TODO: validate audio ASIC caps, encoder */ resource_build_info_frame(pipe_ctx); return DC_OK; }
static bool stream_adjust_vmin_vmax(struct dc *dc, struct dc_stream_state **streams, int num_streams, int vmin, int vmax) { /* TODO: Support multiple streams */ struct dc_stream_state *stream = streams[0]; int i = 0; bool ret = false; for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->stream == stream && pipe->stream_res.stream_enc) { dc->hwss.set_drr(&pipe, 1, vmin, vmax); /* build and update the info frame */ resource_build_info_frame(pipe); dc->hwss.update_info_frame(pipe); ret = true; } } return ret; }
static void commit_planes_for_stream(struct dc *dc, struct dc_surface_update *srf_updates, int surface_count, struct dc_stream_state *stream, struct dc_stream_update *stream_update, enum surface_update_type update_type, struct dc_state *context) { int i, j; if (update_type == UPDATE_TYPE_FULL) { dc->hwss.set_bandwidth(dc, context, false); context_clock_trace(dc, context); } if (update_type > UPDATE_TYPE_FAST) { for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe_ctx); } } if (surface_count == 0) { /* * In case of turning off screen, no need to program front end a second time. * just return after program front end. */ dc->hwss.apply_ctx_for_surface(dc, stream, surface_count, context); return; } /* Lock pipes for provided surfaces, or all active if full update*/ for (i = 0; i < surface_count; i++) { struct dc_plane_state *plane_state = srf_updates[i].surface; for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; if (update_type != UPDATE_TYPE_FULL && pipe_ctx->plane_state != plane_state) continue; if (!pipe_ctx->plane_state || pipe_ctx->top_pipe) continue; dc->hwss.pipe_control_lock( dc, pipe_ctx, true); } if (update_type == UPDATE_TYPE_FULL) break; } /* Full fe update*/ for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state) continue; if (!pipe_ctx->top_pipe && pipe_ctx->stream) { struct dc_stream_status *stream_status = stream_get_status(context, pipe_ctx->stream); dc->hwss.apply_ctx_for_surface( dc, pipe_ctx->stream, stream_status->plane_count, context); } } if (update_type > UPDATE_TYPE_FAST) context_timing_trace(dc, &context->res_ctx); /* Perform requested Updates */ for (i = 0; i < surface_count; i++) { struct dc_plane_state *plane_state = srf_updates[i].surface; if (update_type == UPDATE_TYPE_MED) dc->hwss.apply_ctx_for_surface( dc, stream, surface_count, context); for (j = 0; j < dc->res_pool->pipe_count; j++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; if (pipe_ctx->plane_state != plane_state) continue; if (srf_updates[i].flip_addr) dc->hwss.update_plane_addr(dc, pipe_ctx); if (update_type == UPDATE_TYPE_FAST) continue; /* work around to program degamma regs for split pipe after set mode. */ if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe && pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state)) dc->hwss.set_input_transfer_func( pipe_ctx, pipe_ctx->plane_state); if (stream_update != NULL && stream_update->out_transfer_func != NULL) { dc->hwss.set_output_transfer_func( pipe_ctx, pipe_ctx->stream); } if (srf_updates[i].hdr_static_metadata) { resource_build_info_frame(pipe_ctx); dc->hwss.update_info_frame(pipe_ctx); } } } /* Unlock pipes */ for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; for (j = 0; j < surface_count; j++) { if (update_type != UPDATE_TYPE_FULL && srf_updates[j].surface != pipe_ctx->plane_state) continue; if (!pipe_ctx->plane_state || pipe_ctx->top_pipe) continue; dc->hwss.pipe_control_lock( dc, pipe_ctx, false); break; } } }