diff options
author | Dave Airlie <airlied@redhat.com> | 2014-05-02 15:02:19 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-05-02 15:02:19 +1000 |
commit | 67df7b41e3aba1d58b7033a0f5e62f9ee1f551f5 (patch) | |
tree | 6b2960d09710a07692ecf605f2b12209c9f7b3c9 | |
parent | de2dd7b137ea6eaa846e60b0ef1d0f7082517d5e (diff) |
drm/dp: fix up enum path resource and path msgsi915-mst-hacks
This fixes up the enum path resource message so we get a response
correctly for it.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 48 | ||||
-rw-r--r-- | include/drm/drm_dp_mst_helper.h | 1 |
2 files changed, 24 insertions, 25 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index c6a088151eca..313af6a4d4e5 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -41,7 +41,7 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_sideband_msg_tx *txmsg); static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb, - int port_num); + struct drm_dp_mst_port *port); static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr, int id, @@ -418,7 +418,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, if (!port->input && port->ddps) drm_dp_send_enum_path_resources(mstb->mgr, mstb, - port->port_num); + port); if (!port->input) port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port); @@ -446,23 +446,8 @@ static void drm_dp_update_port(struct drm_dp_mst_branch *mstb, } if (!port->input && port->ddps) - drm_dp_send_enum_path_resources(mstb->mgr, mstb, - port->port_num); - - drm_dp_put_port(port); -} - -static void drm_dp_update_port_pbn(struct drm_dp_mst_branch *mstb, - uint8_t port_number, - uint16_t available_pbn) -{ - struct drm_dp_mst_port *port; - - port = drm_dp_get_port(mstb, port_number); - if (!port) - return; + drm_dp_send_enum_path_resources(mstb->mgr, mstb, port); - port->available_pbn = available_pbn; drm_dp_put_port(port); } @@ -1160,6 +1145,7 @@ static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg, int por req.req_type = DP_ENUM_PATH_RESOURCES; req.u.port_num.port_number = port_num; drm_dp_encode_sideband_req(&req, msg); + msg->path_msg = true; return 0; } @@ -1173,6 +1159,7 @@ static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_n req.u.allocate_payload.vcpi = vcpi; req.u.allocate_payload.pbn = pbn; drm_dp_encode_sideband_req(&req, msg); + msg->path_msg = true; return 0; } @@ -1218,7 +1205,7 @@ static int set_hdr_from_dst(struct drm_dp_sideband_msg_hdr *hdr, spin_unlock(&mstb->slots_lock); } hdr->broadcast = 0; - hdr->path_msg = 0; + hdr->path_msg = txmsg->path_msg; hdr->lct = mstb->lct; hdr->lcr = mstb->lct - 1; if (mstb->lct > 1) @@ -1370,22 +1357,35 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb, - int port_num) + struct drm_dp_mst_port *port) { int len; struct drm_dp_sideband_msg_tx *txmsg; + int ret; - /* TODO redo this properly */ - return 0; txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); if (!txmsg) return -ENOMEM; txmsg->dst = mstb; - len = build_enum_path_resources(txmsg, port_num); + len = build_enum_path_resources(txmsg, port->port_num); drm_dp_queue_down_tx(mgr, txmsg); + ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); + if (ret > 0) { + if (txmsg->reply.reply_type == 1) + DRM_DEBUG_KMS("enum path resources nak received\n"); + else { + if (port->port_num != txmsg->reply.u.path_resources.port_number) + DRM_ERROR("got incorrect port in response\n"); + printk(KERN_DEBUG "enum path resources %d: %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.full_payload_bw_number, + txmsg->reply.u.path_resources.avail_payload_bw_number); + port->available_pbn = txmsg->reply.u.path_resources.avail_payload_bw_number; + } + } + + kfree(txmsg); return 0; } @@ -1789,8 +1789,6 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr) drm_dp_sideband_parse_reply(&mgr->down_rep_recv, &txmsg->reply); if (txmsg->reply.reply_type == 1) { DRM_DEBUG_KMS("Got NAK reply: req 0x%02x, reason 0x%02x, nak data 0x%02x\n", txmsg->reply.req_type, txmsg->reply.u.nak.reason, txmsg->reply.u.nak.nak_data); - } else if (txmsg->reply.req_type == DP_ENUM_PATH_RESOURCES) { - drm_dp_update_port_pbn(mstb, txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.avail_payload_bw_number); } drm_dp_put_mst_branch_device(mstb); diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index 290f3cd15991..d1f6b8dba181 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -315,6 +315,7 @@ struct drm_dp_sideband_msg_tx { struct list_head next; int seqno; int state; + bool path_msg; struct drm_dp_sideband_msg_reply_body reply; }; |