diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0526-drm-amd-dal-MST-two-monitors-light-up-add-PHY-payloa.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0526-drm-amd-dal-MST-two-monitors-light-up-add-PHY-payloa.patch | 500 |
1 files changed, 0 insertions, 500 deletions
diff --git a/common/recipes-kernel/linux/files/0526-drm-amd-dal-MST-two-monitors-light-up-add-PHY-payloa.patch b/common/recipes-kernel/linux/files/0526-drm-amd-dal-MST-two-monitors-light-up-add-PHY-payloa.patch deleted file mode 100644 index a5412898..00000000 --- a/common/recipes-kernel/linux/files/0526-drm-amd-dal-MST-two-monitors-light-up-add-PHY-payloa.patch +++ /dev/null @@ -1,500 +0,0 @@ -From 7bf1102eda7d1e5ef2eeec7a04fe9e91bf321dfa Mon Sep 17 00:00:00 2001 -From: Hersen Wu <hersenxs.wu@amd.com> -Date: Mon, 23 Nov 2015 15:44:57 -0500 -Subject: [PATCH 0526/1110] drm/amd/dal: MST two monitors light up add PHY - payload alloaction 2 - -Signed-off-by: Hersen Wu <hersenxs.wu@amd.com> -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Acked-by: Harry Wentland <harry.wentland@amd.com> ---- - .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c | 116 ++++++++++++++++++++- - drivers/gpu/drm/amd/dal/dc/core/dc_link.c | 63 ++++++++++- - drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c | 17 ++- - drivers/gpu/drm/amd/dal/dc/dc_helpers.h | 2 +- - .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 40 ++++--- - .../drm/amd/dal/dc/dce110/dce110_link_encoder.c | 7 +- - drivers/gpu/drm/amd/dal/dc/inc/core_types.h | 3 + - drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h | 2 + - .../gpu/drm/amd/dal/include/link_service_types.h | 9 +- - 9 files changed, 228 insertions(+), 31 deletions(-) - -diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c -index c3b6715..7a07af5 100644 ---- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c -+++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c -@@ -32,6 +32,8 @@ - #include <drm/drm_edid.h> - - #include "dc_types.h" -+#include "core_types.h" -+#include "stream_encoder_types.h" - #include "amdgpu.h" - #include "dc.h" - #include "dc_services.h" -@@ -167,12 +169,14 @@ static struct amdgpu_connector *get_connector_for_link( - bool dc_helpers_dp_mst_write_payload_allocation_table( - struct dc_context *ctx, - const struct dc_sink *sink, -- struct dp_mst_stream_allocation *alloc_entity, -+ struct dp_mst_stream_allocation_table *table, - bool enable) - { - struct amdgpu_device *adev = ctx->driver_context; - struct drm_device *dev = adev->ddev; - struct amdgpu_connector *aconnector; -+ struct drm_connector *connector; -+ struct amdgpu_crtc *amdgpu_crtc; - struct drm_crtc *crtc; - struct drm_dp_mst_topology_mgr *mst_mgr; - struct drm_dp_mst_port *mst_port; -@@ -181,10 +185,16 @@ bool dc_helpers_dp_mst_write_payload_allocation_table( - int clock; - int bpp; - int pbn = 0; -+ uint8_t i; -+ uint8_t vcid; -+ bool find_stream_for_sink; - - aconnector = get_connector_for_sink(dev, sink); - crtc = aconnector->base.state->crtc; - -+ if (!crtc) -+ return false; -+ - if (!aconnector->mst_port) - return false; - -@@ -201,6 +211,8 @@ bool dc_helpers_dp_mst_write_payload_allocation_table( - pbn = drm_dp_calc_pbn_mode(clock, bpp); - - ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, pbn, &slots); -+ /* mst_port->vcpi.vcpi is vc_id for this stream.*/ -+ vcid = mst_port->vcpi.vcpi; - - if (!ret) - return false; -@@ -209,11 +221,105 @@ bool dc_helpers_dp_mst_write_payload_allocation_table( - drm_dp_mst_reset_vcpi_slots(mst_mgr, mst_port); - } - -- alloc_entity->slot_count = slots; -- alloc_entity->pbn = pbn; -- alloc_entity->pbn_per_slot = mst_mgr->pbn_div; -- - ret = drm_dp_update_payload_part1(mst_mgr); -+ -+ /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or -+ * AUX message. The sequence is slot 1-63 allocated sequence for each -+ * stream. AMD ASIC stream slot allocation should follow the same -+ * sequence. copy DRM MST allocation to dc */ -+ -+ mutex_lock(&mst_mgr->payload_lock); -+ -+ /* number of active streams */ -+ for (i = 0; i < mst_mgr->max_payloads; i++) { -+ if (mst_mgr->payloads[i].num_slots == 0) -+ break; -+ table->stream_count++; -+ } -+ -+ for (i = 0; i < table->stream_count; i++) { -+ table->stream_allocations[i].slot_count = -+ mst_mgr->proposed_vcpis[i]->num_slots; -+ /* mst_mgr->pbn_div is fixed value after link training for -+ * current link PHY */ -+ table->stream_allocations[i].pbn_per_slot = mst_mgr->pbn_div; -+ -+ /* find which payload is for current stream -+ * after drm_dp_update_payload_part1, payload and proposed_vcpis -+ * are sync to the same allocation sequence. vcpi is not saved -+ * into payload by drm_dp_update_payload_part1. In order to -+ * find sequence of a payload within allocation sequence, we -+ * need check vcpi from proposed_vcpis*/ -+ -+ table->stream_allocations[i].pbn = -+ mst_mgr->proposed_vcpis[i]->pbn; -+ -+ if (mst_mgr->proposed_vcpis[i]->vcpi == vcid) -+ table->cur_stream_payload_idx = i; -+ -+ find_stream_for_sink = false; -+ -+ list_for_each_entry(connector, -+ &dev->mode_config.connector_list, head) { -+ -+ aconnector = to_amdgpu_connector(connector); -+ -+ /* not mst connector */ -+ if (!aconnector->mst_port) -+ continue; -+ mst_port = aconnector->port; -+ -+ if (mst_port->vcpi.vcpi == -+ mst_mgr->proposed_vcpis[i]->vcpi) { -+ /* find connector with same vcid as payload */ -+ -+ const struct dc_sink *dc_sink_connector; -+ struct core_sink *core_sink; -+ struct dc_target *dc_target; -+ struct core_target *core_target; -+ struct stream_encoder *stream_enc; -+ uint8_t j; -+ -+ dc_sink_connector = aconnector->dc_sink; -+ core_sink = DC_SINK_TO_CORE(dc_sink_connector); -+ -+ /* find stream to drive this sink -+ * crtc -> target -> stream -> sink */ -+ crtc = aconnector->base.state->crtc; -+ amdgpu_crtc = to_amdgpu_crtc(crtc); -+ dc_target = amdgpu_crtc->target; -+ core_target = DC_TARGET_TO_CORE(dc_target); -+ -+ for (j = 0; j < core_target->stream_count; -+ j++) { -+ if (core_target->streams[j]->sink == -+ core_sink) -+ break; -+ } -+ -+ if (j < core_target->stream_count) { -+ /* find sink --> stream --> target --> -+ * connector*/ -+ stream_enc = -+ core_target->streams[j]->stream_enc; -+ table->stream_allocations[i].engine = -+ stream_enc->id; -+ /* exit loop connector */ -+ find_stream_for_sink = true; -+ break; -+ } -+ } -+ } -+ if (!find_stream_for_sink) { -+ /* TODO: do not find stream for sink. This should not -+ * happen -+ */ -+ ASSERT(0); -+ } -+ } -+ -+ mutex_unlock(&mst_mgr->payload_lock); -+ - if (ret) - return false; - -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 a0a131e..54766ae 100644 ---- a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c -+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c -@@ -708,6 +708,7 @@ static bool construct( - dal_adapter_service_release_irq( - init_params->adapter_srv, hpd_gpio); - } -+ - break; - case CONNECTOR_ID_EDP: - link->public.connector_signal = SIGNAL_TYPE_EDP; -@@ -915,6 +916,51 @@ static enum dc_status enable_link_dp(struct core_stream *stream) - return status; - } - -+static enum dc_status enable_link_dp_mst(struct core_stream *stream) -+{ -+ enum dc_status status; -+ bool skip_video_pattern; -+ struct core_link *link = stream->sink->link; -+ struct link_settings link_settings = {0}; -+ enum dp_panel_mode panel_mode; -+ -+ /* sink signal type after MST branch is MST. Multiple MST sinks -+ * share one link. Link DP PHY is enable or training only once. -+ */ -+ if (link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) -+ return DC_OK; -+ -+ /* get link settings for video mode timing */ -+ decide_link_settings(stream, &link_settings); -+ status = dp_enable_link_phy( -+ stream->sink->link, -+ stream->signal, -+ stream->stream_enc->id, -+ &link_settings); -+ -+ panel_mode = dp_get_panel_mode(link); -+ dpcd_configure_panel_mode(link, panel_mode); -+ -+ skip_video_pattern = true; -+ -+ if (link_settings.link_rate == LINK_RATE_LOW) -+ skip_video_pattern = false; -+ -+ if (perform_link_training(link, &link_settings, skip_video_pattern)) { -+ link->cur_link_settings = link_settings; -+ -+ /* TODO MST link shared by stream. counter? */ -+ if (link->stream_count < 4) -+ link->stream_count++; -+ -+ status = DC_OK; -+ } -+ else -+ status = DC_ERROR_UNEXPECTED; -+ -+ return status; -+} -+ - static enum dc_status enable_link_hdmi(struct core_stream *stream) - { - struct core_link *link = stream->sink->link; -@@ -977,11 +1023,13 @@ enum dc_status core_link_enable(struct core_stream *stream) - { - enum dc_status status; - switch (stream->signal) { -- case SIGNAL_TYPE_DISPLAY_PORT_MST: - case SIGNAL_TYPE_DISPLAY_PORT: - case SIGNAL_TYPE_EDP: - status = enable_link_dp(stream); - break; -+ case SIGNAL_TYPE_DISPLAY_PORT_MST: -+ status = enable_link_dp_mst(stream); -+ break; - case SIGNAL_TYPE_DVI_SINGLE_LINK: - case SIGNAL_TYPE_DVI_DUAL_LINK: - case SIGNAL_TYPE_HDMI_TYPE_A: -@@ -1019,8 +1067,17 @@ enum dc_status core_link_disable(struct core_stream *stream) - * it will lead to querying dynamic link capabilities - * which should be done before enable output */ - -- if (dc_is_dp_signal(stream->signal)) -- dp_disable_link_phy(stream->sink->link, stream->signal); -+ if (dc_is_dp_signal(stream->signal)) { -+ /* SST DP, eDP */ -+ if (dc_is_dp_sst_signal(stream->signal)) -+ dp_disable_link_phy( -+ stream->sink->link, stream->signal); -+ else { -+ dp_disable_link_phy_mst( -+ stream->sink->link, stream->signal); -+ } -+ } -+ - else if (ENCODER_RESULT_OK != dc->hwss.encoder_disable_output( - stream->sink->link->link_enc, stream->signal)) - status = DC_ERROR_UNEXPECTED; -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 164cdeb..3d6e2ea 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 -@@ -73,7 +73,22 @@ enum dc_status dp_enable_link_phy( - - void dp_disable_link_phy(struct core_link *link, enum signal_type signal) - { -- if(!link) -+ if (!link->dp_wa.bits.KEEP_RECEIVER_POWERED) -+ dp_receiver_power_ctrl(link, false); -+ -+ link->dc->hwss.encoder_disable_output(link->link_enc, signal); -+ -+ /* Clear current link setting.*/ -+ dc_service_memset(&link->cur_link_settings, 0, -+ sizeof(link->cur_link_settings)); -+} -+ -+void dp_disable_link_phy_mst(struct core_link *link, enum signal_type signal) -+{ -+ /* MST disable link only when no stream use the link */ -+ if (link->stream_count > 0) -+ link->stream_count--; -+ if (link->stream_count > 0) - return; - - if (!link->dp_wa.bits.KEEP_RECEIVER_POWERED) -diff --git a/drivers/gpu/drm/amd/dal/dc/dc_helpers.h b/drivers/gpu/drm/amd/dal/dc/dc_helpers.h -index c06eb8c..874c839 100644 ---- a/drivers/gpu/drm/amd/dal/dc/dc_helpers.h -+++ b/drivers/gpu/drm/amd/dal/dc/dc_helpers.h -@@ -44,7 +44,7 @@ enum dc_edid_status dc_helpers_parse_edid_caps( - bool dc_helpers_dp_mst_write_payload_allocation_table( - struct dc_context *ctx, - const struct dc_sink *sink, -- struct dp_mst_stream_allocation *alloc_entity, -+ struct dp_mst_stream_allocation_table *table, - bool enable); - - /* -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 dddc6e2..e631593 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 -@@ -780,25 +780,31 @@ static enum color_space get_output_color_space( - - static enum dc_status allocate_mst_payload(struct core_stream *stream) - { -- struct link_encoder *link_encoder = stream->sink->link->link_enc; -+ struct core_link *link = stream->sink->link; -+ struct link_encoder *link_encoder = link->link_enc; - struct stream_encoder *stream_encoder = stream->stream_enc; -- struct dp_mst_stream_allocation_table table; -+ struct dp_mst_stream_allocation_table table = {0}; - struct fixed31_32 avg_time_slots_per_mtp; -+ uint8_t cur_stream_payload_idx; - -- /* TODO: remove hardcode */ -- table.stream_count = 1; -- table.stream_allocations[0].engine = stream_encoder->id; -+ if (stream_encoder->id == ENGINE_ID_UNKNOWN) { -+ /* TODO ASSERT */ -+ return DC_ERROR_UNEXPECTED; -+ } - -+ /* get calculate VC payload for stream: stream_alloc */ - dc_helpers_dp_mst_write_payload_allocation_table( - stream->ctx, - &stream->sink->public, -- &table.stream_allocations[0], -+ &table, - true); - -+ /* program DP source TX for payload */ - dce110_link_encoder_update_mst_stream_allocation_table( - link_encoder, - &table); - -+ /* send down message */ - dc_helpers_dp_mst_poll_for_allocation_change_trigger( - stream->ctx, - &stream->sink->public); -@@ -808,9 +814,11 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) - &stream->sink->public, - true); - -+ /* slot X.Y for only current stream */ -+ cur_stream_payload_idx = table.cur_stream_payload_idx; - avg_time_slots_per_mtp = dal_fixed31_32_from_fraction( -- table.stream_allocations[0].pbn, -- table.stream_allocations[0].pbn_per_slot); -+ table.stream_allocations[cur_stream_payload_idx].pbn, -+ table.stream_allocations[cur_stream_payload_idx].pbn_per_slot); - - dce110_stream_encoder_set_mst_bandwidth( - stream_encoder, -@@ -823,24 +831,28 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream) - - static enum dc_status deallocate_mst_payload(struct core_stream *stream) - { -- struct link_encoder *link_encoder = stream->sink->link->link_enc; -+ struct core_link *link = stream->sink->link; -+ struct link_encoder *link_encoder = link->link_enc; - struct stream_encoder *stream_encoder = stream->stream_enc; -- struct dp_mst_stream_allocation_table table; -+ struct dp_mst_stream_allocation_table table = {0}; - struct fixed31_32 avg_time_slots_per_mtp = dal_fixed31_32_from_int(0); - -- /* TODO: remove hardcode */ -- table.stream_count = 1; -- table.stream_allocations[0].slot_count = 0; -+ if (stream_encoder->id == ENGINE_ID_UNKNOWN) { -+ /* TODO ASSERT */ -+ return DC_ERROR_UNEXPECTED; -+ } - -+ /* slot X.Y */ - dce110_stream_encoder_set_mst_bandwidth( - stream_encoder, - stream_encoder->id, - avg_time_slots_per_mtp); - -+ /* TODO: which component is responsible for remove payload table? */ - dc_helpers_dp_mst_write_payload_allocation_table( - stream->ctx, - &stream->sink->public, -- &table.stream_allocations[0], -+ &table, - false); - - dce110_link_encoder_update_mst_stream_allocation_table( -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 0ad582b..c2c201f 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 -@@ -1591,8 +1591,8 @@ void dce110_link_encoder_update_mst_stream_allocation_table( - const struct dp_mst_stream_allocation_table *table) - { - int32_t addr_offset = enc->be_engine_offset; -- uint32_t value0; -- uint32_t value1; -+ uint32_t value0 = 0; -+ uint32_t value1 = 0; - uint32_t retries = 0; - - /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/ -@@ -1602,9 +1602,6 @@ void dce110_link_encoder_update_mst_stream_allocation_table( - * 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, -diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h -index 22ab6cb..0b06314 100644 ---- a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h -+++ b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h -@@ -225,6 +225,9 @@ struct core_link { - - enum edp_revision edp_revision; - union dp_wa dp_wa; -+ -+ /* MST record stream using this link */ -+ uint8_t stream_count; - }; - - #define DC_LINK_TO_LINK(dc_link) container_of(dc_link, struct core_link, public) -diff --git a/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h -index 7110357..a008544 100644 ---- a/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h -+++ b/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h -@@ -50,6 +50,8 @@ void dp_receiver_power_ctrl(struct core_link *link, bool on); - - void dp_disable_link_phy(struct core_link *link, enum signal_type signal); - -+void dp_disable_link_phy_mst(struct core_link *link, enum signal_type signal); -+ - bool dp_set_hw_training_pattern( - struct core_link *link, - enum hw_dp_training_pattern pattern); -diff --git a/drivers/gpu/drm/amd/dal/include/link_service_types.h b/drivers/gpu/drm/amd/dal/include/link_service_types.h -index 0df5687..bd3dd6d 100644 ---- a/drivers/gpu/drm/amd/dal/include/link_service_types.h -+++ b/drivers/gpu/drm/amd/dal/include/link_service_types.h -@@ -37,6 +37,10 @@ - struct ddc; - struct irq_manager; - -+enum { -+ MAX_CONTROLLER_NUM = 6 -+}; -+ - enum link_service_type { - LINK_SERVICE_TYPE_LEGACY = 0, - LINK_SERVICE_TYPE_DP_SST, -@@ -399,9 +403,10 @@ struct dp_mst_stream_allocation { - /* DP MST stream allocation table */ - struct dp_mst_stream_allocation_table { - /* number of DP video streams */ -- uint32_t stream_count; -+ uint8_t stream_count; -+ uint8_t cur_stream_payload_idx; - /* array of stream allocations */ -- struct dp_mst_stream_allocation stream_allocations[1]; -+ struct dp_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; - }; - - struct dp_test_event_data { --- -2.7.4 - |