aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch')
-rw-r--r--common/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch1527
1 files changed, 1527 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch b/common/recipes-kernel/linux/files/0520-drm-amd-dal-Clean-up-Link-Stream-Encoder.patch
new file mode 100644
index 00000000..5e3d0e64
--- /dev/null
+++ b/common/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, &params);
+ }
+
+@@ -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
+