diff options
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 5539a91b4031..54604633e65c 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3708,19 +3708,24 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms /* set the device into MST mode */ if (mst_state) { struct drm_dp_payload reset_pay; + int lane_count; + int link_rate; WARN_ON(mgr->mst_primary); /* get dpcd info */ - ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); - if (ret != DP_RECEIVER_CAP_SIZE) { - drm_dbg_kms(mgr->dev, "failed to read DPCD\n"); + ret = drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd); + if (ret < 0) { + drm_dbg_kms(mgr->dev, "%s: failed to read DPCD, ret %d\n", + mgr->aux->name, ret); goto out_unlock; } + lane_count = min_t(int, mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count); + link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate); mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr, - drm_dp_bw_code_to_link_rate(mgr->dpcd[1]), - mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK); + drm_dp_bw_code_to_link_rate(link_rate), + lane_count); if (mgr->pbn_div == 0) { ret = -EINVAL; goto out_unlock; @@ -5448,14 +5453,17 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state); * @aux: DP helper aux channel to talk to this device * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit * @max_payloads: maximum number of payloads this GPU can source + * @max_lane_count: maximum number of lanes this GPU supports + * @max_link_rate: maximum link rate this GPU supports, units as in DPCD * @conn_base_id: the connector object ID the MST device is connected to. * * Return 0 for success, or negative error code on failure */ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, struct drm_device *dev, struct drm_dp_aux *aux, - int max_dpcd_transaction_bytes, - int max_payloads, int conn_base_id) + int max_dpcd_transaction_bytes, int max_payloads, + u8 max_lane_count, u8 max_link_rate, + int conn_base_id) { struct drm_dp_mst_topology_state *mst_state; @@ -5490,6 +5498,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, mgr->aux = aux; mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes; mgr->max_payloads = max_payloads; + mgr->max_lane_count = max_lane_count; + mgr->max_link_rate = max_link_rate; mgr->conn_base_id = conn_base_id; if (max_payloads + 1 > sizeof(mgr->payload_mask) * 8 || max_payloads + 1 > sizeof(mgr->vcpi_mask) * 8) @@ -5896,14 +5906,13 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port) if (drm_dp_has_quirk(&desc, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) && port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 && port->parent == port->mgr->mst_primary) { - u8 downstreamport; + u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; - if (drm_dp_dpcd_read(&port->aux, DP_DOWNSTREAMPORT_PRESENT, - &downstreamport, 1) < 0) + if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0) return NULL; - if ((downstreamport & DP_DWN_STRM_PORT_PRESENT) && - ((downstreamport & DP_DWN_STRM_PORT_TYPE_MASK) + if ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT) && + ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) != DP_DWN_STRM_PORT_TYPE_ANALOG)) return port->mgr->aux; } |