static int nouveau_mst = 1;
 module_param_named(mst, nouveau_mst, int, 0400);
 
+static bool
+nouveau_dp_has_sink_count(struct drm_connector *connector,
+                         struct nouveau_encoder *outp)
+{
+       return drm_dp_read_sink_count_cap(connector, outp->dp.dpcd, &outp->dp.desc);
+}
+
 static enum drm_connector_status
 nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
                      struct nouveau_encoder *outp)
 {
+       struct drm_connector *connector = &nv_connector->base;
        struct drm_dp_aux *aux = &nv_connector->aux;
        struct nv50_mstm *mstm = NULL;
+       enum drm_connector_status status = connector_status_disconnected;
        int ret;
        u8 *dpcd = outp->dp.dpcd;
 
                ret = drm_dp_read_desc(aux, &outp->dp.desc,
                                       drm_dp_is_branch(dpcd));
                if (ret < 0)
-                       return connector_status_disconnected;
+                       goto out;
        } else {
-               return connector_status_disconnected;
+               goto out;
        }
 
        if (nouveau_mst) {
                        mstm->can_mst = drm_dp_read_mst_cap(aux, dpcd);
        }
 
+       if (nouveau_dp_has_sink_count(connector, outp)) {
+               ret = drm_dp_read_sink_count(aux);
+               if (ret < 0)
+                       goto out;
+
+               outp->dp.sink_count = ret;
+
+               /*
+                * Dongle connected, but no display. Don't bother reading
+                * downstream port info
+                */
+               if (!outp->dp.sink_count)
+                       return connector_status_disconnected;
+       }
+
        ret = drm_dp_read_downstream_info(aux, dpcd,
                                          outp->dp.downstream_ports);
        if (ret < 0)
-               return connector_status_disconnected;
+               goto out;
 
-       return connector_status_connected;
+       status = connector_status_connected;
+out:
+       if (status != connector_status_connected) {
+               /* Clear any cached info */
+               outp->dp.sink_count = 0;
+       }
+       return status;
 }
 
 int
        struct drm_connector *connector = &nv_connector->base;
        struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
        struct nv50_mstm *mstm;
+       int ret;
+       bool send_hpd = false;
 
        if (!outp)
                return;
 
        if (mstm && mstm->is_mst) {
                if (!nv50_mstm_service(drm, nv_connector, mstm))
-                       nouveau_connector_hpd(connector);
+                       send_hpd = true;
        } else {
                drm_dp_cec_irq(&nv_connector->aux);
+
+               if (nouveau_dp_has_sink_count(connector, outp)) {
+                       ret = drm_dp_read_sink_count(&nv_connector->aux);
+                       if (ret != outp->dp.sink_count)
+                               send_hpd = true;
+                       if (ret >= 0)
+                               outp->dp.sink_count = ret;
+               }
        }
 
        mutex_unlock(&outp->dp.hpd_irq_lock);
+
+       if (send_hpd)
+               nouveau_connector_hpd(connector);
 }
 
 /* TODO: