diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0518-drm-amd-dal-Reorganize-link-encoder-and-stream-encod.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0518-drm-amd-dal-Reorganize-link-encoder-and-stream-encod.patch | 1691 |
1 files changed, 0 insertions, 1691 deletions
diff --git a/common/recipes-kernel/linux/files/0518-drm-amd-dal-Reorganize-link-encoder-and-stream-encod.patch b/common/recipes-kernel/linux/files/0518-drm-amd-dal-Reorganize-link-encoder-and-stream-encod.patch deleted file mode 100644 index 5f22ada6..00000000 --- a/common/recipes-kernel/linux/files/0518-drm-amd-dal-Reorganize-link-encoder-and-stream-encod.patch +++ /dev/null @@ -1,1691 +0,0 @@ -From 2e6975280175f40d209cc2e86c1141a9a61fe23b Mon Sep 17 00:00:00 2001 -From: Chris Park <Chris.Park@amd.com> -Date: Wed, 25 Nov 2015 11:14:09 -0500 -Subject: [PATCH 0518/1110] drm/amd/dal: Reorganize link encoder and stream - encoder interface function order - -Part of link encoder & stream encoder clean-up. No functionality change. - -Signed-off-by: Chris Park <Chris.Park@amd.com> -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Acked-by: Harry Wentland <harry.wentland@amd.com> ---- - .../drm/amd/dal/dc/dce110/dce110_link_encoder.c | 1103 ++++++++++---------- - .../drm/amd/dal/dc/dce110/dce110_link_encoder.h | 41 +- - .../drm/amd/dal/dc/dce110/dce110_stream_encoder.c | 335 +++--- - .../drm/amd/dal/dc/dce110/dce110_stream_encoder.h | 18 +- - 4 files changed, 750 insertions(+), 747 deletions(-) - -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 0297bd3..9817318 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 -@@ -461,45 +461,6 @@ static void set_dp_phy_pattern_80bit_custom( - enable_phy_bypass_mode(ctx, be_addr_offset, true); - } - --void dce110_link_encoder_setup( -- struct link_encoder *enc, -- enum signal_type signal) --{ -- const uint32_t addr = mmDIG_BE_CNTL + enc->be_engine_offset; -- uint32_t value = dal_read_reg(enc->ctx, addr); -- -- switch (signal) { -- case SIGNAL_TYPE_EDP: -- case SIGNAL_TYPE_DISPLAY_PORT: -- /* DP SST */ -- set_reg_field_value(value, 0, DIG_BE_CNTL, DIG_MODE); -- break; -- case SIGNAL_TYPE_LVDS: -- /* LVDS */ -- set_reg_field_value(value, 1, DIG_BE_CNTL, DIG_MODE); -- break; -- case SIGNAL_TYPE_DVI_SINGLE_LINK: -- case SIGNAL_TYPE_DVI_DUAL_LINK: -- /* TMDS-DVI */ -- set_reg_field_value(value, 2, DIG_BE_CNTL, DIG_MODE); -- break; -- case SIGNAL_TYPE_HDMI_TYPE_A: -- /* TMDS-HDMI */ -- set_reg_field_value(value, 3, DIG_BE_CNTL, DIG_MODE); -- break; -- case SIGNAL_TYPE_DISPLAY_PORT_MST: -- /* DP MST */ -- set_reg_field_value(value, 5, DIG_BE_CNTL, DIG_MODE); -- break; -- default: -- ASSERT_CRITICAL(false); -- /* invalid mode ! */ -- break; -- } -- -- dal_write_reg(enc->ctx, addr, value); --} -- - static void set_dp_phy_pattern_hbr2_compliance( - struct link_encoder *enc, - const int32_t be_addr_offset) -@@ -751,137 +712,6 @@ static void construct( - FEATURE_SUPPORT_DP_YUV); - } - --struct link_encoder *dce110_link_encoder_create( -- const struct encoder_init_data *init) --{ -- struct link_encoder *enc = -- dc_service_alloc(init->ctx, sizeof(struct link_encoder)); -- -- if (!enc) -- goto enc_create_fail; -- -- construct(enc, init); -- -- return enc; -- --enc_create_fail: -- return NULL; --} -- --void dce110_link_encoder_destroy(struct link_encoder **enc) --{ -- struct link_encoder *encoder = *enc; -- dc_service_free(encoder->ctx, encoder); -- *enc = NULL; --} -- --void dce110_link_encoder_set_dp_phy_pattern( -- struct link_encoder *enc, -- const struct encoder_set_dp_phy_pattern_param *param) --{ -- const int32_t offset = enc->be_engine_offset; -- -- -- switch (param->dp_phy_pattern) { -- case DP_TEST_PATTERN_TRAINING_PATTERN1: -- set_dp_phy_pattern_training_pattern(enc->ctx, -- offset, 0); -- break; -- case DP_TEST_PATTERN_TRAINING_PATTERN2: -- set_dp_phy_pattern_training_pattern(enc->ctx, -- offset, 1); -- break; -- case DP_TEST_PATTERN_TRAINING_PATTERN3: -- set_dp_phy_pattern_training_pattern(enc->ctx, -- offset, 2); -- break; -- case DP_TEST_PATTERN_D102: -- set_dp_phy_pattern_d102(enc->ctx, offset); -- break; -- case DP_TEST_PATTERN_SYMBOL_ERROR: -- set_dp_phy_pattern_symbol_error(enc->ctx, offset); -- break; -- case DP_TEST_PATTERN_PRBS7: -- set_dp_phy_pattern_prbs7(enc->ctx, offset); -- break; -- case DP_TEST_PATTERN_80BIT_CUSTOM: -- set_dp_phy_pattern_80bit_custom( -- enc->ctx, -- offset, param->custom_pattern); -- break; -- case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE: -- set_dp_phy_pattern_hbr2_compliance( -- enc, offset); -- break; -- case DP_TEST_PATTERN_VIDEO_MODE: { -- set_dp_phy_pattern_passthrough_mode( -- enc->ctx, -- offset, -- param->dp_panel_mode); -- break; -- } -- -- -- default: -- /* invalid phy pattern */ -- ASSERT_CRITICAL(false); -- break; -- } --} -- --enum encoder_result dce110_link_encoder_dp_set_lane_settings( -- struct link_encoder *enc, -- const struct link_training_settings *link_settings) --{ -- union dpcd_training_lane_set training_lane_set = { { 0 } }; -- -- int32_t lane = 0; -- -- struct bp_transmitter_control cntl = { 0 }; -- -- if (!link_settings) { -- BREAK_TO_DEBUGGER(); -- return ENCODER_RESULT_ERROR; -- } -- -- cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS; -- cntl.transmitter = enc->transmitter; -- cntl.connector_obj_id = enc->connector; -- cntl.lanes_number = link_settings->link_settings.lane_count; -- cntl.hpd_sel = enc->hpd_source; -- cntl.pixel_clock = link_settings->link_settings.link_rate * -- LINK_RATE_REF_FREQ_IN_KHZ; -- -- for (lane = 0; lane < link_settings->link_settings.lane_count; ++lane) { -- /* translate lane settings */ -- -- training_lane_set.bits.VOLTAGE_SWING_SET = -- link_settings->lane_settings[lane].VOLTAGE_SWING; -- training_lane_set.bits.PRE_EMPHASIS_SET = -- link_settings->lane_settings[lane].PRE_EMPHASIS; -- -- /* post cursor 2 setting only applies to HBR2 link rate */ -- if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) { -- /* this is passed to VBIOS -- * to program post cursor 2 level */ -- -- training_lane_set.bits.POST_CURSOR2_SET = -- link_settings->lane_settings[lane].POST_CURSOR2; -- } -- -- cntl.lane_select = lane; -- cntl.lane_settings = training_lane_set.raw; -- -- /* call VBIOS table to set voltage swing and pre-emphasis */ -- -- dal_bios_parser_transmitter_control( -- dal_adapter_service_get_bios_parser( -- enc->adapter_service), &cntl); -- } -- -- return ENCODER_RESULT_OK; --} -- - /* return value is bit-vector */ - static uint8_t get_frontend_source( - enum engine_id engine) -@@ -1167,72 +997,6 @@ static enum encoder_result link_encoder_edp_backlight_control( - return ENCODER_RESULT_OK; - } - --/* -- * @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, -- 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; -- -- if (DELAY_AFTER_PIXEL_FORMAT_CHANGE) -- dc_service_sleep_in_milliseconds( -- enc->ctx, -- DELAY_AFTER_PIXEL_FORMAT_CHANGE); -- -- dal_bios_parser_transmitter_control( -- dal_adapter_service_get_bios_parser( -- enc->adapter_service), -- &cntl); -- -- return ENCODER_RESULT_OK; --} -- - static bool is_dig_enabled(const struct link_encoder *link_enc) - { - uint32_t value; -@@ -1268,141 +1032,18 @@ static void link_encoder_disable(struct link_encoder *link_enc) - dal_write_reg(link_enc->ctx, addr, value); - } - --/* -- * @brief -- * Disable transmitter and its encoder -- */ --enum encoder_result dce110_link_encoder_disable_output( -- struct link_encoder *link_enc, -- enum signal_type signal) -+static void hpd_initialize( -+ struct link_encoder *enc, -+ enum hpd_source_id hpd_source) - { -- struct bp_transmitter_control cntl = { 0 }; -- -- if (link_enc->connector.id == CONNECTOR_ID_EDP) { -- /* have to turn off the backlight -- * before power down eDP panel */ -- link_encoder_edp_backlight_control( -- link_enc, false); -- } -- -- if (!is_dig_enabled(link_enc) && -- dal_adapter_service_should_optimize(link_enc->adapter_service, -- OF_SKIP_POWER_DOWN_INACTIVE_ENCODER)) { -- return ENCODER_RESULT_OK; -- } -- /* Power-down RX and disable GPU PHY should be paired. -- * Disabling PHY without powering down RX may cause -- * symbol lock loss, on which we will get DP Sink interrupt. */ -- -- /* There is a case for the DP active dongles -- * where we want to disable the PHY but keep RX powered, -- * for those we need to ignore DP Sink interrupt -- * by checking lane count that has been set -- * on the last do_enable_output(). */ -- -- /* disable transmitter */ -- cntl.action = TRANSMITTER_CONTROL_DISABLE; -- cntl.transmitter = link_enc->transmitter; -- cntl.hpd_sel = link_enc->hpd_source; -- cntl.signal = signal; -- cntl.connector_obj_id = link_enc->connector; -- -- dal_bios_parser_transmitter_control( -- dal_adapter_service_get_bios_parser( -- link_enc->adapter_service), &cntl); -- -- /* disable encoder */ -- if (dc_is_dp_signal(signal)) -- link_encoder_disable(link_enc); -- -- if (link_enc->connector.id == CONNECTOR_ID_EDP) { -- /* power down eDP panel */ -- /* TODO: Power control cause regression, we should implement -- * it properly, for now just comment it. -- * -- * link_encoder_edp_wait_for_hpd_ready( -- link_enc, -- link_enc->connector, -- false); -- -- * link_encoder_edp_power_control( -- link_enc, false); */ -- } -- -- return ENCODER_RESULT_OK; --} -- --static void hpd_initialize( -- struct link_encoder *enc, -- enum hpd_source_id hpd_source) --{ -- /* Associate HPD with DIG_BE */ -- const uint32_t addr = mmDIG_BE_CNTL + enc->be_engine_offset; -- uint32_t value = dal_read_reg(enc->ctx, addr); -+ /* Associate HPD with DIG_BE */ -+ const uint32_t addr = mmDIG_BE_CNTL + enc->be_engine_offset; -+ uint32_t value = dal_read_reg(enc->ctx, addr); - - set_reg_field_value(value, hpd_source, DIG_BE_CNTL, DIG_HPD_SELECT); - dal_write_reg(enc->ctx, addr, value); - } - --enum encoder_result dce110_link_encoder_power_up( -- struct link_encoder *enc) --{ -- struct bp_transmitter_control cntl = { 0 }; -- -- enum bp_result result; -- -- cntl.action = TRANSMITTER_CONTROL_INIT; -- cntl.engine_id = ENGINE_ID_UNKNOWN; -- cntl.transmitter = enc->transmitter; -- cntl.connector_obj_id = enc->connector; -- cntl.lanes_number = LANE_COUNT_FOUR; -- cntl.coherent = false; -- cntl.hpd_sel = enc->hpd_source; -- -- result = dal_bios_parser_transmitter_control( -- dal_adapter_service_get_bios_parser( -- enc->adapter_service), -- &cntl); -- -- if (result != BP_RESULT_OK) { -- dal_logger_write(enc->ctx->logger, -- LOG_MAJOR_ERROR, -- LOG_MINOR_COMPONENT_ENCODER, -- "%s: Failed to execute VBIOS command table!\n", -- __func__); -- BREAK_TO_DEBUGGER(); -- return ENCODER_RESULT_ERROR; -- } -- -- if (enc->connector.id == CONNECTOR_ID_LVDS) { -- cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS; -- -- result = dal_bios_parser_transmitter_control( -- dal_adapter_service_get_bios_parser( -- enc->adapter_service), -- &cntl); -- ASSERT(result == BP_RESULT_OK); -- -- } else if (enc->connector.id == CONNECTOR_ID_EDP) { -- link_encoder_edp_power_control(enc, true); -- -- link_encoder_edp_wait_for_hpd_ready( -- enc, enc->connector, true); -- -- } -- aux_initialize(enc, enc->hpd_source); -- -- /* reinitialize HPD. -- * hpd_initialize() will pass DIG_FE id to HW context. -- * All other routine within HW context will use fe_engine_offset -- * as DIG_FE id even caller pass DIG_FE id. -- * So this routine must be called first. */ -- hpd_initialize(enc, enc->hpd_source); -- -- return ENCODER_RESULT_OK; --} -- -- - static bool validate_dvi_output( - const struct link_encoder *enc, - enum signal_type connector_signal, -@@ -1569,6 +1210,31 @@ static bool validate_wireless_output( - return false; - } - -+struct link_encoder *dce110_link_encoder_create( -+ const struct encoder_init_data *init) -+{ -+ struct link_encoder *enc = -+ dc_service_alloc(init->ctx, sizeof(struct link_encoder)); -+ -+ if (!enc) -+ goto enc_create_fail; -+ -+ construct(enc, init); -+ -+ return enc; -+ -+enc_create_fail: -+ return NULL; -+} -+ -+void dce110_link_encoder_destroy(struct link_encoder **enc) -+{ -+ struct link_encoder *encoder = *enc; -+ -+ dc_service_free(encoder->ctx, encoder); -+ *enc = NULL; -+} -+ - enum encoder_result dce110_link_encoder_validate_output_with_stream( - struct link_encoder *enc, - const struct core_stream *stream) -@@ -1614,84 +1280,540 @@ enum encoder_result dce110_link_encoder_validate_output_with_stream( - return is_valid ? ENCODER_RESULT_OK : ENCODER_RESULT_ERROR; - } - --/* -- * 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) -+enum encoder_result dce110_link_encoder_power_up( -+ 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; -+ struct bp_transmitter_control cntl = { 0 }; - -- if (enc->connector.id == CONNECTOR_ID_EDP /*|| wireless*/) -- result.u_all = (1 << enc->preferred_engine); -+ enum bp_result result; - -- return result; --} -+ cntl.action = TRANSMITTER_CONTROL_INIT; -+ cntl.engine_id = ENGINE_ID_UNKNOWN; -+ cntl.transmitter = enc->transmitter; -+ cntl.connector_obj_id = enc->connector; -+ cntl.lanes_number = LANE_COUNT_FOUR; -+ cntl.coherent = false; -+ cntl.hpd_sel = enc->hpd_source; - --void dce110_link_encoder_set_lcd_backlight_level( -- struct link_encoder *enc, -- uint32_t level) --{ -- struct dc_context *ctx = enc->ctx; -+ result = dal_bios_parser_transmitter_control( -+ dal_adapter_service_get_bios_parser( -+ enc->adapter_service), -+ &cntl); - -- const uint32_t backlight_update_pending_max_retry = 1000; -+ if (result != BP_RESULT_OK) { -+ dal_logger_write(enc->ctx->logger, -+ LOG_MAJOR_ERROR, -+ LOG_MINOR_COMPONENT_ENCODER, -+ "%s: Failed to execute VBIOS command table!\n", -+ __func__); -+ BREAK_TO_DEBUGGER(); -+ return ENCODER_RESULT_ERROR; -+ } - -- uint32_t backlight; -- uint32_t backlight_period; -- uint32_t backlight_lock; -+ if (enc->connector.id == CONNECTOR_ID_LVDS) { -+ cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS; - -- uint32_t i; -- uint32_t backlight_24bit; -- uint32_t backlight_17bit; -- uint32_t backlight_16bit; -- uint32_t masked_pwm_period; -- uint8_t rounding_bit; -- uint8_t bit_count; -- uint64_t active_duty_cycle; -+ result = dal_bios_parser_transmitter_control( -+ dal_adapter_service_get_bios_parser( -+ enc->adapter_service), -+ &cntl); -+ ASSERT(result == BP_RESULT_OK); - -- backlight = dal_read_reg(ctx, mmBL_PWM_CNTL); -- backlight_period = dal_read_reg(ctx, mmBL_PWM_PERIOD_CNTL); -- backlight_lock = dal_read_reg(ctx, mmBL_PWM_GRP1_REG_LOCK); -+ } else if (enc->connector.id == CONNECTOR_ID_EDP) { -+ link_encoder_edp_power_control(enc, true); - -- /* -- * 1. Convert 8-bit value to 17 bit U1.16 format -- * (1 integer, 16 fractional bits) -- */ -+ link_encoder_edp_wait_for_hpd_ready( -+ enc, enc->connector, true); - -- /* 1.1 multiply 8 bit value by 0x10101 to get a 24 bit value, -- * effectively multiplying value by 256/255 -- * eg. for a level of 0xEF, backlight_24bit = 0xEF * 0x10101 = 0xEFEFEF -- */ -- backlight_24bit = level * 0x10101; -+ } -+ aux_initialize(enc, enc->hpd_source); - -- /* 1.2 The upper 16 bits of the 24 bit value is the fraction, lower 8 -- * used for rounding, take most significant bit of fraction for -- * rounding, e.g. for 0xEFEFEF, rounding bit is 1 -- */ -- rounding_bit = (backlight_24bit >> 7) & 1; -+ /* reinitialize HPD. -+ * hpd_initialize() will pass DIG_FE id to HW context. -+ * All other routine within HW context will use fe_engine_offset -+ * as DIG_FE id even caller pass DIG_FE id. -+ * So this routine must be called first. */ -+ hpd_initialize(enc, enc->hpd_source); - -- /* 1.3 Add the upper 16 bits of the 24 bit value with the rounding bit -- * resulting in a 17 bit value e.g. 0xEFF0 = (0xEFEFEF >> 8) + 1 -- */ -- backlight_17bit = (backlight_24bit >> 8) + rounding_bit; -+ return ENCODER_RESULT_OK; -+} - -- /* -- * 2. Find 16 bit backlight active duty cycle, where 0 <= backlight -- * active duty cycle <= backlight period -- */ -+void dce110_link_encoder_setup( -+ struct link_encoder *enc, -+ enum signal_type signal) -+{ -+ const uint32_t addr = mmDIG_BE_CNTL + enc->be_engine_offset; -+ uint32_t value = dal_read_reg(enc->ctx, addr); -+ -+ switch (signal) { -+ case SIGNAL_TYPE_EDP: -+ case SIGNAL_TYPE_DISPLAY_PORT: -+ /* DP SST */ -+ set_reg_field_value(value, 0, DIG_BE_CNTL, DIG_MODE); -+ break; -+ case SIGNAL_TYPE_LVDS: -+ /* LVDS */ -+ set_reg_field_value(value, 1, DIG_BE_CNTL, DIG_MODE); -+ break; -+ case SIGNAL_TYPE_DVI_SINGLE_LINK: -+ case SIGNAL_TYPE_DVI_DUAL_LINK: -+ /* TMDS-DVI */ -+ set_reg_field_value(value, 2, DIG_BE_CNTL, DIG_MODE); -+ break; -+ case SIGNAL_TYPE_HDMI_TYPE_A: -+ /* TMDS-HDMI */ -+ set_reg_field_value(value, 3, DIG_BE_CNTL, DIG_MODE); -+ break; -+ case SIGNAL_TYPE_DISPLAY_PORT_MST: -+ /* DP MST */ -+ set_reg_field_value(value, 5, DIG_BE_CNTL, DIG_MODE); -+ break; -+ default: -+ ASSERT_CRITICAL(false); -+ /* invalid mode ! */ -+ break; -+ } -+ -+ 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( -+ 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; -+ -+ if (DELAY_AFTER_PIXEL_FORMAT_CHANGE) -+ dc_service_sleep_in_milliseconds( -+ enc->ctx, -+ DELAY_AFTER_PIXEL_FORMAT_CHANGE); -+ -+ dal_bios_parser_transmitter_control( -+ dal_adapter_service_get_bios_parser( -+ enc->adapter_service), -+ &cntl); -+ -+ return ENCODER_RESULT_OK; -+} -+ -+/* -+ * @brief -+ * Disable transmitter and its encoder -+ */ -+enum encoder_result dce110_link_encoder_disable_output( -+ struct link_encoder *link_enc, -+ enum signal_type signal) -+{ -+ struct bp_transmitter_control cntl = { 0 }; -+ -+ if (link_enc->connector.id == CONNECTOR_ID_EDP) { -+ /* have to turn off the backlight -+ * before power down eDP panel */ -+ link_encoder_edp_backlight_control( -+ link_enc, false); -+ } -+ -+ if (!is_dig_enabled(link_enc) && -+ dal_adapter_service_should_optimize(link_enc->adapter_service, -+ OF_SKIP_POWER_DOWN_INACTIVE_ENCODER)) { -+ return ENCODER_RESULT_OK; -+ } -+ /* Power-down RX and disable GPU PHY should be paired. -+ * Disabling PHY without powering down RX may cause -+ * symbol lock loss, on which we will get DP Sink interrupt. */ -+ -+ /* There is a case for the DP active dongles -+ * where we want to disable the PHY but keep RX powered, -+ * for those we need to ignore DP Sink interrupt -+ * by checking lane count that has been set -+ * on the last do_enable_output(). */ -+ -+ /* disable transmitter */ -+ cntl.action = TRANSMITTER_CONTROL_DISABLE; -+ cntl.transmitter = link_enc->transmitter; -+ cntl.hpd_sel = link_enc->hpd_source; -+ cntl.signal = signal; -+ cntl.connector_obj_id = link_enc->connector; -+ -+ dal_bios_parser_transmitter_control( -+ dal_adapter_service_get_bios_parser( -+ link_enc->adapter_service), &cntl); -+ -+ /* disable encoder */ -+ if (dc_is_dp_signal(signal)) -+ link_encoder_disable(link_enc); -+ -+ if (link_enc->connector.id == CONNECTOR_ID_EDP) { -+ /* power down eDP panel */ -+ /* TODO: Power control cause regression, we should implement -+ * it properly, for now just comment it. -+ * -+ * link_encoder_edp_wait_for_hpd_ready( -+ link_enc, -+ link_enc->connector, -+ false); -+ -+ * link_encoder_edp_power_control( -+ link_enc, false); */ -+ } -+ -+ return ENCODER_RESULT_OK; -+} -+ -+enum encoder_result dce110_link_encoder_dp_set_lane_settings( -+ struct link_encoder *enc, -+ const struct link_training_settings *link_settings) -+{ -+ union dpcd_training_lane_set training_lane_set = { { 0 } }; -+ -+ int32_t lane = 0; -+ -+ struct bp_transmitter_control cntl = { 0 }; -+ -+ if (!link_settings) { -+ BREAK_TO_DEBUGGER(); -+ return ENCODER_RESULT_ERROR; -+ } -+ -+ cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS; -+ cntl.transmitter = enc->transmitter; -+ cntl.connector_obj_id = enc->connector; -+ cntl.lanes_number = link_settings->link_settings.lane_count; -+ cntl.hpd_sel = enc->hpd_source; -+ cntl.pixel_clock = link_settings->link_settings.link_rate * -+ LINK_RATE_REF_FREQ_IN_KHZ; -+ -+ for (lane = 0; lane < link_settings->link_settings.lane_count; ++lane) { -+ /* translate lane settings */ -+ -+ training_lane_set.bits.VOLTAGE_SWING_SET = -+ link_settings->lane_settings[lane].VOLTAGE_SWING; -+ training_lane_set.bits.PRE_EMPHASIS_SET = -+ link_settings->lane_settings[lane].PRE_EMPHASIS; -+ -+ /* post cursor 2 setting only applies to HBR2 link rate */ -+ if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) { -+ /* this is passed to VBIOS -+ * to program post cursor 2 level */ -+ -+ training_lane_set.bits.POST_CURSOR2_SET = -+ link_settings->lane_settings[lane].POST_CURSOR2; -+ } -+ -+ cntl.lane_select = lane; -+ cntl.lane_settings = training_lane_set.raw; -+ -+ /* call VBIOS table to set voltage swing and pre-emphasis */ -+ -+ dal_bios_parser_transmitter_control( -+ dal_adapter_service_get_bios_parser( -+ enc->adapter_service), &cntl); -+ } -+ -+ return ENCODER_RESULT_OK; -+} -+ -+void dce110_link_encoder_set_dp_phy_pattern( -+ struct link_encoder *enc, -+ const struct encoder_set_dp_phy_pattern_param *param) -+{ -+ const int32_t offset = enc->be_engine_offset; -+ -+ -+ switch (param->dp_phy_pattern) { -+ case DP_TEST_PATTERN_TRAINING_PATTERN1: -+ set_dp_phy_pattern_training_pattern(enc->ctx, -+ offset, 0); -+ break; -+ case DP_TEST_PATTERN_TRAINING_PATTERN2: -+ set_dp_phy_pattern_training_pattern(enc->ctx, -+ offset, 1); -+ break; -+ case DP_TEST_PATTERN_TRAINING_PATTERN3: -+ set_dp_phy_pattern_training_pattern(enc->ctx, -+ offset, 2); -+ break; -+ case DP_TEST_PATTERN_D102: -+ set_dp_phy_pattern_d102(enc->ctx, offset); -+ break; -+ case DP_TEST_PATTERN_SYMBOL_ERROR: -+ set_dp_phy_pattern_symbol_error(enc->ctx, offset); -+ break; -+ case DP_TEST_PATTERN_PRBS7: -+ set_dp_phy_pattern_prbs7(enc->ctx, offset); -+ break; -+ case DP_TEST_PATTERN_80BIT_CUSTOM: -+ set_dp_phy_pattern_80bit_custom( -+ enc->ctx, -+ offset, param->custom_pattern); -+ break; -+ case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE: -+ set_dp_phy_pattern_hbr2_compliance( -+ enc, offset); -+ break; -+ case DP_TEST_PATTERN_VIDEO_MODE: { -+ set_dp_phy_pattern_passthrough_mode( -+ enc->ctx, -+ offset, -+ param->dp_panel_mode); -+ break; -+ } -+ -+ -+ default: -+ /* invalid phy pattern */ -+ ASSERT_CRITICAL(false); -+ break; -+ } -+} -+ -+/* -+ * 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; -+} -+ -+void dce110_link_encoder_update_mst_stream_allocation_table( -+ struct link_encoder *enc, -+ const struct dp_mst_stream_allocation_table *table, -+ bool is_removal) -+{ -+ int32_t addr_offset = enc->be_engine_offset; -+ uint32_t value0; -+ uint32_t value1; -+ uint32_t retries = 0; -+ -+ /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/ -+ -+ /* --- Set MSE Stream Attribute - -+ * Setup VC Payload Table on Tx Side, -+ * Issue allocation change trigger -+ * to commit payload on both tx and rx side */ -+ -+ value0 = dal_read_reg(enc->ctx, mmDP_MSE_SAT0 + addr_offset); -+ value1 = dal_read_reg(enc->ctx, mmDP_MSE_SAT1 + addr_offset); -+ -+ if (table->stream_count >= 1) { -+ set_reg_field_value( -+ value0, -+ table->stream_allocations[0].engine, -+ DP_MSE_SAT0, -+ DP_MSE_SAT_SRC0); -+ -+ set_reg_field_value( -+ value0, -+ table->stream_allocations[0].slot_count, -+ DP_MSE_SAT0, -+ DP_MSE_SAT_SLOT_COUNT0); -+ } -+ -+ if (table->stream_count >= 2) { -+ set_reg_field_value( -+ value0, -+ table->stream_allocations[1].engine, -+ DP_MSE_SAT0, -+ DP_MSE_SAT_SRC1); -+ -+ set_reg_field_value( -+ value0, -+ table->stream_allocations[1].slot_count, -+ DP_MSE_SAT0, -+ DP_MSE_SAT_SLOT_COUNT1); -+ } -+ -+ if (table->stream_count >= 3) { -+ set_reg_field_value( -+ value1, -+ table->stream_allocations[2].engine, -+ DP_MSE_SAT1, -+ DP_MSE_SAT_SRC2); -+ -+ set_reg_field_value( -+ value1, -+ table->stream_allocations[2].slot_count, -+ DP_MSE_SAT1, -+ DP_MSE_SAT_SLOT_COUNT2); -+ } -+ -+ /* update ASIC MSE stream allocation table */ -+ dal_write_reg(enc->ctx, mmDP_MSE_SAT0 + addr_offset, value0); -+ dal_write_reg(enc->ctx, mmDP_MSE_SAT1 + addr_offset, value1); -+ -+ /* --- wait for transaction finish */ -+ -+ /* send allocation change trigger (ACT) ? -+ * this step first sends the ACT, -+ * then double buffers the SAT into the hardware -+ * making the new allocation active on the DP MST mode link */ -+ -+ value0 = dal_read_reg(enc->ctx, mmDP_MSE_SAT_UPDATE + addr_offset); -+ -+ /* DP_MSE_SAT_UPDATE: -+ * 0 - No Action -+ * 1 - Update SAT with trigger -+ * 2 - Update SAT without trigger */ -+ -+ set_reg_field_value( -+ value0, -+ 1, -+ DP_MSE_SAT_UPDATE, -+ DP_MSE_SAT_UPDATE); -+ -+ dal_write_reg(enc->ctx, mmDP_MSE_SAT_UPDATE + addr_offset, value0); -+ -+ /* wait for update to complete -+ * (i.e. DP_MSE_SAT_UPDATE field is reset to 0) -+ * then wait for the transmission -+ * of at least 16 MTP headers on immediate local link. -+ * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0 -+ * a value of 1 indicates that DP MST mode -+ * is in the 16 MTP keepout region after a VC has been added. -+ * MST stream bandwidth (VC rate) can be configured -+ * after this bit is cleared */ -+ -+ do { -+ dc_service_delay_in_microseconds(enc->ctx, 10); -+ -+ value0 = dal_read_reg(enc->ctx, -+ mmDP_MSE_SAT_UPDATE + addr_offset); -+ -+ value1 = get_reg_field_value( -+ value0, -+ DP_MSE_SAT_UPDATE, -+ DP_MSE_16_MTP_KEEPOUT); -+ -+ /* bit field DP_MSE_SAT_UPDATE is set to 1 already */ -+ if (value1) -+ 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); -+ */ -+} -+ -+ -+void dce110_link_encoder_set_lcd_backlight_level( -+ struct link_encoder *enc, -+ uint32_t level) -+{ -+ struct dc_context *ctx = enc->ctx; -+ -+ const uint32_t backlight_update_pending_max_retry = 1000; -+ -+ uint32_t backlight; -+ uint32_t backlight_period; -+ uint32_t backlight_lock; -+ -+ uint32_t i; -+ uint32_t backlight_24bit; -+ uint32_t backlight_17bit; -+ uint32_t backlight_16bit; -+ uint32_t masked_pwm_period; -+ uint8_t rounding_bit; -+ uint8_t bit_count; -+ uint64_t active_duty_cycle; -+ -+ backlight = dal_read_reg(ctx, mmBL_PWM_CNTL); -+ backlight_period = dal_read_reg(ctx, mmBL_PWM_PERIOD_CNTL); -+ backlight_lock = dal_read_reg(ctx, mmBL_PWM_GRP1_REG_LOCK); -+ -+ /* -+ * 1. Convert 8-bit value to 17 bit U1.16 format -+ * (1 integer, 16 fractional bits) -+ */ -+ -+ /* 1.1 multiply 8 bit value by 0x10101 to get a 24 bit value, -+ * effectively multiplying value by 256/255 -+ * eg. for a level of 0xEF, backlight_24bit = 0xEF * 0x10101 = 0xEFEFEF -+ */ -+ backlight_24bit = level * 0x10101; -+ -+ /* 1.2 The upper 16 bits of the 24 bit value is the fraction, lower 8 -+ * used for rounding, take most significant bit of fraction for -+ * rounding, e.g. for 0xEFEFEF, rounding bit is 1 -+ */ -+ rounding_bit = (backlight_24bit >> 7) & 1; -+ -+ /* 1.3 Add the upper 16 bits of the 24 bit value with the rounding bit -+ * resulting in a 17 bit value e.g. 0xEFF0 = (0xEFEFEF >> 8) + 1 -+ */ -+ backlight_17bit = (backlight_24bit >> 8) + rounding_bit; -+ -+ /* -+ * 2. Find 16 bit backlight active duty cycle, where 0 <= backlight -+ * active duty cycle <= backlight period -+ */ - - /* 2.1 Apply bitmask for backlight period value based on value of BITCNT - */ -@@ -1831,127 +1953,6 @@ void dce110_set_afmt_memory_power_state( - dal_write_reg(ctx, mmDCO_MEM_PWR_CTRL, value); - } - --void dce110_link_encoder_update_mst_stream_allocation_table( -- struct link_encoder *enc, -- const struct dp_mst_stream_allocation_table *table, -- bool is_removal) --{ -- int32_t addr_offset = enc->be_engine_offset; -- uint32_t value0; -- uint32_t value1; -- uint32_t retries = 0; -- -- /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/ -- -- /* --- Set MSE Stream Attribute - -- * Setup VC Payload Table on Tx Side, -- * Issue allocation change trigger -- * to commit payload on both tx and rx side */ -- -- value0 = dal_read_reg(enc->ctx, mmDP_MSE_SAT0 + addr_offset); -- value1 = dal_read_reg(enc->ctx, mmDP_MSE_SAT1 + addr_offset); -- -- if (table->stream_count >= 1) { -- set_reg_field_value( -- value0, -- table->stream_allocations[0].engine, -- DP_MSE_SAT0, -- DP_MSE_SAT_SRC0); -- -- set_reg_field_value( -- value0, -- table->stream_allocations[0].slot_count, -- DP_MSE_SAT0, -- DP_MSE_SAT_SLOT_COUNT0); -- } -- -- if (table->stream_count >= 2) { -- set_reg_field_value( -- value0, -- table->stream_allocations[1].engine, -- DP_MSE_SAT0, -- DP_MSE_SAT_SRC1); -- -- set_reg_field_value( -- value0, -- table->stream_allocations[1].slot_count, -- DP_MSE_SAT0, -- DP_MSE_SAT_SLOT_COUNT1); -- } -- -- if (table->stream_count >= 3) { -- set_reg_field_value( -- value1, -- table->stream_allocations[2].engine, -- DP_MSE_SAT1, -- DP_MSE_SAT_SRC2); -- -- set_reg_field_value( -- value1, -- table->stream_allocations[2].slot_count, -- DP_MSE_SAT1, -- DP_MSE_SAT_SLOT_COUNT2); -- } -- -- /* update ASIC MSE stream allocation table */ -- dal_write_reg(enc->ctx, mmDP_MSE_SAT0 + addr_offset, value0); -- dal_write_reg(enc->ctx, mmDP_MSE_SAT1 + addr_offset, value1); -- -- /* --- wait for transaction finish */ -- -- /* send allocation change trigger (ACT) ? -- * this step first sends the ACT, -- * then double buffers the SAT into the hardware -- * making the new allocation active on the DP MST mode link */ -- -- value0 = dal_read_reg(enc->ctx, mmDP_MSE_SAT_UPDATE + addr_offset); -- -- /* DP_MSE_SAT_UPDATE: -- * 0 - No Action -- * 1 - Update SAT with trigger -- * 2 - Update SAT without trigger */ -- -- set_reg_field_value( -- value0, -- 1, -- DP_MSE_SAT_UPDATE, -- DP_MSE_SAT_UPDATE); -- -- dal_write_reg(enc->ctx, mmDP_MSE_SAT_UPDATE + addr_offset, value0); -- -- /* wait for update to complete -- * (i.e. DP_MSE_SAT_UPDATE field is reset to 0) -- * then wait for the transmission -- * of at least 16 MTP headers on immediate local link. -- * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0 -- * a value of 1 indicates that DP MST mode -- * is in the 16 MTP keepout region after a VC has been added. -- * MST stream bandwidth (VC rate) can be configured -- * after this bit is cleared */ -- -- do { -- dc_service_delay_in_microseconds(enc->ctx, 10); -- -- value0 = dal_read_reg(enc->ctx, -- mmDP_MSE_SAT_UPDATE + addr_offset); -- -- value1 = get_reg_field_value( -- value0, -- DP_MSE_SAT_UPDATE, -- DP_MSE_16_MTP_KEEPOUT); -- -- /* bit field DP_MSE_SAT_UPDATE is set to 1 already */ -- if (value1) -- 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); -- */ --} -- - void dce110_link_encoder_set_mst_bandwidth( - struct link_encoder *enc, - enum engine_id engine, -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 4331bf0..eae2267 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 -@@ -30,26 +30,11 @@ struct link_encoder *dce110_link_encoder_create( - const struct encoder_init_data *init); - void dce110_link_encoder_destroy(struct link_encoder **enc); - --void dce110_link_encoder_set_dp_phy_pattern( -- struct link_encoder *enc, -- const struct encoder_set_dp_phy_pattern_param *param); -- --enum encoder_result dce110_link_encoder_power_up(struct link_encoder *enc); -- --enum encoder_result dce110_link_encoder_dp_set_lane_settings( -- struct link_encoder *enc, -- const struct link_training_settings *link_settings); -- --union supported_stream_engines dce110_get_supported_stream_engines( -- const struct link_encoder *enc); -- - enum encoder_result dce110_link_encoder_validate_output_with_stream( - struct link_encoder *enc, - const struct core_stream *stream); - --void dce110_link_encoder_set_lcd_backlight_level( -- struct link_encoder *enc, -- uint32_t level); -+enum encoder_result dce110_link_encoder_power_up(struct link_encoder *enc); - - void dce110_link_encoder_setup( - struct link_encoder *enc, -@@ -68,16 +53,32 @@ enum encoder_result dce110_link_encoder_disable_output( - struct link_encoder *link_enc, - enum signal_type signal); - --void dce110_set_afmt_memory_power_state( -- const struct dc_context *ctx, -- enum engine_id id, -- bool enable); -+ -+enum encoder_result dce110_link_encoder_dp_set_lane_settings( -+ struct link_encoder *enc, -+ const struct link_training_settings *link_settings); -+ -+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); - - void dce110_link_encoder_update_mst_stream_allocation_table( - struct link_encoder *enc, - const struct dp_mst_stream_allocation_table *table, - bool is_removal); - -+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( - struct link_encoder *enc, - enum engine_id engine, -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 a9edf96..d3ab89a 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 -@@ -54,29 +54,6 @@ static void construct( - enc->adapter_service = init->adapter_service; - } - --struct stream_encoder *dce110_stream_encoder_create( -- struct stream_enc_init_data *init) --{ -- struct stream_encoder *enc = -- dc_service_alloc(init->ctx, sizeof(struct stream_encoder)); -- -- if (!enc) -- goto enc_create_fail; -- -- construct(enc, init); -- -- return enc; -- --enc_create_fail: -- return NULL; --} -- --void dce110_stream_encoder_destroy(struct stream_encoder **enc) --{ -- dc_service_free((*enc)->ctx, *enc); -- *enc = NULL; --} -- - static void stop_hdmi_info_packets(struct dc_context *ctx, uint32_t offset) - { - uint32_t addr = 0; -@@ -207,22 +184,6 @@ static void stop_dp_info_packets(struct dc_context *ctx, int32_t offset) - dal_write_reg(ctx, addr, value); - } - --void dce110_stream_encoder_stop_info_packets( -- struct stream_encoder *enc, -- enum engine_id engine, -- enum signal_type signal) --{ -- 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]); --} -- -- - static void update_avi_info_packet( - struct stream_encoder *enc, - enum engine_id engine, -@@ -615,24 +576,6 @@ static void update_dp_info_packet( - dal_write_reg(enc->ctx, addr, value); - } - --void dce110_stream_encoder_update_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); --} -- - static void dp_steer_fifo_reset( - struct dc_context *ctx, - enum engine_id engine, -@@ -647,76 +590,6 @@ static void dp_steer_fifo_reset( - dal_write_reg(ctx, addr, value); - } - --/* -- * @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) --{ -- enum engine_id engine = enc->id; -- const uint32_t addr = mmDP_VID_STREAM_CNTL + fe_engine_offsets[engine]; -- uint32_t value = dal_read_reg(enc->ctx, addr); -- 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 -- * handful of panels that cannot handle disable stream at -- * HBLANK and will result in a white line flash across the -- * screen on stream disable. */ -- -- /* Specify the video stream disable point -- * (2 = start of the next vertical blank) */ -- set_reg_field_value( -- value, -- 2, -- DP_VID_STREAM_CNTL, -- DP_VID_STREAM_DIS_DEFER); -- /* Larger delay to wait until VBLANK - use max retry of -- * 10us*3000=30ms. This covers 16.6ms of typical 60 Hz mode + -- * a little more because we may not trust delay accuracy. */ -- max_retries = DP_BLANK_MAX_RETRY * 150; -- -- /* disable DP stream */ -- set_reg_field_value(value, 0, DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE); -- dal_write_reg(enc->ctx, addr, value); -- -- /* the encoder stops sending the video stream -- * at the start of the vertical blanking. -- * Poll for DP_VID_STREAM_STATUS == 0 */ -- -- do { -- value = dal_read_reg(enc->ctx, addr); -- -- if (!get_reg_field_value( -- value, -- DP_VID_STREAM_CNTL, -- DP_VID_STREAM_STATUS)) -- break; -- -- dc_service_delay_in_microseconds(enc->ctx, 10); -- -- ++retries; -- } while (retries < max_retries); -- -- ASSERT(retries <= max_retries); -- -- /* Tell the DP encoder to ignore timing from CRTC, must be done after -- * the polling. If we set DP_STEER_FIFO_RESET before DP stream blank is -- * 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; --} -- - static void unblank_dp_output( - struct stream_encoder *enc, - enum engine_id engine) -@@ -786,46 +659,6 @@ static void setup_vid_stream( - set_reg_field_value(value, 1, DP_VID_TIMING, DP_VID_M_N_GEN_EN); - dal_write_reg(enc->ctx, addr, value); - } --/* -- * @brief -- * Stop sending blank data, -- * output the actual surface data on active transmitter -- */ --enum encoder_result dce110_stream_encoder_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; -- -- /* M / N = Fstream / Flink -- * m_vid / n_vid = pixel rate / link rate */ -- -- uint64_t m_vid_l = n_vid; -- -- m_vid_l *= param->crtc_timing.pixel_clock; -- m_vid_l = div_u64(m_vid_l, -- param->link_settings.link_rate -- * LINK_RATE_REF_FREQ_IN_KHZ); -- -- m_vid = (uint32_t) m_vid_l; -- -- setup_vid_stream(enc, -- enc->id, m_vid, n_vid); -- } -- -- unblank_dp_output(enc, enc->id); -- -- return ENCODER_RESULT_OK; --} - - static void set_dp_stream_attributes( - struct stream_encoder *enc, -@@ -1106,6 +939,29 @@ static void set_tmds_stream_attributes( - dal_write_reg(enc->ctx, addr, value); - } - -+struct stream_encoder *dce110_stream_encoder_create( -+ struct stream_enc_init_data *init) -+{ -+ struct stream_encoder *enc = -+ dc_service_alloc(init->ctx, sizeof(struct stream_encoder)); -+ -+ if (!enc) -+ goto enc_create_fail; -+ -+ construct(enc, init); -+ -+ return enc; -+ -+enc_create_fail: -+ return NULL; -+} -+ -+void dce110_stream_encoder_destroy(struct stream_encoder **enc) -+{ -+ dc_service_free((*enc)->ctx, *enc); -+ *enc = NULL; -+} -+ - /* - * @brief - * Associate digital encoder with specified output transmitter -@@ -1166,3 +1022,148 @@ enum encoder_result dce110_stream_encoder_setup( - - return ENCODER_RESULT_OK; - } -+ -+void dce110_stream_encoder_update_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); -+} -+ -+void dce110_stream_encoder_stop_info_packets( -+ struct stream_encoder *enc, -+ enum engine_id engine, -+ enum signal_type signal) -+{ -+ 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]); -+} -+ -+/* -+ * @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) -+{ -+ enum engine_id engine = enc->id; -+ const uint32_t addr = mmDP_VID_STREAM_CNTL + fe_engine_offsets[engine]; -+ uint32_t value = dal_read_reg(enc->ctx, addr); -+ 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 -+ * handful of panels that cannot handle disable stream at -+ * HBLANK and will result in a white line flash across the -+ * screen on stream disable. */ -+ -+ /* Specify the video stream disable point -+ * (2 = start of the next vertical blank) */ -+ set_reg_field_value( -+ value, -+ 2, -+ DP_VID_STREAM_CNTL, -+ DP_VID_STREAM_DIS_DEFER); -+ /* Larger delay to wait until VBLANK - use max retry of -+ * 10us*3000=30ms. This covers 16.6ms of typical 60 Hz mode + -+ * a little more because we may not trust delay accuracy. */ -+ max_retries = DP_BLANK_MAX_RETRY * 150; -+ -+ /* disable DP stream */ -+ set_reg_field_value(value, 0, DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE); -+ dal_write_reg(enc->ctx, addr, value); -+ -+ /* the encoder stops sending the video stream -+ * at the start of the vertical blanking. -+ * Poll for DP_VID_STREAM_STATUS == 0 */ -+ -+ do { -+ value = dal_read_reg(enc->ctx, addr); -+ -+ if (!get_reg_field_value( -+ value, -+ DP_VID_STREAM_CNTL, -+ DP_VID_STREAM_STATUS)) -+ break; -+ -+ dc_service_delay_in_microseconds(enc->ctx, 10); -+ -+ ++retries; -+ } while (retries < max_retries); -+ -+ ASSERT(retries <= max_retries); -+ -+ /* Tell the DP encoder to ignore timing from CRTC, must be done after -+ * the polling. If we set DP_STEER_FIFO_RESET before DP stream blank is -+ * 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( -+ 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; -+ -+ /* M / N = Fstream / Flink -+ * m_vid / n_vid = pixel rate / link rate */ -+ -+ uint64_t m_vid_l = n_vid; -+ -+ m_vid_l *= param->crtc_timing.pixel_clock; -+ m_vid_l = div_u64(m_vid_l, -+ param->link_settings.link_rate -+ * LINK_RATE_REF_FREQ_IN_KHZ); -+ -+ m_vid = (uint32_t) m_vid_l; -+ -+ setup_vid_stream(enc, -+ enc->id, m_vid, n_vid); -+ } -+ -+ 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 d2c7b90..83df255 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 -@@ -37,16 +37,22 @@ struct stream_encoder *dce110_stream_encoder_create( - - void dce110_stream_encoder_destroy(struct stream_encoder **enc); - --void dce110_stream_encoder_stop_info_packets( -+enum encoder_result dce110_stream_encoder_setup( - struct stream_encoder *enc, -- enum engine_id engine, -- enum signal_type signal); -+ struct dc_crtc_timing *crtc_timing, -+ enum signal_type signal, -+ bool enable_audio); - - void dce110_stream_encoder_update_info_packets( - struct stream_encoder *enc, - enum signal_type signal, - const struct encoder_info_frame *info_frame); - -+void dce110_stream_encoder_stop_info_packets( -+ struct stream_encoder *enc, -+ enum engine_id engine, -+ enum signal_type signal); -+ - enum encoder_result dce110_stream_encoder_blank( - struct stream_encoder *enc, - enum signal_type signal); -@@ -55,10 +61,4 @@ enum encoder_result dce110_stream_encoder_unblank( - struct stream_encoder *enc, - const struct encoder_unblank_param *param); - --enum encoder_result dce110_stream_encoder_setup( -- struct stream_encoder *enc, -- struct dc_crtc_timing *crtc_timing, -- enum signal_type signal, -- bool enable_audio); -- - #endif /* __DC_STREAM_ENCODER_DCE110_H__ */ --- -2.7.4 - |