summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h1
3 files changed, 15 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 8e1effb10425..d2141ca16107 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1258,7 +1258,10 @@ nv50_mstc_detect(struct drm_connector *connector,
ret = drm_dp_mst_detect_port(connector, ctx, mstc->port->mgr,
mstc->port);
+ if (ret != connector_status_connected)
+ goto out;
+out:
pm_runtime_mark_last_busy(connector->dev->dev);
pm_runtime_put_autosuspend(connector->dev->dev);
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 005750aeb6d4..ad852e572cfe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -61,6 +61,11 @@ nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
mstm->can_mst = drm_dp_read_mst_cap(aux, dpcd);
}
+ ret = drm_dp_read_downstream_info(aux, dpcd,
+ outp->dp.downstream_ports);
+ if (ret < 0)
+ return connector_status_disconnected;
+
return connector_status_connected;
}
@@ -176,8 +181,6 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
/* TODO:
* - Use the minimum possible BPC here, once we add support for the max bpc
* property.
- * - Validate the mode against downstream port caps (see
- * drm_dp_downstream_max_clock())
* - Validate against the DP caps advertised by the GPU (we don't check these
* yet)
*/
@@ -188,15 +191,19 @@ nv50_dp_mode_valid(struct drm_connector *connector,
unsigned *out_clock)
{
const unsigned min_clock = 25000;
- unsigned max_clock, clock;
+ unsigned max_clock, ds_clock, clock;
enum drm_mode_status ret;
if (mode->flags & DRM_MODE_FLAG_INTERLACE && !outp->caps.dp_interlace)
return MODE_NO_INTERLACE;
max_clock = outp->dp.link_nr * outp->dp.link_bw;
- clock = mode->clock * (connector->display_info.bpc * 3) / 10;
+ ds_clock = drm_dp_downstream_max_clock(outp->dp.dpcd,
+ outp->dp.downstream_ports);
+ if (ds_clock)
+ max_clock = min(max_clock, ds_clock);
+ clock = mode->clock * (connector->display_info.bpc * 3) / 10;
ret = nouveau_conn_mode_clock_valid(mode, min_clock, max_clock,
&clock);
if (out_clock)
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index eef4643f5f98..c1924a4529a7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -72,6 +72,7 @@ struct nouveau_encoder {
struct mutex hpd_irq_lock;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
+ u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
struct drm_dp_desc desc;
} dp;
};