From fbc821c4a506a960e85f3e97e32cfab63d43f7d0 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 13 Feb 2020 16:15:19 -0500 Subject: drm/mst: Support simultaneous down replies Currently we have one down reply message servicing the mst manager, so we need to serialize all tx msgs to ensure we only have one message in flight at a time. For obvious reasons this is suboptimal (but less suboptimal than the free-for-all we had before serialization). This patch removes the single down_rep_recv message from manager and adds 2 replies in the branch structure. The 2 replies mirrors the tx_slots which we use to rate-limit outgoing messages and correspond to seqno in the packet headers. Cc: Wayne Lin Reviewed-by: Lyude Paul Reviewed-by: Wayne Lin Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200213211523.156998-3-sean@poorly.run --- include/drm/drm_dp_mst_helper.h | 59 +++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'include/drm/drm_dp_mst_helper.h') diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 9a1e8ba4f839..cff135070535 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -160,6 +160,31 @@ struct drm_dp_mst_port { bool fec_capable; }; +/* sideband msg header - not bit struct */ +struct drm_dp_sideband_msg_hdr { + u8 lct; + u8 lcr; + u8 rad[8]; + bool broadcast; + bool path_msg; + u8 msg_len; + bool somt; + bool eomt; + bool seqno; +}; + +struct drm_dp_sideband_msg_rx { + u8 chunk[48]; + u8 msg[256]; + u8 curchunk_len; + u8 curchunk_idx; /* chunk we are parsing now */ + u8 curchunk_hdrlen; + u8 curlen; /* total length of the msg */ + bool have_somt; + bool have_eomt; + struct drm_dp_sideband_msg_hdr initial_hdr; +}; + /** * struct drm_dp_mst_branch - MST branch device. * @rad: Relative Address to talk to this branch device. @@ -232,24 +257,16 @@ struct drm_dp_mst_branch { int last_seqno; bool link_address_sent; + /** + * @down_rep_recv: Message receiver state for down replies. + */ + struct drm_dp_sideband_msg_rx down_rep_recv[2]; + /* global unique identifier to identify branch devices */ u8 guid[16]; }; -/* sideband msg header - not bit struct */ -struct drm_dp_sideband_msg_hdr { - u8 lct; - u8 lcr; - u8 rad[8]; - bool broadcast; - bool path_msg; - u8 msg_len; - bool somt; - bool eomt; - bool seqno; -}; - struct drm_dp_nak_reply { u8 guid[16]; u8 reason; @@ -306,18 +323,6 @@ struct drm_dp_remote_i2c_write_ack_reply { }; -struct drm_dp_sideband_msg_rx { - u8 chunk[48]; - u8 msg[256]; - u8 curchunk_len; - u8 curchunk_idx; /* chunk we are parsing now */ - u8 curchunk_hdrlen; - u8 curlen; /* total length of the msg */ - bool have_somt; - bool have_eomt; - struct drm_dp_sideband_msg_hdr initial_hdr; -}; - #define DRM_DP_MAX_SDP_STREAMS 16 struct drm_dp_allocate_payload { u8 port_number; @@ -555,10 +560,6 @@ struct drm_dp_mst_topology_mgr { */ int conn_base_id; - /** - * @down_rep_recv: Message receiver state for down replies. - */ - struct drm_dp_sideband_msg_rx down_rep_recv; /** * @up_req_recv: Message receiver state for up requests. */ -- cgit v1.2.3-70-g09d2 From 6bb0942e8f46863a745489cce27efe5be2a3885e Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 13 Feb 2020 16:15:20 -0500 Subject: drm/dp_mst: Remove single tx msg restriction. Now that we can support multiple simultaneous replies, remove the restrictions placed on sending new tx msgs. This patch essentially just reverts commit 5a64967a2f3b ("drm/dp_mst: Have DP_Tx send one msg at a time") now that the problem is solved in a different way. Cc: Wayne Lin Reviewed-by: Lyude Paul Reviewed-by: Wayne Lin Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200213211523.156998-4-sean@poorly.run --- drivers/gpu/drm/drm_dp_mst_topology.c | 14 ++------------ include/drm/drm_dp_mst_helper.h | 5 ----- 2 files changed, 2 insertions(+), 17 deletions(-) (limited to 'include/drm/drm_dp_mst_helper.h') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 236a4beb7bd6..840c6370fb39 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1205,8 +1205,6 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb, txmsg->state == DRM_DP_SIDEBAND_TX_SENT) { mstb->tx_slots[txmsg->seqno] = NULL; } - mgr->is_waiting_for_dwn_reply = false; - } out: if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) { @@ -1216,7 +1214,6 @@ out: } mutex_unlock(&mgr->qlock); - drm_dp_mst_kick_tx(mgr); return ret; } @@ -2796,11 +2793,9 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) ret = process_single_tx_qlock(mgr, txmsg, false); if (ret == 1) { /* txmsg is sent it should be in the slots now */ - mgr->is_waiting_for_dwn_reply = true; list_del(&txmsg->next); } else if (ret) { DRM_DEBUG_KMS("failed to send msg in q %d\n", ret); - mgr->is_waiting_for_dwn_reply = false; list_del(&txmsg->next); if (txmsg->seqno != -1) txmsg->dst->tx_slots[txmsg->seqno] = NULL; @@ -2840,8 +2835,7 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, drm_dp_mst_dump_sideband_msg_tx(&p, txmsg); } - if (list_is_singular(&mgr->tx_msg_downq) && - !mgr->is_waiting_for_dwn_reply) + if (list_is_singular(&mgr->tx_msg_downq)) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); } @@ -3828,7 +3822,6 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) mutex_lock(&mgr->qlock); txmsg->state = DRM_DP_SIDEBAND_TX_RX; mstb->tx_slots[seqno] = NULL; - mgr->is_waiting_for_dwn_reply = false; mutex_unlock(&mgr->qlock); wake_up_all(&mgr->tx_waitq); @@ -3836,9 +3829,6 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) return 0; out_clear_reply: - mutex_lock(&mgr->qlock); - mgr->is_waiting_for_dwn_reply = false; - mutex_unlock(&mgr->qlock); if (msg) memset(msg, 0, sizeof(struct drm_dp_sideband_msg_rx)); out: @@ -4696,7 +4686,7 @@ static void drm_dp_tx_work(struct work_struct *work) struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work); mutex_lock(&mgr->qlock); - if (!list_empty(&mgr->tx_msg_downq) && !mgr->is_waiting_for_dwn_reply) + if (!list_empty(&mgr->tx_msg_downq)) process_single_down_tx_qlock(mgr); mutex_unlock(&mgr->qlock); } diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index cff135070535..bf5e65d2303e 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -590,11 +590,6 @@ struct drm_dp_mst_topology_mgr { */ bool payload_id_table_cleared : 1; - /** - * @is_waiting_for_dwn_reply: whether we're waiting for a down reply. - */ - bool is_waiting_for_dwn_reply : 1; - /** * @mst_primary: Pointer to the primary/first branch device. */ -- cgit v1.2.3-70-g09d2 From 6c0ac4d5fff7fc5d990cc79c0231f02d88a69b9b Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 28 Mar 2020 14:20:24 +0100 Subject: drm/dp_mst: add kernel-doc for drm_dp_mst_port.fec_capable Fix kernel-doc warnings for drm_dp_mst_port.fec_capable. This fixed the following warning: drm_dp_mst_helper.h:162: warning: Function parameter or member 'fec_capable' not described in 'drm_dp_mst_port' Signed-off-by: Sam Ravnborg Cc: David Francis Cc: Lyude Paul Cc: Harry Wentland Cc: Mikita Lipski Cc: Alex Deucher Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter [Wrapped commit msg + s/network/topology] Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200328132025.19910-6-sam@ravnborg.org --- include/drm/drm_dp_mst_helper.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/drm/drm_dp_mst_helper.h') diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index bf5e65d2303e..e1f212b2505a 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -157,6 +157,10 @@ struct drm_dp_mst_port { */ bool has_audio; + /** + * @fec_capable: bool indicating if FEC can be supported up to that + * point in the MST topology. + */ bool fec_capable; }; -- cgit v1.2.3-70-g09d2 From 72dc0f5159138b61762a500d0fde9bbc1af82884 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Tue, 31 Mar 2020 16:57:37 -0400 Subject: drm/dp_mst: Remove drm_dp_mst_topology_cbs.destroy_connector Now that we've removed the last user of this callback, get rid of it and drm_dp_destroy_connector(). Signed-off-by: Lyude Paul Cc: Pankaj Bharadiya Link: https://patchwork.freedesktop.org/patch/msgid/20200331205740.135525-5-lyude@redhat.com Reviewed-by: Alex Deucher --- drivers/gpu/drm/drm_dp_mst_topology.c | 16 +++------------- include/drm/drm_dp_mst_helper.h | 2 -- 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'include/drm/drm_dp_mst_helper.h') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 17a7a744fb14..3331de086580 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -4690,23 +4690,13 @@ static void drm_dp_tx_work(struct work_struct *work) mutex_unlock(&mgr->qlock); } -static inline void drm_dp_destroy_connector(struct drm_dp_mst_port *port) +static inline void +drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port) { - if (!port->connector) - return; - - if (port->mgr->cbs->destroy_connector) { - port->mgr->cbs->destroy_connector(port->mgr, port->connector); - } else { + if (port->connector) { drm_connector_unregister(port->connector); drm_connector_put(port->connector); } -} - -static inline void -drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port) -{ - drm_dp_destroy_connector(port); drm_dp_port_set_pdt(port, DP_PEER_DEVICE_NONE, port->mcs); drm_dp_mst_put_port_malloc(port); diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index e1f212b2505a..e36e53de269e 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -488,8 +488,6 @@ struct drm_dp_mst_topology_mgr; struct drm_dp_mst_topology_cbs { /* create a connector for a port */ struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path); - void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr, - struct drm_connector *connector); }; #define DP_MAX_PAYLOAD (sizeof(unsigned long) * 8) -- cgit v1.2.3-70-g09d2 From 20c22ad3295766b9a7f6da29b3620f570993c2f3 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Mon, 6 Apr 2020 16:06:42 -0400 Subject: drm/dp_mst: Remove drm_dp_mst_has_audio() Drive-by fix I noticed the other day - drm_dp_mst_has_audio() only ever made sense back when we still had to validate ports before accessing them in order to (attempt to) avoid NULL dereferences. Since we have proper reference counting that guarantees we always can safely access the MST port, there's no use in keeping this function around as all it does is validate the port pointer before checking the audio status. Note - drm_dp_mst_port->has_audio is technically protected by drm_device->mode_config.connection_mutex, since it's only ever updated from drm_dp_mst_get_edid(). Additionally, we change the declaration for port in struct intel_connector to be properly typed, so we can directly access it. Changes since v1: * Change type of intel_connector->port in a separate patch - Sean Paul Cc: "Lee, Shawn C" Reviewed-by: Sean Paul Signed-off-by: Lyude Paul Link: https://patchwork.freedesktop.org/patch/msgid/20200406200646.1263435-2-lyude@redhat.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 21 --------------------- .../gpu/drm/i915/display/intel_display_debugfs.c | 10 ++-------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 +-- include/drm/drm_dp_mst_helper.h | 2 -- 4 files changed, 3 insertions(+), 33 deletions(-) (limited to 'include/drm/drm_dp_mst_helper.h') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 80067ea5c50e..3842336f63a5 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -4062,27 +4062,6 @@ out: } EXPORT_SYMBOL(drm_dp_mst_detect_port); -/** - * drm_dp_mst_port_has_audio() - Check whether port has audio capability or not - * @mgr: manager for this port - * @port: unverified pointer to a port. - * - * This returns whether the port supports audio or not. - */ -bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, - struct drm_dp_mst_port *port) -{ - bool ret = false; - - port = drm_dp_mst_topology_get_port_validated(mgr, port); - if (!port) - return ret; - ret = port->has_audio; - drm_dp_mst_topology_put_port(port); - return ret; -} -EXPORT_SYMBOL(drm_dp_mst_port_has_audio); - /** * drm_dp_mst_get_edid() - get EDID for an MST port * @connector: toplevel connector to get EDID for diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 424f4e52f783..9f736420d83f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -631,15 +631,9 @@ static void intel_dp_info(struct seq_file *m, } static void intel_dp_mst_info(struct seq_file *m, - struct intel_connector *intel_connector) + struct intel_connector *intel_connector) { - struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector); - struct intel_dp_mst_encoder *intel_mst = - enc_to_mst(intel_encoder); - struct intel_digital_port *intel_dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &intel_dig_port->dp; - bool has_audio = drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, - intel_connector->port); + bool has_audio = intel_connector->port->has_audio; seq_printf(m, "\taudio support: %s\n", yesno(has_audio)); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 44f3fd251ca1..35debce71366 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -158,8 +158,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->has_pch_encoder = false; if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) - pipe_config->has_audio = - drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port); + pipe_config->has_audio = connector->port->has_audio; else pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON; diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index e36e53de269e..e689f8d25869 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -732,8 +732,6 @@ drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); -bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, - struct drm_dp_mst_port *port); struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); -- cgit v1.2.3-70-g09d2