Loading drivers/gpu/drm/drm_dp_mst_topology.c +73 −2 Original line number Diff line number Diff line Loading @@ -486,6 +486,7 @@ static bool drm_dp_sideband_parse_enum_path_resources_ack(struct drm_dp_sideband { int idx = 1; repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf; repmsg->u.path_resources.fec_capability = (raw->msg[idx]) & 0x1; idx++; if (idx > raw->curlen) goto fail_len; Loading Loading @@ -1693,9 +1694,14 @@ static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, else { if (port->port_num != txmsg->reply.u.path_resources.port_number) DRM_ERROR("got incorrect port in response\n"); DRM_DEBUG_KMS("enum path resources %d: %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.full_payload_bw_number, DRM_DEBUG_KMS("enum path resources %d: %d %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.fec_capability, 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; port->fec_capability = txmsg->reply.u.path_resources.fec_capability; } } Loading Loading @@ -1850,6 +1856,42 @@ static int drm_dp_send_clear_payload_table(struct drm_dp_mst_topology_mgr *mgr, return ret; } int drm_dp_mst_get_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info) { if (!dsc_info) return -EINVAL; port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return -EINVAL; memcpy(dsc_info, &port->dsc_info, sizeof(struct drm_dp_mst_dsc_info)); drm_dp_put_port(port); return 0; } EXPORT_SYMBOL(drm_dp_mst_get_dsc_info); int drm_dp_mst_update_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info) { if (!dsc_info) return -EINVAL; port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return -EINVAL; memcpy(&port->dsc_info, dsc_info, sizeof(struct drm_dp_mst_dsc_info)); drm_dp_put_port(port); return 0; } EXPORT_SYMBOL(drm_dp_mst_update_dsc_info); static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr, int id, struct drm_dp_payload *payload) Loading Loading @@ -2122,6 +2164,21 @@ int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, } EXPORT_SYMBOL(drm_dp_send_dpcd_write); int drm_dp_mst_get_max_sdp_streams_supported( struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) { int ret = -1; port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return ret; ret = port->num_sdp_streams; drm_dp_put_port(port); return ret; } EXPORT_SYMBOL(drm_dp_mst_get_max_sdp_streams_supported); static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req_type) { struct drm_dp_sideband_msg_reply_body reply; Loading Loading @@ -2639,6 +2696,20 @@ bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, } EXPORT_SYMBOL(drm_dp_mst_port_has_audio); bool drm_dp_mst_has_fec(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->fec_capability; drm_dp_put_port(port); return ret; } EXPORT_SYMBOL(drm_dp_mst_has_fec); /** * drm_dp_mst_get_edid() - get EDID for an MST port * @connector: toplevel connector to get EDID for Loading include/drm/drm_dp_mst_helper.h +42 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <drm/drm_atomic.h> struct drm_dp_mst_branch; struct drm_dp_mst_port; /** * struct drm_dp_vcpi - Virtual Channel Payload Identifier Loading @@ -42,6 +43,18 @@ struct drm_dp_vcpi { int num_slots; }; struct drm_dp_mst_dsc_dpcd_cache { bool valid; bool use_parent_dpcd; u8 dsc_dpcd[16]; }; struct drm_dp_mst_dsc_info { bool dsc_support; struct drm_dp_mst_port *dsc_port; struct drm_dp_mst_dsc_dpcd_cache dsc_dpcd_cache; }; /** * struct drm_dp_mst_port - MST port * @kref: reference count for this port. Loading @@ -62,6 +75,8 @@ struct drm_dp_vcpi { * @vcpi: Virtual Channel Payload info for this port. * @connector: DRM connector this port is connected to. * @mgr: topology manager this port lives under. * @fec_capability: Tracks full path fec capability. * @dsc_info: stores dpcd and configuration information. * * This structure represents an MST port endpoint on a device somewhere * in the MST topology. Loading Loading @@ -98,6 +113,16 @@ struct drm_dp_mst_port { * audio-capable. */ bool has_audio; /** * @fec_capability: Tracks full path fec capability as reported by * enum path resources. */ bool fec_capability; /** * @dsc_info: stores dpcd and configuration information for the mst * port where dsc decoding will be enabled. */ struct drm_dp_mst_dsc_info dsc_info; }; /** Loading Loading @@ -291,6 +316,7 @@ struct drm_dp_port_number_req { struct drm_dp_enum_path_resources_ack_reply { u8 port_number; bool fec_capability; u16 full_payload_bw_number; u16 avail_payload_bw_number; }; Loading Loading @@ -588,6 +614,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); bool drm_dp_mst_has_fec(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); Loading Loading @@ -634,6 +664,14 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, bool power_up); int drm_dp_mst_get_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info); int drm_dp_mst_update_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info); int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int offset, int size, u8 *bytes); Loading @@ -642,4 +680,8 @@ int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int offset, int size, u8 *bytes); int drm_dp_mst_get_max_sdp_streams_supported( struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); #endif Loading
drivers/gpu/drm/drm_dp_mst_topology.c +73 −2 Original line number Diff line number Diff line Loading @@ -486,6 +486,7 @@ static bool drm_dp_sideband_parse_enum_path_resources_ack(struct drm_dp_sideband { int idx = 1; repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf; repmsg->u.path_resources.fec_capability = (raw->msg[idx]) & 0x1; idx++; if (idx > raw->curlen) goto fail_len; Loading Loading @@ -1693,9 +1694,14 @@ static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, else { if (port->port_num != txmsg->reply.u.path_resources.port_number) DRM_ERROR("got incorrect port in response\n"); DRM_DEBUG_KMS("enum path resources %d: %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.full_payload_bw_number, DRM_DEBUG_KMS("enum path resources %d: %d %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.fec_capability, 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; port->fec_capability = txmsg->reply.u.path_resources.fec_capability; } } Loading Loading @@ -1850,6 +1856,42 @@ static int drm_dp_send_clear_payload_table(struct drm_dp_mst_topology_mgr *mgr, return ret; } int drm_dp_mst_get_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info) { if (!dsc_info) return -EINVAL; port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return -EINVAL; memcpy(dsc_info, &port->dsc_info, sizeof(struct drm_dp_mst_dsc_info)); drm_dp_put_port(port); return 0; } EXPORT_SYMBOL(drm_dp_mst_get_dsc_info); int drm_dp_mst_update_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info) { if (!dsc_info) return -EINVAL; port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return -EINVAL; memcpy(&port->dsc_info, dsc_info, sizeof(struct drm_dp_mst_dsc_info)); drm_dp_put_port(port); return 0; } EXPORT_SYMBOL(drm_dp_mst_update_dsc_info); static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr, int id, struct drm_dp_payload *payload) Loading Loading @@ -2122,6 +2164,21 @@ int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, } EXPORT_SYMBOL(drm_dp_send_dpcd_write); int drm_dp_mst_get_max_sdp_streams_supported( struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) { int ret = -1; port = drm_dp_get_validated_port_ref(mgr, port); if (!port) return ret; ret = port->num_sdp_streams; drm_dp_put_port(port); return ret; } EXPORT_SYMBOL(drm_dp_mst_get_max_sdp_streams_supported); static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req_type) { struct drm_dp_sideband_msg_reply_body reply; Loading Loading @@ -2639,6 +2696,20 @@ bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, } EXPORT_SYMBOL(drm_dp_mst_port_has_audio); bool drm_dp_mst_has_fec(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->fec_capability; drm_dp_put_port(port); return ret; } EXPORT_SYMBOL(drm_dp_mst_has_fec); /** * drm_dp_mst_get_edid() - get EDID for an MST port * @connector: toplevel connector to get EDID for Loading
include/drm/drm_dp_mst_helper.h +42 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <drm/drm_atomic.h> struct drm_dp_mst_branch; struct drm_dp_mst_port; /** * struct drm_dp_vcpi - Virtual Channel Payload Identifier Loading @@ -42,6 +43,18 @@ struct drm_dp_vcpi { int num_slots; }; struct drm_dp_mst_dsc_dpcd_cache { bool valid; bool use_parent_dpcd; u8 dsc_dpcd[16]; }; struct drm_dp_mst_dsc_info { bool dsc_support; struct drm_dp_mst_port *dsc_port; struct drm_dp_mst_dsc_dpcd_cache dsc_dpcd_cache; }; /** * struct drm_dp_mst_port - MST port * @kref: reference count for this port. Loading @@ -62,6 +75,8 @@ struct drm_dp_vcpi { * @vcpi: Virtual Channel Payload info for this port. * @connector: DRM connector this port is connected to. * @mgr: topology manager this port lives under. * @fec_capability: Tracks full path fec capability. * @dsc_info: stores dpcd and configuration information. * * This structure represents an MST port endpoint on a device somewhere * in the MST topology. Loading Loading @@ -98,6 +113,16 @@ struct drm_dp_mst_port { * audio-capable. */ bool has_audio; /** * @fec_capability: Tracks full path fec capability as reported by * enum path resources. */ bool fec_capability; /** * @dsc_info: stores dpcd and configuration information for the mst * port where dsc decoding will be enabled. */ struct drm_dp_mst_dsc_info dsc_info; }; /** Loading Loading @@ -291,6 +316,7 @@ struct drm_dp_port_number_req { struct drm_dp_enum_path_resources_ack_reply { u8 port_number; bool fec_capability; u16 full_payload_bw_number; u16 avail_payload_bw_number; }; Loading Loading @@ -588,6 +614,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); bool drm_dp_mst_has_fec(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); Loading Loading @@ -634,6 +664,14 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, bool power_up); int drm_dp_mst_get_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info); int drm_dp_mst_update_dsc_info(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, struct drm_dp_mst_dsc_info *dsc_info); int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int offset, int size, u8 *bytes); Loading @@ -642,4 +680,8 @@ int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int offset, int size, u8 *bytes); int drm_dp_mst_get_max_sdp_streams_supported( struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); #endif