aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0644-drm-amd-dal-Refactor-link-encoder-interface.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0644-drm-amd-dal-Refactor-link-encoder-interface.patch')
-rw-r--r--common/recipes-kernel/linux/files/0644-drm-amd-dal-Refactor-link-encoder-interface.patch483
1 files changed, 483 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0644-drm-amd-dal-Refactor-link-encoder-interface.patch b/common/recipes-kernel/linux/files/0644-drm-amd-dal-Refactor-link-encoder-interface.patch
new file mode 100644
index 00000000..158510f1
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0644-drm-amd-dal-Refactor-link-encoder-interface.patch
@@ -0,0 +1,483 @@
+From 23c6d8e0bf49db5d89c2a6e6030979d7f9a229da Mon Sep 17 00:00:00 2001
+From: Yongqiang Sun <yongqiang.sun@amd.com>
+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 <yongqiang.sun@amd.com>
+Acked-by: Jordan Lazare <Jordan.Lazare@amd.com>
+---
+ 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
+