From: Sean Paul <sean@poorly.run>
To: Lyude Paul <lyude@redhat.com>
Cc: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
amd-gfx@lists.freedesktop.org, "Juston Li" <juston.li@intel.com>,
"Imre Deak" <imre.deak@intel.com>,
"Ville Syrjälä" <ville.syrjala@linux.intel.com>,
"Harry Wentland" <hwentlan@amd.com>,
"Daniel Vetter" <daniel.vetter@ffwll.ch>,
"Harry Wentland" <harry.wentland@amd.com>,
"Leo Li" <sunpeng.li@amd.com>,
"Alex Deucher" <alexander.deucher@amd.com>,
"Christian König" <christian.koenig@amd.com>,
"David (ChunMing) Zhou" <David1.Zhou@amd.com>,
"David Airlie" <airlied@linux.ie>,
"Daniel Vetter" <daniel@ffwll.ch>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Sean Paul" <sean@poorly.run>,
"Jani Nikula" <jani.nikula@linux.intel.com>,
"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
"Ben Skeggs" <bskeggs@redhat.com>,
"Nicholas Kazlauskas" <nicholas.kazlauskas@amd.com>,
"David Francis" <David.Francis@amd.com>,
"Mario Kleiner" <mario.kleiner.de@gmail.com>,
"Bhawanpreet Lakha" <Bhawanpreet.Lakha@amd.com>,
"Chris Wilson" <chris@chris-wilson.co.uk>,
"Manasi Navare" <manasi.d.navare@intel.com>,
"Dhinakaran Pandiyan" <dhinakaran.pandiyan@intel.com>,
"José Roberto de Souza" <jose.souza@intel.com>,
"Karol Herbst" <karolherbst@gmail.com>,
"Laurent Pinchart" <laurent.pinchart@ideasonboard.com>,
"Ilia Mirkin" <imirkin@alum.mit.edu>,
linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2 25/27] drm/dp_mst: Add basic topology reprobing when resuming
Date: Fri, 27 Sep 2019 09:52:07 -0400 [thread overview]
Message-ID: <20190927135207.GR218215@art_vandelay> (raw)
In-Reply-To: <20190903204645.25487-26-lyude@redhat.com>
On Tue, Sep 03, 2019 at 04:46:03PM -0400, Lyude Paul wrote:
> Finally! For a very long time, our MST helpers have had one very
> annoying issue: They don't know how to reprobe the topology state when
> coming out of suspend. This means that if a user has a machine connected
> to an MST topology and decides to suspend their machine, we lose all
> topology changes that happened during that period. That can be a big
> problem if the machine was connected to a different topology on the same
> port before resuming, as we won't bother reprobing any of the ports and
> likely cause the user's monitors not to come back up as expected.
>
> So, we start fixing this by teaching our MST helpers how to reprobe the
> link addresses of each connected topology when resuming. As it turns
> out, the behavior that we want here is identical to the behavior we want
> when initially probing a newly connected MST topology, with a couple of
> important differences:
>
> - We need to be more careful about handling the potential races between
> events from the MST hub that could change the topology state as we're
> performing the link address reprobe
> - We need to be more careful about handling unlikely state changes on
> ports - such as an input port turning into an output port, something
> that would be far more likely to happen in situations like the MST hub
> we're connected to being changed while we're suspend
>
> Both of which have been solved by previous commits. That leaves one
> requirement:
>
> - We need to prune any MST ports in our in-memory topology state that
> were present when suspending, but have not appeared in the post-resume
> link address response from their parent branch device
>
> Which we can now handle in this commit by modifying
> drm_dp_send_link_address(). We then introduce suspend/resume reprobing
> by introducing drm_dp_mst_topology_mgr_invalidate_mstb(), which we call
> in drm_dp_mst_topology_mgr_suspend() to traverse the in-memory topology
> state to indicate that each mstb needs it's link address resent and PBN
> resources reprobed.
>
> On resume, we start back up &mgr->work and have it reprobe the topology
> in the same way we would on a hotplug, removing any leftover ports that
> no longer appear in the topology state.
>
> Cc: Juston Li <juston.li@intel.com>
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Harry Wentland <hwentlan@amd.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Lyude Paul <lyude@redhat.com>
> ---
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
> drivers/gpu/drm/drm_dp_mst_topology.c | 138 +++++++++++++-----
> drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
> drivers/gpu/drm/nouveau/dispnv50/disp.c | 6 +-
> include/drm/drm_dp_mst_helper.h | 3 +-
> 5 files changed, 112 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 4d3c8bff77da..27ee3e045b86 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -973,7 +973,7 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
> if (suspend) {
> drm_dp_mst_topology_mgr_suspend(mgr);
> } else {
> - ret = drm_dp_mst_topology_mgr_resume(mgr);
> + ret = drm_dp_mst_topology_mgr_resume(mgr, true);
> if (ret < 0) {
> drm_dp_mst_topology_mgr_set_mst(mgr, false);
> need_hotplug = true;
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> index e407aba1fbd2..2fe24e366925 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -2020,6 +2020,14 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
> goto fail_unlock;
> }
>
> + /*
> + * If this port wasn't just created, then we're reprobing because
> + * we're coming out of suspend. In this case, always resend the link
> + * address if there's an MSTB on this port
> + */
> + if (!created && port->pdt == DP_PEER_DEVICE_MST_BRANCHING)
> + send_link_addr = true;
> +
> if (send_link_addr) {
> mutex_lock(&mgr->lock);
> if (port->mstb) {
> @@ -2530,7 +2538,8 @@ static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
> {
> struct drm_dp_sideband_msg_tx *txmsg;
> struct drm_dp_link_address_ack_reply *reply;
> - int i, len, ret;
> + struct drm_dp_mst_port *port, *tmp;
> + int i, len, ret, port_mask = 0;
>
> txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> if (!txmsg)
> @@ -2560,9 +2569,28 @@ static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
>
> drm_dp_check_mstb_guid(mstb, reply->guid);
>
> - for (i = 0; i < reply->nports; i++)
> + for (i = 0; i < reply->nports; i++) {
> + port_mask |= BIT(reply->ports[i].port_number);
> drm_dp_mst_handle_link_address_port(mstb, mgr->dev,
> &reply->ports[i]);
> + }
> +
> + /* Prune any ports that are currently a part of mstb in our in-memory
> + * topology, but were not seen in this link address. Usually this
> + * means that they were removed while the topology was out of sync,
> + * e.g. during suspend/resume
> + */
> + mutex_lock(&mgr->lock);
> + list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
> + if (port_mask & BIT(port->port_num))
> + continue;
> +
> + DRM_DEBUG_KMS("port %d was not in link address, removing\n",
> + port->port_num);
> + list_del(&port->next);
> + drm_dp_mst_topology_put_port(port);
> + }
> + mutex_unlock(&mgr->lock);
>
> drm_kms_helper_hotplug_event(mgr->dev);
>
> @@ -3191,6 +3219,23 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
> }
> EXPORT_SYMBOL(drm_dp_mst_topology_mgr_set_mst);
>
> +static void
> +drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb)
> +{
> + struct drm_dp_mst_port *port;
> +
> + /* The link address will need to be re-sent on resume */
> + mstb->link_address_sent = false;
> +
> + list_for_each_entry(port, &mstb->ports, next) {
> + /* The PBN for each port will also need to be re-probed */
> + port->available_pbn = 0;
> +
> + if (port->mstb)
> + drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb);
> + }
> +}
> +
> /**
> * drm_dp_mst_topology_mgr_suspend() - suspend the MST manager
> * @mgr: manager to suspend
> @@ -3207,60 +3252,85 @@ void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)
> flush_work(&mgr->up_req_work);
> flush_work(&mgr->work);
> flush_work(&mgr->delayed_destroy_work);
> +
> + mutex_lock(&mgr->lock);
> + if (mgr->mst_state && mgr->mst_primary)
> + drm_dp_mst_topology_mgr_invalidate_mstb(mgr->mst_primary);
> + mutex_unlock(&mgr->lock);
> }
> EXPORT_SYMBOL(drm_dp_mst_topology_mgr_suspend);
>
> /**
> * drm_dp_mst_topology_mgr_resume() - resume the MST manager
> * @mgr: manager to resume
> + * @sync: whether or not to perform topology reprobing synchronously
> *
> * This will fetch DPCD and see if the device is still there,
> * if it is, it will rewrite the MSTM control bits, and return.
> *
> - * if the device fails this returns -1, and the driver should do
> + * If the device fails this returns -1, and the driver should do
> * a full MST reprobe, in case we were undocked.
nit: I don't think this sentence applies any longer since we're doing the reprobe.
> + *
> + * During system resume (where it is assumed that the driver will be calling
> + * drm_atomic_helper_resume()) this function should be called beforehand with
> + * @sync set to true. In contexts like runtime resume where the driver is not
> + * expected to be calling drm_atomic_helper_resume(), this function should be
> + * called with @sync set to false in order to avoid deadlocking.
> + *
> + * Returns: -1 if the MST topology was removed while we were suspended, 0
> + * otherwise.
> */
> -int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
> +int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
> + bool sync)
> {
> - int ret = 0;
> + int ret;
> + u8 guid[16];
>
> mutex_lock(&mgr->lock);
> + if (!mgr->mst_primary)
> + goto out_fail;
>
> - if (mgr->mst_primary) {
> - int sret;
> - u8 guid[16];
> + ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd,
> + DP_RECEIVER_CAP_SIZE);
> + if (ret != DP_RECEIVER_CAP_SIZE) {
> + DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
> + goto out_fail;
> + }
>
> - sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
> - if (sret != DP_RECEIVER_CAP_SIZE) {
> - DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
> - ret = -1;
> - goto out_unlock;
> - }
> + ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
> + DP_MST_EN |
> + DP_UP_REQ_EN |
> + DP_UPSTREAM_IS_SRC);
> + if (ret < 0) {
> + DRM_DEBUG_KMS("mst write failed - undocked during suspend?\n");
> + goto out_fail;
> + }
>
> - ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
> - DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
> - if (ret < 0) {
> - DRM_DEBUG_KMS("mst write failed - undocked during suspend?\n");
> - ret = -1;
> - goto out_unlock;
> - }
> + /* Some hubs forget their guids after they resume */
> + ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
> + if (ret != 16) {
> + DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
> + goto out_fail;
> + }
> + drm_dp_check_mstb_guid(mgr->mst_primary, guid);
>
> - /* Some hubs forget their guids after they resume */
> - sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16);
> - if (sret != 16) {
> - DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
> - ret = -1;
> - goto out_unlock;
> - }
> - drm_dp_check_mstb_guid(mgr->mst_primary, guid);
> + /* For the final step of resuming the topology, we need to bring the
> + * state of our in-memory topology back into sync with reality. So,
> + * restart the probing process as if we're probing a new hub
> + */
> + queue_work(system_long_wq, &mgr->work);
> + mutex_unlock(&mgr->lock);
>
> - ret = 0;
> - } else
> - ret = -1;
> + if (sync) {
> + DRM_DEBUG_KMS("Waiting for link probe work to finish re-syncing topology...\n");
> + flush_work(&mgr->work);
> + }
It took me longer than I'd like to admit to realize that most of the diff in
this function is just removing the indent. Would you mind splitting that out
into a separate patch so the reprobe change is more obvious?
With these nits fixed,
Reviewed-by: Sean Paul <sean@poorly.run>
>
> -out_unlock:
> + return 0;
> +
> +out_fail:
> mutex_unlock(&mgr->lock);
> - return ret;
> + return -1;
> }
> EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 5673ed75e428..b78364dcdef9 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -7400,7 +7400,8 @@ void intel_dp_mst_resume(struct drm_i915_private *dev_priv)
> if (!intel_dp->can_mst)
> continue;
>
> - ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr);
> + ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr,
> + true);
> if (ret) {
> intel_dp->is_mst = false;
> drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
> diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> index 307584107d77..e459e2a79d78 100644
> --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
> +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
> @@ -1309,14 +1309,14 @@ nv50_mstm_fini(struct nv50_mstm *mstm)
> }
>
> static void
> -nv50_mstm_init(struct nv50_mstm *mstm)
> +nv50_mstm_init(struct nv50_mstm *mstm, bool runtime)
> {
> int ret;
>
> if (!mstm || !mstm->mgr.mst_state)
> return;
>
> - ret = drm_dp_mst_topology_mgr_resume(&mstm->mgr);
> + ret = drm_dp_mst_topology_mgr_resume(&mstm->mgr, !runtime);
> if (ret == -1) {
> drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false);
> drm_kms_helper_hotplug_event(mstm->mgr.dev);
> @@ -2262,7 +2262,7 @@ nv50_display_init(struct drm_device *dev, bool resume, bool runtime)
> if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
> struct nouveau_encoder *nv_encoder =
> nouveau_encoder(encoder);
> - nv50_mstm_init(nv_encoder->dp.mstm);
> + nv50_mstm_init(nv_encoder->dp.mstm, runtime);
> }
> }
>
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index 1efbb086f7ac..1bdee5ee6dcd 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -685,7 +685,8 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
>
> void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
> int __must_check
> -drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
> +drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
> + bool sync);
>
> ssize_t drm_dp_mst_dpcd_read(struct drm_dp_aux *aux,
> unsigned int offset, void *buffer, size_t size);
> --
> 2.21.0
>
--
Sean Paul, Software Engineer, Google / Chromium OS
next prev parent reply other threads:[~2019-09-27 13:52 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20190903204645.25487-1-lyude@redhat.com>
2019-09-03 20:45 ` [PATCH v2 01/27] drm/dp_mst: Move link address dumping into a function Lyude Paul
2019-09-25 17:45 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 02/27] drm/dp_mst: Get rid of list clear in destroy_connector_work Lyude Paul
2019-09-25 17:45 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 03/27] drm/dp_mst: Destroy MSTBs asynchronously Lyude Paul
2019-09-25 18:16 ` Sean Paul
2019-09-25 20:08 ` Lyude Paul
2019-09-27 13:31 ` Sean Paul
2019-10-08 9:45 ` Daniel Vetter
2019-09-03 20:45 ` [PATCH v2 04/27] drm/dp_mst: Move test_calc_pbn_mode() into an actual selftest Lyude Paul
2019-09-25 18:17 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 05/27] drm/print: Add drm_err_printer() Lyude Paul
2019-09-03 20:45 ` [PATCH v2 06/27] drm/dp_mst: Combine redundant cases in drm_dp_encode_sideband_req() Lyude Paul
2019-09-03 21:35 ` Dave Airlie
2019-09-03 21:57 ` [PATCH v3] " Lyude Paul
2019-09-03 20:45 ` [PATCH v2 07/27] drm/dp_mst: Add sideband down request tracing + selftests Lyude Paul
2019-09-10 9:01 ` Jani Nikula
2019-09-03 20:45 ` [PATCH v2 08/27] drm/dp_mst: Remove PDT teardown in drm_dp_destroy_port() and refactor Lyude Paul
2019-09-25 19:00 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 09/27] drm/dp_mst: Refactor drm_dp_send_enum_path_resources Lyude Paul
2019-09-03 20:45 ` [PATCH v2 10/27] drm/dp_mst: Remove huge conditional in drm_dp_mst_handle_up_req() Lyude Paul
2019-09-03 20:45 ` [PATCH v2 11/27] drm/dp_mst: Constify guid in drm_dp_get_mst_branch_by_guid() Lyude Paul
2019-09-03 21:41 ` Dave Airlie
2019-09-03 20:45 ` [PATCH v2 12/27] drm/dp_mst: Refactor drm_dp_mst_handle_up_req() Lyude Paul
2019-09-03 20:45 ` [PATCH v2 13/27] drm/dp_mst: Refactor drm_dp_mst_handle_down_rep() Lyude Paul
2019-09-03 20:45 ` [PATCH v2 14/27] drm/dp_mst: Destroy topology_mgr mutexes Lyude Paul
2019-09-25 19:14 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 15/27] drm/dp_mst: Cleanup drm_dp_send_link_address() a bit Lyude Paul
2019-09-03 21:42 ` Dave Airlie
2019-09-03 20:45 ` [PATCH v2 16/27] drm/dp_mst: Refactor pdt setup/teardown, add more locking Lyude Paul
2019-09-25 19:27 ` Sean Paul
2019-09-25 21:00 ` Lyude Paul
2019-09-27 13:30 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 17/27] drm/dp_mst: Rename drm_dp_add_port and drm_dp_update_port Lyude Paul
2019-09-25 19:30 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 18/27] drm/dp_mst: Remove lies in {up,down}_rep_recv documentation Lyude Paul
2019-09-25 19:32 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 19/27] drm/dp_mst: Handle UP requests asynchronously Lyude Paul
2019-09-25 19:46 ` Sean Paul
2019-09-03 20:45 ` [PATCH v2 20/27] drm/dp_mst: Protect drm_dp_mst_port members with connection_mutex Lyude Paul
2019-09-25 20:00 ` Sean Paul
2019-09-25 21:01 ` Lyude Paul
2019-09-03 20:45 ` [PATCH v2 21/27] drm/dp_mst: Don't forget to update port->input in drm_dp_mst_handle_conn_stat() Lyude Paul
2019-09-25 20:03 ` Sean Paul
2019-09-03 20:46 ` [PATCH v2 22/27] drm/nouveau: Don't grab runtime PM refs for HPD IRQs Lyude Paul
2019-09-25 20:06 ` Sean Paul
2019-09-03 20:46 ` [PATCH v2 23/27] drm/amdgpu: Iterate through DRM connectors correctly Lyude Paul
2019-09-13 20:45 ` Alex Deucher
2019-09-27 13:48 ` Alex Deucher
2019-09-03 20:46 ` [PATCH v2 24/27] drm/amdgpu/dm: Resume short HPD IRQs before resuming MST topology Lyude Paul
2019-09-13 20:46 ` Alex Deucher
2019-09-25 20:08 ` Sean Paul
2019-09-25 21:52 ` [PATCH v4] " Lyude Paul
2019-09-27 13:29 ` Alex Deucher
2019-09-03 20:46 ` [PATCH v2 25/27] drm/dp_mst: Add basic topology reprobing when resuming Lyude Paul
2019-09-27 13:52 ` Sean Paul [this message]
2019-10-09 19:06 ` Lyude Paul
2019-09-03 20:46 ` [PATCH v2 26/27] drm/dp_mst: Also print unhashed pointers for malloc/topology references Lyude Paul
2019-09-27 14:25 ` Sean Paul
2019-10-09 19:40 ` Lyude Paul
2019-09-03 20:46 ` [PATCH v2 27/27] drm/dp_mst: Add topology ref history tracking for debugging Lyude Paul
2019-09-27 14:51 ` Sean Paul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190927135207.GR218215@art_vandelay \
--to=sean@poorly.run \
--cc=Bhawanpreet.Lakha@amd.com \
--cc=David.Francis@amd.com \
--cc=David1.Zhou@amd.com \
--cc=airlied@linux.ie \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=bskeggs@redhat.com \
--cc=chris@chris-wilson.co.uk \
--cc=christian.koenig@amd.com \
--cc=daniel.vetter@ffwll.ch \
--cc=daniel@ffwll.ch \
--cc=dhinakaran.pandiyan@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=harry.wentland@amd.com \
--cc=hwentlan@amd.com \
--cc=imirkin@alum.mit.edu \
--cc=imre.deak@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=jose.souza@intel.com \
--cc=juston.li@intel.com \
--cc=karolherbst@gmail.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lyude@redhat.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=manasi.d.navare@intel.com \
--cc=mario.kleiner.de@gmail.com \
--cc=mripard@kernel.org \
--cc=nicholas.kazlauskas@amd.com \
--cc=nouveau@lists.freedesktop.org \
--cc=rodrigo.vivi@intel.com \
--cc=sunpeng.li@amd.com \
--cc=ville.syrjala@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox