From c49d3cd9af2452b28e673fa354f057989062011e Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Fri, 5 Feb 2016 11:41:55 -0500 Subject: [PATCH 0789/1110] drm/amd/dal: non destructive validate This changes the way resources are handled to make validate non destructive to current state and allow allocating mpo resources if needed. Signed-off-by: Dmytro Laktyushkin Acked-by: Harry Wentland --- drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_irq.c | 2 +- .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c | 3 +- drivers/gpu/drm/amd/dal/dc/core/dc.c | 46 +- drivers/gpu/drm/amd/dal/dc/core/dc_link.c | 133 +++-- drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c | 4 +- drivers/gpu/drm/amd/dal/dc/core/dc_resource.c | 398 +++++++------- drivers/gpu/drm/amd/dal/dc/core/dc_target.c | 350 +++++++----- drivers/gpu/drm/amd/dal/dc/dc.h | 8 +- drivers/gpu/drm/amd/dal/dc/dc_types.h | 23 +- .../gpu/drm/amd/dal/dc/dce100/dce100_resource.c | 210 ++++---- .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 586 +++++++++------------ .../drm/amd/dal/dc/dce110/dce110_link_encoder.c | 13 +- .../drm/amd/dal/dc/dce110/dce110_link_encoder.h | 2 +- .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 345 ++++++------ drivers/gpu/drm/amd/dal/dc/inc/core_types.h | 107 ++-- drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h | 23 +- drivers/gpu/drm/amd/dal/dc/inc/link_encoder.h | 5 +- drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h | 2 +- drivers/gpu/drm/amd/dal/dc/inc/resource.h | 13 +- .../drm/amd/dal/dc/virtual/virtual_link_encoder.c | 2 +- drivers/gpu/drm/amd/dal/include/grph_csc_types.h | 13 - 21 files changed, 1145 insertions(+), 1143 deletions(-) diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_irq.c index 9b5fd70..2ba79ab 100644 --- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_irq.c @@ -688,7 +688,7 @@ static inline int dm_irq_state( return 0; } - irq_source = dc_target_get_irq_src(acrtc->target, dal_irq_type); + irq_source = dc_target_get_irq_src(adev->dm.dc, acrtc->target, dal_irq_type); st = (state == AMDGPU_IRQ_STATE_ENABLE); diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c index 2cb445d..39490bf 100644 --- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c @@ -484,8 +484,7 @@ static void fill_plane_attributes_from_fb( surface->scaling_quality.v_taps_c = 2; /* TODO: unhardcode */ - surface->colorimetry.limited_range = false; - surface->colorimetry.color_space = SURFACE_COLOR_SPACE_SRGB; + surface->color_space = COLOR_SPACE_SRGB_FULL_RANGE; surface->scaling_quality.h_taps = 2; surface->scaling_quality.v_taps = 2; surface->stereo_format = PLANE_STEREO_FORMAT_NONE; diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c index d788917..bcc6f68 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c @@ -172,7 +172,7 @@ static void init_hw(struct dc *dc) struct transform *xfm; bp = dal_adapter_service_get_bios_parser(dc->res_pool.adapter_srv); - for(i = 0; i < dc->res_pool.controller_count; i++) { + for (i = 0; i < dc->res_pool.pipe_count; i++) { xfm = dc->res_pool.transforms[i]; dc->hwss.enable_display_power_gating( @@ -201,7 +201,7 @@ static void init_hw(struct dc *dc) link->link_enc->funcs->hw_init(link->link_enc); } - for(i = 0; i < dc->res_pool.controller_count; i++) { + for (i = 0; i < dc->res_pool.pipe_count; i++) { struct timing_generator *tg = dc->res_pool.timing_generators[i]; tg->funcs->disable_vga(tg); @@ -466,11 +466,11 @@ static void program_timing_sync( uint8_t i; uint8_t j; uint8_t group_size = 0; - uint8_t tg_count = ctx->res_ctx.pool.controller_count; + uint8_t tg_count = ctx->res_ctx.pool.pipe_count; struct timing_generator *tg_set[3]; for (i = 0; i < tg_count; i++) { - if (!ctx->res_ctx.controller_ctx[i].stream) + if (!ctx->res_ctx.pipe_ctx[i].stream) continue; tg_set[0] = ctx->res_ctx.pool.timing_generators[i]; @@ -480,13 +480,13 @@ static void program_timing_sync( * same timing, add all tgs with same timing to the group */ for (j = i + 1; j < tg_count; j++) { - if (!ctx->res_ctx.controller_ctx[j].stream) + if (!ctx->res_ctx.pipe_ctx[j].stream) continue; if (is_same_timing( - &ctx->res_ctx.controller_ctx[j].stream->public + &ctx->res_ctx.pipe_ctx[j].stream->public .timing, - &ctx->res_ctx.controller_ctx[i].stream->public + &ctx->res_ctx.pipe_ctx[i].stream->public .timing)) { tg_set[group_size] = ctx->res_ctx.pool.timing_generators[j]; @@ -580,7 +580,7 @@ bool dc_commit_targets( } if (result == DC_OK) { - dc->hwss.reset_hw_ctx(dc, context, target_count); + dc->hwss.reset_hw_ctx(dc, context); if (context->target_count > 0) result = dc->hwss.apply_ctx_to_hw(dc, context); @@ -588,7 +588,7 @@ bool dc_commit_targets( for (i = 0; i < context->target_count; i++) { struct dc_target *dc_target = &context->targets[i]->public; - if (context->targets[i]->status.surface_count > 0) + if (context->target_status[i].surface_count > 0) dc_target_enable_memory_requests(dc_target); } @@ -609,7 +609,6 @@ bool dc_commit_targets( pplib_apply_display_requirements(dc, context, &context->pp_display_cfg); - /* TODO: disable unused plls*/ fail: dm_free(dc->ctx, context); @@ -659,12 +658,13 @@ const struct audio **dc_get_audios(struct dc *dc) void dc_get_caps(const struct dc *dc, struct dc_caps *caps) { - caps->max_targets = dc->res_pool.controller_count; + caps->max_targets = dc->res_pool.pipe_count; caps->max_links = dc->link_count; caps->max_audios = dc->res_pool.audio_count; } -void dc_flip_surface_addrs(struct dc* dc, +void dc_flip_surface_addrs( + struct dc *dc, const struct dc_surface *const surfaces[], struct dc_flip_addrs flip_addrs[], uint32_t count) @@ -679,10 +679,8 @@ void dc_flip_surface_addrs(struct dc* dc, surface->public.address = flip_addrs[i].address; surface->public.flip_immediate = flip_addrs[i].flip_immediate; - dc->hwss.update_plane_address( - dc, - surface, - DC_TARGET_TO_CORE(surface->status.dc_target)); + dc->hwss.update_plane_addrs( + dc, &dc->current_context.res_ctx, surface); } } @@ -737,27 +735,19 @@ const struct dc_target *dc_get_target_on_irq_source( for (i = 0; i < dc->current_context.target_count; i++) { struct core_target *target = dc->current_context.targets[i]; - - struct dc_target *dc_target; - - if (NULL == target) { - dm_error("%s: 'dc_target' is NULL for irq source: %d\n!", - __func__, src); - continue; - } - - dc_target = &target->public; + struct dc_target *dc_target = &target->public; for (j = 0; j < target->public.stream_count; j++) { const struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[j]); - const uint8_t controller_idx = stream->controller_idx; - if (controller_idx == crtc_idx) + if (dc->current_context.res_ctx. + pipe_ctx[crtc_idx].stream == stream) return dc_target; } } + dm_error("%s: 'dc_target' is NULL for irq source: %d\n!", __func__, src); return NULL; } diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c index 9a5eadf..5fd5800 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c @@ -1142,8 +1142,9 @@ static void dpcd_configure_panel_mode( panel_mode_edp); } -static enum dc_status enable_link_dp(struct core_stream *stream) +static enum dc_status enable_link_dp(struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; enum dc_status status; bool skip_video_pattern; struct core_link *link = stream->sink->link; @@ -1154,7 +1155,7 @@ static enum dc_status enable_link_dp(struct core_stream *stream) decide_link_settings(stream, &link_settings); dp_enable_link_phy( stream->sink->link, - stream->signal, + pipe_ctx->signal, &link_settings); panel_mode = dp_get_panel_mode(link); @@ -1175,9 +1176,9 @@ static enum dc_status enable_link_dp(struct core_stream *stream) return status; } -static enum dc_status enable_link_dp_mst(struct core_stream *stream) +static enum dc_status enable_link_dp_mst(struct pipe_ctx *pipe_ctx) { - struct core_link *link = stream->sink->link; + struct core_link *link = pipe_ctx->stream->sink->link; /* sink signal type after MST branch is MST. Multiple MST sinks * share one link. Link DP PHY is enable or training only once. @@ -1185,11 +1186,12 @@ static enum dc_status enable_link_dp_mst(struct core_stream *stream) if (link->public.cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) return DC_OK; - return enable_link_dp(stream); + return enable_link_dp(pipe_ctx); } -static void enable_link_hdmi(struct core_stream *stream) +static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; struct core_link *link = stream->sink->link; /* enable video output */ @@ -1214,7 +1216,7 @@ static void enable_link_hdmi(struct core_stream *stream) break; } - if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) + if (pipe_ctx->signal == SIGNAL_TYPE_HDMI_TYPE_A) dal_ddc_service_write_scdc_data( stream->sink->link->ddc, normalized_pix_clk, @@ -1225,33 +1227,33 @@ static void enable_link_hdmi(struct core_stream *stream) link->link_enc->funcs->enable_tmds_output( link->link_enc, - stream->clock_source->id, + pipe_ctx->clock_source->id, stream->public.timing.display_color_depth, - stream->signal == SIGNAL_TYPE_HDMI_TYPE_A, - stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK, + pipe_ctx->signal == SIGNAL_TYPE_HDMI_TYPE_A, + pipe_ctx->signal == SIGNAL_TYPE_DVI_DUAL_LINK, stream->public.timing.pix_clk_khz); - if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) + if (pipe_ctx->signal == SIGNAL_TYPE_HDMI_TYPE_A) dal_ddc_service_read_scdc_data(link->ddc); } /****************************enable_link***********************************/ -static enum dc_status enable_link(struct core_stream *stream) +static enum dc_status enable_link(struct pipe_ctx *pipe_ctx) { enum dc_status status = DC_ERROR_UNEXPECTED; - switch (stream->signal) { + switch (pipe_ctx->signal) { case SIGNAL_TYPE_DISPLAY_PORT: case SIGNAL_TYPE_EDP: - status = enable_link_dp(stream); + status = enable_link_dp(pipe_ctx); break; case SIGNAL_TYPE_DISPLAY_PORT_MST: - status = enable_link_dp_mst(stream); - dm_sleep_in_milliseconds(stream->ctx, 200); + status = enable_link_dp_mst(pipe_ctx); + dm_sleep_in_milliseconds(pipe_ctx->stream->ctx, 200); break; case SIGNAL_TYPE_DVI_SINGLE_LINK: case SIGNAL_TYPE_DVI_DUAL_LINK: case SIGNAL_TYPE_HDMI_TYPE_A: - enable_link_hdmi(stream); + enable_link_hdmi(pipe_ctx); status = DC_OK; break; case SIGNAL_TYPE_VIRTUAL: @@ -1261,20 +1263,20 @@ static enum dc_status enable_link(struct core_stream *stream) break; } - if (stream->audio && status == DC_OK) { + if (pipe_ctx->audio && status == DC_OK) { /* notify audio driver for audio modes of monitor */ - dal_audio_enable_azalia_audio_jack_presence(stream->audio, - stream->stream_enc->id); + dal_audio_enable_azalia_audio_jack_presence(pipe_ctx->audio, + pipe_ctx->stream_enc->id); /* un-mute audio */ - dal_audio_unmute(stream->audio, stream->stream_enc->id, - stream->signal); + dal_audio_unmute(pipe_ctx->audio, pipe_ctx->stream_enc->id, + pipe_ctx->signal); } return status; } -static void disable_link(struct core_stream *stream) +static void disable_link(struct core_link *link, enum signal_type signal) { /* * TODO: implement call for dp_set_hw_test_pattern @@ -1286,21 +1288,14 @@ static void disable_link(struct core_stream *stream) * it will lead to querying dynamic link capabilities * which should be done before enable output */ - if (dc_is_dp_signal(stream->signal)) { + if (dc_is_dp_signal(signal)) { /* SST DP, eDP */ - if (dc_is_dp_sst_signal(stream->signal)) - dp_disable_link_phy( - stream->sink->link, stream->signal); - else { - dp_disable_link_phy_mst( - stream->sink->link, stream); - } - } else { - struct link_encoder *encoder = - stream->sink->link->link_enc; - - encoder->funcs->disable_output(encoder, stream->signal); - } + if (dc_is_dp_sst_signal(signal)) + dp_disable_link_phy(link, signal); + else + dp_disable_link_phy_mst(link, signal); + } else + link->link_enc->funcs->disable_output(link->link_enc, signal); } enum dc_status dc_link_validate_mode_timing( @@ -1360,9 +1355,9 @@ static struct fixed31_32 get_pbn_per_slot(struct core_stream *stream) return dal_fixed31_32_div_int(mbps, 54); } -static int get_color_depth(struct core_stream *stream) +static int get_color_depth(enum dc_color_depth color_depth) { - switch (stream->pix_clk_params.color_depth) { + switch (color_depth) { case COLOR_DEPTH_666: return 6; case COLOR_DEPTH_888: return 8; case COLOR_DEPTH_101010: return 10; @@ -1373,7 +1368,7 @@ static int get_color_depth(struct core_stream *stream) } } -static struct fixed31_32 get_pbn_from_timing(struct core_stream *stream) +static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx) { uint32_t bpc; uint64_t kbps; @@ -1381,8 +1376,8 @@ static struct fixed31_32 get_pbn_from_timing(struct core_stream *stream) uint32_t numerator; uint32_t denominator; - bpc = get_color_depth(stream); - kbps = stream->pix_clk_params.requested_pix_clk * bpc * 3; + bpc = get_color_depth(pipe_ctx->pix_clk_params.color_depth); + kbps = pipe_ctx->pix_clk_params.requested_pix_clk * bpc * 3; /* * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 @@ -1405,7 +1400,7 @@ static struct fixed31_32 get_pbn_from_timing(struct core_stream *stream) static void update_mst_stream_alloc_table( struct core_link *link, - struct core_stream *stream, + struct stream_encoder *stream_enc, const struct dp_mst_stream_allocation_table *proposed_table) { struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { @@ -1440,7 +1435,7 @@ static void update_mst_stream_alloc_table( proposed_table->stream_allocations[i].vcp_id; work_table[i].slot_count = proposed_table->stream_allocations[i].slot_count; - work_table[i].stream_enc = stream->stream_enc; + work_table[i].stream_enc = stream_enc; } } @@ -1455,11 +1450,12 @@ static void update_mst_stream_alloc_table( /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table * because stream_encoder is not exposed to dm */ -static enum dc_status allocate_mst_payload(struct core_stream *stream) +static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; struct core_link *link = stream->sink->link; struct link_encoder *link_encoder = link->link_enc; - struct stream_encoder *stream_encoder = stream->stream_enc; + struct stream_encoder *stream_encoder = pipe_ctx->stream_enc; struct dp_mst_stream_allocation_table proposed_table = {0}; struct fixed31_32 avg_time_slots_per_mtp; struct fixed31_32 pbn; @@ -1478,7 +1474,8 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) &proposed_table, true); - update_mst_stream_alloc_table(link, stream, &proposed_table); + update_mst_stream_alloc_table( + link, pipe_ctx->stream_enc, &proposed_table); dal_logger_write(link->ctx->logger, LOG_MAJOR_MST, @@ -1532,7 +1529,7 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) /* slot X.Y for only current stream */ pbn_per_slot = get_pbn_per_slot(stream); - pbn = get_pbn_from_timing(stream); + pbn = get_pbn_from_timing(pipe_ctx); avg_time_slots_per_mtp = dal_fixed31_32_div(pbn, pbn_per_slot); @@ -1545,11 +1542,12 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) } -static enum dc_status deallocate_mst_payload(struct core_stream *stream) +static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; struct core_link *link = stream->sink->link; struct link_encoder *link_encoder = link->link_enc; - struct stream_encoder *stream_encoder = stream->stream_enc; + struct stream_encoder *stream_encoder = pipe_ctx->stream_enc; struct dp_mst_stream_allocation_table proposed_table = {0}; struct fixed31_32 avg_time_slots_per_mtp = dal_fixed31_32_from_int(0); uint8_t i; @@ -1575,7 +1573,8 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream) &proposed_table, false); - update_mst_stream_alloc_table(link, stream, &proposed_table); + update_mst_stream_alloc_table( + link, pipe_ctx->stream_enc, &proposed_table); dal_logger_write(link->ctx->logger, LOG_MAJOR_MST, @@ -1618,38 +1617,32 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream) return DC_OK; } -void core_link_enable_stream( - struct core_link *link, - struct core_stream *stream) +void core_link_enable_stream(struct pipe_ctx *pipe_ctx) { - struct dc *dc = stream->ctx->dc; + struct dc *dc = pipe_ctx->stream->ctx->dc; - if (DC_OK != enable_link(stream)) { + if (DC_OK != enable_link(pipe_ctx)) { BREAK_TO_DEBUGGER(); return; } - dc->hwss.enable_stream(stream); - stream->status.link = &link->public; + dc->hwss.enable_stream(pipe_ctx); - if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) - allocate_mst_payload(stream); + if (pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + allocate_mst_payload(pipe_ctx); } -void core_link_disable_stream( - struct core_link *link, - struct core_stream *stream) +void core_link_disable_stream(struct pipe_ctx *pipe_ctx) { - struct dc *dc = stream->ctx->dc; - - if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) - deallocate_mst_payload(stream); + struct dc *dc = pipe_ctx->stream->ctx->dc; - stream->status.link = NULL; - dc->hwss.disable_stream(stream); + pipe_ctx->stream->status.link = NULL; + if (pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + deallocate_mst_payload(pipe_ctx); - disable_link(stream); + dc->hwss.disable_stream(pipe_ctx); + disable_link(pipe_ctx->stream->sink->link, pipe_ctx->signal); } diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c index 92d70ed..04a0c17 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c @@ -93,13 +93,13 @@ void dp_disable_link_phy(struct core_link *link, enum signal_type signal) sizeof(link->public.cur_link_settings)); } -void dp_disable_link_phy_mst(struct core_link *link, struct core_stream *stream) +void dp_disable_link_phy_mst(struct core_link *link, enum signal_type signal) { /* MST disable link only when no stream use the link */ if (link->mst_stream_alloc_table.stream_count > 0) return; - dp_disable_link_phy(link, stream->signal); + dp_disable_link_phy(link, signal); } bool dp_set_hw_training_pattern( diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c index ec6db8d..70bf935 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c @@ -99,13 +99,13 @@ bool is_same_timing( } static bool is_sharable_clk_src( - const struct core_stream *stream_with_clk_src, - const struct core_stream *stream) + const struct pipe_ctx *pipe_with_clk_src, + const struct pipe_ctx *pipe) { - enum clock_source_id id = stream_with_clk_src->clock_source->id; + enum clock_source_id id = pipe_with_clk_src->clock_source->id; #if defined(CONFIG_DRM_AMD_DAL_DCE10_0) enum dce_version dce_ver = dal_adapter_service_get_dce_version( - stream->sink->link->adapter_srv); + pipe->stream->sink->link->adapter_srv); /* Currently no clocks are shared for DCE 10 until VBIOS behaviour * is verified for this use case @@ -114,37 +114,32 @@ static bool is_sharable_clk_src( return false; #endif - if (stream_with_clk_src->clock_source == NULL) + if (pipe_with_clk_src->clock_source == NULL) return false; if (id == CLOCK_SOURCE_ID_EXTERNAL) return false; - if(!is_same_timing( - &stream_with_clk_src->public.timing, &stream->public.timing)) + &pipe_with_clk_src->stream->public.timing, + &pipe->stream->public.timing)) return false; return true; } struct clock_source *find_used_clk_src_for_sharing( - struct validate_context *context, - struct core_stream *stream) + struct resource_context *res_ctx, + struct pipe_ctx *pipe_ctx) { - uint8_t i, j; - for (i = 0; i < context->target_count; i++) { - struct core_target *target = context->targets[i]; - for (j = 0; j < target->public.stream_count; j++) { - struct core_stream *clock_source_stream = - DC_STREAM_TO_CORE(target->public.streams[j]); + uint8_t i; - if (clock_source_stream->clock_source == NULL) - continue; + for (i = 0; i < MAX_PIPES; i++) { + if (res_ctx->pipe_ctx[i].clock_source == NULL) + continue; - if (is_sharable_clk_src(clock_source_stream, stream)) - return clock_source_stream->clock_source; - } + if (is_sharable_clk_src(&res_ctx->pipe_ctx[i], pipe_ctx)) + return res_ctx->pipe_ctx[i].clock_source; } return NULL; @@ -236,7 +231,7 @@ static enum pixel_format convert_pixel_format_to_dalsurface( static void calculate_viewport( const struct dc_surface *surface, - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { const struct rect src = surface->src_rect; const struct rect clip = surface->clip_rect; @@ -245,61 +240,59 @@ static void calculate_viewport( /* offset = src.ofs + (clip.ofs - dst.ofs) * scl_ratio * num_pixels = clip.num_pix * scl_ratio */ - stream->viewport.x = src.x + (clip.x - dst.x) * src.width / dst.width; - stream->viewport.width = clip.width * src.width / dst.width; + pipe_ctx->viewport.x = src.x + (clip.x - dst.x) * src.width / dst.width; + pipe_ctx->viewport.width = clip.width * src.width / dst.width; - stream->viewport.y = src.y + (clip.y - dst.y) * src.height / dst.height; - stream->viewport.height = clip.height * src.height / dst.height; + pipe_ctx->viewport.y = src.y + (clip.y - dst.y) * src.height / dst.height; + pipe_ctx->viewport.height = clip.height * src.height / dst.height; /* Minimum viewport such that 420/422 chroma vp is non 0 */ - if (stream->viewport.width < 2) - { - stream->viewport.width = 2; - } - if (stream->viewport.height < 2) - { - stream->viewport.height = 2; - } + if (pipe_ctx->viewport.width < 2) + pipe_ctx->viewport.width = 2; + if (pipe_ctx->viewport.height < 2) + pipe_ctx->viewport.height = 2; } static void calculate_overscan( const struct dc_surface *surface, - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { - stream->overscan.left = stream->public.dst.x; + struct core_stream *stream = pipe_ctx->stream; + + pipe_ctx->overscan.left = stream->public.dst.x; if (stream->public.src.x < surface->clip_rect.x) - stream->overscan.left += (surface->clip_rect.x + pipe_ctx->overscan.left += (surface->clip_rect.x - stream->public.src.x) * stream->public.dst.width / stream->public.src.width; - stream->overscan.right = stream->public.timing.h_addressable + pipe_ctx->overscan.right = stream->public.timing.h_addressable - stream->public.dst.x - stream->public.dst.width; if (stream->public.src.x + stream->public.src.width > surface->clip_rect.x + surface->clip_rect.width) - stream->overscan.right = stream->public.timing.h_addressable - + pipe_ctx->overscan.right = stream->public.timing.h_addressable - dal_fixed31_32_floor(dal_fixed31_32_div( dal_fixed31_32_from_int( - stream->viewport.width), - stream->ratios.horz)) - - stream->overscan.left; + pipe_ctx->viewport.width), + pipe_ctx->ratios.horz)) - + pipe_ctx->overscan.left; - stream->overscan.top = stream->public.dst.y; + pipe_ctx->overscan.top = stream->public.dst.y; if (stream->public.src.y < surface->clip_rect.y) - stream->overscan.top += (surface->clip_rect.y + pipe_ctx->overscan.top += (surface->clip_rect.y - stream->public.src.y) * stream->public.dst.height / stream->public.src.height; - stream->overscan.bottom = stream->public.timing.v_addressable + pipe_ctx->overscan.bottom = stream->public.timing.v_addressable - stream->public.dst.y - stream->public.dst.height; if (stream->public.src.y + stream->public.src.height > surface->clip_rect.y + surface->clip_rect.height) - stream->overscan.bottom = stream->public.timing.v_addressable - + pipe_ctx->overscan.bottom = stream->public.timing.v_addressable - dal_fixed31_32_floor(dal_fixed31_32_div( dal_fixed31_32_from_int( - stream->viewport.height), - stream->ratios.vert)) - - stream->overscan.top; + pipe_ctx->viewport.height), + pipe_ctx->ratios.vert)) - + pipe_ctx->overscan.top; /* TODO: Add timing overscan to finalize overscan calculation*/ @@ -307,81 +300,81 @@ static void calculate_overscan( static void calculate_scaling_ratios( const struct dc_surface *surface, - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; const uint32_t in_w = stream->public.src.width; const uint32_t in_h = stream->public.src.height; const uint32_t out_w = stream->public.dst.width; const uint32_t out_h = stream->public.dst.height; - stream->ratios.horz = dal_fixed31_32_from_fraction( + pipe_ctx->ratios.horz = dal_fixed31_32_from_fraction( surface->src_rect.width, surface->dst_rect.width); - stream->ratios.vert = dal_fixed31_32_from_fraction( + pipe_ctx->ratios.vert = dal_fixed31_32_from_fraction( surface->src_rect.height, surface->dst_rect.height); if (surface->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE) - stream->ratios.horz.value *= 2; + pipe_ctx->ratios.horz.value *= 2; else if (surface->stereo_format == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM) - stream->ratios.vert.value *= 2; + pipe_ctx->ratios.vert.value *= 2; - stream->ratios.vert.value = div64_s64(stream->ratios.vert.value * in_h, + pipe_ctx->ratios.vert.value = div64_s64(pipe_ctx->ratios.vert.value * in_h, out_h); - stream->ratios.horz.value = div64_s64(stream->ratios.horz.value * in_w , + pipe_ctx->ratios.horz.value = div64_s64(pipe_ctx->ratios.horz.value * in_w, out_w); - stream->ratios.horz_c = stream->ratios.horz; - stream->ratios.vert_c = stream->ratios.vert; + pipe_ctx->ratios.horz_c = pipe_ctx->ratios.horz; + pipe_ctx->ratios.vert_c = pipe_ctx->ratios.vert; - if (stream->format == PIXEL_FORMAT_420BPP12) { - stream->ratios.horz_c.value /= 2; - stream->ratios.vert_c.value /= 2; - } else if (stream->format == PIXEL_FORMAT_422BPP16) { - stream->ratios.horz_c.value /= 2; + if (pipe_ctx->format == PIXEL_FORMAT_420BPP12) { + pipe_ctx->ratios.horz_c.value /= 2; + pipe_ctx->ratios.vert_c.value /= 2; + } else if (pipe_ctx->format == PIXEL_FORMAT_422BPP16) { + pipe_ctx->ratios.horz_c.value /= 2; } } -/*TODO: per pipe not per stream*/ void build_scaling_params( const struct dc_surface *surface, - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { /* Important: scaling ratio calculation requires pixel format, * overscan calculation requires scaling ratios and viewport * and lb depth/taps calculation requires overscan. Call sequence * is therefore important */ - stream->format = convert_pixel_format_to_dalsurface(surface->format); + pipe_ctx->format = convert_pixel_format_to_dalsurface(surface->format); - calculate_viewport(surface, stream); + calculate_viewport(surface, pipe_ctx); - calculate_scaling_ratios(surface, stream); + calculate_scaling_ratios(surface, pipe_ctx); - calculate_overscan(surface, stream); + calculate_overscan(surface, pipe_ctx); /* Check if scaling is required update taps if not */ - if (dal_fixed31_32_u2d19(stream->ratios.horz) == 1 << 19) - stream->taps.h_taps = 1; + if (dal_fixed31_32_u2d19(pipe_ctx->ratios.horz) == 1 << 19) + pipe_ctx->taps.h_taps = 1; else - stream->taps.h_taps = surface->scaling_quality.h_taps; + pipe_ctx->taps.h_taps = surface->scaling_quality.h_taps; - if (dal_fixed31_32_u2d19(stream->ratios.horz_c) == 1 << 19) - stream->taps.h_taps_c = 1; + if (dal_fixed31_32_u2d19(pipe_ctx->ratios.horz_c) == 1 << 19) + pipe_ctx->taps.h_taps_c = 1; else - stream->taps.h_taps_c = surface->scaling_quality.h_taps_c; + pipe_ctx->taps.h_taps_c = surface->scaling_quality.h_taps_c; - if (dal_fixed31_32_u2d19(stream->ratios.vert) == 1 << 19) - stream->taps.v_taps = 1; + if (dal_fixed31_32_u2d19(pipe_ctx->ratios.vert) == 1 << 19) + pipe_ctx->taps.v_taps = 1; else - stream->taps.v_taps = surface->scaling_quality.v_taps; + pipe_ctx->taps.v_taps = surface->scaling_quality.v_taps; - if (dal_fixed31_32_u2d19(stream->ratios.vert_c) == 1 << 19) - stream->taps.v_taps_c = 1; + if (dal_fixed31_32_u2d19(pipe_ctx->ratios.vert_c) == 1 << 19) + pipe_ctx->taps.v_taps_c = 1; else - stream->taps.v_taps_c = surface->scaling_quality.v_taps_c; + pipe_ctx->taps.v_taps_c = surface->scaling_quality.v_taps_c; - dal_logger_write(stream->ctx->logger, + dal_logger_write(pipe_ctx->stream->ctx->logger, LOG_MAJOR_DCP, LOG_MINOR_DCP_SCALER, "%s: Overscan:\n bot:%d left:%d right:%d " @@ -389,14 +382,14 @@ void build_scaling_params( "y:%d\n dst_rect:\nheight:%d width:%d x:%d " "y:%d\n", __func__, - stream->overscan.bottom, - stream->overscan.left, - stream->overscan.right, - stream->overscan.top, - stream->viewport.height, - stream->viewport.width, - stream->viewport.x, - stream->viewport.y, + pipe_ctx->overscan.bottom, + pipe_ctx->overscan.left, + pipe_ctx->overscan.right, + pipe_ctx->overscan.top, + pipe_ctx->viewport.height, + pipe_ctx->viewport.width, + pipe_ctx->viewport.x, + pipe_ctx->viewport.y, surface->dst_rect.height, surface->dst_rect.width, surface->dst_rect.x, @@ -407,32 +400,25 @@ void build_scaling_params_for_context( const struct dc *dc, struct validate_context *context) { - uint8_t i, j, k; - for (i = 0; i < context->target_count; i++) { - struct core_target *target = context->targets[i]; - if (context->target_flags[i].unchanged) - continue; - for (j = 0; j < target->status.surface_count; j++) { - const struct dc_surface *surface = - target->status.surfaces[j]; - for (k = 0; k < target->public.stream_count; k++) { - struct core_stream *stream = - DC_STREAM_TO_CORE( - target->public.streams[k]); - - build_scaling_params(surface, stream); - } - } + uint8_t i; + + for (i = 0; i < MAX_PIPES; i++) { + if (context->res_ctx.pipe_ctx[i].surface != NULL && + context->res_ctx.pipe_ctx[i].stream != NULL) + build_scaling_params( + &context->res_ctx.pipe_ctx[i].surface->public, + &context->res_ctx.pipe_ctx[i]); } } -bool logical_attach_surfaces_to_target( +bool attach_surfaces_to_context( struct dc_surface *surfaces[], uint8_t surface_count, - struct dc_target *dc_target) + struct dc_target *dc_target, + struct validate_context *context) { - uint8_t i; - struct core_target *target = DC_TARGET_TO_CORE(dc_target); + uint8_t i, j, k; + struct dc_target_status *target_status = NULL; if (surface_count > MAX_SURFACE_NUM) { dm_error("Surface: can not attach %d surfaces! Maximum is: %d\n", @@ -440,16 +426,46 @@ bool logical_attach_surfaces_to_target( return false; } - for (i = 0; i < target->status.surface_count; i++) - dc_surface_release(target->status.surfaces[i]); + for (i = 0; i < context->target_count; i++) + if (&context->targets[i]->public == dc_target) { + target_status = &context->target_status[i]; + break; + } + if (target_status == NULL) { + dm_error("Existing target not found; failed to attach surfaces\n"); + return false; + } + + for (i = 0; i < target_status->surface_count; i++) + dc_surface_release(target_status->surfaces[i]); for (i = 0; i < surface_count; i++) { - struct core_surface *surface = DC_SURFACE_TO_CORE(surfaces[i]); - surface->status.dc_target = &target->public; - target->status.surfaces[i] = surfaces[i]; - dc_surface_retain(target->status.surfaces[i]); + target_status->surfaces[i] = surfaces[i]; + dc_surface_retain(target_status->surfaces[i]); + } + target_status->surface_count = surface_count; + + for (i = 0; i < dc_target->stream_count; i++) { + k = 0; + for (j = 0; j < MAX_PIPES; j++) { + struct core_surface *surface = + DC_SURFACE_TO_CORE(surfaces[k]); + + if (context->res_ctx.pipe_ctx[j].stream != + DC_STREAM_TO_CORE(dc_target->streams[i])) + continue; + if (k == surface_count) { + /* this means there are more pipes per stream + * than there are planes and makes no sense + */ + BREAK_TO_DEBUGGER(); + continue; + } + + context->res_ctx.pipe_ctx[j].surface = surface; + k++; + } } - target->status.surface_count = surface_count; return true; } @@ -492,13 +508,21 @@ static void fill_display_configs( for (j = 0; j < target->public.stream_count; j++) { const struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); + DC_STREAM_TO_CORE(target->public.streams[j]); struct dc_pp_single_disp_config *cfg = &pp_display_cfg->disp_configs[num_cfgs]; + const struct pipe_ctx *pipe_ctx = NULL; + + for (j = 0; j < MAX_PIPES; j++) + if (stream == + context->res_ctx.pipe_ctx[j].stream) { + pipe_ctx = &context->res_ctx.pipe_ctx[j]; + break; + } num_cfgs++; - cfg->signal = stream->signal; - cfg->pipe_idx = stream->opp->inst; + cfg->signal = pipe_ctx->signal; + cfg->pipe_idx = pipe_ctx->pipe_idx; cfg->src_height = stream->public.src.height; cfg->src_width = stream->public.src.width; cfg->ddi_channel_mapping = @@ -582,13 +606,6 @@ void pplib_apply_display_requirements( /* Maximum TMDS single link pixel clock 165MHz */ #define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000 -static void attach_stream_to_controller( - struct resource_context *res_ctx, - struct core_stream *stream) -{ - res_ctx->controller_ctx[stream->controller_idx].stream = stream; -} - static void set_stream_engine_in_use( struct resource_context *res_ctx, struct stream_encoder *stream_enc) @@ -614,24 +631,28 @@ static void set_audio_in_use( } } -static bool assign_first_free_controller( +static int8_t acquire_first_free_pipe( struct resource_context *res_ctx, struct core_stream *stream) { uint8_t i; - for (i = 0; i < res_ctx->pool.controller_count; i++) { - if (!res_ctx->controller_ctx[i].stream) { - stream->tg = res_ctx->pool.timing_generators[i]; - stream->mi = res_ctx->pool.mis[i]; - stream->ipp = res_ctx->pool.ipps[i]; - stream->xfm = res_ctx->pool.transforms[i]; - stream->opp = res_ctx->pool.opps[i]; - stream->controller_idx = i; - stream->dis_clk = res_ctx->pool.display_clock; - return true; + for (i = 0; i < res_ctx->pool.pipe_count; i++) { + if (!res_ctx->pipe_ctx[i].stream) { + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; + + pipe_ctx->tg = res_ctx->pool.timing_generators[i]; + pipe_ctx->mi = res_ctx->pool.mis[i]; + pipe_ctx->ipp = res_ctx->pool.ipps[i]; + pipe_ctx->xfm = res_ctx->pool.transforms[i]; + pipe_ctx->opp = res_ctx->pool.opps[i]; + pipe_ctx->dis_clk = res_ctx->pool.display_clock; + pipe_ctx->pipe_idx = i; + + pipe_ctx->stream = stream; + return i; } } - return false; + return -1; } static struct stream_encoder *find_first_free_match_stream_enc_for_link( @@ -704,9 +725,10 @@ static bool check_timing_change(struct core_stream *cur_stream, &new_stream->public.timing); } -static void set_stream_signal(struct core_stream *stream) +static void set_stream_signal(struct pipe_ctx *pipe_ctx) { - struct dc_sink *dc_sink = (struct dc_sink *)stream->public.sink; + struct dc_sink *dc_sink = + (struct dc_sink *) pipe_ctx->stream->public.sink; /* For asic supports dual link DVI, we should adjust signal type * based on timing pixel clock. If pixel clock more than 165Mhz, @@ -714,21 +736,21 @@ static void set_stream_signal(struct core_stream *stream) */ if (dc_sink->sink_signal == SIGNAL_TYPE_DVI_SINGLE_LINK || dc_sink->sink_signal == SIGNAL_TYPE_DVI_DUAL_LINK) { - if (stream->public.timing.pix_clk_khz > - TMDS_MAX_PIXEL_CLOCK_IN_KHZ) + if (pipe_ctx->stream->public.timing.pix_clk_khz > + TMDS_MAX_PIXEL_CLOCK_IN_KHZ) dc_sink->sink_signal = SIGNAL_TYPE_DVI_DUAL_LINK; else dc_sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK; } - stream->signal = dc_sink->sink_signal; + pipe_ctx->signal = dc_sink->sink_signal; } enum dc_status map_resources( const struct dc *dc, struct validate_context *context) { - uint8_t i, j; + uint8_t i, j, k; /* mark resources used for targets that are already active */ for (i = 0; i < context->target_count; i++) { @@ -741,21 +763,29 @@ enum dc_status map_resources( struct core_stream *stream = DC_STREAM_TO_CORE(target->public.streams[j]); - attach_stream_to_controller( - &context->res_ctx, - stream); + for (k = 0; k < MAX_PIPES; k++) { + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[k]; - set_stream_engine_in_use( - &context->res_ctx, - stream->stream_enc); + if (dc->current_context.res_ctx.pipe_ctx[k].stream + != stream) + continue; - reference_clock_source( - &context->res_ctx, - stream->clock_source); + *pipe_ctx = + dc->current_context.res_ctx.pipe_ctx[k]; + pipe_ctx->flags.timing_changed = false; + pipe_ctx->flags.unchanged = true; + + set_stream_engine_in_use( + &context->res_ctx, + pipe_ctx->stream_enc); + + reference_clock_source( + &context->res_ctx, + pipe_ctx->clock_source); - if (stream->audio) { set_audio_in_use(&context->res_ctx, - stream->audio); + pipe_ctx->audio); } } } @@ -768,49 +798,48 @@ enum dc_status map_resources( continue; for (j = 0; j < target->public.stream_count; j++) { + struct pipe_ctx *pipe_ctx = NULL; struct core_stream *stream = DC_STREAM_TO_CORE(target->public.streams[j]); struct core_stream *curr_stream; - if (!assign_first_free_controller( - &context->res_ctx, stream)) + int8_t pipe_idx = acquire_first_free_pipe( + &context->res_ctx, stream); + if (pipe_idx < 0) return DC_NO_CONTROLLER_RESOURCE; - attach_stream_to_controller(&context->res_ctx, stream); - - set_stream_signal(stream); + pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; + set_stream_signal(pipe_ctx); curr_stream = - dc->current_context.res_ctx.controller_ctx - [stream->controller_idx].stream; - context->res_ctx.controller_ctx[stream->controller_idx] - .flags.timing_changed = + dc->current_context.res_ctx.pipe_ctx[pipe_idx].stream; + context->res_ctx.pipe_ctx[pipe_idx].flags.timing_changed = check_timing_change(curr_stream, stream); - stream->stream_enc = + pipe_ctx->stream_enc = find_first_free_match_stream_enc_for_link( &context->res_ctx, stream->sink->link); - if (!stream->stream_enc) + if (!pipe_ctx->stream_enc) return DC_NO_STREAM_ENG_RESOURCE; set_stream_engine_in_use( &context->res_ctx, - stream->stream_enc); + pipe_ctx->stream_enc); /* TODO: Add check if ASIC support and EDID audio */ if (!stream->sink->converter_disable_audio && dc_is_audio_capable_signal( - stream->signal)) { - stream->audio = find_first_free_audio( + pipe_ctx->signal)) { + pipe_ctx->audio = find_first_free_audio( &context->res_ctx); - if (!stream->audio) + if (!pipe_ctx->audio) return DC_NO_STREAM_AUDIO_RESOURCE; set_audio_in_use(&context->res_ctx, - stream->audio); + pipe_ctx->audio); } } } @@ -819,13 +848,13 @@ enum dc_status map_resources( } static enum ds_color_space build_default_color_space( - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { enum ds_color_space color_space = DS_COLOR_SPACE_SRGB_FULLRANGE; - struct dc_crtc_timing *timing = &stream->public.timing; + struct dc_crtc_timing *timing = &pipe_ctx->stream->public.timing; - switch (stream->signal) { + switch (pipe_ctx->signal) { /* TODO: implement other signal color space setting */ case SIGNAL_TYPE_DISPLAY_PORT: case SIGNAL_TYPE_DISPLAY_PORT_MST: @@ -934,9 +963,11 @@ static void translate_info_frame(const struct hw_info_frame *hw_info_frame, } } -static void set_avi_info_frame(struct hw_info_packet *info_packet, - struct core_stream *stream) +static void set_avi_info_frame( + struct hw_info_packet *info_packet, + struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; enum ds_color_space color_space = DS_COLOR_SPACE_UNKNOWN; struct info_frame info_frame = { {0} }; uint32_t pixel_encoding = 0; @@ -950,7 +981,7 @@ static void set_avi_info_frame(struct hw_info_packet *info_packet, if (info_packet == NULL) return; - color_space = build_default_color_space(stream); + color_space = build_default_color_space(pipe_ctx); /* Initialize header */ info_frame.avi_info_packet.info_packet_hdmi.bits.header. @@ -1223,7 +1254,7 @@ static void set_vendor_info_packet(struct core_stream *stream, info_packet->valid = true; } -void build_info_frame(struct core_stream *stream) +void build_info_frame(struct pipe_ctx *pipe_ctx) { enum signal_type signal = SIGNAL_TYPE_NONE; struct hw_info_frame info_frame = { { 0 } }; @@ -1235,15 +1266,16 @@ void build_info_frame(struct core_stream *stream) info_frame.spd_packet.valid = false; info_frame.vsc_packet.valid = false; - signal = stream->sink->public.sink_signal; + signal = pipe_ctx->stream->sink->public.sink_signal; /* HDMi and DP have different info packets*/ if (signal == SIGNAL_TYPE_HDMI_TYPE_A) { - set_avi_info_frame(&info_frame.avi_info_packet, - stream); - set_vendor_info_packet(stream, &info_frame.vendor_info_packet); + set_avi_info_frame( + &info_frame.avi_info_packet, pipe_ctx); + set_vendor_info_packet( + pipe_ctx->stream, &info_frame.vendor_info_packet); } translate_info_frame(&info_frame, - &stream->encoder_info_frame); + &pipe_ctx->encoder_info_frame); } diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c index e8579bc..f00b5af 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c @@ -65,12 +65,20 @@ static void construct( static void destruct(struct core_target *core_target) { - int i; + int i, j; + struct validate_context *context = + &core_target->ctx->dc->current_context; - for (i = 0; i < core_target->status.surface_count; i++) { - dc_surface_release(core_target->status.surfaces[i]); - core_target->status.surfaces[i] = NULL; + for (i = 0; i < context->target_count; i++) { + if (context->targets[i] != core_target) + continue; + for (j = 0; j < context->target_status[i].surface_count; j++) + dc_surface_release( + context->target_status[i].surfaces[j]); + context->target_status[i].surface_count = 0; + break; } + for (i = 0; i < core_target->public.stream_count; i++) { dc_stream_release( (struct dc_stream *)core_target->public.streams[i]); @@ -101,8 +109,15 @@ void dc_target_release(struct dc_target *dc_target) const struct dc_target_status *dc_target_get_status( const struct dc_target* dc_target) { + uint8_t i; struct core_target* target = DC_TARGET_TO_CORE(dc_target); - return &target->status; + struct dc *dc = target->ctx->dc; + + for (i = 0; i < dc->current_context.target_count; i++) + if (target == dc->current_context.targets[i]) + return &dc->current_context.target_status[i]; + + return NULL; } struct dc_target *dc_create_target_for_streams( @@ -169,26 +184,28 @@ bool dc_commit_surfaces_to_target( int i, j; uint32_t prev_disp_clk = dc->current_context.bw_results.dispclk_khz; struct core_target *target = DC_TARGET_TO_CORE(dc_target); - + struct dc_target_status *status = NULL; + struct validate_context *context; int current_enabled_surface_count = 0; int new_enabled_surface_count = 0; - if (!dal_adapter_service_is_in_accelerated_mode( - dc->res_pool.adapter_srv) || - dc->current_context.target_count == 0) { - return false; - } - - for (i = 0; i < dc->current_context.target_count; i++) - if (target == dc->current_context.targets[i]) - break; + context = dm_alloc(dc->ctx, sizeof(struct validate_context)); + *context = dc->current_context; /* Cannot commit surface to a target that is not commited */ - if (i == dc->current_context.target_count) - return false; + for (i = 0; i < context->target_count; i++) + if (target == context->targets[i]) + break; + status = &context->target_status[i]; + if (!dal_adapter_service_is_in_accelerated_mode( + dc->res_pool.adapter_srv) + || i == context->target_count) { + BREAK_TO_DEBUGGER(); + goto unexpected_fail; + } - for (i = 0; i < target->status.surface_count; i++) - if (target->status.surfaces[i]->visible) + for (i = 0; i < status->surface_count; i++) + if (status->surfaces[i]->visible) current_enabled_surface_count++; for (i = 0; i < new_surface_count; i++) @@ -204,83 +221,100 @@ bool dc_commit_surfaces_to_target( dc_target); - if (!logical_attach_surfaces_to_target( - new_surfaces, - new_surface_count, - dc_target)) { + if (!attach_surfaces_to_context( + new_surfaces, new_surface_count, dc_target, context)) { BREAK_TO_DEBUGGER(); goto unexpected_fail; } for (i = 0; i < new_surface_count; i++) - for (j = 0; j < target->public.stream_count; j++) + for (j = 0; j < MAX_PIPES; j++) { + if (context->res_ctx.pipe_ctx[j].surface != + DC_SURFACE_TO_CORE(new_surfaces[i])) + continue; + build_scaling_params( - new_surfaces[i], - DC_STREAM_TO_CORE(target->public.streams[j])); + new_surfaces[i], &context->res_ctx.pipe_ctx[j]); + } - if (dc->res_pool.funcs->validate_bandwidth(dc, &dc->current_context) - != DC_OK) { + if (dc->res_pool.funcs->validate_bandwidth(dc, context) != DC_OK) { BREAK_TO_DEBUGGER(); goto unexpected_fail; } - if (prev_disp_clk < dc->current_context.bw_results.dispclk_khz) { - dc->hwss.program_bw(dc, &dc->current_context); - pplib_apply_display_requirements(dc, &dc->current_context, - &dc->current_context.pp_display_cfg); + if (prev_disp_clk < context->bw_results.dispclk_khz) { + dc->hwss.program_bw(dc, context); + pplib_apply_display_requirements(dc, context, + &context->pp_display_cfg); } if (current_enabled_surface_count > 0 && new_enabled_surface_count == 0) dc_target_disable_memory_requests(dc_target); - for (i = 0; i < new_surface_count; i++) { - struct dc_surface *surface = new_surfaces[i]; - struct core_surface *core_surface = DC_SURFACE_TO_CORE(surface); - struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[0]); - bool is_valid_address = - validate_surface_address(surface->address); - - - dal_logger_write(dc->ctx->logger, - LOG_MAJOR_INTERFACE_TRACE, - LOG_MINOR_COMPONENT_DC, - "0x%x:", - surface); - - if (surface->gamma_correction) { - struct core_gamma *gamma = DC_GAMMA_TO_CORE( - surface->gamma_correction); - - dc->hwss.set_gamma_correction( - stream->ipp, - stream->opp, - gamma, core_surface); + for (i = 0; i < new_surface_count; i++) + for (j = 0; j < MAX_PIPES; j++) { + struct dc_surface *dc_surface = new_surfaces[i]; + struct core_surface *surface = + DC_SURFACE_TO_CORE(dc_surface); + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[j]; + + if (pipe_ctx->surface != + DC_SURFACE_TO_CORE(new_surfaces[i])) + continue; + + dal_logger_write(dc->ctx->logger, + LOG_MAJOR_INTERFACE_TRACE, + LOG_MINOR_COMPONENT_DC, + "Pipe:%d 0x%x: src: %d, %d, %d," + " %d; dst: %d, %d, %d, %d;\n", + pipe_ctx->pipe_idx, + dc_surface, + dc_surface->src_rect.x, + dc_surface->src_rect.y, + dc_surface->src_rect.width, + dc_surface->src_rect.height, + dc_surface->dst_rect.x, + dc_surface->dst_rect.y, + dc_surface->dst_rect.width, + dc_surface->dst_rect.height); + + if (dc_surface->gamma_correction) { + struct core_gamma *gamma = DC_GAMMA_TO_CORE( + dc_surface->gamma_correction); + + dc->hwss.set_gamma_correction( + pipe_ctx->ipp, + pipe_ctx->opp, + gamma, surface); + } + + dc->hwss.set_plane_config(dc, surface, pipe_ctx); + + if (validate_surface_address(dc_surface->address)) + dc->hwss.update_plane_addrs( + dc, &context->res_ctx, surface); } - dc->hwss.set_plane_config(dc, core_surface, target); - - if (is_valid_address) - dc->hwss.update_plane_address(dc, core_surface, target); - } - if (current_enabled_surface_count == 0 && new_enabled_surface_count > 0) dc_target_enable_memory_requests(dc_target); /* Lower display clock if necessary */ - if (prev_disp_clk > dc->current_context.bw_results.dispclk_khz) { - dc->hwss.program_bw(dc, &dc->current_context); - pplib_apply_display_requirements(dc, &dc->current_context, - &dc->current_context.pp_display_cfg); + if (prev_disp_clk > context->bw_results.dispclk_khz) { + dc->hwss.program_bw(dc, context); + pplib_apply_display_requirements(dc, context, + &context->pp_display_cfg); } + dc->current_context = *context; + dm_free(dc->ctx, context); return true; unexpected_fail: for (i = 0; i < new_surface_count; i++) { - target->status.surfaces[i] = NULL; + status->surfaces[i] = NULL; } - target->status.surface_count = 0; + status->surface_count = 0; return false; } @@ -298,38 +332,48 @@ bool dc_target_is_connected_to_sink( return false; } -void dc_target_enable_memory_requests(struct dc_target *target) +void dc_target_enable_memory_requests(struct dc_target *dc_target) { - uint8_t i; - struct core_target *core_target = DC_TARGET_TO_CORE(target); - for (i = 0; i < core_target->public.stream_count; i++) { - struct timing_generator *tg = - DC_STREAM_TO_CORE(core_target->public.streams[i])->tg; + uint8_t i, j; + struct core_target *target = DC_TARGET_TO_CORE(dc_target); + struct resource_context *res_ctx = + &target->ctx->dc->current_context.res_ctx; + + for (i = 0; i < target->public.stream_count; i++) { + for (j = 0; j < MAX_PIPES; j++) { + struct timing_generator *tg = res_ctx->pipe_ctx[j].tg; + + if (res_ctx->pipe_ctx[j].stream != + DC_STREAM_TO_CORE(target->public.streams[i])) + continue; - if (!tg->funcs->set_blank(tg, false)) { - dm_error("DC: failed to unblank crtc!\n"); - BREAK_TO_DEBUGGER(); + if (!tg->funcs->set_blank(tg, false)) { + dm_error("DC: failed to unblank crtc!\n"); + BREAK_TO_DEBUGGER(); + } } } } -void dc_target_disable_memory_requests(struct dc_target *target) +void dc_target_disable_memory_requests(struct dc_target *dc_target) { - uint8_t i; - struct core_target *core_target = DC_TARGET_TO_CORE(target); - for (i = 0; i < core_target->public.stream_count; i++) { - struct timing_generator *tg = - DC_STREAM_TO_CORE(core_target->public.streams[i])->tg; + uint8_t i, j; + struct core_target *target = DC_TARGET_TO_CORE(dc_target); + struct resource_context *res_ctx = + &target->ctx->dc->current_context.res_ctx; - if (NULL == tg) { - dm_error("DC: timing generator is NULL!\n"); - BREAK_TO_DEBUGGER(); - continue; - } + for (i = 0; i < target->public.stream_count; i++) { + for (j = 0; j < MAX_PIPES; j++) { + struct timing_generator *tg = res_ctx->pipe_ctx[j].tg; + + if (res_ctx->pipe_ctx[j].stream != + DC_STREAM_TO_CORE(target->public.streams[i])) + continue; - if (false == tg->funcs->set_blank(tg, true)) { - dm_error("DC: failed to blank crtc!\n"); - BREAK_TO_DEBUGGER(); + if (!tg->funcs->set_blank(tg, true)) { + dm_error("DC: failed to blank crtc!\n"); + BREAK_TO_DEBUGGER(); + } } } } @@ -341,25 +385,42 @@ bool dc_target_set_cursor_attributes( struct dc_target *dc_target, const struct dc_cursor_attributes *attributes) { - struct core_target *core_target; - struct input_pixel_processor *ipp; + uint8_t i, j; + struct core_target *target; + struct resource_context *res_ctx; if (NULL == dc_target) { dm_error("DC: dc_target is NULL!\n"); return false; } + if (NULL == attributes) { + dm_error("DC: attributes is NULL!\n"); + return false; - core_target = DC_TARGET_TO_CORE(dc_target); - ipp = DC_STREAM_TO_CORE(core_target->public.streams[0])->ipp; - - if (NULL == ipp) { - dm_error("DC: input pixel processor is NULL!\n"); - return false; } - if (true == ipp->funcs->ipp_cursor_set_attributes(ipp, attributes)) - return true; + target = DC_TARGET_TO_CORE(dc_target); + res_ctx = &target->ctx->dc->current_context.res_ctx; + + for (i = 0; i < target->public.stream_count; i++) { + for (j = 0; j < MAX_PIPES; j++) { + struct input_pixel_processor *ipp = + res_ctx->pipe_ctx[j].ipp; + + if (res_ctx->pipe_ctx[j].stream != + DC_STREAM_TO_CORE(target->public.streams[i])) + continue; + + /* As of writing of this code cursor is on the top + * plane so we only need to set it on first pipe we + * find. May need to make this code dce specific later. + */ + if (ipp->funcs->ipp_cursor_set_attributes( + ipp, attributes)) + return true; + } + } return false; } @@ -368,8 +429,9 @@ bool dc_target_set_cursor_position( struct dc_target *dc_target, const struct dc_cursor_position *position) { - struct core_target *core_target; - struct input_pixel_processor *ipp; + uint8_t i, j; + struct core_target *target; + struct resource_context *res_ctx; if (NULL == dc_target) { dm_error("DC: dc_target is NULL!\n"); @@ -381,62 +443,67 @@ bool dc_target_set_cursor_position( return false; } - core_target = DC_TARGET_TO_CORE(dc_target); - ipp = DC_STREAM_TO_CORE(core_target->public.streams[0])->ipp; + target = DC_TARGET_TO_CORE(dc_target); + res_ctx = &target->ctx->dc->current_context.res_ctx; - if (NULL == ipp) { - dm_error("DC: input pixel processor is NULL!\n"); - return false; + for (i = 0; i < target->public.stream_count; i++) { + for (j = 0; j < MAX_PIPES; j++) { + struct input_pixel_processor *ipp = + res_ctx->pipe_ctx[j].ipp; + + if (res_ctx->pipe_ctx[j].stream != + DC_STREAM_TO_CORE(target->public.streams[i])) + continue; + + /* As of writing of this code cursor is on the top + * plane so we only need to set it on first pipe we + * find. May need to make this code dce specific later. + */ + if (ipp->funcs->ipp_cursor_set_position(ipp, position)) + return true; + } } - - if (true == ipp->funcs->ipp_cursor_set_position(ipp, position)) - return true; - return false; } -/* TODO: #flip temporary to make flip work */ -uint8_t dc_target_get_link_index(const struct dc_target *dc_target) +uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target) { - const struct core_target *target = CONST_DC_TARGET_TO_CORE(dc_target); - const struct core_sink *sink = - DC_SINK_TO_CORE(target->public.streams[0]->sink); + uint8_t i, j; + struct core_target *target = DC_TARGET_TO_CORE(dc_target); + struct resource_context *res_ctx = + &target->ctx->dc->current_context.res_ctx; - return sink->link->public.link_index; -} + for (i = 0; i < target->public.stream_count; i++) { + for (j = 0; j < MAX_PIPES; j++) { + struct timing_generator *tg = res_ctx->pipe_ctx[j].tg; -uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target) -{ - struct core_target *core_target = DC_TARGET_TO_CORE(dc_target); - struct timing_generator *tg = - DC_STREAM_TO_CORE(core_target->public.streams[0])->tg; + if (res_ctx->pipe_ctx[j].stream != + DC_STREAM_TO_CORE(target->public.streams[i])) + continue; - return tg->funcs->get_frame_count(tg); + return tg->funcs->get_frame_count(tg); + } + } + + return 0; } enum dc_irq_source dc_target_get_irq_src( - const struct dc_target *dc_target, const enum irq_type irq_type) + const struct dc *dc, + const struct dc_target *dc_target, + const enum irq_type irq_type) { + uint8_t i; struct core_target *core_target = DC_TARGET_TO_CORE(dc_target); - - /* #TODO - Remove the assumption that the controller is always in the - * first stream of a core target */ struct core_stream *stream = - DC_STREAM_TO_CORE(core_target->public.streams[0]); - uint8_t controller_idx = stream->controller_idx; - - /* Get controller id */ - enum controller_id crtc_id = controller_idx + 1; - - /* Calculate controller offset */ - unsigned int offset = crtc_id - CONTROLLER_ID_D0; - unsigned int base = irq_type; + DC_STREAM_TO_CORE(core_target->public.streams[0]); - /* Calculate irq source */ - enum dc_irq_source src = base + offset; + for (i = 0; i < MAX_PIPES; i++) + if (dc->current_context.res_ctx.pipe_ctx[i].stream == stream) + return irq_type + i; - return src; + return irq_type; } void dc_target_log( @@ -453,9 +520,8 @@ void dc_target_log( dal_logger_write(dal_logger, log_major, log_minor, - "core_target 0x%x: surface_count=%d, stream_count=%d\n", + "core_target 0x%x: stream_count=%d\n", core_target, - core_target->status.surface_count, core_target->public.stream_count); for (i = 0; i < core_target->public.stream_count; i++) { diff --git a/drivers/gpu/drm/amd/dal/dc/dc.h b/drivers/gpu/drm/amd/dal/dc/dc.h index 901c8c4..9cd239c 100644 --- a/drivers/gpu/drm/amd/dal/dc/dc.h +++ b/drivers/gpu/drm/amd/dal/dc/dc.h @@ -108,7 +108,7 @@ struct dc_surface { union plane_size plane_size; struct dc_tiling_info tiling_info; - struct plane_colorimetry colorimetry; + enum color_space color_space; enum surface_pixel_format format; enum dc_rotation_angle rotation; @@ -125,7 +125,6 @@ struct dc_surface { struct dc_surface_status { struct dc_plane_address requested_address; struct dc_plane_address current_address; - const struct dc_target *dc_target; }; /* @@ -228,12 +227,13 @@ bool dc_target_is_connected_to_sink( const struct dc_target *dc_target, const struct dc_sink *dc_sink); -uint8_t dc_target_get_link_index(const struct dc_target *dc_target); uint8_t dc_target_get_controller_id(const struct dc_target *dc_target); uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target); enum dc_irq_source dc_target_get_irq_src( - const struct dc_target *dc_target, const enum irq_type irq_type); + const struct dc *dc, + const struct dc_target *dc_target, + const enum irq_type irq_type); void dc_target_enable_memory_requests(struct dc_target *target); void dc_target_disable_memory_requests(struct dc_target *target); diff --git a/drivers/gpu/drm/amd/dal/dc/dc_types.h b/drivers/gpu/drm/amd/dal/dc/dc_types.h index 5593c17..863443b 100644 --- a/drivers/gpu/drm/amd/dal/dc/dc_types.h +++ b/drivers/gpu/drm/amd/dal/dc/dc_types.h @@ -67,13 +67,17 @@ enum dce_environment { #define MAX_SURFACE_NUM 2 #define NUM_PIXEL_FORMATS 10 -enum surface_color_space { - SURFACE_COLOR_SPACE_SRGB = 0x0000, - SURFACE_COLOR_SPACE_BT601 = 0x0001, - SURFACE_COLOR_SPACE_BT709 = 0x0002, - SURFACE_COLOR_SPACE_XVYCC_BT601 = 0x0004, - SURFACE_COLOR_SPACE_XVYCC_BT709 = 0x0008, - SURFACE_COLOR_SPACE_XRRGB = 0x0010 +enum color_space { + COLOR_SPACE_UNKNOWN, + COLOR_SPACE_SRGB_FULL_RANGE, + COLOR_SPACE_SRGB_LIMITED_RANGE, + COLOR_SPACE_YPBPR601, + COLOR_SPACE_YPBPR709, + COLOR_SPACE_YCBCR601, + COLOR_SPACE_YCBCR709, + COLOR_SPACE_YCBCR601_YONLY, + COLOR_SPACE_YCBCR709_YONLY, + COLOR_SPACE_N_MVPU_SUPER_AA, }; @@ -170,11 +174,6 @@ enum dc_edid_status { EDID_BAD_CHECKSUM, }; -struct plane_colorimetry { - enum surface_color_space color_space; - bool limited_range; -}; - /* audio capability from EDID*/ struct dc_cea_audio_mode { uint8_t format_code; /* ucData[0] [6:3]*/ diff --git a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c index 783d47e..efa592f 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/dce100/dce100_resource.c @@ -530,7 +530,7 @@ void dce100_destruct_resource_pool(struct resource_pool *pool) { unsigned int i; - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { if (pool->opps[i] != NULL) dce100_opp_destroy(&pool->opps[i]); @@ -615,12 +615,13 @@ static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) } static void build_audio_output( - const struct core_stream *stream, + const struct pipe_ctx *pipe_ctx, struct audio_output *audio_output) { - audio_output->engine_id = stream->stream_enc->id; + const struct core_stream *stream = pipe_ctx->stream; + audio_output->engine_id = pipe_ctx->stream_enc->id; - audio_output->signal = stream->signal; + audio_output->signal = pipe_ctx->signal; /* audio_crtc_info */ @@ -654,44 +655,45 @@ static void build_audio_output( stream->public.timing.display_color_depth; audio_output->crtc_info.requested_pixel_clock = - stream->pix_clk_params.requested_pix_clk; + pipe_ctx->pix_clk_params.requested_pix_clk; /* * TODO - Investigate why calculated pixel clk has to be * requested pixel clk */ audio_output->crtc_info.calculated_pixel_clock = - stream->pix_clk_params.requested_pix_clk; + pipe_ctx->pix_clk_params.requested_pix_clk; - if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || - stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + if (pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT || + pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { audio_output->pll_info.dp_dto_source_clock_in_khz = dal_display_clock_get_dp_ref_clk_frequency( - stream->dis_clk); + pipe_ctx->dis_clk); } audio_output->pll_info.feed_back_divider = - stream->pll_settings.feedback_divider; + pipe_ctx->pll_settings.feedback_divider; audio_output->pll_info.dto_source = translate_to_dto_source( - stream->controller_idx + 1); + pipe_ctx->pipe_idx + 1); /* TODO hard code to enable for now. Need get from stream */ audio_output->pll_info.ss_enabled = true; audio_output->pll_info.ss_percentage = - stream->pll_settings.ss_percentage; + pipe_ctx->pll_settings.ss_percentage; } static void get_pixel_clock_parameters( - const struct core_stream *stream, + const struct pipe_ctx *pipe_ctx, struct pixel_clk_params *pixel_clk_params) { + const struct core_stream *stream = pipe_ctx->stream; pixel_clk_params->requested_pix_clk = stream->public.timing.pix_clk_khz; pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id; pixel_clk_params->signal_type = stream->sink->public.sink_signal; - pixel_clk_params->controller_id = stream->controller_idx + 1; + pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1; /* TODO: un-hardcode*/ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW * LINK_RATE_REF_FREQ_IN_KHZ; @@ -701,20 +703,20 @@ static void get_pixel_clock_parameters( pixel_clk_params->flags.DISPLAY_BLANKED = 1; } -static enum dc_status build_stream_hw_param(struct core_stream *stream) +static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx) { /*TODO: unhardcode*/ - stream->max_tmds_clk_from_edid_in_mhz = 0; - stream->max_hdmi_deep_color = COLOR_DEPTH_121212; - stream->max_hdmi_pixel_clock = 600000; + pipe_ctx->max_tmds_clk_from_edid_in_mhz = 0; + pipe_ctx->max_hdmi_deep_color = COLOR_DEPTH_121212; + pipe_ctx->max_hdmi_pixel_clock = 600000; - get_pixel_clock_parameters(stream, &stream->pix_clk_params); - stream->clock_source->funcs->get_pix_clk_dividers( - stream->clock_source, - &stream->pix_clk_params, - &stream->pll_settings); + get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->pix_clk_params); + pipe_ctx->clock_source->funcs->get_pix_clk_dividers( + pipe_ctx->clock_source, + &pipe_ctx->pix_clk_params, + &pipe_ctx->pll_settings); - build_audio_output(stream, &stream->audio_output); + build_audio_output(pipe_ctx, &pipe_ctx->audio_output); return DC_OK; } @@ -724,7 +726,7 @@ static enum dc_status validate_mapped_resource( struct validate_context *context) { enum dc_status status = DC_OK; - uint8_t i, j; + uint8_t i, j, k; for (i = 0; i < context->target_count; i++) { struct core_target *target = context->targets[i]; @@ -736,33 +738,44 @@ static enum dc_status validate_mapped_resource( DC_STREAM_TO_CORE(target->public.streams[j]); struct core_link *link = stream->sink->link; - if (!stream->tg->funcs->validate_timing( - stream->tg, &stream->public.timing)) - return DC_FAIL_CONTROLLER_VALIDATE; + for (k = 0; k < MAX_PIPES; k++) { + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[k]; + + if (context->res_ctx.pipe_ctx[k].stream != stream) + continue; + + if (!pipe_ctx->tg->funcs->validate_timing( + pipe_ctx->tg, &stream->public.timing)) + return DC_FAIL_CONTROLLER_VALIDATE; + + if (pipe_ctx->signal == SIGNAL_TYPE_VIRTUAL) + return status; - if (stream->signal == SIGNAL_TYPE_VIRTUAL) - return status; + status = build_pipe_hw_param(pipe_ctx); - status = build_stream_hw_param(stream); + if (status != DC_OK) + return status; - if (status != DC_OK) - return status; + if (!link->link_enc->funcs->validate_output_with_stream( + link->link_enc, + pipe_ctx)) + return DC_FAIL_ENC_VALIDATE; - if (!link->link_enc->funcs->validate_output_with_stream( - link->link_enc, - stream)) - return DC_FAIL_ENC_VALIDATE; + /* TODO: validate audio ASIC caps, encoder */ - /* TODO: validate audio ASIC caps, encoder */ + status = dc_link_validate_mode_timing(stream->sink, + link, + &stream->public.timing); - status = dc_link_validate_mode_timing(stream->sink, - link, - &stream->public.timing); + if (status != DC_OK) + return status; - if (status != DC_OK) - return status; + build_info_frame(pipe_ctx); - build_info_frame(stream); + /* do not need to validate non root pipes */ + break; + } } } @@ -783,16 +796,17 @@ static void set_target_unchanged( struct validate_context *context, uint8_t target_idx) { - uint8_t i; + uint8_t i, j; struct core_target *target = context->targets[target_idx]; - context->target_flags[target_idx].unchanged = true; for (i = 0; i < target->public.stream_count; i++) { - struct core_stream *core_stream = + struct core_stream *stream = DC_STREAM_TO_CORE(target->public.streams[i]); - uint8_t index = core_stream->controller_idx; - - context->res_ctx.controller_ctx[index].flags.unchanged = true; + for (j = 0; j < MAX_PIPES; j++) { + if (context->res_ctx.pipe_ctx[j].stream == stream) + context->res_ctx.pipe_ctx[j].flags.unchanged = + true; + } } } @@ -800,24 +814,7 @@ static enum dc_status map_clock_resources( const struct dc *dc, struct validate_context *context) { - uint8_t i, j; - - /* mark resources used for targets that are already active */ - for (i = 0; i < context->target_count; i++) { - struct core_target *target = context->targets[i]; - - if (!context->target_flags[i].unchanged) - continue; - - for (j = 0; j < target->public.stream_count; j++) { - struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); - - reference_clock_source( - &context->res_ctx, - stream->clock_source); - } - } + uint8_t i, j, k; /* acquire new resources */ for (i = 0; i < context->target_count; i++) { @@ -830,24 +827,35 @@ static enum dc_status map_clock_resources( struct core_stream *stream = DC_STREAM_TO_CORE(target->public.streams[j]); - if (dc_is_dp_signal(stream->signal) - || stream->signal == SIGNAL_TYPE_VIRTUAL) - stream->clock_source = context->res_ctx. - pool.clock_sources[DCE100_CLK_SRC_EXT]; - else - stream->clock_source = - find_used_clk_src_for_sharing( - context, stream); - if (stream->clock_source == NULL) - stream->clock_source = - find_first_free_pll(&context->res_ctx); - - if (stream->clock_source == NULL) - return DC_NO_CLOCK_SOURCE_RESOURCE; - - reference_clock_source( - &context->res_ctx, - stream->clock_source); + for (k = 0; k < MAX_PIPES; k++) { + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[k]; + + if (context->res_ctx.pipe_ctx[k].stream != stream) + continue; + + if (dc_is_dp_signal(pipe_ctx->signal) + || pipe_ctx->signal == SIGNAL_TYPE_VIRTUAL) + pipe_ctx->clock_source = context->res_ctx. + pool.clock_sources[DCE100_CLK_SRC_EXT]; + else + pipe_ctx->clock_source = + find_used_clk_src_for_sharing( + &context->res_ctx, pipe_ctx); + if (pipe_ctx->clock_source == NULL) + pipe_ctx->clock_source = + find_first_free_pll(&context->res_ctx); + + if (pipe_ctx->clock_source == NULL) + return DC_NO_CLOCK_SOURCE_RESOURCE; + + reference_clock_source( + &context->res_ctx, + pipe_ctx->clock_source); + + /* only one cs per stream regardless of mpo */ + break; + } } } @@ -865,24 +873,30 @@ enum dc_status dce100_validate_with_context( struct dc_context *dc_ctx = dc->ctx; for (i = 0; i < set_count; i++) { + bool unchanged = false; + context->targets[i] = DC_TARGET_TO_CORE(set[i].target); + context->target_count++; for (j = 0; j < dc->current_context.target_count; j++) - if (dc->current_context.targets[j] == context->targets[i]) + if (dc->current_context.targets[j] + == context->targets[i]) { + unchanged = true; set_target_unchanged(context, i); - - if (!context->target_flags[i].unchanged) - if (!logical_attach_surfaces_to_target( + context->target_status[i] = + dc->current_context.target_status[j]; + } + if (!unchanged) + if (!attach_surfaces_to_context( (struct dc_surface **)set[i].surfaces, set[i].surface_count, - &context->targets[i]->public)) { + &context->targets[i]->public, + context)) { DC_ERROR("Failed to attach surface to target!\n"); return DC_FAIL_ATTACH_SURFACES; } } - context->target_count = set_count; - context->res_ctx.pool = dc->res_pool; result = map_resources(dc, context); @@ -969,7 +983,7 @@ bool dce100_construct_resource_pool( } - pool->controller_count = + pool->pipe_count = dal_adapter_service_get_func_controllers_num(adapter_serv); pool->stream_enc_count = dal_adapter_service_get_stream_engines_num( adapter_serv); @@ -980,7 +994,7 @@ bool dce100_construct_resource_pool( goto filter_create_fail; } - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { pool->timing_generators[i] = dce100_timing_generator_create( adapter_serv, ctx, i, &dce100_tg_offsets[i]); if (pool->timing_generators[i] == NULL) { @@ -1031,7 +1045,7 @@ bool dce100_construct_resource_pool( audio_init_data.as = adapter_serv; audio_init_data.ctx = ctx; pool->audio_count = 0; - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { struct graphics_object_id obj_id; obj_id = dal_adapter_service_enum_audio_object(adapter_serv, i); @@ -1089,13 +1103,13 @@ stream_enc_create_fail: } audio_create_fail: - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { if (pool->audios[i] != NULL) dal_audio_destroy(&pool->audios[i]); } controller_create_fail: - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { if (pool->opps[i] != NULL) dce100_opp_destroy(&pool->opps[i]); diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c index a815a6d..70349a0 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c @@ -546,17 +546,17 @@ prescale_alloc_fail: } static enum dc_status bios_parser_crtc_source_select( - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { struct dc_bios *dcb; /* call VBIOS table to set CRTC source for the HW * encoder block * note: video bios clears all FMT setting here. */ struct bp_crtc_source_select crtc_source_select = {0}; - const struct core_sink *sink = stream->sink; + const struct core_sink *sink = pipe_ctx->stream->sink; - crtc_source_select.engine_id = stream->stream_enc->id; - crtc_source_select.controller_id = stream->controller_idx + 1; + crtc_source_select.engine_id = pipe_ctx->stream_enc->id; + crtc_source_select.controller_id = pipe_ctx->pipe_idx + 1; /*TODO: Need to un-hardcode color depth, dp_audio and account for * the case where signal and sink signal is different (translator * encoder)*/ @@ -576,32 +576,6 @@ static enum dc_status bios_parser_crtc_source_select( return DC_OK; } -static enum color_space surface_color_to_color_space( - struct plane_colorimetry *colorimetry) -{ - enum color_space color_space = COLOR_SPACE_UNKNOWN; - - switch (colorimetry->color_space) { - case SURFACE_COLOR_SPACE_SRGB: - case SURFACE_COLOR_SPACE_XRRGB: - if (colorimetry->limited_range) - color_space = COLOR_SPACE_SRGB_LIMITED_RANGE; - else - color_space = COLOR_SPACE_SRGB_FULL_RANGE; - break; - case SURFACE_COLOR_SPACE_BT601: - case SURFACE_COLOR_SPACE_XVYCC_BT601: - color_space = COLOR_SPACE_YCBCR601; - break; - case SURFACE_COLOR_SPACE_BT709: - case SURFACE_COLOR_SPACE_XVYCC_BT709: - color_space = COLOR_SPACE_YCBCR709; - break; - } - - return color_space; -} - /*******************************FMT**************************************/ static void program_fmt( struct output_pixel_processor *opp, @@ -630,35 +604,35 @@ static void update_bios_scratch_critical_state(struct adapter_service *as, dcb->funcs->set_scratch_critical_state(dcb, state); } -static void update_info_frame(struct core_stream *stream) +static void update_info_frame(struct pipe_ctx *pipe_ctx) { - if (dc_is_hdmi_signal(stream->signal)) - stream->stream_enc->funcs->update_hdmi_info_packets( - stream->stream_enc, - &stream->encoder_info_frame); - else if (dc_is_dp_signal(stream->signal)) - stream->stream_enc->funcs->update_dp_info_packets( - stream->stream_enc, - &stream->encoder_info_frame); + if (dc_is_hdmi_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->update_hdmi_info_packets( + pipe_ctx->stream_enc, + &pipe_ctx->encoder_info_frame); + else if (dc_is_dp_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->update_dp_info_packets( + pipe_ctx->stream_enc, + &pipe_ctx->encoder_info_frame); } -static void enable_stream(struct core_stream *stream) +static void enable_stream(struct pipe_ctx *pipe_ctx) { enum dc_lane_count lane_count = - stream->sink->link->public.cur_link_settings.lane_count; + pipe_ctx->stream->sink->link->public.cur_link_settings.lane_count; - struct dc_crtc_timing *timing = &stream->public.timing; - struct core_link *link = stream->sink->link; + struct dc_crtc_timing *timing = &pipe_ctx->stream->public.timing; + struct core_link *link = pipe_ctx->stream->sink->link; /* 1. update AVI info frame (HDMI, DP) * we always need to update info frame */ uint32_t active_total_with_borders; uint32_t early_control = 0; - struct timing_generator *tg = stream->tg; + struct timing_generator *tg = pipe_ctx->tg; - update_info_frame(stream); + update_info_frame(pipe_ctx); /* enable early control to avoid corruption on DP monitor*/ active_total_with_borders = timing->h_addressable @@ -674,11 +648,11 @@ static void enable_stream(struct core_stream *stream) tg->funcs->set_early_control(tg, early_control); /* enable audio only within mode set */ - if (stream->audio != NULL) { + if (pipe_ctx->audio != NULL) { dal_audio_enable_output( - stream->audio, - stream->stream_enc->id, - stream->signal); + pipe_ctx->audio, + pipe_ctx->stream_enc->id, + pipe_ctx->signal); } /* For MST, there are multiply stream go to only one link. @@ -686,26 +660,27 @@ static void enable_stream(struct core_stream *stream) * disconnect them during disable_stream * BY this, it is logic clean to separate stream and link */ link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, - stream->stream_enc->id, true); + pipe_ctx->stream_enc->id, true); } -static void disable_stream(struct core_stream *stream) +static void disable_stream(struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; struct core_link *link = stream->sink->link; - if (dc_is_hdmi_signal(stream->signal)) - stream->stream_enc->funcs->stop_hdmi_info_packets( - stream->stream_enc); + if (dc_is_hdmi_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->stop_hdmi_info_packets( + pipe_ctx->stream_enc); - if (dc_is_dp_signal(stream->signal)) - stream->stream_enc->funcs->stop_dp_info_packets( - stream->stream_enc); + if (dc_is_dp_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->stop_dp_info_packets( + pipe_ctx->stream_enc); - if (stream->audio) { + if (pipe_ctx->audio) { /* mute audio */ - dal_audio_mute(stream->audio, stream->stream_enc->id, - stream->signal); + dal_audio_mute(pipe_ctx->audio, pipe_ctx->stream_enc->id, + pipe_ctx->signal); /* TODO: notify audio driver for if audio modes list changed * add audio mode list change flag */ @@ -715,27 +690,26 @@ static void disable_stream(struct core_stream *stream) } /* blank at encoder level */ - if (dc_is_dp_signal(stream->signal)) - stream->stream_enc->funcs->dp_blank(stream->stream_enc); + if (dc_is_dp_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->dp_blank(pipe_ctx->stream_enc); link->link_enc->funcs->connect_dig_be_to_fe( link->link_enc, - stream->stream_enc->id, + pipe_ctx->stream_enc->id, false); } -static void unblank_stream(struct core_stream *stream, +static void unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings) { struct encoder_unblank_param params = { { 0 } }; /* only 3 items below are used by unblank */ params.crtc_timing.pixel_clock = - stream->public.timing.pix_clk_khz; + pipe_ctx->stream->public.timing.pix_clk_khz; params.link_settings.link_rate = link_settings->link_rate; - stream->stream_enc->funcs->dp_unblank( - stream->stream_enc, ¶ms); + pipe_ctx->stream_enc->funcs->dp_unblank(pipe_ctx->stream_enc, ¶ms); } static enum color_space get_output_color_space( @@ -776,106 +750,102 @@ static enum color_space get_output_color_space( return color_space; } -static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, +static enum dc_status apply_single_controller_ctx_to_hw( + struct pipe_ctx *pipe_ctx, struct validate_context *context, - const struct dc *dc) + struct dc *dc) { - struct core_stream *stream = - context->res_ctx.controller_ctx[controller_idx].stream; - struct core_stream *old_stream = - dc->current_context.res_ctx.controller_ctx[controller_idx].stream; - struct output_pixel_processor *opp = - context->res_ctx.pool.opps[controller_idx]; - bool timing_changed = context->res_ctx.controller_ctx[controller_idx] - .flags.timing_changed; + struct core_stream *stream = pipe_ctx->stream; + struct pipe_ctx *old_pipe_ctx = + &dc->current_context.res_ctx.pipe_ctx[pipe_ctx->pipe_idx]; + bool timing_changed = context->res_ctx.pipe_ctx[pipe_ctx->pipe_idx] + .flags.timing_changed; enum color_space color_space; if (timing_changed) { /* Must blank CRTC after disabling power gating and before any * programming, otherwise CRTC will be hung in bad state */ - stream->tg->funcs->set_blank(stream->tg, true); + pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); /* * only disable stream in case it was ever enabled */ - if (old_stream) - core_link_disable_stream( - old_stream->sink->link, - old_stream); + if (old_pipe_ctx->stream) + core_link_disable_stream(old_pipe_ctx); /*TODO: AUTO check if timing changed*/ - if (false == stream->clock_source->funcs->program_pix_clk( - stream->clock_source, - &stream->pix_clk_params, - &stream->pll_settings)) { + if (false == pipe_ctx->clock_source->funcs->program_pix_clk( + pipe_ctx->clock_source, + &pipe_ctx->pix_clk_params, + &pipe_ctx->pll_settings)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; } - stream->tg->funcs->program_timing( - stream->tg, + pipe_ctx->tg->funcs->program_timing( + pipe_ctx->tg, &stream->public.timing, true); } /*TODO: mst support - use total stream count*/ - stream->mi->funcs->allocate_mem_input( - stream->mi, + pipe_ctx->mi->funcs->allocate_mem_input( + pipe_ctx->mi, stream->public.timing.h_total, stream->public.timing.v_total, stream->public.timing.pix_clk_khz, context->target_count); if (timing_changed) { - if (false == stream->tg->funcs->enable_crtc( - stream->tg)) { + if (false == pipe_ctx->tg->funcs->enable_crtc( + pipe_ctx->tg)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; } } /* TODO: move to stream encoder */ - if (stream->signal != SIGNAL_TYPE_VIRTUAL) - if (DC_OK != bios_parser_crtc_source_select(stream)) { + if (pipe_ctx->signal != SIGNAL_TYPE_VIRTUAL) + if (DC_OK != bios_parser_crtc_source_select(pipe_ctx)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; } - opp->funcs->opp_set_dyn_expansion( - opp, + pipe_ctx->opp->funcs->opp_set_dyn_expansion( + pipe_ctx->opp, COLOR_SPACE_YCBCR601, stream->public.timing.display_color_depth, stream->sink->public.sink_signal); - program_fmt(opp, &stream->bit_depth_params, &stream->clamping); + program_fmt(pipe_ctx->opp, &stream->bit_depth_params, &stream->clamping); stream->sink->link->link_enc->funcs->setup( stream->sink->link->link_enc, - stream->signal); + pipe_ctx->signal); - if (dc_is_dp_signal(stream->signal)) - stream->stream_enc->funcs->dp_set_stream_attribute( - stream->stream_enc, + if (dc_is_dp_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->dp_set_stream_attribute( + pipe_ctx->stream_enc, &stream->public.timing); - if (dc_is_hdmi_signal(stream->signal)) - stream->stream_enc->funcs->hdmi_set_stream_attribute( - stream->stream_enc, + if (dc_is_hdmi_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->hdmi_set_stream_attribute( + pipe_ctx->stream_enc, &stream->public.timing, - stream->audio != NULL); + pipe_ctx->audio != NULL); - if (dc_is_dvi_signal(stream->signal)) - stream->stream_enc->funcs->dvi_set_stream_attribute( - stream->stream_enc, + if (dc_is_dvi_signal(pipe_ctx->signal)) + pipe_ctx->stream_enc->funcs->dvi_set_stream_attribute( + pipe_ctx->stream_enc, &stream->public.timing, - (stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? + (pipe_ctx->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? true : false); - if (stream->audio != NULL) { + if (pipe_ctx->audio != NULL) { if (AUDIO_RESULT_OK != dal_audio_setup( - stream->audio, - &stream->audio_output, + pipe_ctx->audio, + &pipe_ctx->audio_output, &stream->public.audio_info)) { BREAK_TO_DEBUGGER(); return DC_ERROR_UNEXPECTED; @@ -883,24 +853,24 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, } /* Setup audio rate clock source */ - if (stream->audio != NULL) + if (pipe_ctx->audio != NULL) dal_audio_setup_audio_wall_dto( - stream->audio, - stream->signal, - &stream->audio_output.crtc_info, - &stream->audio_output.pll_info); + pipe_ctx->audio, + pipe_ctx->signal, + &pipe_ctx->audio_output.crtc_info, + &pipe_ctx->audio_output.pll_info); /* program blank color */ color_space = get_output_color_space(&stream->public.timing); - stream->tg->funcs->set_blank_color( - context->res_ctx.pool.timing_generators[controller_idx], + pipe_ctx->tg->funcs->set_blank_color( + pipe_ctx->tg, color_space); if (timing_changed) - core_link_enable_stream(stream->sink->link, stream); + core_link_enable_stream(pipe_ctx); - if (dc_is_dp_signal(stream->signal)) - unblank_stream(stream, + if (dc_is_dp_signal(pipe_ctx->signal)) + unblank_stream(pipe_ctx, &stream->sink->link->public.cur_link_settings); return DC_OK; @@ -923,7 +893,7 @@ static void power_down_controllers(struct dc *dc) { int i; - for (i = 0; i < dc->res_pool.controller_count; i++) { + for (i = 0; i < dc->res_pool.pipe_count; i++) { dc->res_pool.timing_generators[i]->funcs->disable_crtc( dc->res_pool.timing_generators[i]); } @@ -960,7 +930,7 @@ static void disable_vga_and_power_gate_all_controllers( dcb = dal_adapter_service_get_bios_parser( dc->res_pool.adapter_srv); - for (i = 0; i < dc->res_pool.controller_count; i++) { + for (i = 0; i < dc->res_pool.pipe_count; i++) { tg = dc->res_pool.timing_generators[i]; ctx = dc->ctx; @@ -1133,14 +1103,13 @@ static void set_display_clock(struct validate_context *context) } static uint32_t compute_pstate_blackout_duration( - const struct dc *dc, + struct bw_fixed blackout_duration, const struct core_stream *stream) { uint32_t total_dest_line_time_ns; uint32_t pstate_blackout_duration_ns; - pstate_blackout_duration_ns = 1000 * - dc->bw_vbios.blackout_duration.value >> 24; + pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; total_dest_line_time_ns = 1000000UL * stream->public.timing.h_total / @@ -1154,63 +1123,50 @@ static void set_displaymarks( const struct dc *dc, struct validate_context *context) { - uint8_t i, j; - uint8_t total_streams = 0; - uint8_t target_count = context->target_count; - uint32_t pstate_blackout_duration_ns; + uint8_t i, num_pipes; + + for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + uint32_t total_dest_line_time_ns; + + if (pipe_ctx->stream == NULL) + continue; - for (i = 0; i < target_count; i++) { - const struct core_target *target = context->targets[i]; - - for (j = 0; j < target->public.stream_count; j++) { - const struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); - - pstate_blackout_duration_ns = - compute_pstate_blackout_duration(dc, stream); - - stream->mi->funcs->mem_input_program_display_marks( - stream->mi, - context->bw_results - .nbp_state_change_wm_ns[total_streams], - context->bw_results - .stutter_exit_wm_ns[total_streams], - context->bw_results. - urgent_wm_ns[total_streams], - pstate_blackout_duration_ns); - - total_streams++; - } /* for ()*/ - } /* for() */ + total_dest_line_time_ns = compute_pstate_blackout_duration( + dc->bw_vbios.blackout_duration, pipe_ctx->stream); + pipe_ctx->mi->funcs->mem_input_program_display_marks( + pipe_ctx->mi, + context->bw_results.nbp_state_change_wm_ns[num_pipes], + context->bw_results.stutter_exit_wm_ns[num_pipes], + context->bw_results.urgent_wm_ns[num_pipes], + total_dest_line_time_ns); + num_pipes++; + } } -static void set_safe_displaymarks(const struct dc *dc, struct validate_context *context) + +static void set_safe_displaymarks(struct resource_context *res_ctx) { - uint8_t i, j; - uint8_t target_count = context->target_count; + uint8_t i; struct bw_watermarks max_marks = { MAX_WATERMARK, MAX_WATERMARK }; struct bw_watermarks nbp_marks = { SAFE_NBP_MARK, SAFE_NBP_MARK }; - for (i = 0; i < target_count; i++) { - struct core_target *target = context->targets[i]; - - for (j = 0; j < target->public.stream_count; j++) { - struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); + for (i = 0; i < MAX_PIPES; i++) { + if (res_ctx->pipe_ctx[i].stream == NULL) + continue; - stream->mi->funcs->mem_input_program_display_marks( - stream->mi, + res_ctx->pipe_ctx[i].mi->funcs->mem_input_program_display_marks( + res_ctx->pipe_ctx[i].mi, nbp_marks, max_marks, max_marks, MAX_WATERMARK); - } } } static void program_bw(struct dc *dc, struct validate_context *context) { - set_safe_displaymarks(dc, context); + set_safe_displaymarks(&context->res_ctx); /*TODO: when pplib works*/ /*dc_set_clocks_and_clock_state(context);*/ @@ -1220,31 +1176,27 @@ static void program_bw(struct dc *dc, struct validate_context *context) static void switch_dp_clock_sources( const struct dc *dc, - struct validate_context *val_context) + struct resource_context *res_ctx) { - uint8_t i, j; - for (i = 0; i < val_context->target_count; i++) { - struct core_target *target = val_context->targets[i]; - for (j = 0; j < target->public.stream_count; j++) { - struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); - - if (dc_is_dp_signal(stream->signal)) { - struct clock_source *clk_src = - find_used_clk_src_for_sharing( - val_context, stream); - - if (clk_src && - clk_src != stream->clock_source) { - unreference_clock_source( - &val_context->res_ctx, - stream->clock_source); - stream->clock_source = clk_src; - reference_clock_source( - &val_context->res_ctx, clk_src); - dc->hwss.crtc_switch_to_clk_src( - clk_src, stream->opp->inst); - } + uint8_t i; + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; + + if (pipe_ctx->stream == NULL) + continue; + + if (dc_is_dp_signal(pipe_ctx->signal)) { + struct clock_source *clk_src = + find_used_clk_src_for_sharing( + res_ctx, pipe_ctx); + + if (clk_src && + clk_src != pipe_ctx->clock_source) { + unreference_clock_source( + res_ctx, pipe_ctx->clock_source); + pipe_ctx->clock_source = clk_src; + reference_clock_source(res_ctx, clk_src); + dc->hwss.crtc_switch_to_clk_src(clk_src, i); } } } @@ -1256,22 +1208,20 @@ static void switch_dp_clock_sources( /*TODO: const validate_context*/ static enum dc_status apply_ctx_to_hw( - const struct dc *dc, + struct dc *dc, struct validate_context *context) { enum dc_status status; uint8_t i; - struct resource_pool *pool = &context->res_ctx.pool; update_bios_scratch_critical_state(context->res_ctx.pool.adapter_srv, true); - for (i = 0; i < pool->controller_count; i++) { - struct controller_ctx *ctlr_ctx - = &context->res_ctx.controller_ctx[i]; + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; struct dc_bios *dcb; - if (ctlr_ctx->flags.unchanged || !ctlr_ctx->stream) + if (pipe_ctx->stream == NULL || pipe_ctx->flags.unchanged) continue; dcb = dal_adapter_service_get_bios_parser( @@ -1282,7 +1232,7 @@ static enum dc_status apply_ctx_to_hw( PIPE_GATING_CONTROL_DISABLE); } - set_safe_displaymarks(dc, context); + set_safe_displaymarks(&context->res_ctx); /*TODO: when pplib works*/ /*dc_set_clocks_and_clock_state(context);*/ @@ -1290,14 +1240,14 @@ static enum dc_status apply_ctx_to_hw( > dc->current_context.bw_results.dispclk_khz) set_display_clock(context); - for (i = 0; i < pool->controller_count; i++) { - struct controller_ctx *ctlr_ctx - = &context->res_ctx.controller_ctx[i]; - if (ctlr_ctx->flags.unchanged || !ctlr_ctx->stream) + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + + if (pipe_ctx->stream == NULL || pipe_ctx->flags.unchanged) continue; status = apply_single_controller_ctx_to_hw( - i, + pipe_ctx, context, dc); @@ -1309,7 +1259,7 @@ static enum dc_status apply_ctx_to_hw( update_bios_scratch_critical_state(context->res_ctx.pool.adapter_srv, false); - switch_dp_clock_sources(dc, context); + switch_dp_clock_sources(dc, &context->res_ctx); return DC_OK; } @@ -1320,14 +1270,14 @@ static enum dc_status apply_ctx_to_hw( ******************************************************************************/ static bool setup_line_buffer_pixel_depth( - const struct core_stream *stream, + const struct pipe_ctx *pipe_ctx, enum lb_pixel_depth depth, bool blank) { enum lb_pixel_depth current_depth; - struct timing_generator *tg = stream->tg; - struct transform *xfm = stream->xfm; + struct timing_generator *tg = pipe_ctx->tg; + struct transform *xfm = pipe_ctx->xfm; if (!xfm->funcs->transform_get_current_pixel_storage_depth( xfm, @@ -1339,14 +1289,14 @@ static bool setup_line_buffer_pixel_depth( tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); return xfm->funcs->transform_set_pixel_storage_depth(xfm, depth, - &stream->bit_depth_params); + &pipe_ctx->stream->bit_depth_params); } return false; } static void hw_sequencer_build_scaler_parameter_plane( - const struct core_stream *stream, + const struct pipe_ctx *pipe_ctx, struct scaler_data *scaler_data) { /*TODO: per pipe not per stream*/ @@ -1361,15 +1311,15 @@ static void hw_sequencer_build_scaler_parameter_plane( scaler_data->flags.bits.INTERLACED = 0; - scaler_data->dal_pixel_format = stream->format; + scaler_data->dal_pixel_format = pipe_ctx->format; - scaler_data->taps = stream->taps; + scaler_data->taps = pipe_ctx->taps; - scaler_data->viewport = stream->viewport; + scaler_data->viewport = pipe_ctx->viewport; - scaler_data->overscan = stream->overscan; + scaler_data->overscan = pipe_ctx->overscan; - scaler_data->ratios = &stream->ratios; + scaler_data->ratios = &pipe_ctx->ratios; /*TODO rotation and adjustment */ scaler_data->h_sharpness = 0; @@ -1377,23 +1327,19 @@ static void hw_sequencer_build_scaler_parameter_plane( } -static void set_default_colors( - struct input_pixel_processor *ipp, - struct output_pixel_processor *opp, - enum pixel_format format, - enum color_space input_color_space, - enum color_space output_color_space, - enum dc_color_depth color_depth) +static void set_default_colors(struct pipe_ctx *pipe_ctx) { struct default_adjustment default_adjust = { 0 }; default_adjust.force_hw_default = false; - default_adjust.color_space = output_color_space; + default_adjust.color_space = get_output_color_space( + &pipe_ctx->stream->public.timing); default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; - default_adjust.surface_pixel_format = format; + default_adjust.surface_pixel_format = pipe_ctx->format; /* display color depth */ - default_adjust.color_depth = color_depth; + default_adjust.color_depth = + pipe_ctx->stream->public.timing.display_color_depth; /* Lb color depth */ default_adjust.lb_color_depth = LB_PIXEL_DEPTH_24BPP; @@ -1401,99 +1347,74 @@ static void set_default_colors( build_params-> line_buffer_params[path_id][plane_id].depth);*/ - opp->funcs->opp_set_csc_default(opp, &default_adjust); + pipe_ctx->opp->funcs->opp_set_csc_default( + pipe_ctx->opp, &default_adjust); } static void program_scaler( - uint8_t controller_idx, - struct timing_generator *tg, - struct transform *xfm, const struct core_surface *surface, - const struct core_stream *stream) + const struct pipe_ctx *pipe_ctx) { struct scaler_data scaler_data = { { 0 } }; hw_sequencer_build_scaler_parameter_plane( - stream, + pipe_ctx, &scaler_data); setup_line_buffer_pixel_depth( - stream, + pipe_ctx, LB_PIXEL_DEPTH_24BPP, false); - tg->funcs->set_overscan_blank_color(tg, surface->public.colorimetry.color_space); + pipe_ctx->tg->funcs->set_overscan_blank_color( + pipe_ctx->tg, surface->public.color_space); - xfm->funcs->transform_set_scaler(xfm, &scaler_data); + pipe_ctx->xfm->funcs->transform_set_scaler(pipe_ctx->xfm, &scaler_data); - xfm->funcs->transform_update_viewport( - xfm, - &scaler_data.viewport, - false); + pipe_ctx->xfm->funcs->transform_update_viewport( + pipe_ctx->xfm, &scaler_data.viewport, false); } /** * Program the Front End of the Pipe. * The Back End was already programmed by Set Mode. */ -static bool set_plane_config( +static void set_plane_config( const struct dc *dc, struct core_surface *surface, - struct core_target *target) + struct pipe_ctx *pipe_ctx) { - const struct core_stream *core_stream = - DC_STREAM_TO_CORE(target->public.streams[0]); - const struct dc_crtc_timing *dc_crtc_timing = - &target->public.streams[0]->timing; - struct mem_input *mi = core_stream->mi; - struct input_pixel_processor *ipp = core_stream->ipp; - struct timing_generator *tg = core_stream->tg; - struct transform *xfm = core_stream->xfm; - struct output_pixel_processor *opp = core_stream->opp; - struct dc_context *ctx = core_stream->ctx; - uint8_t controller_idx = core_stream->controller_idx; - - /* TODO: Clean up change, possibly change to use same type */ - enum color_space input_color_space = - surface_color_to_color_space(&(surface->public.colorimetry)); + const struct dc_crtc_timing *crtc_timing = + &pipe_ctx->stream->public.timing; + struct mem_input *mi = pipe_ctx->mi; + struct timing_generator *tg = pipe_ctx->tg; + struct dc_context *ctx = pipe_ctx->stream->ctx; dc->hwss.pipe_control_lock( - ctx, - controller_idx, - PIPE_LOCK_CONTROL_MODE, - false); + ctx, pipe_ctx->pipe_idx, PIPE_LOCK_CONTROL_MODE, false); /* While a non-root controller is programmed we * have to lock the root controller. */ dc->hwss.pipe_control_lock( ctx, - controller_idx, + pipe_ctx->pipe_idx, PIPE_LOCK_CONTROL_GRAPHICS | PIPE_LOCK_CONTROL_SCL | PIPE_LOCK_CONTROL_BLENDER | PIPE_LOCK_CONTROL_SURFACE, true); - tg->funcs->program_timing(tg, dc_crtc_timing, false); + tg->funcs->program_timing(tg, crtc_timing, false); - dc->hwss.enable_fe_clock(ctx, controller_idx, true); + dc->hwss.enable_fe_clock(ctx, pipe_ctx->pipe_idx, true); - set_default_colors( - ipp, - opp, - core_stream->format, - input_color_space, - get_output_color_space(dc_crtc_timing), - dc_crtc_timing->display_color_depth); + set_default_colors(pipe_ctx); /* program Scaler */ - program_scaler( - controller_idx, tg, xfm, surface, core_stream); + program_scaler(surface, pipe_ctx); dc->hwss.set_blender_mode( - ctx, - controller_idx, - BLENDER_MODE_CURRENT_PIPE); + ctx, pipe_ctx->pipe_idx, BLENDER_MODE_CURRENT_PIPE); mi->funcs->mem_input_program_surface_config( mi, @@ -1504,96 +1425,92 @@ static bool set_plane_config( dc->hwss.pipe_control_lock( ctx, - controller_idx, + pipe_ctx->pipe_idx, PIPE_LOCK_CONTROL_GRAPHICS | PIPE_LOCK_CONTROL_SCL | PIPE_LOCK_CONTROL_BLENDER | PIPE_LOCK_CONTROL_SURFACE, false); - - return true; } -static bool update_plane_address( - const struct dc *dc, - const struct core_surface *surface, - struct core_target *target) +static void update_plane_addrs( + struct dc *dc, + struct resource_context *res_ctx, + const struct core_surface *surface) { - const struct core_stream *core_stream = - DC_STREAM_TO_CORE(target->public.streams[0]); - struct dc_context *ctx = core_stream->ctx; - struct mem_input *mi = core_stream->mi; - uint8_t controller_id = core_stream->controller_idx; + uint8_t j; - /* TODO: crtc should be per surface, NOT per-target */ - dc->hwss.pipe_control_lock( - ctx, - controller_id, - PIPE_LOCK_CONTROL_SURFACE, - true); - - if (false == - core_stream->mi->funcs->mem_input_program_surface_flip_and_addr( - mi, &surface->public.address, surface->public.flip_immediate)) - return false; + for (j = 0; j < MAX_PIPES; j++) { + struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[j]; - dc->hwss.pipe_control_lock( - ctx, - controller_id, - PIPE_LOCK_CONTROL_SURFACE, - false); + if (pipe_ctx->surface != surface) + continue; - return true; + dc->hwss.pipe_control_lock( + dc->ctx, + j, + PIPE_LOCK_CONTROL_SURFACE, + true); + + pipe_ctx->mi->funcs->mem_input_program_surface_flip_and_addr( + pipe_ctx->mi, + &surface->public.address, + surface->public.flip_immediate); + + dc->hwss.pipe_control_lock( + dc->ctx, + j, + PIPE_LOCK_CONTROL_SURFACE, + false); + + break; + } } -static void reset_single_stream_hw_ctx( +static void reset_single_pipe_hw_ctx( const struct dc *dc, - struct core_stream *stream, + struct pipe_ctx *pipe_ctx, struct validate_context *context) { struct dc_bios *dcb; dcb = dal_adapter_service_get_bios_parser( context->res_ctx.pool.adapter_srv); - if (stream->audio) { - dal_audio_disable_output(stream->audio, - stream->stream_enc->id, - stream->signal); - stream->audio = NULL; + if (pipe_ctx->audio) { + dal_audio_disable_output(pipe_ctx->audio, + pipe_ctx->stream_enc->id, + pipe_ctx->signal); + pipe_ctx->audio = NULL; } - core_link_disable_stream(stream->sink->link, stream); + core_link_disable_stream(pipe_ctx); - stream->tg->funcs->set_blank(stream->tg, true); - stream->tg->funcs->disable_crtc(stream->tg); - stream->mi->funcs->free_mem_input( - stream->mi, context->target_count); - stream->xfm->funcs->transform_set_scaler_bypass(stream->xfm); - unreference_clock_source(&context->res_ctx, stream->clock_source); + pipe_ctx->tg->funcs->set_blank(pipe_ctx->tg, true); + pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg); + pipe_ctx->mi->funcs->free_mem_input( + pipe_ctx->mi, context->target_count); + pipe_ctx->xfm->funcs->transform_set_scaler_bypass(pipe_ctx->xfm); + unreference_clock_source(&context->res_ctx, pipe_ctx->clock_source); dc->hwss.enable_display_power_gating( - stream->ctx, stream->controller_idx, dcb, + pipe_ctx->stream->ctx, pipe_ctx->pipe_idx, dcb, PIPE_GATING_CONTROL_ENABLE); } -static void reset_hw_ctx(struct dc *dc, - struct validate_context *context, - uint8_t target_count) +static void reset_hw_ctx( + struct dc *dc, + struct validate_context *new_context) { uint8_t i; - /* look up the targets that have been removed since last commit */ - for (i = 0; i < dc->current_context.target_count; i++) { - const struct core_target *core_target = - dc->current_context.targets[i]; - struct core_stream *core_stream = - DC_STREAM_TO_CORE(core_target->public.streams[0]); - uint8_t controller_idx = core_stream->controller_idx; - - if (context->res_ctx.controller_ctx[controller_idx].stream && - !context->res_ctx.controller_ctx[controller_idx] - .flags.timing_changed) - continue; - reset_single_stream_hw_ctx(dc, core_stream, &dc->current_context); + /* look up the targets that have been removed since last commit */ + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx_old = + &dc->current_context.res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe_ctx = &new_context->res_ctx.pipe_ctx[i]; + + if (pipe_ctx_old->stream && !pipe_ctx->stream) + reset_single_pipe_hw_ctx( + dc, pipe_ctx_old, &dc->current_context); } } @@ -1601,7 +1518,6 @@ static void power_down(struct dc *dc) { power_down_all_hw_blocks(dc); disable_vga_and_power_gate_all_controllers(dc); - } static bool wait_for_reset_trigger_to_occur( @@ -1697,7 +1613,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .apply_ctx_to_hw = apply_ctx_to_hw, .reset_hw_ctx = reset_hw_ctx, .set_plane_config = set_plane_config, - .update_plane_address = update_plane_address, + .update_plane_addrs = update_plane_addrs, .set_gamma_correction = set_gamma_ramp, .power_down = power_down, .enable_accelerated_mode = enable_accelerated_mode, diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c index 3c78431..9efed4f 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c +++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c @@ -1168,27 +1168,28 @@ bool dce110_link_encoder_construct( bool dce110_link_encoder_validate_output_with_stream( struct link_encoder *enc, - struct core_stream *stream) + struct pipe_ctx *pipe_ctx) { + struct core_stream *stream = pipe_ctx->stream; struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); bool is_valid; - switch (stream->signal) { + switch (pipe_ctx->signal) { case SIGNAL_TYPE_DVI_SINGLE_LINK: case SIGNAL_TYPE_DVI_DUAL_LINK: is_valid = validate_dvi_output( enc110, stream->sink->link->public.connector_signal, - stream->signal, + pipe_ctx->signal, &stream->public.timing); break; case SIGNAL_TYPE_HDMI_TYPE_A: is_valid = validate_hdmi_output( enc110, &stream->public.timing, - stream->max_tmds_clk_from_edid_in_mhz, - stream->max_hdmi_deep_color, - stream->max_hdmi_pixel_clock); + pipe_ctx->max_tmds_clk_from_edid_in_mhz, + pipe_ctx->max_hdmi_deep_color, + pipe_ctx->max_hdmi_pixel_clock); break; case SIGNAL_TYPE_RGB: is_valid = validate_rgb_output( diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h index 64a81f2..bbddd0b 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h +++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h @@ -81,7 +81,7 @@ bool dce110_link_encoder_construct( bool dce110_link_encoder_validate_output_with_stream( struct link_encoder *enc, - struct core_stream *stream); + struct pipe_ctx *pipe_ctx); /****************** HW programming ************************/ diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c index 9e2b5d9..4fdf1f0 100644 --- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c @@ -477,7 +477,7 @@ void dce110_destruct_resource_pool(struct resource_pool *pool) { unsigned int i; - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { if (pool->opps[i] != NULL) dce110_opp_destroy(&pool->opps[i]); @@ -567,12 +567,13 @@ static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) } static void build_audio_output( - const struct core_stream *stream, + const struct pipe_ctx *pipe_ctx, struct audio_output *audio_output) { - audio_output->engine_id = stream->stream_enc->id; + const struct core_stream *stream = pipe_ctx->stream; + audio_output->engine_id = pipe_ctx->stream_enc->id; - audio_output->signal = stream->signal; + audio_output->signal = pipe_ctx->signal; /* audio_crtc_info */ @@ -604,42 +605,43 @@ static void build_audio_output( stream->public.timing.display_color_depth; audio_output->crtc_info.requested_pixel_clock = - stream->pix_clk_params.requested_pix_clk; + pipe_ctx->pix_clk_params.requested_pix_clk; /* TODO - Investigate why calculated pixel clk has to be * requested pixel clk */ audio_output->crtc_info.calculated_pixel_clock = - stream->pix_clk_params.requested_pix_clk; + pipe_ctx->pix_clk_params.requested_pix_clk; - if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || - stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { + if (pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT || + pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { audio_output->pll_info.dp_dto_source_clock_in_khz = dal_display_clock_get_dp_ref_clk_frequency( - stream->dis_clk); + pipe_ctx->dis_clk); } audio_output->pll_info.feed_back_divider = - stream->pll_settings.feedback_divider; + pipe_ctx->pll_settings.feedback_divider; audio_output->pll_info.dto_source = translate_to_dto_source( - stream->controller_idx + 1); + pipe_ctx->pipe_idx + 1); /* TODO hard code to enable for now. Need get from stream */ audio_output->pll_info.ss_enabled = true; audio_output->pll_info.ss_percentage = - stream->pll_settings.ss_percentage; + pipe_ctx->pll_settings.ss_percentage; } static void get_pixel_clock_parameters( - const struct core_stream *stream, + const struct pipe_ctx *pipe_ctx, struct pixel_clk_params *pixel_clk_params) { + const struct core_stream *stream = pipe_ctx->stream; pixel_clk_params->requested_pix_clk = stream->public.timing.pix_clk_khz; pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id; pixel_clk_params->signal_type = stream->sink->public.sink_signal; - pixel_clk_params->controller_id = stream->controller_idx + 1; + pixel_clk_params->controller_id = pipe_ctx->pipe_idx + 1; /* TODO: un-hardcode*/ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW * LINK_RATE_REF_FREQ_IN_KHZ; @@ -649,20 +651,20 @@ static void get_pixel_clock_parameters( pixel_clk_params->flags.DISPLAY_BLANKED = 1; } -static enum dc_status build_stream_hw_param(struct core_stream *stream) +static enum dc_status build_pipe_hw_param(struct pipe_ctx *pipe_ctx) { /*TODO: unhardcode*/ - stream->max_tmds_clk_from_edid_in_mhz = 0; - stream->max_hdmi_deep_color = COLOR_DEPTH_121212; - stream->max_hdmi_pixel_clock = 600000; + pipe_ctx->max_tmds_clk_from_edid_in_mhz = 0; + pipe_ctx->max_hdmi_deep_color = COLOR_DEPTH_121212; + pipe_ctx->max_hdmi_pixel_clock = 600000; - get_pixel_clock_parameters(stream, &stream->pix_clk_params); - stream->clock_source->funcs->get_pix_clk_dividers( - stream->clock_source, - &stream->pix_clk_params, - &stream->pll_settings); + get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->pix_clk_params); + pipe_ctx->clock_source->funcs->get_pix_clk_dividers( + pipe_ctx->clock_source, + &pipe_ctx->pix_clk_params, + &pipe_ctx->pll_settings); - build_audio_output(stream, &stream->audio_output); + build_audio_output(pipe_ctx, &pipe_ctx->audio_output); return DC_OK; } @@ -672,7 +674,7 @@ static enum dc_status validate_mapped_resource( struct validate_context *context) { enum dc_status status = DC_OK; - uint8_t i, j; + uint8_t i, j, k; for (i = 0; i < context->target_count; i++) { struct core_target *target = context->targets[i]; @@ -683,30 +685,41 @@ static enum dc_status validate_mapped_resource( DC_STREAM_TO_CORE(target->public.streams[j]); struct core_link *link = stream->sink->link; - if (!stream->tg->funcs->validate_timing( - stream->tg, &stream->public.timing)) - return DC_FAIL_CONTROLLER_VALIDATE; + for (k = 0; k < MAX_PIPES; k++) { + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[k]; + + if (context->res_ctx.pipe_ctx[k].stream != stream) + continue; + + if (!pipe_ctx->tg->funcs->validate_timing( + pipe_ctx->tg, &stream->public.timing)) + return DC_FAIL_CONTROLLER_VALIDATE; - status = build_stream_hw_param(stream); + status = build_pipe_hw_param(pipe_ctx); - if (status != DC_OK) - return status; + if (status != DC_OK) + return status; - if (!link->link_enc->funcs->validate_output_with_stream( - link->link_enc, - stream)) - return DC_FAIL_ENC_VALIDATE; + if (!link->link_enc->funcs->validate_output_with_stream( + link->link_enc, + pipe_ctx)) + return DC_FAIL_ENC_VALIDATE; - /* TODO: validate audio ASIC caps, encoder */ + /* TODO: validate audio ASIC caps, encoder */ - status = dc_link_validate_mode_timing(stream->sink, - link, - &stream->public.timing); + status = dc_link_validate_mode_timing(stream->sink, + link, + &stream->public.timing); - if (status != DC_OK) - return status; + if (status != DC_OK) + return status; - build_info_frame(stream); + build_info_frame(pipe_ctx); + + /* do not need to validate non root pipes */ + break; + } } } @@ -717,7 +730,7 @@ enum dc_status dce110_validate_bandwidth( const struct dc *dc, struct validate_context *context) { - uint8_t i, j; + uint8_t i; enum dc_status result = DC_ERROR_UNEXPECTED; uint8_t number_of_displays = 0; uint8_t max_htaps = 1; @@ -727,76 +740,75 @@ enum dc_status dce110_validate_bandwidth( memset(&context->bw_mode_data, 0, sizeof(context->bw_mode_data)); - for (i = 0; i < context->target_count; i++) { - struct core_target *target = context->targets[i]; - for (j = 0; j < target->public.stream_count; j++) { - struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); - struct bw_calcs_input_single_display *disp = &context-> - bw_mode_data.displays_data[number_of_displays]; - - if (target->status.surface_count == 0) { - disp->graphics_scale_ratio = bw_int_to_fixed(1); - disp->graphics_h_taps = 2; - disp->graphics_v_taps = 2; - - /* TODO: remove when bw formula accepts taps per - * display - */ - if (max_vtaps < 2) - max_vtaps = 2; - if (max_htaps < 2) - max_htaps = 2; - - } else { - disp->graphics_scale_ratio = - fixed31_32_to_bw_fixed( - stream->ratios.vert.value); - disp->graphics_h_taps = stream->taps.h_taps; - disp->graphics_v_taps = stream->taps.v_taps; - - /* TODO: remove when bw formula accepts taps per - * display - */ - if (max_vtaps < stream->taps.v_taps) - max_vtaps = stream->taps.v_taps; - if (max_htaps < stream->taps.h_taps) - max_htaps = stream->taps.h_taps; - } + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + struct bw_calcs_input_single_display *disp = &context-> + bw_mode_data.displays_data[number_of_displays]; + + if (pipe_ctx->stream == NULL) + continue; - disp->graphics_src_width = - stream->public.timing.h_addressable; - disp->graphics_src_height = - stream->public.timing.v_addressable; - disp->h_total = stream->public.timing.h_total; - disp->pixel_rate = bw_frc_to_fixed( - stream->public.timing.pix_clk_khz, 1000); - - /*TODO: get from surface*/ - disp->graphics_bytes_per_pixel = 4; - disp->graphics_tiling_mode = bw_def_tiled; - - /* DCE11 defaults*/ - disp->graphics_lb_bpc = 10; - disp->graphics_interlace_mode = false; - disp->fbc_enable = false; - disp->lpt_enable = false; - disp->graphics_stereo_mode = bw_def_mono; - disp->underlay_mode = bw_def_none; - - /*All displays will be synchronized if timings are all - * the same + if (pipe_ctx->ratios.vert.value == 0) { + disp->graphics_scale_ratio = bw_int_to_fixed(1); + disp->graphics_h_taps = 2; + disp->graphics_v_taps = 2; + + /* TODO: remove when bw formula accepts taps per + * display + */ + if (max_vtaps < 2) + max_vtaps = 2; + if (max_htaps < 2) + max_htaps = 2; + + } else { + disp->graphics_scale_ratio = + fixed31_32_to_bw_fixed( + pipe_ctx->ratios.vert.value); + disp->graphics_h_taps = pipe_ctx->taps.h_taps; + disp->graphics_v_taps = pipe_ctx->taps.v_taps; + + /* TODO: remove when bw formula accepts taps per + * display */ - if (number_of_displays != 0 && all_displays_in_sync) - if (dm_memcmp(&prev_timing, - &stream->public.timing, - sizeof(struct dc_crtc_timing))!= 0) - all_displays_in_sync = false; - if (number_of_displays == 0) - prev_timing = stream->public.timing; - - number_of_displays++; + if (max_vtaps < pipe_ctx->taps.v_taps) + max_vtaps = pipe_ctx->taps.v_taps; + if (max_htaps < pipe_ctx->taps.h_taps) + max_htaps = pipe_ctx->taps.h_taps; } + + disp->graphics_src_width = + pipe_ctx->stream->public.timing.h_addressable; + disp->graphics_src_height = + pipe_ctx->stream->public.timing.v_addressable; + disp->h_total = pipe_ctx->stream->public.timing.h_total; + disp->pixel_rate = bw_frc_to_fixed( + pipe_ctx->stream->public.timing.pix_clk_khz, 1000); + + /*TODO: get from surface*/ + disp->graphics_bytes_per_pixel = 4; + disp->graphics_tiling_mode = bw_def_tiled; + + /* DCE11 defaults*/ + disp->graphics_lb_bpc = 10; + disp->graphics_interlace_mode = false; + disp->fbc_enable = false; + disp->lpt_enable = false; + disp->graphics_stereo_mode = bw_def_mono; + disp->underlay_mode = bw_def_none; + + /*All displays will be synchronized if timings are all + * the same + */ + if (number_of_displays != 0 && all_displays_in_sync) + if (dm_memcmp(&prev_timing, + &pipe_ctx->stream->public.timing, + sizeof(struct dc_crtc_timing)) != 0) + all_displays_in_sync = false; + if (number_of_displays == 0) + prev_timing = pipe_ctx->stream->public.timing; + + number_of_displays++; } /* TODO: remove when bw formula accepts taps per @@ -813,7 +825,7 @@ enum dc_status dce110_validate_bandwidth( dc->ctx->logger, LOG_MAJOR_BWM, LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS, - "%s: start\n", + "%s: start", __func__); if (!bw_calcs( @@ -891,14 +903,17 @@ static void set_target_unchanged( struct validate_context *context, uint8_t target_idx) { - uint8_t i; + uint8_t i, j; struct core_target *target = context->targets[target_idx]; context->target_flags[target_idx].unchanged = true; for (i = 0; i < target->public.stream_count; i++) { - struct core_stream *core_stream = + struct core_stream *stream = DC_STREAM_TO_CORE(target->public.streams[i]); - uint8_t index = core_stream->controller_idx; - context->res_ctx.controller_ctx[index].flags.unchanged = true; + for (j = 0; j < MAX_PIPES; j++) { + if (context->res_ctx.pipe_ctx[j].stream == stream) + context->res_ctx.pipe_ctx[j].flags.unchanged = + true; + } } } @@ -906,24 +921,7 @@ static enum dc_status map_clock_resources( const struct dc *dc, struct validate_context *context) { - uint8_t i, j; - - /* mark resources used for targets that are already active */ - for (i = 0; i < context->target_count; i++) { - struct core_target *target = context->targets[i]; - - if (!context->target_flags[i].unchanged) - continue; - - for (j = 0; j < target->public.stream_count; j++) { - struct core_stream *stream = - DC_STREAM_TO_CORE(target->public.streams[j]); - - reference_clock_source( - &context->res_ctx, - stream->clock_source); - } - } + uint8_t i, j, k; /* acquire new resources */ for (i = 0; i < context->target_count; i++) { @@ -936,24 +934,35 @@ static enum dc_status map_clock_resources( struct core_stream *stream = DC_STREAM_TO_CORE(target->public.streams[j]); - if (dc_is_dp_signal(stream->signal) - || stream->signal == SIGNAL_TYPE_VIRTUAL) - stream->clock_source = context->res_ctx. - pool.clock_sources[DCE110_CLK_SRC_EXT]; - else - stream->clock_source = - find_used_clk_src_for_sharing( - context, stream); - if (stream->clock_source == NULL) - stream->clock_source = - find_first_free_pll(&context->res_ctx); - - if (stream->clock_source == NULL) - return DC_NO_CLOCK_SOURCE_RESOURCE; - - reference_clock_source( - &context->res_ctx, - stream->clock_source); + for (k = 0; k < MAX_PIPES; k++) { + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[k]; + + if (context->res_ctx.pipe_ctx[k].stream != stream) + continue; + + if (dc_is_dp_signal(pipe_ctx->signal) + || pipe_ctx->signal == SIGNAL_TYPE_VIRTUAL) + pipe_ctx->clock_source = context->res_ctx. + pool.clock_sources[DCE110_CLK_SRC_EXT]; + else + pipe_ctx->clock_source = + find_used_clk_src_for_sharing( + &context->res_ctx, pipe_ctx); + if (pipe_ctx->clock_source == NULL) + pipe_ctx->clock_source = + find_first_free_pll(&context->res_ctx); + + if (pipe_ctx->clock_source == NULL) + return DC_NO_CLOCK_SOURCE_RESOURCE; + + reference_clock_source( + &context->res_ctx, + pipe_ctx->clock_source); + + /* only one cs per stream regardless of mpo */ + break; + } } } @@ -971,24 +980,30 @@ enum dc_status dce110_validate_with_context( struct dc_context *dc_ctx = dc->ctx; for (i = 0; i < set_count; i++) { + bool unchanged = false; + context->targets[i] = DC_TARGET_TO_CORE(set[i].target); + context->target_count++; for (j = 0; j < dc->current_context.target_count; j++) - if (dc->current_context.targets[j] == context->targets[i]) + if (dc->current_context.targets[j] + == context->targets[i]) { + unchanged = true; set_target_unchanged(context, i); - - if (!context->target_flags[i].unchanged) - if (!logical_attach_surfaces_to_target( - (struct dc_surface **)set[i].surfaces, - set[i].surface_count, - &context->targets[i]->public)) { + context->target_status[i] = + dc->current_context.target_status[j]; + } + if (!unchanged) + if (!attach_surfaces_to_context( + (struct dc_surface **)set[i].surfaces, + set[i].surface_count, + &context->targets[i]->public, + context)) { DC_ERROR("Failed to attach surface to target!\n"); return DC_FAIL_ATTACH_SURFACES; } } - context->target_count = set_count; - context->res_ctx.pool = dc->res_pool; result = map_resources(dc, context); @@ -1073,7 +1088,7 @@ bool dce110_construct_resource_pool( } - pool->controller_count = + pool->pipe_count = dal_adapter_service_get_func_controllers_num(adapter_serv); pool->stream_enc_count = dal_adapter_service_get_stream_engines_num( adapter_serv); @@ -1084,7 +1099,7 @@ bool dce110_construct_resource_pool( goto filter_create_fail; } - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { pool->timing_generators[i] = dce110_timing_generator_create( adapter_serv, ctx, i, &dce110_tg_offsets[i]); if (pool->timing_generators[i] == NULL) { @@ -1134,7 +1149,7 @@ bool dce110_construct_resource_pool( audio_init_data.as = adapter_serv; audio_init_data.ctx = ctx; pool->audio_count = 0; - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { struct graphics_object_id obj_id; obj_id = dal_adapter_service_enum_audio_object(adapter_serv, i); @@ -1192,13 +1207,13 @@ stream_enc_create_fail: } audio_create_fail: - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { if (pool->audios[i] != NULL) dal_audio_destroy(&pool->audios[i]); } controller_create_fail: - for (i = 0; i < pool->controller_count; i++) { + for (i = 0; i < pool->pipe_count; i++) { if (pool->opps[i] != NULL) dce110_opp_destroy(&pool->opps[i]); diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h index e3dbaeb..18bd2da 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h @@ -39,12 +39,10 @@ struct core_stream; container_of(dc_target, struct core_target, public) #define MAX_PIPES 6 -#define MAX_STREAMS 6 #define MAX_CLOCK_SOURCES 7 struct core_target { struct dc_target public; - struct dc_target_status status; struct dc_context *ctx; }; @@ -90,53 +88,12 @@ struct core_stream { struct dc_stream public; /* field internal to DC */ + struct dc_context *ctx; const struct core_sink *sink; - struct clock_source *clock_source; - - struct mem_input *mi; - struct input_pixel_processor *ipp; - struct transform *xfm; - struct output_pixel_processor *opp; - struct timing_generator *tg; - struct stream_encoder *stream_enc; - struct display_clock *dis_clk; - - struct overscan_info overscan; - struct scaling_ratios ratios; - struct rect viewport; - struct scaling_taps taps; - enum pixel_format format; - - uint8_t controller_idx; - - struct audio *audio; - - enum signal_type signal; - - /* TODO: move these members into appropriate places (work in progress)*/ - /* timing validation (HDMI only) */ - uint32_t max_tmds_clk_from_edid_in_mhz; - /* maximum supported deep color depth for HDMI */ - enum dc_color_depth max_hdmi_deep_color; - /* maximum supported pixel clock for HDMI */ - uint32_t max_hdmi_pixel_clock; - /* end of TODO */ - - /*TODO: AUTO merge if possible*/ - struct pixel_clk_params pix_clk_params; - struct pll_settings pll_settings; - - /*fmt*/ - /*TODO: AUTO new codepath in apply_context to hw to - * generate these bw unrelated/no fail params*/ - struct bit_depth_reduction_params bit_depth_params;/* used by DCP and FMT */ + /* used by DCP and FMT */ + struct bit_depth_reduction_params bit_depth_params; struct clamping_and_pixel_encoding_params clamping; - struct hw_info_frame info_frame; - struct encoder_info_frame encoder_info_frame; - - struct audio_output audio_output; - struct dc_context *ctx; struct dc_stream_status status; }; @@ -267,13 +224,9 @@ enum dc_status dc_link_validate_mode_timing( void core_link_resume(struct core_link *link); -void core_link_enable_stream( - struct core_link *link, - struct core_stream *stream); +void core_link_enable_stream(struct pipe_ctx *pipe_ctx); -void core_link_disable_stream( - struct core_link *link, - struct core_stream *stream); +void core_link_disable_stream(struct pipe_ctx *pipe_ctx); /********** DAL Core*********************/ #include "display_clock_interface.h" @@ -304,10 +257,10 @@ struct resource_pool { struct input_pixel_processor *ipps[MAX_PIPES]; struct transform *transforms[MAX_PIPES]; struct output_pixel_processor *opps[MAX_PIPES]; - struct timing_generator *timing_generators[MAX_STREAMS]; + struct timing_generator *timing_generators[MAX_PIPES]; struct stream_encoder *stream_enc[MAX_PIPES * 2]; - uint8_t controller_count; + uint8_t pipe_count; uint8_t stream_enc_count; union supported_stream_engines stream_engines; @@ -315,7 +268,7 @@ struct resource_pool { struct clock_source *clock_sources[MAX_CLOCK_SOURCES]; uint8_t clk_src_count; - struct audio *audios[MAX_STREAMS]; + struct audio *audios[MAX_PIPES]; uint8_t audio_count; struct display_clock *display_clock; @@ -325,9 +278,46 @@ struct resource_pool { struct resource_funcs *funcs; }; -struct controller_ctx { +struct pipe_ctx { struct core_surface *surface; struct core_stream *stream; + + struct mem_input *mi; + struct input_pixel_processor *ipp; + struct transform *xfm; + struct output_pixel_processor *opp; + struct timing_generator *tg; + + struct overscan_info overscan; + struct scaling_ratios ratios; + struct rect viewport; + struct scaling_taps taps; + enum pixel_format format; + + struct stream_encoder *stream_enc; + struct display_clock *dis_clk; + struct clock_source *clock_source; + + struct audio *audio; + struct audio_output audio_output; + + enum signal_type signal; + + /* timing validation (HDMI only) */ + uint32_t max_tmds_clk_from_edid_in_mhz; + /* maximum supported deep color depth for HDMI */ + enum dc_color_depth max_hdmi_deep_color; + /* maximum supported pixel clock for HDMI */ + uint32_t max_hdmi_pixel_clock; + + struct pixel_clk_params pix_clk_params; + struct pll_settings pll_settings; + + /*fmt*/ + struct encoder_info_frame encoder_info_frame; + + uint8_t pipe_idx; + struct flags { bool unchanged; bool timing_changed; @@ -336,10 +326,10 @@ struct controller_ctx { struct resource_context { struct resource_pool pool; - struct controller_ctx controller_ctx[MAX_PIPES]; + struct pipe_ctx pipe_ctx[MAX_PIPES]; union supported_stream_engines used_stream_engines; bool is_stream_enc_acquired[MAX_PIPES * 2]; - bool is_audio_acquired[MAX_STREAMS]; + bool is_audio_acquired[MAX_PIPES]; uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES]; }; @@ -348,6 +338,7 @@ struct target_flags { }; struct validate_context { struct core_target *targets[MAX_PIPES]; + struct dc_target_status target_status[MAX_PIPES]; struct target_flags target_flags[MAX_PIPES]; uint8_t target_count; diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h index 5dd16dc..8b0afe1 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h @@ -39,22 +39,19 @@ enum pipe_gating_control { struct hw_sequencer_funcs { enum dc_status (*apply_ctx_to_hw)( - const struct dc *dc, struct validate_context *context); + struct dc *dc, struct validate_context *context); - void (*reset_hw_ctx)( - struct dc *dc, - struct validate_context *context, - uint8_t target_count); + void (*reset_hw_ctx)(struct dc *dc, struct validate_context *context); - bool (*set_plane_config)( + void (*set_plane_config)( const struct dc *dc, struct core_surface *surface, - struct core_target *target); + struct pipe_ctx *pipe_ctx); - bool (*update_plane_address)( - const struct dc *dc, - const struct core_surface *surface, - struct core_target *target); + void (*update_plane_addrs)( + struct dc *dc, + struct resource_context *res_ctx, + const struct core_surface *surface); bool (*set_gamma_correction)( struct input_pixel_processor *ipp, @@ -93,9 +90,9 @@ struct hw_sequencer_funcs { void (*program_bw)(struct dc *dc, struct validate_context *context); - void (*enable_stream)(struct core_stream *stream); + void (*enable_stream)(struct pipe_ctx *pipe_ctx); - void (*disable_stream)(struct core_stream *stream); + void (*disable_stream)(struct pipe_ctx *pipe_ctx); void (*enable_fe_clock)( struct dc_context *ctx, uint8_t controller_id, bool enable); diff --git a/drivers/gpu/drm/amd/dal/dc/inc/link_encoder.h b/drivers/gpu/drm/amd/dal/dc/inc/link_encoder.h index 54e75dc..d11ef05 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/link_encoder.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/link_encoder.h @@ -19,6 +19,7 @@ struct link_mst_stream_allocation_table; struct dc_link_settings; struct link_training_settings; struct core_stream; +struct pipe_ctx; struct encoder_init_data { struct adapter_service *adapter_service; @@ -82,8 +83,8 @@ struct link_encoder { }; struct link_encoder_funcs { - bool (*validate_output_with_stream)(struct link_encoder *enc, - struct core_stream *stream); + bool (*validate_output_with_stream)( + struct link_encoder *enc, struct pipe_ctx *pipe_ctx); void (*hw_init)(struct link_encoder *enc); void (*setup)(struct link_encoder *enc, enum signal_type signal); diff --git a/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h index 551caa3..d56b5d1 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h @@ -49,7 +49,7 @@ void dp_receiver_power_ctrl(struct core_link *link, bool on); void dp_disable_link_phy(struct core_link *link, enum signal_type signal); -void dp_disable_link_phy_mst(struct core_link *link, struct core_stream *stream); +void dp_disable_link_phy_mst(struct core_link *link, enum signal_type signal); bool dp_set_hw_training_pattern( struct core_link *link, diff --git a/drivers/gpu/drm/amd/dal/dc/inc/resource.h b/drivers/gpu/drm/amd/dal/dc/inc/resource.h index b4936b4..a7b0032 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/resource.h @@ -38,7 +38,7 @@ bool dc_construct_resource_pool(struct adapter_service *adapter_serv, void build_scaling_params( const struct dc_surface *surface, - struct core_stream *stream); + struct pipe_ctx *pipe_ctx); void build_scaling_params_for_context( const struct dc *dc, @@ -57,13 +57,14 @@ bool is_same_timing( const struct dc_crtc_timing *timing2); struct clock_source *find_used_clk_src_for_sharing( - struct validate_context *context, - struct core_stream *stream); + struct resource_context *res_ctx, + struct pipe_ctx *pipe_ctx); -bool logical_attach_surfaces_to_target( +bool attach_surfaces_to_context( struct dc_surface *surfaces[], uint8_t surface_count, - struct dc_target *dc_target); + struct dc_target *dc_target, + struct validate_context *context); void pplib_apply_safe_state(const struct dc *dc); @@ -72,7 +73,7 @@ void pplib_apply_display_requirements( const struct validate_context *context, struct dc_pp_display_configuration *pp_display_cfg); -void build_info_frame(struct core_stream *stream); +void build_info_frame(struct pipe_ctx *pipe_ctx); enum dc_status map_resources( const struct dc *dc, diff --git a/drivers/gpu/drm/amd/dal/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/dal/dc/virtual/virtual_link_encoder.c index 36886a4..0b3b1b8 100644 --- a/drivers/gpu/drm/amd/dal/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/dal/dc/virtual/virtual_link_encoder.c @@ -31,7 +31,7 @@ static bool virtual_link_encoder_validate_output_with_stream( struct link_encoder *enc, - struct core_stream *stream) { return true; } + struct pipe_ctx *pipe_ctx) { return true; } static void virtual_link_encoder_hw_init(struct link_encoder *enc) {} diff --git a/drivers/gpu/drm/amd/dal/include/grph_csc_types.h b/drivers/gpu/drm/amd/dal/include/grph_csc_types.h index 711b458..5927dd0 100644 --- a/drivers/gpu/drm/amd/dal/include/grph_csc_types.h +++ b/drivers/gpu/drm/amd/dal/include/grph_csc_types.h @@ -28,19 +28,6 @@ #include "set_mode_types.h" -enum color_space { - COLOR_SPACE_UNKNOWN, - COLOR_SPACE_SRGB_FULL_RANGE, - COLOR_SPACE_SRGB_LIMITED_RANGE, - COLOR_SPACE_YPBPR601, - COLOR_SPACE_YPBPR709, - COLOR_SPACE_YCBCR601, - COLOR_SPACE_YCBCR709, - COLOR_SPACE_YCBCR601_YONLY, - COLOR_SPACE_YCBCR709_YONLY, - COLOR_SPACE_N_MVPU_SUPER_AA, -}; - enum grph_color_adjust_option { GRPH_COLOR_MATRIX_HW_DEFAULT = 1, GRPH_COLOR_MATRIX_SW -- 2.7.4