21,10 → 21,6 |
*/ |
|
#include <linux/kernel.h> |
#include <linux/mutex.h> |
#include <linux/kref.h> |
#include <linux/wait.h> |
#include <linux/workqueue.h> |
#include <linux/delay.h> |
#include <linux/init.h> |
#include <linux/errno.h> |
674,7 → 670,9 |
} |
|
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)); |
682,6 → 680,9 |
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; |
916,7 → 917,6 |
/* no need to clean up vcpi |
* as if we have no connector we never setup a vcpi */ |
drm_dp_port_teardown_pdt(port, port->pdt); |
port->pdt = DP_PEER_DEVICE_NONE; |
} |
kfree(port); |
} |
1162,9 → 1162,7 |
drm_dp_put_port(port); |
goto out; |
} |
if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV || |
port->pdt == DP_PEER_DEVICE_SST_SINK) && |
port->port_num >= DP_MST_LOGICAL_PORT_0) { |
if (port->port_num >= DP_MST_LOGICAL_PORT_0) { |
port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc); |
drm_mode_connector_set_tile_property(port->connector); |
} |
1674,6 → 1672,8 |
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 = drm_dp_get_validated_port_ref(mgr, port); |
if (!port) |
1696,10 → 1696,13 |
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); |
|
1802,6 → 1805,7 |
return -EINVAL; |
} |
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; |
1817,9 → 1821,10 |
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, mgr->payloads[i].vcpi, &mgr->payloads[i]); |
drm_dp_destroy_payload_step1(mgr, port, port->vcpi.vcpi, &mgr->payloads[i]); |
req_payload.payload_state = mgr->payloads[i].payload_state; |
mgr->payloads[i].start_slot = 0; |
} |
1955,7 → 1960,7 |
{ |
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; |
2411,6 → 2416,27 |
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 |
* @mgr: manager for this port |
2435,6 → 2461,7 |
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; |
} |
2821,6 → 2848,9 |
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; |
2828,7 → 2858,9 |
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); |