aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0679-drm-amd-dal-MST-get-stream-hadle-refact.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0679-drm-amd-dal-MST-get-stream-hadle-refact.patch')
-rw-r--r--common/recipes-kernel/linux/files/0679-drm-amd-dal-MST-get-stream-hadle-refact.patch498
1 files changed, 498 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0679-drm-amd-dal-MST-get-stream-hadle-refact.patch b/common/recipes-kernel/linux/files/0679-drm-amd-dal-MST-get-stream-hadle-refact.patch
new file mode 100644
index 00000000..6a6c82bf
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0679-drm-amd-dal-MST-get-stream-hadle-refact.patch
@@ -0,0 +1,498 @@
+From ddd580e8ff564c5d5f0b4fa941f8e64e365ea0d3 Mon Sep 17 00:00:00 2001
+From: Hersen Wu <hersenxs.wu@amd.com>
+Date: Thu, 7 Jan 2016 15:06:08 -0500
+Subject: [PATCH 0679/1110] drm/amd/dal: MST get stream hadle refact
+
+Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
+Acked-by: Jordan Lazare <Jordan.Lazare@amd.com>
+---
+ .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dc_helpers.c | 94 ++++++-------
+ drivers/gpu/drm/amd/dal/dc/core/dc_link.c | 147 +++++++++++++++------
+ drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c | 11 +-
+ drivers/gpu/drm/amd/dal/dc/dc_helpers.h | 3 +-
+ .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 2 +
+ drivers/gpu/drm/amd/dal/dc/inc/core_types.h | 7 +-
+ .../gpu/drm/amd/dal/include/link_service_types.h | 1 +
+ 7 files changed, 167 insertions(+), 98 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 578517f..ff9b5c1 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
+@@ -160,74 +160,73 @@ static struct amdgpu_connector *get_connector_for_link(
+ return aconnector;
+ }
+
+-static const struct dc_stream *get_stream_for_vcid(
+- struct drm_device *dev,
+- struct amdgpu_connector *master_port,
+- int vcid)
++const struct dp_mst_stream_allocation *find_stream_with_matching_vcpi(
++ const struct dp_mst_stream_allocation_table *table,
++ uint32_t vcpi)
+ {
+- struct drm_connector *connector;
+- struct amdgpu_connector *aconnector;
+- struct drm_crtc *crtc;
+- struct amdgpu_crtc *acrtc;
+- struct dc_target *dc_target;
+-
+- list_for_each_entry(
+- connector,
+- &dev->mode_config.connector_list,
+- head) {
+-
+- aconnector = to_amdgpu_connector(connector);
+-
+- /* Check whether mst connector */
+- if (!aconnector->mst_port)
+- continue;
+-
+- /* Check whether same physical connector. */
+- if (master_port != aconnector->mst_port) {
+- continue;
+- }
++ int i;
+
+- if (aconnector->port->vcpi.vcpi == vcid) {
+- crtc = aconnector->base.state->crtc;
+- acrtc = to_amdgpu_crtc(crtc);
+- dc_target = acrtc->target;
+- return dc_target->streams[0];
+- }
++ for (i = 0; i < table->stream_count; i++) {
++ const struct dp_mst_stream_allocation *sa =
++ &table->stream_allocations[i];
++ if (sa->vcp_id == vcpi)
++ return sa;
+ }
+ return NULL;
+ }
+
++
+ static void get_payload_table(
+ struct drm_device *dev,
+ struct amdgpu_connector *aconnector,
+- struct dp_mst_stream_allocation_table *table)
++ const struct dc_stream *stream,
++ const struct dp_mst_stream_allocation_table *cur_table,
++ struct dp_mst_stream_allocation_table *proposed_table)
+ {
+ int i;
+- struct drm_dp_mst_topology_mgr *mst_mgr = &aconnector->mst_port->mst_mgr;
+- struct amdgpu_connector *master_port = aconnector->mst_port;
++ struct drm_dp_mst_topology_mgr *mst_mgr =
++ &aconnector->mst_port->mst_mgr;
+
+ mutex_lock(&mst_mgr->payload_lock);
+
++ proposed_table->stream_count = 0;
++
+ /* number of active streams */
+ for (i = 0; i < mst_mgr->max_payloads; i++) {
+ if (mst_mgr->payloads[i].num_slots == 0)
+- break;
++ break; /* end of vcp_id table */
++
++ ASSERT(mst_mgr->payloads[i].payload_state !=
++ DP_PAYLOAD_DELETE_LOCAL);
+
+ if (mst_mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL ||
+- mst_mgr->payloads[i].payload_state == DP_PAYLOAD_REMOTE) {
+- table->stream_allocations[i].slot_count = mst_mgr->payloads[i].num_slots;
+- table->stream_allocations[i].stream =
+- get_stream_for_vcid(
+- dev,
+- master_port,
+- mst_mgr->payloads[i].vcpi);
++ mst_mgr->payloads[i].payload_state ==
++ DP_PAYLOAD_REMOTE) {
++
++ const struct dp_mst_stream_allocation *sa_src
++ = find_stream_with_matching_vcpi(
++ cur_table,
++ mst_mgr->proposed_vcpis[i]->vcpi);
++
++ if (sa_src) {
++ proposed_table->stream_allocations[
++ proposed_table->stream_count] = *sa_src;
++ proposed_table->stream_count++;
++ } else {
++ struct dp_mst_stream_allocation *sa =
++ &proposed_table->stream_allocations[
++ proposed_table->stream_count];
++
++ sa->slot_count =
++ mst_mgr->payloads[i].num_slots;
++ sa->stream = stream;
++ sa->vcp_id = mst_mgr->proposed_vcpis[i]->vcpi;
++ proposed_table->stream_count++;
++ }
+ }
+ }
+
+- table->stream_count = i;
+-
+ mutex_unlock(&mst_mgr->payload_lock);
+-
+ }
+
+ /*
+@@ -236,7 +235,8 @@ static void get_payload_table(
+ bool dc_helpers_dp_mst_write_payload_allocation_table(
+ struct dc_context *ctx,
+ const struct dc_stream *stream,
+- struct dp_mst_stream_allocation_table *table,
++ const struct dp_mst_stream_allocation_table *cur_table,
++ struct dp_mst_stream_allocation_table *proposed_table,
+ bool enable)
+ {
+ struct amdgpu_device *adev = ctx->driver_context;
+@@ -312,7 +312,7 @@ bool dc_helpers_dp_mst_write_payload_allocation_table(
+ * stream. AMD ASIC stream slot allocation should follow the same
+ * sequence. copy DRM MST allocation to dc */
+
+- get_payload_table(dev, aconnector, table);
++ get_payload_table(dev, aconnector, stream, cur_table, proposed_table);
+
+ 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 ac6785a..794465e 100644
+--- a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
++++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
+@@ -1106,18 +1106,6 @@ static enum dc_status enable_link_dp(struct core_stream *stream)
+ static enum dc_status enable_link_dp_mst(struct core_stream *stream)
+ {
+ struct core_link *link = stream->sink->link;
+- bool already_enabled = false;
+- int i;
+-
+- for (i = 0; i < link->enabled_stream_count; i++) {
+- if (link->enabled_streams[i] == stream)
+- already_enabled = true;
+- }
+-
+- if (!already_enabled && link->enabled_stream_count < MAX_SINKS_PER_LINK)
+- link->enabled_streams[link->enabled_stream_count++] = stream;
+- else if (link->enabled_stream_count >= MAX_SINKS_PER_LINK)
+- return DC_ERROR_UNEXPECTED;
+
+ /* sink signal type after MST branch is MST. Multiple MST sinks
+ * share one link. Link DP PHY is enable or training only once.
+@@ -1285,9 +1273,12 @@ void core_link_resume(struct core_link *link)
+
+ static struct fixed31_32 get_pbn_per_slot(struct core_stream *stream)
+ {
+- struct link_settings *link_settings = &stream->sink->link->cur_link_settings;
+- uint32_t link_rate_in_mbps = link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ;
+- struct fixed31_32 mbps = dal_fixed31_32_from_int(link_rate_in_mbps * link_settings->lane_count);
++ struct link_settings *link_settings =
++ &stream->sink->link->cur_link_settings;
++ uint32_t link_rate_in_mbps =
++ link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ;
++ struct fixed31_32 mbps = dal_fixed31_32_from_int(
++ link_rate_in_mbps * link_settings->lane_count);
+
+ return dal_fixed31_32_div_int(mbps, 54);
+ }
+@@ -1318,15 +1309,13 @@ static struct fixed31_32 get_pbn_from_timing(struct core_stream *stream)
+
+ /*
+ * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
+- *
+ * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on
+ * common multiplier to render an integer PBN for all link rate/lane
+ * counts combinations
+- * *
+ * calculate
+- * peak_kbps *= (1006/1000)
+- * peak_kbps *= (64/54)
+- * peak_kbps *= 8 convert to bytes
++ * peak_kbps *= (1006/1000)
++ * peak_kbps *= (64/54)
++ * peak_kbps *= 8 convert to bytes
+ */
+
+ numerator = 64 * PEAK_FACTOR_X1000;
+@@ -1342,11 +1331,12 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream)
+ 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 = {0};
++ struct dp_mst_stream_allocation_table proposed_table = {0};
+ struct fixed31_32 avg_time_slots_per_mtp;
+ struct dc *dc = stream->ctx->dc;
+ struct fixed31_32 pbn;
+ struct fixed31_32 pbn_per_slot;
++ uint8_t i;
+
+ /* enable_link_dp_mst already check link->enabled_stream_count
+ * and stream is in link->stream[]. This is called during set mode,
+@@ -1357,22 +1347,53 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream)
+ dc_helpers_dp_mst_write_payload_allocation_table(
+ stream->ctx,
+ &stream->public,
+- &table,
++ &link->stream_alloc_table,
++ &proposed_table,
+ true);
+
++ dal_logger_write(link->ctx->logger,
++ LOG_MAJOR_MST,
++ LOG_MINOR_MST_PROGRAMMING,
++ "%s "
++ "stream_count: %d: \n ",
++ __func__,
++ proposed_table.stream_count);
++
++ for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
++ dal_logger_write(link->ctx->logger,
++ LOG_MAJOR_MST,
++ LOG_MINOR_MST_PROGRAMMING,
++ "stream[%d]: 0x%x "
++ "stream[%d].vcp_id: %d "
++ "stream[%d].slot_count: %d\n",
++ i,
++ proposed_table.stream_allocations[i].stream,
++ i,
++ proposed_table.stream_allocations[i].vcp_id,
++ i,
++ proposed_table.stream_allocations[i].slot_count);
++ }
++
++ ASSERT(proposed_table.stream_count > 0);
++ ASSERT(proposed_table.stream_count -
++ link->stream_alloc_table.stream_count == 1);
++
+ /*
+ * temporary fix. Unplug of MST chain happened (two displays),
+ * table is empty on first reset mode, and cause 0 division in
+ * avg_time_slots_per_mtp calculation
+ */
+
+- if (table.stream_count == 0)
++ /* to be removed or debugged */
++ if (proposed_table.stream_count == 0)
+ return DC_OK;
+
+ /* program DP source TX for payload */
+ dc->hwss.update_mst_stream_allocation_table(
+ link_encoder,
+- &table);
++ &proposed_table);
++
++ link->stream_alloc_table = proposed_table;
+
+ /* send down message */
+ dc_helpers_dp_mst_poll_for_allocation_change_trigger(
+@@ -1384,10 +1405,12 @@ static enum dc_status allocate_mst_payload(struct core_stream *stream)
+ &stream->public,
+ true);
+
++ /* slot X.Y for only current stream */
+ pbn_per_slot = get_pbn_per_slot(stream);
+ pbn = get_pbn_from_timing(stream);
+ avg_time_slots_per_mtp = dal_fixed31_32_div(pbn, pbn_per_slot);
+
++
+ dc->hwss.set_mst_bandwidth(
+ stream_encoder,
+ avg_time_slots_per_mtp);
+@@ -1401,10 +1424,10 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream)
+ 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 = {0};
++ struct dp_mst_stream_allocation_table proposed_table = {0};
+ struct fixed31_32 avg_time_slots_per_mtp = dal_fixed31_32_from_int(0);
+- uint8_t i;
+ struct dc *dc = stream->ctx->dc;
++ uint8_t i;
+
+ /* deallocate_mst_payload is called before disable link. When mode or
+ * disable/enable monitor, new stream is created which is not in link
+@@ -1412,16 +1435,6 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream)
+ * should not done. For new mode set, map_resources will get engine
+ * for new stream, so stream_enc->id should be validated until here.
+ */
+- if (link->enabled_stream_count == 0)
+- return DC_OK;
+-
+- for (i = 0; i < link->enabled_stream_count; i++) {
+- if (link->enabled_streams[i] == stream)
+- break;
+- }
+- /* stream is not in link stream list */
+- if (i == link->enabled_stream_count)
+- return DC_OK;
+
+ /* slot X.Y */
+ dc->hwss.set_mst_bandwidth(
+@@ -1432,12 +1445,41 @@ static enum dc_status deallocate_mst_payload(struct core_stream *stream)
+ dc_helpers_dp_mst_write_payload_allocation_table(
+ stream->ctx,
+ &stream->public,
+- &table,
++ &link->stream_alloc_table,
++ &proposed_table,
+ false);
+
++ dal_logger_write(link->ctx->logger,
++ LOG_MAJOR_MST,
++ LOG_MINOR_MST_PROGRAMMING,
++ "%s"
++ "stream_count: %d: ",
++ __func__,
++ proposed_table.stream_count);
++
++ for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
++ dal_logger_write(link->ctx->logger,
++ LOG_MAJOR_MST,
++ LOG_MINOR_MST_PROGRAMMING,
++ "stream[%d]: 0x%x"
++ "stream[%d].vcp_id: %d"
++ "stream[%d].slot_count: %d",
++ i,
++ proposed_table.stream_allocations[i].stream,
++ i,
++ proposed_table.stream_allocations[i].vcp_id,
++ i,
++ proposed_table.stream_allocations[i].slot_count);
++ }
++
++ ASSERT(link->stream_alloc_table.stream_count -
++ proposed_table.stream_count == 1);
++
+ dc->hwss.update_mst_stream_allocation_table(
+ link_encoder,
+- &table);
++ &proposed_table);
++
++ link->stream_alloc_table = proposed_table;
+
+ dc_helpers_dp_mst_poll_for_allocation_change_trigger(
+ stream->ctx,
+@@ -1482,3 +1524,32 @@ void core_link_disable_stream(
+ disable_link(stream);
+
+ }
++
++void core_link_update_stream(
++ struct core_link *link,
++ struct core_stream *stream)
++{
++ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
++ uint32_t i;
++
++ for (i = 0; i < link->stream_alloc_table.stream_count; i++) {
++ const struct core_stream *s;
++
++ s = DC_STREAM_TO_CORE(
++ link->stream_alloc_table.
++ stream_allocations[i].stream);
++
++ if (stream->stream_enc == s->stream_enc) {
++ link->stream_alloc_table.stream_allocations[i].stream =
++ &stream->public;
++
++ dal_logger_write(link->ctx->logger,
++ LOG_MAJOR_MST,
++ LOG_MINOR_MST_PROGRAMMING,
++ "%s ",
++ __func__);
++ break;
++ }
++ }
++ }
++}
+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 1356238..27acac8 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
+@@ -84,17 +84,8 @@ void dp_disable_link_phy(struct core_link *link, enum signal_type signal)
+
+ void dp_disable_link_phy_mst(struct core_link *link, struct core_stream *stream)
+ {
+- int i, j;
+-
+- for (i = 0; i < link->enabled_stream_count; i++) {
+- if (link->enabled_streams[i] == stream) {
+- link->enabled_stream_count--;
+- for (j = i; j < link->enabled_stream_count; j++)
+- link->enabled_streams[j] = link->enabled_streams[j+1];
+- }
+- }
+ /* MST disable link only when no stream use the link */
+- if (link->enabled_stream_count > 0)
++ if (link->stream_alloc_table.stream_count > 0)
+ return;
+
+ dp_disable_link_phy(link, stream->signal);
+diff --git a/drivers/gpu/drm/amd/dal/dc/dc_helpers.h b/drivers/gpu/drm/amd/dal/dc/dc_helpers.h
+index d96e907..b4c338a 100644
+--- a/drivers/gpu/drm/amd/dal/dc/dc_helpers.h
++++ b/drivers/gpu/drm/amd/dal/dc/dc_helpers.h
+@@ -44,7 +44,8 @@ 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_stream *stream,
+- struct dp_mst_stream_allocation_table *table,
++ const struct dp_mst_stream_allocation_table *cur_table,
++ struct dp_mst_stream_allocation_table *proposed_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 1085137..685301b 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
+@@ -900,6 +900,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx,
+
+ if (timing_changed) {
+ core_link_enable_stream(stream->sink->link, stream);
++ } else {
++ core_link_update_stream(stream->sink->link, stream);
+ }
+
+ if (dc_is_dp_signal(stream->signal))
+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 2b97d4d..5f918c1 100644
+--- a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h
++++ b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h
+@@ -224,8 +224,7 @@ struct core_link {
+ union dp_wa dp_wa;
+
+ /* MST record stream using this link */
+- const struct core_stream *enabled_streams[MAX_SINKS_PER_LINK];
+- uint8_t enabled_stream_count;
++ struct dp_mst_stream_allocation_table stream_alloc_table;
+ };
+
+ #define DC_LINK_TO_LINK(dc_link) container_of(dc_link, struct core_link, public)
+@@ -248,6 +247,10 @@ void core_link_disable_stream(
+ struct core_link *link,
+ struct core_stream *stream);
+
++void core_link_update_stream(
++ struct core_link *link,
++ struct core_stream *stream);
++
+ /********** DAL Core*********************/
+ #include "display_clock_interface.h"
+
+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 429d969..573dd5c 100644
+--- a/drivers/gpu/drm/amd/dal/include/link_service_types.h
++++ b/drivers/gpu/drm/amd/dal/include/link_service_types.h
+@@ -393,6 +393,7 @@ struct mst_device_info {
+ struct dp_mst_stream_allocation {
+ /* stream engine id (DIG) */
+ const struct dc_stream *stream;
++ uint32_t vcp_id;
+ /* number of slots required for the DP stream in
+ * transport packet */
+ uint32_t slot_count;
+--
+2.7.4
+