From 23c6d8e0bf49db5d89c2a6e6030979d7f9a229da Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Mon, 21 Dec 2015 13:46:25 -0500 Subject: [PATCH 0644/1110] drm/amd/dal: Refactor link encoder interface. Signed-off-by: Yongqiang Sun Acked-by: Jordan Lazare --- drivers/gpu/drm/amd/dal/dc/core/dc.c | 2 +- drivers/gpu/drm/amd/dal/dc/core/dc_link.c | 20 +-- drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c | 18 +-- .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 9 +- .../drm/amd/dal/dc/dce110/dce110_link_encoder.c | 159 +++++++++++++++++---- .../drm/amd/dal/dc/dce110/dce110_link_encoder.h | 41 ++++-- drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h | 42 ++++-- 7 files changed, 222 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c index 2c9a404..df243c2 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c @@ -166,7 +166,7 @@ static void init_hw(struct dc *dc) * required signal (which may be different from the * default signal on connector). */ struct core_link *link = dc->links[i]; - dc->hwss.encoder_power_up(link->link_enc); + dc->hwss.encoder_hw_init(link->link_enc); } for(i = 0; i < dc->res_pool.controller_count; i++) { diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c index 5516ec7..9b8f536 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c @@ -1013,15 +1013,19 @@ static void enable_link_hdmi(struct core_stream *stream) stream->sink->link->cur_link_settings.lane_count = (stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR; + if (stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) + link->ctx->dc->hwss.encoder_enable_dual_link_tmds_output( + stream->sink->link->link_enc, + dal_clock_source_get_id(stream->clock_source), + stream->public.timing.display_color_depth, + stream->public.timing.pix_clk_khz); + else + link->ctx->dc->hwss.encoder_enable_tmds_output( + stream->sink->link->link_enc, + dal_clock_source_get_id(stream->clock_source), + stream->public.timing.display_color_depth, + stream->public.timing.pix_clk_khz); - link->ctx->dc->hwss.encoder_enable_output( - stream->sink->link->link_enc, - &stream->sink->link->cur_link_settings, - stream->stream_enc->id, - dal_clock_source_get_id(stream->clock_source), - stream->signal, - stream->public.timing.display_color_depth, - stream->public.timing.pix_clk_khz); if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) dal_ddc_service_read_scdc_data(link->ddc); diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c index 727c812..a1617bc 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c @@ -58,14 +58,16 @@ void dp_enable_link_phy( enum engine_id engine, const struct link_settings *link_settings) { - link->dc->hwss.encoder_enable_output( - link->link_enc, - link_settings, - engine, - CLOCK_SOURCE_ID_EXTERNAL, - signal, - COLOR_DEPTH_UNDEFINED, - 0); + if (signal == SIGNAL_TYPE_DISPLAY_PORT) + link->dc->hwss.encoder_enable_dp_output( + link->link_enc, + link_settings, + CLOCK_SOURCE_ID_EXTERNAL); + else + link->dc->hwss.encoder_enable_dp_mst_output( + link->link_enc, + link_settings, + CLOCK_SOURCE_ID_EXTERNAL); dp_receiver_power_ctrl(link, true); } 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 d944781..6a59fc3 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 @@ -1723,8 +1723,13 @@ static const struct hw_sequencer_funcs dce110_funcs = { .disable_vga = dce110_timing_generator_disable_vga, .encoder_create = dce110_link_encoder_create, .encoder_destroy = dce110_link_encoder_destroy, - .encoder_power_up = dce110_link_encoder_power_up, - .encoder_enable_output = dce110_link_encoder_enable_output, + .encoder_hw_init = dce110_link_encoder_hw_init, + .encoder_enable_tmds_output = dce110_link_encoder_enable_tmds_output, + .encoder_enable_dual_link_tmds_output = + dce110_link_encoder_enable_dual_link_tmds_output, + .encoder_enable_dp_output = dce110_link_encoder_enable_dp_output, + .encoder_enable_dp_mst_output = + dce110_link_encoder_enable_dp_mst_output, .encoder_disable_output = dce110_link_encoder_disable_output, .encoder_set_dp_phy_pattern = dce110_link_encoder_set_dp_phy_pattern, .encoder_dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, 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 d71efa9..08711c2 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 @@ -33,7 +33,6 @@ #include "dce/dce_11_0_sh_mask.h" #include "dce/dce_11_0_enum.h" -#define DELAY_AFTER_PIXEL_FORMAT_CHANGE 0 /* ms */ /* For current ASICs pixel clock - 600MHz */ #define MAX_ENCODER_CLK 600000 @@ -605,7 +604,6 @@ static uint8_t get_frontend_source( static void configure_encoder( struct dce110_link_encoder *enc110, - enum engine_id engine, const struct link_settings *link_settings) { struct dc_context *ctx = enc110->base.ctx; @@ -1285,7 +1283,7 @@ bool dce110_link_encoder_validate_output_with_stream( return is_valid; } -void dce110_link_encoder_power_up( +void dce110_link_encoder_hw_init( struct link_encoder *enc) { struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); @@ -1383,17 +1381,10 @@ void dce110_link_encoder_setup( dal_write_reg(ctx, addr, value); } -/* - * @brief - * Configure digital transmitter and enable both encoder and transmitter - * Actual output will be available after calling unblank() - */ -void dce110_link_encoder_enable_output( +/* TODO: still need depth or just pass in adjusted pixel clock? */ +void 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) { @@ -1402,6 +1393,87 @@ void dce110_link_encoder_enable_output( struct bp_transmitter_control cntl = { 0 }; enum bp_result result; + /* Enable the PHY */ + + cntl.action = TRANSMITTER_CONTROL_ENABLE; + cntl.engine_id = enc->transmitter; + cntl.transmitter = enc110->base.transmitter; + cntl.pll_id = clock_source; + cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK; + cntl.lanes_number = 4; + cntl.hpd_sel = enc110->base.hpd_source; + + cntl.pixel_clock = pixel_clock; + cntl.color_depth = color_depth; + + result = dal_bios_parser_transmitter_control( + dal_adapter_service_get_bios_parser( + enc110->base.adapter_service), + &cntl); + + if (result != BP_RESULT_OK) { + dal_logger_write(ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_ENCODER, + "%s: Failed to execute VBIOS command table!\n", + __func__); + BREAK_TO_DEBUGGER(); + } +} + +/* enables TMDS PHY output */ +/* TODO: still need this or just pass in adjusted pixel clock? */ +void 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) +{ + struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); + struct dc_context *ctx = enc110->base.ctx; + struct bp_transmitter_control cntl = { 0 }; + enum bp_result result; + + /* Enable the PHY */ + + cntl.action = TRANSMITTER_CONTROL_ENABLE; + cntl.engine_id = enc->transmitter; + cntl.transmitter = enc110->base.transmitter; + cntl.pll_id = clock_source; + cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK; + cntl.lanes_number = 8; + cntl.hpd_sel = enc110->base.hpd_source; + + cntl.pixel_clock = pixel_clock; + cntl.color_depth = color_depth; + + result = dal_bios_parser_transmitter_control( + dal_adapter_service_get_bios_parser( + enc110->base.adapter_service), + &cntl); + + if (result != BP_RESULT_OK) { + dal_logger_write(ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_ENCODER, + "%s: Failed to execute VBIOS command table!\n", + __func__); + BREAK_TO_DEBUGGER(); + } +} + +/* enables DP PHY output */ +void dce110_link_encoder_enable_dp_output( + struct link_encoder *enc, + const struct link_settings *link_settings, + enum clock_source_id clock_source) +{ + struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); + struct dc_context *ctx = enc110->base.ctx; + struct bp_transmitter_control cntl = { 0 }; + enum bp_result result; + enum engine_id engine = enc->transmitter; + if (enc110->base.connector.id == CONNECTOR_ID_EDP) { /* power up eDP panel */ @@ -1421,27 +1493,19 @@ void dce110_link_encoder_enable_output( * but it's not passed to asic_control. * We need to set number of lanes manually. */ - if (dc_is_dp_signal(signal)) - configure_encoder(enc110, engine, link_settings); + configure_encoder(enc110, link_settings); cntl.action = TRANSMITTER_CONTROL_ENABLE; cntl.engine_id = engine; cntl.transmitter = enc110->base.transmitter; cntl.pll_id = clock_source; - cntl.signal = signal; + cntl.signal = SIGNAL_TYPE_DISPLAY_PORT; cntl.lanes_number = link_settings->lane_count; cntl.hpd_sel = enc110->base.hpd_source; - if (dc_is_dp_signal(signal)) - cntl.pixel_clock = link_settings->link_rate + 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( - ctx, - DELAY_AFTER_PIXEL_FORMAT_CHANGE); + /* TODO: check if undefined works */ + cntl.color_depth = COLOR_DEPTH_UNDEFINED; result = dal_bios_parser_transmitter_control( dal_adapter_service_get_bios_parser( @@ -1458,6 +1522,51 @@ void dce110_link_encoder_enable_output( } } +/* enables DP PHY output in MST mode */ +void dce110_link_encoder_enable_dp_mst_output( + struct link_encoder *enc, + const struct link_settings *link_settings, + enum clock_source_id clock_source) +{ + struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); + struct dc_context *ctx = enc110->base.ctx; + struct bp_transmitter_control cntl = { 0 }; + enum bp_result result; + enum engine_id engine = enc->transmitter; + /* 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. + */ + configure_encoder(enc110, link_settings); + + cntl.action = TRANSMITTER_CONTROL_ENABLE; + cntl.engine_id = engine; + cntl.transmitter = enc110->base.transmitter; + cntl.pll_id = clock_source; + cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST; + cntl.lanes_number = link_settings->lane_count; + cntl.hpd_sel = enc110->base.hpd_source; + cntl.pixel_clock = link_settings->link_rate + * LINK_RATE_REF_FREQ_IN_KHZ; + /* TODO: check if undefined works */ + cntl.color_depth = COLOR_DEPTH_UNDEFINED; + + result = dal_bios_parser_transmitter_control( + dal_adapter_service_get_bios_parser( + enc110->base.adapter_service), + &cntl); + + if (result != BP_RESULT_OK) { + dal_logger_write(ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_ENCODER, + "%s: Failed to execute VBIOS command table!\n", + __func__); + BREAK_TO_DEBUGGER(); + } +} /* * @brief * Disable transmitter and its encoder 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 820a7b8..c5b16f6 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 @@ -53,7 +53,7 @@ bool dce110_link_encoder_validate_output_with_stream( /****************** HW programming ************************/ /* initialize HW */ /* why do we initialze aux in here? */ -void dce110_link_encoder_power_up(struct link_encoder *enc); +void dce110_link_encoder_hw_init(struct link_encoder *enc); /* program DIG_MODE in DIG_BE */ /* TODO can this be combined with enable_output? */ @@ -61,9 +61,37 @@ void dce110_link_encoder_setup( struct link_encoder *enc, enum signal_type signal); +/* enables TMDS PHY output */ +/* TODO: still need depth or just pass in adjusted pixel clock? */ +void 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? */ +void 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); + +/* enables DP PHY output */ +void 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 */ +void 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 */ void dce110_link_encoder_disable_output( - struct link_encoder *enc, + struct link_encoder *link_enc, enum signal_type signal); /* set DP lane settings */ @@ -84,15 +112,6 @@ void dce110_link_encoder_set_lcd_backlight_level( struct link_encoder *enc, uint32_t level); -void 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); - void dce110_link_encoder_connect_dig_be_to_fe( struct link_encoder *enc, enum engine_id engine, diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h index b9f21bb..50af714 100644 --- a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h @@ -52,12 +52,12 @@ struct hw_sequencer_funcs { bool (*transform_power_up)(struct transform *xfm); bool (*cursor_set_attributes)( - struct input_pixel_processor *ipp, - const struct dc_cursor_attributes *attributes); + struct input_pixel_processor *ipp, + const struct dc_cursor_attributes *attributes); bool (*cursor_set_position)( - struct input_pixel_processor *ipp, - const struct dc_cursor_position *position); + struct input_pixel_processor *ipp, + const struct dc_cursor_position *position); bool (*set_gamma_ramp)( struct input_pixel_processor *ipp, @@ -86,33 +86,47 @@ struct hw_sequencer_funcs { /* link encoder sequences */ - struct link_encoder *(*encoder_create)(const struct encoder_init_data *init); + struct link_encoder *(*encoder_create)( + const struct encoder_init_data *init); void (*encoder_destroy)(struct link_encoder **enc); - void (*encoder_power_up)( + void (*encoder_hw_init)( struct link_encoder *enc); - void (*encoder_enable_output)( + void (*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); + void (*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); + + void (*encoder_enable_dp_output)( + struct link_encoder *enc, + const struct link_settings *link_settings, + enum clock_source_id clock_source); + + void (*encoder_enable_dp_mst_output)( + struct link_encoder *enc, + const struct link_settings *link_settings, + enum clock_source_id clock_source); + void (*encoder_disable_output)( struct link_encoder *enc, enum signal_type signal); void (*encoder_set_dp_phy_pattern)( - struct link_encoder *enc, - const struct encoder_set_dp_phy_pattern_param *param); + struct link_encoder *enc, + const struct encoder_set_dp_phy_pattern_param *param); void (*encoder_dp_set_lane_settings)( - struct link_encoder *enc, - const struct link_training_settings *link_settings); + struct link_encoder *enc, + const struct link_training_settings *link_settings); /* backlight control */ void (*encoder_set_lcd_backlight_level)(struct link_encoder *enc, -- 2.7.4