From 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Fri, 25 Mar 2016 03:53:42 -0300 Subject: Linux-libre 4.5-gnu --- drivers/gpu/drm/drm_dp_mst_topology.c | 49 +++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 39d7e2e15..27fbd79d0 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 } static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num, - u8 vcpi, uint16_t pbn) + u8 vcpi, uint16_t pbn, + u8 number_sdp_streams, + u8 *sdp_stream_sink) { struct drm_dp_sideband_msg_req_body req; memset(&req, 0, sizeof(req)); @@ -674,6 +676,9 @@ static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_n req.u.allocate_payload.port_number = port_num; req.u.allocate_payload.vcpi = vcpi; req.u.allocate_payload.pbn = pbn; + req.u.allocate_payload.number_sdp_streams = number_sdp_streams; + memcpy(req.u.allocate_payload.sdp_stream_sink, sdp_stream_sink, + number_sdp_streams); drm_dp_encode_sideband_req(&req, msg); msg->path_msg = true; return 0; @@ -1664,6 +1669,8 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_sideband_msg_tx *txmsg; struct drm_dp_mst_branch *mstb; int len, ret, port_num; + u8 sinks[DRM_DP_MAX_SDP_STREAMS]; + int i; port_num = port->port_num; mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); @@ -1680,10 +1687,13 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, goto fail_put; } + for (i = 0; i < port->num_sdp_streams; i++) + sinks[i] = i; + txmsg->dst = mstb; len = build_allocate_payload(txmsg, port_num, id, - pbn); + pbn, port->num_sdp_streams, sinks); drm_dp_queue_down_tx(mgr, txmsg); @@ -1780,6 +1790,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) if (mgr->proposed_vcpis[i]) { port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; + req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; } else { port = NULL; req_payload.num_slots = 0; @@ -1795,6 +1806,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) if (req_payload.num_slots) { drm_dp_create_payload_step1(mgr, mgr->proposed_vcpis[i]->vcpi, &req_payload); mgr->payloads[i].num_slots = req_payload.num_slots; + mgr->payloads[i].vcpi = req_payload.vcpi; } else if (mgr->payloads[i].num_slots) { mgr->payloads[i].num_slots = 0; drm_dp_destroy_payload_step1(mgr, port, port->vcpi.vcpi, &mgr->payloads[i]); @@ -1930,7 +1942,7 @@ static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req { struct drm_dp_sideband_msg_reply_body reply; - reply.reply_type = 1; + reply.reply_type = 0; reply.req_type = req_type; drm_dp_encode_sideband_reply(&reply, msg); return 0; @@ -2375,6 +2387,27 @@ out: } EXPORT_SYMBOL(drm_dp_mst_detect_port); +/** + * drm_dp_mst_port_has_audio() - Check whether port has audio capability or not + * @mgr: manager for this port + * @port: unverified pointer to a port. + * + * This returns whether the port supports audio or not. + */ +bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port) +{ + bool ret = false; + + port = drm_dp_get_validated_port_ref(mgr, port); + if (!port) + return ret; + ret = port->has_audio; + drm_dp_put_port(port); + return ret; +} +EXPORT_SYMBOL(drm_dp_mst_port_has_audio); + /** * drm_dp_mst_get_edid() - get EDID for an MST port * @connector: toplevel connector to get EDID for @@ -2400,6 +2433,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_ edid = drm_get_edid(connector, &port->aux.ddc); drm_mode_connector_set_tile_property(connector); } + port->has_audio = drm_detect_monitor_audio(edid); drm_dp_put_port(port); return edid; } @@ -2695,7 +2729,7 @@ static void drm_dp_mst_dump_mstb(struct seq_file *m, seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports); list_for_each_entry(port, &mstb->ports, next) { - seq_printf(m, "%sport: %d: ddps: %d ldps: %d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port, port->connector); + 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); if (port->mstb) drm_dp_mst_dump_mstb(m, port->mstb); } @@ -2892,6 +2926,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes; mgr->max_payloads = max_payloads; mgr->conn_base_id = conn_base_id; + if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 || + max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8) + return -EINVAL; mgr->payloads = kcalloc(max_payloads, sizeof(struct drm_dp_payload), GFP_KERNEL); if (!mgr->payloads) return -ENOMEM; @@ -2899,7 +2936,9 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, if (!mgr->proposed_vcpis) return -ENOMEM; set_bit(0, &mgr->payload_mask); - test_calc_pbn_mode(); + if (test_calc_pbn_mode() < 0) + DRM_ERROR("MST PBN self-test failed\n"); + return 0; } EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init); -- cgit v1.2.3-54-g00ecf