aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-09-16 03:55:23 -0400
committerDave Airlie <airlied@redhat.com>2015-10-02 01:34:41 -0400
commitd9515c5ec1a20c77d83471e634ad9bb12deb0eac (patch)
treefc0f8cb6098aa942f4dfe6749fb8c55b34161a34
parent68d8c9fc91a0f63a2a10ccf7adf56f69125c11c1 (diff)
drm/dp/mst: split connector registration into two parts (v2)
In order to cache the EDID properly for tiled displays, we need to retrieve it before we register the connector with userspace, otherwise userspace can call get resources and try and get the edid before we've even cached it. This fixes some problems when hotplugging mst monitors, with X/mutter running. As mutter seems to get 0 modes for one of the monitors in the tile. v2: fix warning in radeon handle tile setting in cached path rather than get edid path. Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c8
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_mst.c11
-rw-r--r--include/drm/drm_dp_mst_helper.h1
4 files changed, 23 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index a2f5caaee242..36454a146ae9 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1129,7 +1129,9 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
1129 } 1129 }
1130 if (port->port_num >= 8) { 1130 if (port->port_num >= 8) {
1131 port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc); 1131 port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
1132 drm_mode_connector_set_tile_property(port->connector);
1132 } 1133 }
1134 (*mstb->mgr->cbs->register_connector)(port->connector);
1133 } 1135 }
1134 1136
1135out: 1137out:
@@ -2276,10 +2278,10 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
2276 2278
2277 if (port->cached_edid) 2279 if (port->cached_edid)
2278 edid = drm_edid_duplicate(port->cached_edid); 2280 edid = drm_edid_duplicate(port->cached_edid);
2279 else 2281 else {
2280 edid = drm_get_edid(connector, &port->aux.ddc); 2282 edid = drm_get_edid(connector, &port->aux.ddc);
2281 2283 drm_mode_connector_set_tile_property(connector);
2282 drm_mode_connector_set_tile_property(connector); 2284 }
2283 drm_dp_put_port(port); 2285 drm_dp_put_port(port);
2284 return edid; 2286 return edid;
2285} 2287}
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 3e4be5a3becd..6ade06888432 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -462,11 +462,17 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
462 drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0); 462 drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
463 463
464 drm_mode_connector_set_path_property(connector, pathprop); 464 drm_mode_connector_set_path_property(connector, pathprop);
465 return connector;
466}
467
468static void intel_dp_register_mst_connector(struct drm_connector *connector)
469{
470 struct intel_connector *intel_connector = to_intel_connector(connector);
471 struct drm_device *dev = connector->dev;
465 drm_modeset_lock_all(dev); 472 drm_modeset_lock_all(dev);
466 intel_connector_add_to_fbdev(intel_connector); 473 intel_connector_add_to_fbdev(intel_connector);
467 drm_modeset_unlock_all(dev); 474 drm_modeset_unlock_all(dev);
468 drm_connector_register(&intel_connector->base); 475 drm_connector_register(&intel_connector->base);
469 return connector;
470} 476}
471 477
472static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, 478static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
@@ -512,6 +518,7 @@ static void intel_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
512 518
513static struct drm_dp_mst_topology_cbs mst_cbs = { 519static struct drm_dp_mst_topology_cbs mst_cbs = {
514 .add_connector = intel_dp_add_mst_connector, 520 .add_connector = intel_dp_add_mst_connector,
521 .register_connector = intel_dp_register_mst_connector,
515 .destroy_connector = intel_dp_destroy_mst_connector, 522 .destroy_connector = intel_dp_destroy_mst_connector,
516 .hotplug = intel_dp_mst_hotplug, 523 .hotplug = intel_dp_mst_hotplug,
517}; 524};
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 5e09c061847f..6cddae44fa6e 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -265,7 +265,6 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
265{ 265{
266 struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr); 266 struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr);
267 struct drm_device *dev = master->base.dev; 267 struct drm_device *dev = master->base.dev;
268 struct radeon_device *rdev = dev->dev_private;
269 struct radeon_connector *radeon_connector; 268 struct radeon_connector *radeon_connector;
270 struct drm_connector *connector; 269 struct drm_connector *connector;
271 270
@@ -286,12 +285,19 @@ static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topol
286 drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); 285 drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
287 drm_mode_connector_set_path_property(connector, pathprop); 286 drm_mode_connector_set_path_property(connector, pathprop);
288 287
288 return connector;
289}
290
291static void radeon_dp_register_mst_connector(struct drm_connector *connector)
292{
293 struct drm_device *dev = connector->dev;
294 struct radeon_device *rdev = dev->dev_private;
295
289 drm_modeset_lock_all(dev); 296 drm_modeset_lock_all(dev);
290 radeon_fb_add_connector(rdev, connector); 297 radeon_fb_add_connector(rdev, connector);
291 drm_modeset_unlock_all(dev); 298 drm_modeset_unlock_all(dev);
292 299
293 drm_connector_register(connector); 300 drm_connector_register(connector);
294 return connector;
295} 301}
296 302
297static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, 303static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
@@ -324,6 +330,7 @@ static void radeon_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
324 330
325struct drm_dp_mst_topology_cbs mst_cbs = { 331struct drm_dp_mst_topology_cbs mst_cbs = {
326 .add_connector = radeon_dp_add_mst_connector, 332 .add_connector = radeon_dp_add_mst_connector,
333 .register_connector = radeon_dp_register_mst_connector,
327 .destroy_connector = radeon_dp_destroy_mst_connector, 334 .destroy_connector = radeon_dp_destroy_mst_connector,
328 .hotplug = radeon_dp_mst_hotplug, 335 .hotplug = radeon_dp_mst_hotplug,
329}; 336};
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 86d0b25ed054..0f408b002d98 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -374,6 +374,7 @@ struct drm_dp_mst_topology_mgr;
374struct drm_dp_mst_topology_cbs { 374struct drm_dp_mst_topology_cbs {
375 /* create a connector for a port */ 375 /* create a connector for a port */
376 struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path); 376 struct drm_connector *(*add_connector)(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *path);
377 void (*register_connector)(struct drm_connector *connector);
377 void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr, 378 void (*destroy_connector)(struct drm_dp_mst_topology_mgr *mgr,
378 struct drm_connector *connector); 379 struct drm_connector *connector);
379 void (*hotplug)(struct drm_dp_mst_topology_mgr *mgr); 380 void (*hotplug)(struct drm_dp_mst_topology_mgr *mgr);