aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorLibin Yang <libin.yang@linux.intel.com>2015-12-02 01:09:43 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-12-10 04:00:42 -0500
commitef8f9bea1368b89d0d6d1819025586ae0bea0612 (patch)
treebdbea2eb9bdca851057382f3ed512e3faaf02497 /drivers/gpu/drm
parente8ebd8e2bd06e3509e1a4d65cbc7293d72897dd7 (diff)
dp/mst: add SDP stream support
This adds code to initialise the SDP streams for a sink in the simplest ordering. I've no idea how you'd want to control the ordering at this level, so don't bother until someone comes up with a use case. Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Libin Yang <libin.yang@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1449036584-105393-1-git-send-email-libin.yang@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 809959d56d78..f50eb7b87c2f 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -666,7 +666,9 @@ static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg, int por
666} 666}
667 667
668static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num, 668static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num,
669 u8 vcpi, uint16_t pbn) 669 u8 vcpi, uint16_t pbn,
670 u8 number_sdp_streams,
671 u8 *sdp_stream_sink)
670{ 672{
671 struct drm_dp_sideband_msg_req_body req; 673 struct drm_dp_sideband_msg_req_body req;
672 memset(&req, 0, sizeof(req)); 674 memset(&req, 0, sizeof(req));
@@ -674,6 +676,9 @@ static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_n
674 req.u.allocate_payload.port_number = port_num; 676 req.u.allocate_payload.port_number = port_num;
675 req.u.allocate_payload.vcpi = vcpi; 677 req.u.allocate_payload.vcpi = vcpi;
676 req.u.allocate_payload.pbn = pbn; 678 req.u.allocate_payload.pbn = pbn;
679 req.u.allocate_payload.number_sdp_streams = number_sdp_streams;
680 memcpy(req.u.allocate_payload.sdp_stream_sink, sdp_stream_sink,
681 number_sdp_streams);
677 drm_dp_encode_sideband_req(&req, msg); 682 drm_dp_encode_sideband_req(&req, msg);
678 msg->path_msg = true; 683 msg->path_msg = true;
679 return 0; 684 return 0;
@@ -1562,6 +1567,8 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
1562 struct drm_dp_sideband_msg_tx *txmsg; 1567 struct drm_dp_sideband_msg_tx *txmsg;
1563 struct drm_dp_mst_branch *mstb; 1568 struct drm_dp_mst_branch *mstb;
1564 int len, ret; 1569 int len, ret;
1570 u8 sinks[DRM_DP_MAX_SDP_STREAMS];
1571 int i;
1565 1572
1566 mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); 1573 mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
1567 if (!mstb) 1574 if (!mstb)
@@ -1573,10 +1580,13 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
1573 goto fail_put; 1580 goto fail_put;
1574 } 1581 }
1575 1582
1583 for (i = 0; i < port->num_sdp_streams; i++)
1584 sinks[i] = i;
1585
1576 txmsg->dst = mstb; 1586 txmsg->dst = mstb;
1577 len = build_allocate_payload(txmsg, port->port_num, 1587 len = build_allocate_payload(txmsg, port->port_num,
1578 id, 1588 id,
1579 pbn); 1589 pbn, port->num_sdp_streams, sinks);
1580 1590
1581 drm_dp_queue_down_tx(mgr, txmsg); 1591 drm_dp_queue_down_tx(mgr, txmsg);
1582 1592
@@ -2259,6 +2269,27 @@ out:
2259EXPORT_SYMBOL(drm_dp_mst_detect_port); 2269EXPORT_SYMBOL(drm_dp_mst_detect_port);
2260 2270
2261/** 2271/**
2272 * drm_dp_mst_port_has_audio() - Check whether port has audio capability or not
2273 * @mgr: manager for this port
2274 * @port: unverified pointer to a port.
2275 *
2276 * This returns whether the port supports audio or not.
2277 */
2278bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
2279 struct drm_dp_mst_port *port)
2280{
2281 bool ret = false;
2282
2283 port = drm_dp_get_validated_port_ref(mgr, port);
2284 if (!port)
2285 return ret;
2286 ret = port->has_audio;
2287 drm_dp_put_port(port);
2288 return ret;
2289}
2290EXPORT_SYMBOL(drm_dp_mst_port_has_audio);
2291
2292/**
2262 * drm_dp_mst_get_edid() - get EDID for an MST port 2293 * drm_dp_mst_get_edid() - get EDID for an MST port
2263 * @connector: toplevel connector to get EDID for 2294 * @connector: toplevel connector to get EDID for
2264 * @mgr: manager for this port 2295 * @mgr: manager for this port
@@ -2283,6 +2314,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
2283 edid = drm_get_edid(connector, &port->aux.ddc); 2314 edid = drm_get_edid(connector, &port->aux.ddc);
2284 drm_mode_connector_set_tile_property(connector); 2315 drm_mode_connector_set_tile_property(connector);
2285 } 2316 }
2317 port->has_audio = drm_detect_monitor_audio(edid);
2286 drm_dp_put_port(port); 2318 drm_dp_put_port(port);
2287 return edid; 2319 return edid;
2288} 2320}
@@ -2566,7 +2598,7 @@ static void drm_dp_mst_dump_mstb(struct seq_file *m,
2566 2598
2567 seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports); 2599 seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
2568 list_for_each_entry(port, &mstb->ports, next) { 2600 list_for_each_entry(port, &mstb->ports, next) {
2569 seq_printf(m, "%sport: %d: ddps: %d ldps: %d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port, port->connector); 2601 seq_printf(m, "%sport: %d: ddps: %d ldps: %d, sdp: %d/%d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port->num_sdp_streams, port->num_sdp_stream_sinks, port, port->connector);
2570 if (port->mstb) 2602 if (port->mstb)
2571 drm_dp_mst_dump_mstb(m, port->mstb); 2603 drm_dp_mst_dump_mstb(m, port->mstb);
2572 } 2604 }