Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
		}
	}
}