aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c19
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c2
-rw-r--r--include/drm/drm_dp_mst_helper.h4
3 files changed, 21 insertions, 4 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 9798bb79fe59..0a9d3aad3cba 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -861,6 +861,8 @@ static void drm_dp_destroy_port(struct kref *kref)
861 struct drm_dp_mst_topology_mgr *mgr = port->mgr; 861 struct drm_dp_mst_topology_mgr *mgr = port->mgr;
862 if (!port->input) { 862 if (!port->input) {
863 port->vcpi.num_slots = 0; 863 port->vcpi.num_slots = 0;
864
865 kfree(port->cached_edid);
864 if (port->connector) 866 if (port->connector)
865 (*port->mgr->cbs->destroy_connector)(mgr, port->connector); 867 (*port->mgr->cbs->destroy_connector)(mgr, port->connector);
866 drm_dp_port_teardown_pdt(port, port->pdt); 868 drm_dp_port_teardown_pdt(port, port->pdt);
@@ -1100,6 +1102,10 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
1100 char proppath[255]; 1102 char proppath[255];
1101 build_mst_prop_path(port, mstb, proppath, sizeof(proppath)); 1103 build_mst_prop_path(port, mstb, proppath, sizeof(proppath));
1102 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); 1104 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath);
1105
1106 if (port->port_num >= 8) {
1107 port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
1108 }
1103 } 1109 }
1104 1110
1105 /* put reference to this port */ 1111 /* put reference to this port */
@@ -2170,7 +2176,8 @@ EXPORT_SYMBOL(drm_dp_mst_hpd_irq);
2170 * This returns the current connection state for a port. It validates the 2176 * This returns the current connection state for a port. It validates the
2171 * port pointer still exists so the caller doesn't require a reference 2177 * port pointer still exists so the caller doesn't require a reference
2172 */ 2178 */
2173enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) 2179enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector,
2180 struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
2174{ 2181{
2175 enum drm_connector_status status = connector_status_disconnected; 2182 enum drm_connector_status status = connector_status_disconnected;
2176 2183
@@ -2189,6 +2196,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr
2189 2196
2190 case DP_PEER_DEVICE_SST_SINK: 2197 case DP_PEER_DEVICE_SST_SINK:
2191 status = connector_status_connected; 2198 status = connector_status_connected;
2199 /* for logical ports - cache the EDID */
2200 if (port->port_num >= 8 && !port->cached_edid) {
2201 port->cached_edid = drm_get_edid(connector, &port->aux.ddc);
2202 }
2192 break; 2203 break;
2193 case DP_PEER_DEVICE_DP_LEGACY_CONV: 2204 case DP_PEER_DEVICE_DP_LEGACY_CONV:
2194 if (port->ldps) 2205 if (port->ldps)
@@ -2220,7 +2231,11 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
2220 if (!port) 2231 if (!port)
2221 return NULL; 2232 return NULL;
2222 2233
2223 edid = drm_get_edid(connector, &port->aux.ddc); 2234 if (port->cached_edid)
2235 edid = drm_edid_duplicate(port->cached_edid);
2236 else
2237 edid = drm_get_edid(connector, &port->aux.ddc);
2238
2224 drm_dp_put_port(port); 2239 drm_dp_put_port(port);
2225 return edid; 2240 return edid;
2226} 2241}
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index bfe359506377..428bb3041621 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -283,7 +283,7 @@ intel_dp_mst_detect(struct drm_connector *connector, bool force)
283 struct intel_connector *intel_connector = to_intel_connector(connector); 283 struct intel_connector *intel_connector = to_intel_connector(connector);
284 struct intel_dp *intel_dp = intel_connector->mst_port; 284 struct intel_dp *intel_dp = intel_connector->mst_port;
285 285
286 return drm_dp_mst_detect_port(&intel_dp->mst_mgr, intel_connector->port); 286 return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr, intel_connector->port);
287} 287}
288 288
289static int 289static int
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index cec6383bbdb8..00c1da927245 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -92,6 +92,8 @@ struct drm_dp_mst_port {
92 struct drm_dp_vcpi vcpi; 92 struct drm_dp_vcpi vcpi;
93 struct drm_connector *connector; 93 struct drm_connector *connector;
94 struct drm_dp_mst_topology_mgr *mgr; 94 struct drm_dp_mst_topology_mgr *mgr;
95
96 struct edid *cached_edid; /* for DP logical ports - make tiling work */
95}; 97};
96 98
97/** 99/**
@@ -474,7 +476,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
474int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled); 476int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled);
475 477
476 478
477enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); 479enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
478 480
479struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); 481struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
480 482