diff options
Diffstat (limited to 'meta-amdfalconx86/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch')
-rw-r--r-- | meta-amdfalconx86/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch | 1527 |
1 files changed, 1527 insertions, 0 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch b/meta-amdfalconx86/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch new file mode 100644 index 00000000..5e3d0e64 --- /dev/null +++ b/meta-amdfalconx86/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch @@ -0,0 +1,1527 @@ +From d5172ff2745aed4b4db28cd6d90f3a23dfe1e768 Mon Sep 17 00:00:00 2001 +From: Chris Park <Chris.Park@amd.com> +Date: Wed, 25 Nov 2015 16:01:12 -0500 +Subject: [PATCH 0520/1110] drm/amd/dal: Clean-up Link & Stream Encoder + +Branch out interface functions to display specifics. +Move switch statement to upper layer. + +Signed-off-by: Harry Wentland <harry.wentland@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 84 ++- + .../drm/amd/dal/dc/dce110/dce110_link_encoder.c | 274 +++------ + .../drm/amd/dal/dc/dce110/dce110_link_encoder.h | 57 +- + .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 1 - + .../drm/amd/dal/dc/dce110/dce110_stream_encoder.c | 667 ++++++++++++--------- + .../drm/amd/dal/dc/dce110/dce110_stream_encoder.h | 52 +- + drivers/gpu/drm/amd/dal/include/encoder_types.h | 1 - + 7 files changed, 592 insertions(+), 544 deletions(-) + +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 74294cb..394b645 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 +@@ -634,10 +634,14 @@ static void update_bios_scratch_critical_state(struct adapter_service *as, + + static void update_info_frame(struct core_stream *stream) + { +- dce110_stream_encoder_update_info_packets( +- stream->stream_enc, +- stream->signal, +- &stream->encoder_info_frame); ++ if (dc_is_hdmi_signal(stream->signal)) ++ dce110_stream_encoder_update_hdmi_info_packets( ++ stream->stream_enc, ++ &stream->encoder_info_frame); ++ else if (dc_is_dp_signal(stream->signal)) ++ dce110_stream_encoder_update_dp_info_packets( ++ stream->stream_enc, ++ &stream->encoder_info_frame); + } + + +@@ -690,10 +694,15 @@ static void disable_stream(struct core_stream *stream) + { + struct core_link *link = stream->sink->link; + +- dce110_stream_encoder_stop_info_packets( +- stream->stream_enc, +- stream->stream_enc->id, +- stream->signal); ++ if (dc_is_hdmi_signal(stream->signal)) ++ dce110_stream_encoder_stop_hdmi_info_packets( ++ stream->stream_enc->ctx, ++ stream->stream_enc->id); ++ ++ if (dc_is_dp_signal(stream->signal)) ++ dce110_stream_encoder_stop_dp_info_packets( ++ stream->stream_enc->ctx, ++ stream->stream_enc->id); + + if (stream->audio) { + /* mute audio */ +@@ -708,7 +717,9 @@ static void disable_stream(struct core_stream *stream) + } + + /* blank at encoder level */ +- dce110_stream_encoder_blank(stream->stream_enc, stream->signal); ++ if (dc_is_dp_signal(stream->signal)) ++ dce110_stream_encoder_dp_blank(stream->stream_enc); ++ + dce110_link_encoder_connect_dig_be_to_fe( + link->link_enc, + stream->stream_enc->id, +@@ -725,8 +736,7 @@ static void unblank_stream(struct core_stream *stream, + params.crtc_timing.pixel_clock = + stream->public.timing.pix_clk_khz; + params.link_settings.link_rate = link_settings->link_rate; +- params.signal = stream->signal; +- dce110_stream_encoder_unblank( ++ dce110_stream_encoder_dp_unblank( + stream->stream_enc, ¶ms); + } + +@@ -787,8 +797,7 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) + + dce110_link_encoder_update_mst_stream_allocation_table( + link_encoder, +- &table, +- false); ++ &table); + + dc_helpers_dp_mst_poll_for_allocation_change_trigger( + stream->ctx, +@@ -803,8 +812,8 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) + table.stream_allocations[0].pbn, + table.stream_allocations[0].pbn_per_slot); + +- dce110_link_encoder_set_mst_bandwidth( +- link_encoder, ++ dce110_stream_encoder_set_mst_bandwidth( ++ stream_encoder, + stream_encoder->id, + avg_time_slots_per_mtp); + +@@ -823,8 +832,8 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream) + table.stream_count = 1; + table.stream_allocations[0].slot_count = 0; + +- dce110_link_encoder_set_mst_bandwidth( +- link_encoder, ++ dce110_stream_encoder_set_mst_bandwidth( ++ stream_encoder, + stream_encoder->id, + avg_time_slots_per_mtp); + +@@ -836,8 +845,7 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream) + + dce110_link_encoder_update_mst_stream_allocation_table( + link_encoder, +- &table, +- false); ++ &table); + + dc_helpers_dp_mst_poll_for_allocation_change_trigger( + stream->ctx, +@@ -859,7 +867,6 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, + { + struct core_stream *stream = + 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] +@@ -921,14 +928,31 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, + dce110_link_encoder_setup( + stream->sink->link->link_enc, + stream->signal); +- if (ENCODER_RESULT_OK != dce110_stream_encoder_setup( ++ ++ if (!dc_is_dp_signal(stream->signal)) ++ if (ENCODER_RESULT_OK != dce110_stream_encoder_setup( ++ stream->stream_enc, ++ &stream->public.timing, ++ stream->signal, ++ stream->audio != NULL)) { ++ BREAK_TO_DEBUGGER(); ++ return DC_ERROR_UNEXPECTED; ++ } ++ ++ if (dc_is_dp_signal(stream->signal)) ++ dce110_stream_encoder_dp_set_stream_attribute( + stream->stream_enc, +- &stream->public.timing, +- stream->signal, +- stream->audio != NULL)) { +- BREAK_TO_DEBUGGER(); +- return DC_ERROR_UNEXPECTED; +- } ++ &stream->public.timing); ++ ++ if (dc_is_hdmi_signal(stream->signal)) ++ dce110_stream_encoder_hdmi_set_stream_attribute( ++ stream->stream_enc, ++ &stream->public.timing); ++ ++ if (dc_is_dvi_signal(stream->signal)) ++ dce110_stream_encoder_dvi_set_stream_attribute( ++ stream->stream_enc, ++ &stream->public.timing); + + if (stream->audio != NULL) { + if (AUDIO_RESULT_OK != dal_audio_setup( +@@ -968,7 +992,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx, + + } + +- unblank_stream(stream, &stream->sink->link->cur_link_settings); ++ if (dc_is_dp_signal(stream->signal)) ++ unblank_stream(stream, &stream->sink->link->cur_link_settings); + + return DC_OK; + } +@@ -1810,7 +1835,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .destruct_resource_pool = dce110_destruct_resource_pool, + .validate_with_context = dce110_validate_with_context, + .validate_bandwidth = dce110_validate_bandwidth, +- .set_afmt_memory_power_state = dce110_set_afmt_memory_power_state, ++ .set_afmt_memory_power_state = ++ dce110_stream_encoder_set_afmt_memory_power_state, + .enable_display_pipe_clock_gating = dce110_enable_display_pipe_clock_gating, + .enable_display_power_gating = dce110_enable_display_power_gating, + .program_bw = dce110_program_bw +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 9817318..0ad582b 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 +@@ -1377,69 +1377,39 @@ void dce110_link_encoder_setup( + dal_write_reg(enc->ctx, addr, value); + } + +-/* +- * @brief +- * Configure digital transmitter and enable both encoder and transmitter +- * Actual output will be available after calling unblank() +- */ +-enum encoder_result dce110_link_encoder_enable_output( ++enum encoder_result dce110_link_encoder_enable_tmds_output( + struct link_encoder *enc, +- const struct link_settings *link_settings, +- enum engine_id engine, + enum clock_source_id clock_source, +- enum signal_type signal, + enum dc_color_depth color_depth, + uint32_t pixel_clock) + { +- struct bp_transmitter_control cntl = { 0 }; +- +- if (enc->connector.id == CONNECTOR_ID_EDP) { +- /* power up eDP panel */ +- +- link_encoder_edp_power_control( +- enc, true); +- +- link_encoder_edp_wait_for_hpd_ready( +- enc, enc->connector, true); +- +- /* have to turn off the backlight +- * before power down eDP panel */ +- link_encoder_edp_backlight_control( +- enc, true); +- } +- +- /* Enable the PHY */ +- +- /* number_of_lanes is used for pixel clock adjust, +- * but it's not passed to asic_control. +- * We need to set number of lanes manually. */ +- if (dc_is_dp_signal(signal)) +- configure_encoder(enc, engine, link_settings); +- +- cntl.action = TRANSMITTER_CONTROL_ENABLE; +- cntl.engine_id = engine; +- cntl.transmitter = enc->transmitter; +- cntl.pll_id = clock_source; +- cntl.signal = signal; +- cntl.lanes_number = link_settings->lane_count; +- cntl.hpd_sel = enc->hpd_source; +- if (dc_is_dp_signal(signal)) +- cntl.pixel_clock = link_settings->link_rate +- * LINK_RATE_REF_FREQ_IN_KHZ; +- else +- cntl.pixel_clock = pixel_clock; +- cntl.color_depth = color_depth; ++ return ENCODER_RESULT_OK; ++} + +- if (DELAY_AFTER_PIXEL_FORMAT_CHANGE) +- dc_service_sleep_in_milliseconds( +- enc->ctx, +- DELAY_AFTER_PIXEL_FORMAT_CHANGE); ++enum encoder_result dce110_link_encoder_enable_dual_link_tmds_output( ++ struct link_encoder *enc, ++ enum clock_source_id clock_source, ++ enum dc_color_depth color_depth, ++ uint32_t pixel_clock) ++{ ++ return ENCODER_RESULT_OK; ++} + +- dal_bios_parser_transmitter_control( +- dal_adapter_service_get_bios_parser( +- enc->adapter_service), +- &cntl); ++/* enables DP PHY output */ ++enum encoder_result dce110_link_encoder_enable_dp_output( ++ struct link_encoder *enc, ++ const struct link_settings *link_settings, ++ enum clock_source_id clock_source) ++{ ++ return ENCODER_RESULT_OK; ++} + ++/* enables DP PHY output in MST mode */ ++enum encoder_result dce110_link_encoder_enable_dp_mst_output( ++ struct link_encoder *enc, ++ const struct link_settings *link_settings, ++ enum clock_source_id clock_source) ++{ + return ENCODER_RESULT_OK; + } + +@@ -1560,6 +1530,7 @@ enum encoder_result dce110_link_encoder_dp_set_lane_settings( + return ENCODER_RESULT_OK; + } + ++/* set DP PHY test and training patterns */ + void dce110_link_encoder_set_dp_phy_pattern( + struct link_encoder *enc, + const struct encoder_set_dp_phy_pattern_param *param) +@@ -1614,37 +1585,10 @@ void dce110_link_encoder_set_dp_phy_pattern( + } + } + +-/* +- * get_supported_stream_engines +- * +- * @brief +- * get a list of supported engine +- * +- * @param +- * const struct encoder_impl *enc - not used. +- * +- * @return +- * list of engines with supported ones enabled. +- */ +-union supported_stream_engines dce110_get_supported_stream_engines( +- const struct link_encoder *enc) +-{ +- union supported_stream_engines result = {.u_all = 0}; +- +- result.engine.ENGINE_ID_DIGA = 1; +- result.engine.ENGINE_ID_DIGB = 1; +- result.engine.ENGINE_ID_DIGC = 1; +- +- if (enc->connector.id == CONNECTOR_ID_EDP /*|| wireless*/) +- result.u_all = (1 << enc->preferred_engine); +- +- return result; +-} +- ++/* programs DP MST VC payload allocation */ + void dce110_link_encoder_update_mst_stream_allocation_table( + struct link_encoder *enc, +- const struct dp_mst_stream_allocation_table *table, +- bool is_removal) ++ const struct dp_mst_stream_allocation_table *table) + { + int32_t addr_offset = enc->be_engine_offset; + uint32_t value0; +@@ -1755,14 +1699,9 @@ void dce110_link_encoder_update_mst_stream_allocation_table( + break; + ++retries; + } while (retries < DP_MST_UPDATE_MAX_RETRY); +- +- /* TODO should not need. clean this after light up +- * if (is_removal) +- * dal_write_reg(enc->ctx, addr, value); +- */ + } + +- ++/* black light programming */ + void dce110_link_encoder_set_lcd_backlight_level( + struct link_encoder *enc, + uint32_t level) +@@ -1895,125 +1834,70 @@ void dce110_link_encoder_set_lcd_backlight_level( + } + } + +-/*TODO: move to correct dce specific file*/ +-/** +-* set_afmt_memory_power_state +-* +-* @brief +-* Power up audio formatter memory that is mapped to specified DIG +-*/ +-void dce110_set_afmt_memory_power_state( +- const struct dc_context *ctx, +- enum engine_id id, +- bool enable) +-{ +- uint32_t value; +- uint32_t mem_pwr_force; +- +- value = dal_read_reg(ctx, mmDCO_MEM_PWR_CTRL); +- +- if (enable) +- mem_pwr_force = 0; +- else +- mem_pwr_force = 3; +- +- /* force shutdown mode for appropriate AFMT memory */ +- switch (id) { +- case ENGINE_ID_DIGA: +- set_reg_field_value( +- value, +- mem_pwr_force, +- DCO_MEM_PWR_CTRL, +- HDMI0_MEM_PWR_FORCE); +- break; +- case ENGINE_ID_DIGB: +- set_reg_field_value( +- value, +- mem_pwr_force, +- DCO_MEM_PWR_CTRL, +- HDMI1_MEM_PWR_FORCE); +- break; +- case ENGINE_ID_DIGC: +- set_reg_field_value( +- value, +- mem_pwr_force, +- DCO_MEM_PWR_CTRL, +- HDMI2_MEM_PWR_FORCE); +- break; +- default: +- dal_logger_write( +- ctx->logger, +- LOG_MAJOR_WARNING, +- LOG_MINOR_COMPONENT_ENCODER, +- "%s: Invalid Engine Id\n", +- __func__); +- break; +- } +- +- dal_write_reg(ctx, mmDCO_MEM_PWR_CTRL, value); +-} +- +-void dce110_link_encoder_set_mst_bandwidth( ++/* ++ * @brief ++ * Configure digital transmitter and enable both encoder and transmitter ++ * Actual output will be available after calling unblank() ++ */ ++enum encoder_result dce110_link_encoder_enable_output( + struct link_encoder *enc, ++ const struct link_settings *link_settings, + enum engine_id engine, +- struct fixed31_32 avg_time_slots_per_mtp) ++ enum clock_source_id clock_source, ++ enum signal_type signal, ++ enum dc_color_depth color_depth, ++ uint32_t pixel_clock) + { +- uint32_t x = dal_fixed31_32_floor( +- avg_time_slots_per_mtp); +- +- uint32_t y = dal_fixed31_32_ceil( +- dal_fixed31_32_shl( +- dal_fixed31_32_sub_int( +- avg_time_slots_per_mtp, +- x), +- 26)); ++ struct bp_transmitter_control cntl = { 0 }; + +- { +- const uint32_t addr = mmDP_MSE_RATE_CNTL + +- fe_engine_offsets[engine]; +- uint32_t value = dal_read_reg(enc->ctx, addr); ++ if (enc->connector.id == CONNECTOR_ID_EDP) { ++ /* power up eDP panel */ + +- set_reg_field_value( +- value, +- x, +- DP_MSE_RATE_CNTL, +- DP_MSE_RATE_X); ++ link_encoder_edp_power_control( ++ enc, true); + +- set_reg_field_value( +- value, +- y, +- DP_MSE_RATE_CNTL, +- DP_MSE_RATE_Y); ++ link_encoder_edp_wait_for_hpd_ready( ++ enc, enc->connector, true); + +- dal_write_reg(enc->ctx, addr, value); ++ /* have to turn off the backlight ++ * before power down eDP panel */ ++ link_encoder_edp_backlight_control( ++ enc, true); + } + +- /* wait for update to be completed on the link +- * i.e. DP_MSE_RATE_UPDATE_PENDING field (read only) +- * is reset to 0 (not pending) */ +- { +- const uint32_t addr = mmDP_MSE_RATE_UPDATE + +- fe_engine_offsets[engine]; +- uint32_t value, field; +- uint32_t retries = 0; ++ /* Enable the PHY */ + +- do { +- value = dal_read_reg(enc->ctx, addr); ++ /* number_of_lanes is used for pixel clock adjust, ++ * but it's not passed to asic_control. ++ * We need to set number of lanes manually. */ ++ if (dc_is_dp_signal(signal)) ++ configure_encoder(enc, engine, link_settings); + +- field = get_reg_field_value( +- value, +- DP_MSE_RATE_UPDATE, +- DP_MSE_RATE_UPDATE_PENDING); ++ cntl.action = TRANSMITTER_CONTROL_ENABLE; ++ cntl.engine_id = engine; ++ cntl.transmitter = enc->transmitter; ++ cntl.pll_id = clock_source; ++ cntl.signal = signal; ++ cntl.lanes_number = link_settings->lane_count; ++ cntl.hpd_sel = enc->hpd_source; ++ if (dc_is_dp_signal(signal)) ++ cntl.pixel_clock = link_settings->link_rate ++ * LINK_RATE_REF_FREQ_IN_KHZ; ++ else ++ cntl.pixel_clock = pixel_clock; ++ cntl.color_depth = color_depth; + +- if (!(field & +- DP_MSE_RATE_UPDATE__DP_MSE_RATE_UPDATE_PENDING_MASK)) +- break; ++ if (DELAY_AFTER_PIXEL_FORMAT_CHANGE) ++ dc_service_sleep_in_milliseconds( ++ enc->ctx, ++ DELAY_AFTER_PIXEL_FORMAT_CHANGE); + +- dc_service_delay_in_microseconds(enc->ctx, 10); ++ dal_bios_parser_transmitter_control( ++ dal_adapter_service_get_bios_parser( ++ enc->adapter_service), ++ &cntl); + +- ++retries; +- } while (retries < DP_MST_UPDATE_MAX_RETRY); +- } ++ return ENCODER_RESULT_OK; + } + + void dce110_link_encoder_connect_dig_be_to_fe( +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 eae2267..1032228 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 +@@ -28,32 +28,58 @@ + + struct link_encoder *dce110_link_encoder_create( + const struct encoder_init_data *init); ++ + void dce110_link_encoder_destroy(struct link_encoder **enc); + + enum encoder_result dce110_link_encoder_validate_output_with_stream( + struct link_encoder *enc, + const struct core_stream *stream); + ++/****************** HW programming ************************/ ++ ++/* initialize HW */ /* why do we initialze aux in here? */ + enum encoder_result dce110_link_encoder_power_up(struct link_encoder *enc); + ++/* program DIG_MODE in DIG_BE */ ++/* TODO can this be combined with enable_output? */ + void dce110_link_encoder_setup( + struct link_encoder *enc, + enum signal_type signal); + +-enum encoder_result dce110_link_encoder_enable_output( ++/* enables TMDS PHY output */ ++/* TODO: still need depth or just pass in adjusted pixel clock? */ ++enum encoder_result dce110_link_encoder_enable_tmds_output( ++ struct link_encoder *enc, ++ enum clock_source_id clock_source, ++ enum dc_color_depth color_depth, ++ uint32_t pixel_clock); ++ ++/* enables TMDS PHY output */ ++/* TODO: still need this or just pass in adjusted pixel clock? */ ++enum encoder_result dce110_link_encoder_enable_dual_link_tmds_output( + struct link_encoder *enc, +- const struct link_settings *link_settings, +- enum engine_id engine, + enum clock_source_id clock_source, +- enum signal_type signal, + enum dc_color_depth color_depth, + uint32_t pixel_clock); + ++/* enables DP PHY output */ ++enum encoder_result dce110_link_encoder_enable_dp_output( ++ struct link_encoder *enc, ++ const struct link_settings *link_settings, ++ enum clock_source_id clock_source); ++ ++/* enables DP PHY output in MST mode */ ++enum encoder_result dce110_link_encoder_enable_dp_mst_output( ++ struct link_encoder *enc, ++ const struct link_settings *link_settings, ++ enum clock_source_id clock_source); ++ ++/* disable PHY output */ + enum encoder_result dce110_link_encoder_disable_output( + struct link_encoder *link_enc, + enum signal_type signal); + +- ++/* set DP lane settings */ + enum encoder_result dce110_link_encoder_dp_set_lane_settings( + struct link_encoder *enc, + const struct link_training_settings *link_settings); +@@ -62,31 +88,28 @@ void dce110_link_encoder_set_dp_phy_pattern( + struct link_encoder *enc, + const struct encoder_set_dp_phy_pattern_param *param); + +-union supported_stream_engines dce110_get_supported_stream_engines( +- const struct link_encoder *enc); +- ++/* programs DP MST VC payload allocation */ + void dce110_link_encoder_update_mst_stream_allocation_table( + struct link_encoder *enc, +- const struct dp_mst_stream_allocation_table *table, +- bool is_removal); ++ const struct dp_mst_stream_allocation_table *table); + + void dce110_link_encoder_set_lcd_backlight_level( + struct link_encoder *enc, + uint32_t level); + +-void dce110_set_afmt_memory_power_state( +- const struct dc_context *ctx, +- enum engine_id id, +- bool enable); +- +-void dce110_link_encoder_set_mst_bandwidth( ++enum encoder_result dce110_link_encoder_enable_output( + struct link_encoder *enc, ++ const struct link_settings *link_settings, + enum engine_id engine, +- struct fixed31_32 avg_time_slots_per_mtp); ++ enum clock_source_id clock_source, ++ enum signal_type signal, ++ enum dc_color_depth color_depth, ++ uint32_t pixel_clock); + + void dce110_link_encoder_connect_dig_be_to_fe( + struct link_encoder *enc, + enum engine_id engine, + bool connect); + ++ + #endif /* __DC_LINK_ENCODER__DCE110_H__ */ +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 fb3f5be..0499976 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c +@@ -624,7 +624,6 @@ bool dce110_construct_resource_pool( + struct stream_enc_init_data enc_init_data = { 0 }; + /* TODO: rework fragile code*/ + enc_init_data.stream_engine_id = i; +- enc_init_data.adapter_service = adapter_serv; + enc_init_data.ctx = dc->ctx; + if (pool->stream_engines.u_all & 1 << i) { + pool->stream_enc[i] = dce110_stream_encoder_create( +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c +index d3ab89a..37781ab 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c +@@ -45,155 +45,28 @@ static const uint32_t fe_engine_offsets[] = { + #define HDMI_CONTROL__HDMI_DATA_SCRAMBLE_EN__SHIFT 0x1 + #endif + ++enum { ++ DP_MST_UPDATE_MAX_RETRY = 50 ++}; ++ + static void construct( + struct stream_encoder *enc, + struct stream_enc_init_data *init) + { + enc->ctx = init->ctx; + enc->id = init->stream_engine_id; +- enc->adapter_service = init->adapter_service; +-} +- +-static void stop_hdmi_info_packets(struct dc_context *ctx, uint32_t offset) +-{ +- uint32_t addr = 0; +- uint32_t value = 0; +- +- /* stop generic packets 0 & 1 on HDMI */ +- addr = mmHDMI_GENERIC_PACKET_CONTROL0 + offset; +- +- value = dal_read_reg(ctx, addr); +- +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL0, +- HDMI_GENERIC1_CONT); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL0, +- HDMI_GENERIC1_LINE); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL0, +- HDMI_GENERIC1_SEND); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL0, +- HDMI_GENERIC0_CONT); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL0, +- HDMI_GENERIC0_LINE); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL0, +- HDMI_GENERIC0_SEND); +- +- dal_write_reg(ctx, addr, value); +- +- /* stop generic packets 2 & 3 on HDMI */ +- addr = mmHDMI_GENERIC_PACKET_CONTROL1 + offset; +- +- value = dal_read_reg(ctx, addr); +- +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL1, +- HDMI_GENERIC2_CONT); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL1, +- HDMI_GENERIC2_LINE); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL1, +- HDMI_GENERIC2_SEND); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL1, +- HDMI_GENERIC3_CONT); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL1, +- HDMI_GENERIC3_LINE); +- set_reg_field_value( +- value, +- 0, +- HDMI_GENERIC_PACKET_CONTROL1, +- HDMI_GENERIC3_SEND); +- +- dal_write_reg(ctx, addr, value); +- +- /* stop AVI packet on HDMI */ +- addr = mmHDMI_INFOFRAME_CONTROL0 + offset; +- +- value = dal_read_reg(ctx, addr); +- +- set_reg_field_value( +- value, +- 0, +- HDMI_INFOFRAME_CONTROL0, +- HDMI_AVI_INFO_SEND); +- set_reg_field_value( +- value, +- 0, +- HDMI_INFOFRAME_CONTROL0, +- HDMI_AVI_INFO_CONT); +- +- dal_write_reg(ctx, addr, value); +-} +- +-static void stop_dp_info_packets(struct dc_context *ctx, int32_t offset) +-{ +- /* stop generic packets on DP */ +- +- const uint32_t addr = mmDP_SEC_CNTL + offset; +- +- uint32_t value = dal_read_reg(ctx, addr); +- +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP0_ENABLE); +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP1_ENABLE); +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP2_ENABLE); +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP3_ENABLE); +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_AVI_ENABLE); +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_MPG_ENABLE); +- set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_STREAM_ENABLE); +- +- /* this register shared with audio info frame. +- * therefore we need to keep master enabled +- * if at least one of the fields is not 0 */ +- +- if (value) +- set_reg_field_value( +- value, +- 1, +- DP_SEC_CNTL, +- DP_SEC_STREAM_ENABLE); +- +- dal_write_reg(ctx, addr, value); + } + + static void update_avi_info_packet( + struct stream_encoder *enc, + enum engine_id engine, +- enum signal_type signal, + const struct encoder_info_packet *info_packet) + { + const int32_t offset = fe_engine_offsets[engine]; +- + uint32_t regval; + uint32_t addr; ++ uint32_t control0val; ++ uint32_t control1val; + + if (info_packet->valid) { + const uint32_t *content = +@@ -239,42 +112,36 @@ static void update_avi_info_packet( + regval); + } + +- if (dc_is_hdmi_signal(signal)) { +- +- uint32_t control0val; +- uint32_t control1val; +- +- addr = mmHDMI_INFOFRAME_CONTROL0 + offset; ++ addr = mmHDMI_INFOFRAME_CONTROL0 + offset; + +- control0val = dal_read_reg(enc->ctx, addr); ++ control0val = dal_read_reg(enc->ctx, addr); + +- set_reg_field_value( +- control0val, +- 1, +- HDMI_INFOFRAME_CONTROL0, +- HDMI_AVI_INFO_SEND); ++ set_reg_field_value( ++ control0val, ++ 1, ++ HDMI_INFOFRAME_CONTROL0, ++ HDMI_AVI_INFO_SEND); + +- set_reg_field_value( +- control0val, +- 1, +- HDMI_INFOFRAME_CONTROL0, +- HDMI_AVI_INFO_CONT); ++ set_reg_field_value( ++ control0val, ++ 1, ++ HDMI_INFOFRAME_CONTROL0, ++ HDMI_AVI_INFO_CONT); + +- dal_write_reg(enc->ctx, addr, control0val); ++ dal_write_reg(enc->ctx, addr, control0val); + +- addr = mmHDMI_INFOFRAME_CONTROL1 + offset; ++ addr = mmHDMI_INFOFRAME_CONTROL1 + offset; + +- control1val = dal_read_reg(enc->ctx, addr); ++ control1val = dal_read_reg(enc->ctx, addr); + +- set_reg_field_value( +- control1val, +- VBI_LINE_0 + 2, +- HDMI_INFOFRAME_CONTROL1, +- HDMI_AVI_INFO_LINE); ++ set_reg_field_value( ++ control1val, ++ VBI_LINE_0 + 2, ++ HDMI_INFOFRAME_CONTROL1, ++ HDMI_AVI_INFO_LINE); + +- dal_write_reg(enc->ctx, addr, control1val); +- } +- } else if (dc_is_hdmi_signal(signal)) { ++ dal_write_reg(enc->ctx, addr, control1val); ++ } else { + addr = mmHDMI_INFOFRAME_CONTROL0 + offset; + + regval = dal_read_reg(enc->ctx, addr); +@@ -660,6 +527,48 @@ static void setup_vid_stream( + dal_write_reg(enc->ctx, addr, value); + } + ++static void set_tmds_stream_attributes( ++ struct stream_encoder *enc, ++ enum engine_id engine, ++ const struct dc_crtc_timing *timing, ++ bool is_dvi ++ ) ++{ ++ uint32_t addr = mmDIG_FE_CNTL + fe_engine_offsets[engine]; ++ uint32_t value = dal_read_reg(enc->ctx, addr); ++ ++ switch (timing->pixel_encoding) { ++ case PIXEL_ENCODING_YCBCR422: ++ set_reg_field_value(value, 1, DIG_FE_CNTL, TMDS_PIXEL_ENCODING); ++ break; ++ default: ++ set_reg_field_value(value, 0, DIG_FE_CNTL, TMDS_PIXEL_ENCODING); ++ break; ++ } ++ ++ switch (timing->display_color_depth) { ++ case COLOR_DEPTH_101010: ++ if (is_dvi && ++ timing->pixel_encoding == PIXEL_ENCODING_RGB) ++ set_reg_field_value( ++ value, ++ 2, ++ DIG_FE_CNTL, ++ TMDS_COLOR_FORMAT); ++ else ++ set_reg_field_value( ++ value, ++ 0, ++ DIG_FE_CNTL, ++ TMDS_COLOR_FORMAT); ++ break; ++ default: ++ set_reg_field_value(value, 0, DIG_FE_CNTL, TMDS_COLOR_FORMAT); ++ break; ++ } ++ dal_write_reg(enc->ctx, addr, value); ++} ++ + static void set_dp_stream_attributes( + struct stream_encoder *enc, + enum engine_id engine, +@@ -897,48 +806,6 @@ static void setup_hdmi( + + } + +-static void set_tmds_stream_attributes( +- struct stream_encoder *enc, +- enum engine_id engine, +- enum signal_type signal, +- const struct dc_crtc_timing *timing) +-{ +- uint32_t addr = mmDIG_FE_CNTL + fe_engine_offsets[engine]; +- uint32_t value = dal_read_reg(enc->ctx, addr); +- +- switch (timing->pixel_encoding) { +- case PIXEL_ENCODING_YCBCR422: +- set_reg_field_value(value, 1, DIG_FE_CNTL, TMDS_PIXEL_ENCODING); +- break; +- default: +- set_reg_field_value(value, 0, DIG_FE_CNTL, TMDS_PIXEL_ENCODING); +- break; +- } +- +- switch (timing->pixel_encoding) { +- case COLOR_DEPTH_101010: +- if ((signal == SIGNAL_TYPE_DVI_SINGLE_LINK +- || signal == SIGNAL_TYPE_DVI_DUAL_LINK) +- && timing->pixel_encoding == PIXEL_ENCODING_RGB) +- set_reg_field_value( +- value, +- 2, +- DIG_FE_CNTL, +- TMDS_COLOR_FORMAT); +- else +- set_reg_field_value( +- value, +- 0, +- DIG_FE_CNTL, +- TMDS_COLOR_FORMAT); +- break; +- default: +- set_reg_field_value(value, 0, DIG_FE_CNTL, TMDS_COLOR_FORMAT); +- break; +- } +- dal_write_reg(enc->ctx, addr, value); +-} +- + struct stream_encoder *dce110_stream_encoder_create( + struct stream_enc_init_data *init) + { +@@ -974,96 +841,330 @@ enum encoder_result dce110_stream_encoder_setup( + enum signal_type signal, + bool enable_audio) + { +- if (!dc_is_dp_signal(signal)) { +- struct bp_encoder_control cntl; +- +- cntl.action = ENCODER_CONTROL_SETUP; +- cntl.engine_id = enc->id; +- cntl.signal = signal; +- cntl.enable_dp_audio = enable_audio; +- cntl.pixel_clock = crtc_timing->pix_clk_khz; +- cntl.lanes_number = (signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? +- LANE_COUNT_EIGHT : LANE_COUNT_FOUR; +- cntl.color_depth = crtc_timing->display_color_depth; +- +- if (dal_bios_parser_encoder_control( ++ struct bp_encoder_control cntl; ++ ++ cntl.action = ENCODER_CONTROL_SETUP; ++ cntl.engine_id = enc->id; ++ cntl.signal = signal; ++ cntl.enable_dp_audio = enable_audio; ++ cntl.pixel_clock = crtc_timing->pix_clk_khz; ++ cntl.lanes_number = (signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? ++ LANE_COUNT_EIGHT : LANE_COUNT_FOUR; ++ cntl.color_depth = crtc_timing->display_color_depth; ++ ++ if (dal_bios_parser_encoder_control( + dal_adapter_service_get_bios_parser( +- enc->adapter_service), +- &cntl) != BP_RESULT_OK) +- return ENCODER_RESULT_ERROR; ++ enc->adapter_service), &cntl) != BP_RESULT_OK) ++ return ENCODER_RESULT_ERROR; ++ ++ return ENCODER_RESULT_OK; ++} ++ ++void dce110_stream_encoder_stop_hdmi_info_packets( ++ struct dc_context *ctx, ++ enum engine_id engine) ++{ ++ uint32_t addr = 0; ++ uint32_t value = 0; ++ uint32_t offset = fe_engine_offsets[engine]; ++ ++ /* stop generic packets 0 & 1 on HDMI */ ++ addr = mmHDMI_GENERIC_PACKET_CONTROL0 + offset; ++ ++ value = dal_read_reg(ctx, addr); ++ ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL0, ++ HDMI_GENERIC1_CONT); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL0, ++ HDMI_GENERIC1_LINE); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL0, ++ HDMI_GENERIC1_SEND); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL0, ++ HDMI_GENERIC0_CONT); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL0, ++ HDMI_GENERIC0_LINE); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL0, ++ HDMI_GENERIC0_SEND); ++ ++ dal_write_reg(ctx, addr, value); ++ ++ /* stop generic packets 2 & 3 on HDMI */ ++ addr = mmHDMI_GENERIC_PACKET_CONTROL1 + offset; ++ ++ value = dal_read_reg(ctx, addr); ++ ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL1, ++ HDMI_GENERIC2_CONT); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL1, ++ HDMI_GENERIC2_LINE); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL1, ++ HDMI_GENERIC2_SEND); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL1, ++ HDMI_GENERIC3_CONT); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL1, ++ HDMI_GENERIC3_LINE); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_GENERIC_PACKET_CONTROL1, ++ HDMI_GENERIC3_SEND); ++ ++ dal_write_reg(ctx, addr, value); ++ ++ /* stop AVI packet on HDMI */ ++ addr = mmHDMI_INFOFRAME_CONTROL0 + offset; ++ ++ value = dal_read_reg(ctx, addr); ++ ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_INFOFRAME_CONTROL0, ++ HDMI_AVI_INFO_SEND); ++ set_reg_field_value( ++ value, ++ 0, ++ HDMI_INFOFRAME_CONTROL0, ++ HDMI_AVI_INFO_CONT); ++ ++ dal_write_reg(ctx, addr, value); ++} ++ ++void dce110_stream_encoder_stop_dp_info_packets( ++ struct dc_context *ctx, ++ enum engine_id engine) ++{ ++ /* stop generic packets on DP */ ++ uint32_t offset = fe_engine_offsets[engine]; ++ const uint32_t addr = mmDP_SEC_CNTL + offset; ++ uint32_t value = dal_read_reg(ctx, addr); ++ ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP0_ENABLE); ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP1_ENABLE); ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP2_ENABLE); ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP3_ENABLE); ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_AVI_ENABLE); ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_MPG_ENABLE); ++ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_STREAM_ENABLE); ++ ++ /* this register shared with audio info frame. ++ * therefore we need to keep master enabled ++ * if at least one of the fields is not 0 */ ++ ++ if (value) ++ set_reg_field_value( ++ value, ++ 1, ++ DP_SEC_CNTL, ++ DP_SEC_STREAM_ENABLE); ++ ++ dal_write_reg(ctx, addr, value); ++} ++ ++/* setup stream encoder in dp mode */ ++void dce110_stream_encoder_dp_set_stream_attribute( ++ struct stream_encoder *enc, ++ struct dc_crtc_timing *crtc_timing) ++{ ++ set_dp_stream_attributes(enc, enc->id, crtc_timing); ++} ++ ++/* setup stream encoder in hdmi mode */ ++void dce110_stream_encoder_hdmi_set_stream_attribute( ++ struct stream_encoder *enc, ++ struct dc_crtc_timing *crtc_timing) ++{ ++ set_tmds_stream_attributes(enc, enc->id, crtc_timing, false); ++ ++ /* setup HDMI engine */ ++ setup_hdmi( ++ enc, enc->id, crtc_timing); ++} ++ ++/* setup stream encoder in dvi mode */ ++void dce110_stream_encoder_dvi_set_stream_attribute( ++ struct stream_encoder *enc, ++ struct dc_crtc_timing *crtc_timing) ++{ ++ set_tmds_stream_attributes(enc, enc->id, crtc_timing, true); ++} ++ ++void dce110_stream_encoder_set_mst_bandwidth( ++ struct stream_encoder *enc, ++ enum engine_id engine, ++ struct fixed31_32 avg_time_slots_per_mtp) ++{ ++ uint32_t x = dal_fixed31_32_floor( ++ avg_time_slots_per_mtp); ++ ++ uint32_t y = dal_fixed31_32_ceil( ++ dal_fixed31_32_shl( ++ dal_fixed31_32_sub_int( ++ avg_time_slots_per_mtp, ++ x), ++ 26)); ++ ++ { ++ const uint32_t addr = mmDP_MSE_RATE_CNTL + ++ fe_engine_offsets[engine]; ++ uint32_t value = dal_read_reg(enc->ctx, addr); ++ ++ set_reg_field_value( ++ value, ++ x, ++ DP_MSE_RATE_CNTL, ++ DP_MSE_RATE_X); ++ ++ set_reg_field_value( ++ value, ++ y, ++ DP_MSE_RATE_CNTL, ++ DP_MSE_RATE_Y); ++ ++ dal_write_reg(enc->ctx, addr, value); + } + +- switch (signal) { +- case SIGNAL_TYPE_DVI_SINGLE_LINK: +- case SIGNAL_TYPE_DVI_DUAL_LINK: +- /* set signal format */ +- set_tmds_stream_attributes( +- enc, enc->id, signal, +- crtc_timing); ++ /* wait for update to be completed on the link ++ * i.e. DP_MSE_RATE_UPDATE_PENDING field (read only) ++ * is reset to 0 (not pending) */ ++ { ++ const uint32_t addr = mmDP_MSE_RATE_UPDATE + ++ fe_engine_offsets[engine]; ++ uint32_t value, field; ++ uint32_t retries = 0; ++ ++ do { ++ value = dal_read_reg(enc->ctx, addr); ++ ++ field = get_reg_field_value( ++ value, ++ DP_MSE_RATE_UPDATE, ++ DP_MSE_RATE_UPDATE_PENDING); ++ ++ if (!(field & ++ DP_MSE_RATE_UPDATE__DP_MSE_RATE_UPDATE_PENDING_MASK)) ++ break; ++ ++ dc_service_delay_in_microseconds(enc->ctx, 10); ++ ++ ++retries; ++ } while (retries < DP_MST_UPDATE_MAX_RETRY); ++ } ++} ++ ++ ++/** ++* set_afmt_memory_power_state ++* ++* @brief ++* Power up audio formatter memory that is mapped to specified DIG ++*/ ++void dce110_stream_encoder_set_afmt_memory_power_state( ++ const struct dc_context *ctx, ++ enum engine_id id, ++ bool enable) ++{ ++ uint32_t value; ++ uint32_t mem_pwr_force; ++ ++ value = dal_read_reg(ctx, mmDCO_MEM_PWR_CTRL); ++ ++ if (enable) ++ mem_pwr_force = 0; ++ else ++ mem_pwr_force = 3; ++ ++ /* force shutdown mode for appropriate AFMT memory */ ++ switch (id) { ++ case ENGINE_ID_DIGA: ++ set_reg_field_value( ++ value, ++ mem_pwr_force, ++ DCO_MEM_PWR_CTRL, ++ HDMI0_MEM_PWR_FORCE); + break; +- case SIGNAL_TYPE_HDMI_TYPE_A: +- /* set signal format */ +- set_tmds_stream_attributes( +- enc, enc->id, signal, +- crtc_timing); +- /* setup HDMI engine */ +- setup_hdmi( +- enc, enc->id, crtc_timing); ++ case ENGINE_ID_DIGB: ++ set_reg_field_value( ++ value, ++ mem_pwr_force, ++ DCO_MEM_PWR_CTRL, ++ HDMI1_MEM_PWR_FORCE); + break; +- case SIGNAL_TYPE_DISPLAY_PORT: +- case SIGNAL_TYPE_DISPLAY_PORT_MST: +- case SIGNAL_TYPE_EDP: +- /* set signal format */ +- set_dp_stream_attributes(enc, enc->id, crtc_timing); ++ case ENGINE_ID_DIGC: ++ set_reg_field_value( ++ value, ++ mem_pwr_force, ++ DCO_MEM_PWR_CTRL, ++ HDMI2_MEM_PWR_FORCE); + break; + default: ++ dal_logger_write( ++ ctx->logger, ++ LOG_MAJOR_WARNING, ++ LOG_MINOR_COMPONENT_ENCODER, ++ "%s: Invalid Engine Id\n", ++ __func__); + break; + } + +- return ENCODER_RESULT_OK; ++ dal_write_reg(ctx, mmDCO_MEM_PWR_CTRL, value); + } + +-void dce110_stream_encoder_update_info_packets( ++void dce110_stream_encoder_update_hdmi_info_packets( + struct stream_encoder *enc, +- enum signal_type signal, + const struct encoder_info_frame *info_frame) + { +- if (dc_is_hdmi_signal(signal)) { +- update_avi_info_packet( +- enc, +- enc->id, +- signal, +- &info_frame->avi); +- update_hdmi_info_packet(enc, enc->id, 0, &info_frame->vendor); +- update_hdmi_info_packet(enc, enc->id, 1, &info_frame->gamut); +- update_hdmi_info_packet(enc, enc->id, 2, &info_frame->spd); +- } else if (dc_is_dp_signal(signal)) +- update_dp_info_packet(enc, enc->id, 0, &info_frame->vsc); ++ update_avi_info_packet( ++ enc, ++ enc->id, ++ &info_frame->avi); ++ update_hdmi_info_packet(enc, enc->id, 0, &info_frame->vendor); ++ update_hdmi_info_packet(enc, enc->id, 1, &info_frame->gamut); ++ update_hdmi_info_packet(enc, enc->id, 2, &info_frame->spd); + } + +-void dce110_stream_encoder_stop_info_packets( ++void dce110_stream_encoder_update_dp_info_packets( + struct stream_encoder *enc, +- enum engine_id engine, +- enum signal_type signal) ++ const struct encoder_info_frame *info_frame) + { +- if (dc_is_hdmi_signal(signal)) +- stop_hdmi_info_packets( +- enc->ctx, +- fe_engine_offsets[engine]); +- else if (dc_is_dp_signal(signal)) +- stop_dp_info_packets( +- enc->ctx, +- fe_engine_offsets[engine]); ++ update_dp_info_packet(enc, enc->id, 0, &info_frame->vsc); + } + +-/* +- * @brief +- * Output blank data, +- * prevents output of the actual surface data on active transmitter +- */ +-enum encoder_result dce110_stream_encoder_blank( +- struct stream_encoder *enc, +- enum signal_type signal) ++void dce110_stream_encoder_dp_blank( ++ struct stream_encoder *enc) + { + enum engine_id engine = enc->id; + const uint32_t addr = mmDP_VID_STREAM_CNTL + fe_engine_offsets[engine]; +@@ -1071,9 +1172,6 @@ enum encoder_result dce110_stream_encoder_blank( + uint32_t retries = 0; + uint32_t max_retries = DP_BLANK_MAX_RETRY * 10; + +- if (!dc_is_dp_signal(signal)) +- return ENCODER_RESULT_OK; +- + /* Note: For CZ, we are changing driver default to disable + * stream deferred to next VBLANK. If results are positive, we + * will make the same change to all DCE versions. There are a +@@ -1122,26 +1220,13 @@ enum encoder_result dce110_stream_encoder_blank( + * complete, stream status will be stuck in video stream enabled state, + * i.e. DP_VID_STREAM_STATUS stuck at 1. */ + dp_steer_fifo_reset(enc->ctx, engine, true); +- +- return ENCODER_RESULT_OK; + } + +-/* +- * @brief +- * Stop sending blank data, +- * output the actual surface data on active transmitter +- */ +-enum encoder_result dce110_stream_encoder_unblank( ++/* output video stream to link encoder */ ++void dce110_stream_encoder_dp_unblank( + struct stream_encoder *enc, + const struct encoder_unblank_param *param) + { +- bool is_dp_signal = param->signal == SIGNAL_TYPE_DISPLAY_PORT +- || param->signal == SIGNAL_TYPE_DISPLAY_PORT_MST +- || param->signal == SIGNAL_TYPE_EDP; +- +- if (!is_dp_signal) +- return ENCODER_RESULT_OK; +- + if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) { + uint32_t n_vid = 0x8000; + uint32_t m_vid; +@@ -1163,7 +1248,5 @@ enum encoder_result dce110_stream_encoder_unblank( + } + + unblank_dp_output(enc, enc->id); +- +- return ENCODER_RESULT_OK; + } + +diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h +index 83df255..9c0302a 100644 +--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h ++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h +@@ -28,7 +28,6 @@ + + struct stream_enc_init_data { + enum engine_id stream_engine_id; +- struct adapter_service *adapter_service; + struct dc_context *ctx; + }; + +@@ -37,27 +36,62 @@ struct stream_encoder *dce110_stream_encoder_create( + + void dce110_stream_encoder_destroy(struct stream_encoder **enc); + ++/***** HW programming ***********/ + enum encoder_result dce110_stream_encoder_setup( + struct stream_encoder *enc, + struct dc_crtc_timing *crtc_timing, + enum signal_type signal, + bool enable_audio); + +-void dce110_stream_encoder_update_info_packets( ++void dce110_stream_encoder_stop_hdmi_info_packets( ++ struct dc_context *ctx, ++ enum engine_id engine); ++ ++void dce110_stream_encoder_stop_dp_info_packets( ++ struct dc_context *ctx, ++ enum engine_id engine); ++ ++ ++/* setup stream encoder in dp mode */ ++void dce110_stream_encoder_dp_set_stream_attribute( + struct stream_encoder *enc, +- enum signal_type signal, +- const struct encoder_info_frame *info_frame); ++ struct dc_crtc_timing *crtc_timing); ++ ++/* setup stream encoder in hdmi mode */ ++void dce110_stream_encoder_hdmi_set_stream_attribute( ++ struct stream_encoder *enc, ++ struct dc_crtc_timing *crtc_timing); + +-void dce110_stream_encoder_stop_info_packets( ++/* setup stream encoder in dvi mode */ ++void dce110_stream_encoder_dvi_set_stream_attribute( ++ struct stream_encoder *enc, ++ struct dc_crtc_timing *crtc_timing); ++ ++/* set throttling for DP MST */ ++void dce110_stream_encoder_set_mst_bandwidth( + struct stream_encoder *enc, + enum engine_id engine, +- enum signal_type signal); ++ struct fixed31_32 avg_time_slots_per_mtp); ++ ++void dce110_stream_encoder_set_afmt_memory_power_state( ++ const struct dc_context *ctx, ++ enum engine_id id, ++ bool enable); + +-enum encoder_result dce110_stream_encoder_blank( ++void dce110_stream_encoder_update_hdmi_info_packets( + struct stream_encoder *enc, +- enum signal_type signal); ++ const struct encoder_info_frame *info_frame); ++ ++void dce110_stream_encoder_update_dp_info_packets( ++ struct stream_encoder *enc, ++ const struct encoder_info_frame *info_frame); ++ ++/* output blank/idle stream to link encoder */ ++void dce110_stream_encoder_dp_blank( ++ struct stream_encoder *enc); + +-enum encoder_result dce110_stream_encoder_unblank( ++/* output video stream to link encoder */ ++void dce110_stream_encoder_dp_unblank( + struct stream_encoder *enc, + const struct encoder_unblank_param *param); + +diff --git a/drivers/gpu/drm/amd/dal/include/encoder_types.h b/drivers/gpu/drm/amd/dal/include/encoder_types.h +index 2897a1d..e32498d 100644 +--- a/drivers/gpu/drm/amd/dal/include/encoder_types.h ++++ b/drivers/gpu/drm/amd/dal/include/encoder_types.h +@@ -134,7 +134,6 @@ struct encoder_pre_enable_output_param { + struct encoder_unblank_param { + struct hw_crtc_timing crtc_timing; + struct link_settings link_settings; +- enum signal_type signal; + }; + + /* +-- +2.7.4 + |