@@ -1916,73 +1916,90 @@ static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
19161916 return parent_lct + 1 ;
19171917}
19181918
1919- static int drm_dp_port_set_pdt (struct drm_dp_mst_port * port , u8 new_pdt )
1919+ static bool drm_dp_mst_is_dp_mst_end_device (u8 pdt , bool mcs )
1920+ {
1921+ switch (pdt ) {
1922+ case DP_PEER_DEVICE_DP_LEGACY_CONV :
1923+ case DP_PEER_DEVICE_SST_SINK :
1924+ return true;
1925+ case DP_PEER_DEVICE_MST_BRANCHING :
1926+ /* For sst branch device */
1927+ if (!mcs )
1928+ return true;
1929+
1930+ return false;
1931+ }
1932+ return true;
1933+ }
1934+
1935+ static int
1936+ drm_dp_port_set_pdt (struct drm_dp_mst_port * port , u8 new_pdt ,
1937+ bool new_mcs )
19201938{
19211939 struct drm_dp_mst_topology_mgr * mgr = port -> mgr ;
19221940 struct drm_dp_mst_branch * mstb ;
19231941 u8 rad [8 ], lct ;
19241942 int ret = 0 ;
19251943
1926- if (port -> pdt == new_pdt )
1944+ if (port -> pdt == new_pdt && port -> mcs == new_mcs )
19271945 return 0 ;
19281946
19291947 /* Teardown the old pdt, if there is one */
1930- switch (port -> pdt ) {
1931- case DP_PEER_DEVICE_DP_LEGACY_CONV :
1932- case DP_PEER_DEVICE_SST_SINK :
1933- /*
1934- * If the new PDT would also have an i2c bus, don't bother
1935- * with reregistering it
1936- */
1937- if (new_pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
1938- new_pdt == DP_PEER_DEVICE_SST_SINK ) {
1939- port -> pdt = new_pdt ;
1940- return 0 ;
1941- }
1948+ if (port -> pdt != DP_PEER_DEVICE_NONE ) {
1949+ if ( drm_dp_mst_is_dp_mst_end_device ( port -> pdt , port -> mcs )) {
1950+ /*
1951+ * If the new PDT would also have an i2c bus,
1952+ * don't bother with reregistering it
1953+ */
1954+ if ( new_pdt != DP_PEER_DEVICE_NONE &&
1955+ drm_dp_mst_is_dp_mst_end_device (new_pdt , new_mcs )) {
1956+ port -> pdt = new_pdt ;
1957+ port -> mcs = new_mcs ;
1958+ return 0 ;
1959+ }
19421960
1943- /* remove i2c over sideband */
1944- drm_dp_mst_unregister_i2c_bus (& port -> aux );
1945- break ;
1946- case DP_PEER_DEVICE_MST_BRANCHING :
1947- mutex_lock (& mgr -> lock );
1948- drm_dp_mst_topology_put_mstb (port -> mstb );
1949- port -> mstb = NULL ;
1950- mutex_unlock (& mgr -> lock );
1951- break ;
1961+ /* remove i2c over sideband */
1962+ drm_dp_mst_unregister_i2c_bus (& port -> aux );
1963+ } else {
1964+ mutex_lock (& mgr -> lock );
1965+ drm_dp_mst_topology_put_mstb (port -> mstb );
1966+ port -> mstb = NULL ;
1967+ mutex_unlock (& mgr -> lock );
1968+ }
19521969 }
19531970
19541971 port -> pdt = new_pdt ;
1955- switch (port -> pdt ) {
1956- case DP_PEER_DEVICE_DP_LEGACY_CONV :
1957- case DP_PEER_DEVICE_SST_SINK :
1958- /* add i2c over sideband */
1959- ret = drm_dp_mst_register_i2c_bus (& port -> aux );
1960- break ;
1972+ port -> mcs = new_mcs ;
19611973
1962- case DP_PEER_DEVICE_MST_BRANCHING :
1963- lct = drm_dp_calculate_rad (port , rad );
1964- mstb = drm_dp_add_mst_branch_device (lct , rad );
1965- if (!mstb ) {
1966- ret = - ENOMEM ;
1967- DRM_ERROR ("Failed to create MSTB for port %p" , port );
1968- goto out ;
1969- }
1974+ if (port -> pdt != DP_PEER_DEVICE_NONE ) {
1975+ if (drm_dp_mst_is_dp_mst_end_device (port -> pdt , port -> mcs )) {
1976+ /* add i2c over sideband */
1977+ ret = drm_dp_mst_register_i2c_bus (& port -> aux );
1978+ } else {
1979+ lct = drm_dp_calculate_rad (port , rad );
1980+ mstb = drm_dp_add_mst_branch_device (lct , rad );
1981+ if (!mstb ) {
1982+ ret = - ENOMEM ;
1983+ DRM_ERROR ("Failed to create MSTB for port %p" ,
1984+ port );
1985+ goto out ;
1986+ }
19701987
1971- mutex_lock (& mgr -> lock );
1972- port -> mstb = mstb ;
1973- mstb -> mgr = port -> mgr ;
1974- mstb -> port_parent = port ;
1988+ mutex_lock (& mgr -> lock );
1989+ port -> mstb = mstb ;
1990+ mstb -> mgr = port -> mgr ;
1991+ mstb -> port_parent = port ;
19751992
1976- /*
1977- * Make sure this port's memory allocation stays
1978- * around until its child MSTB releases it
1979- */
1980- drm_dp_mst_get_port_malloc (port );
1981- mutex_unlock (& mgr -> lock );
1993+ /*
1994+ * Make sure this port's memory allocation stays
1995+ * around until its child MSTB releases it
1996+ */
1997+ drm_dp_mst_get_port_malloc (port );
1998+ mutex_unlock (& mgr -> lock );
19821999
1983- /* And make sure we send a link address for this */
1984- ret = 1 ;
1985- break ;
2000+ /* And make sure we send a link address for this */
2001+ ret = 1 ;
2002+ }
19862003 }
19872004
19882005out :
@@ -2135,9 +2152,8 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb,
21352152 goto error ;
21362153 }
21372154
2138- if ((port -> pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
2139- port -> pdt == DP_PEER_DEVICE_SST_SINK ) &&
2140- port -> port_num >= DP_MST_LOGICAL_PORT_0 ) {
2155+ if (port -> pdt != DP_PEER_DEVICE_NONE &&
2156+ drm_dp_mst_is_dp_mst_end_device (port -> pdt , port -> mcs )) {
21412157 port -> cached_edid = drm_get_edid (port -> connector ,
21422158 & port -> aux .ddc );
21432159 drm_connector_set_tile_property (port -> connector );
@@ -2201,6 +2217,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
22012217 struct drm_dp_mst_port * port ;
22022218 int old_ddps = 0 , ret ;
22032219 u8 new_pdt = DP_PEER_DEVICE_NONE ;
2220+ bool new_mcs = 0 ;
22042221 bool created = false, send_link_addr = false, changed = false;
22052222
22062223 port = drm_dp_get_port (mstb , port_msg -> port_number );
@@ -2245,7 +2262,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
22452262 port -> input = port_msg -> input_port ;
22462263 if (!port -> input )
22472264 new_pdt = port_msg -> peer_device_type ;
2248- port -> mcs = port_msg -> mcs ;
2265+ new_mcs = port_msg -> mcs ;
22492266 port -> ddps = port_msg -> ddps ;
22502267 port -> ldps = port_msg -> legacy_device_plug_status ;
22512268 port -> dpcd_rev = port_msg -> dpcd_revision ;
@@ -2272,7 +2289,7 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
22722289 }
22732290 }
22742291
2275- ret = drm_dp_port_set_pdt (port , new_pdt );
2292+ ret = drm_dp_port_set_pdt (port , new_pdt , new_mcs );
22762293 if (ret == 1 ) {
22772294 send_link_addr = true;
22782295 } else if (ret < 0 ) {
@@ -2286,7 +2303,8 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
22862303 * we're coming out of suspend. In this case, always resend the link
22872304 * address if there's an MSTB on this port
22882305 */
2289- if (!created && port -> pdt == DP_PEER_DEVICE_MST_BRANCHING )
2306+ if (!created && port -> pdt == DP_PEER_DEVICE_MST_BRANCHING &&
2307+ port -> mcs )
22902308 send_link_addr = true;
22912309
22922310 if (port -> connector )
@@ -2323,6 +2341,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
23232341 struct drm_dp_mst_port * port ;
23242342 int old_ddps , old_input , ret , i ;
23252343 u8 new_pdt ;
2344+ bool new_mcs ;
23262345 bool dowork = false, create_connector = false;
23272346
23282347 port = drm_dp_get_port (mstb , conn_stat -> port_number );
@@ -2354,7 +2373,6 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
23542373 old_ddps = port -> ddps ;
23552374 old_input = port -> input ;
23562375 port -> input = conn_stat -> input_port ;
2357- port -> mcs = conn_stat -> message_capability_status ;
23582376 port -> ldps = conn_stat -> legacy_device_plug_status ;
23592377 port -> ddps = conn_stat -> displayport_device_plug_status ;
23602378
@@ -2367,8 +2385,8 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
23672385 }
23682386
23692387 new_pdt = port -> input ? DP_PEER_DEVICE_NONE : conn_stat -> peer_device_type ;
2370-
2371- ret = drm_dp_port_set_pdt (port , new_pdt );
2388+ new_mcs = conn_stat -> message_capability_status ;
2389+ ret = drm_dp_port_set_pdt (port , new_pdt , new_mcs );
23722390 if (ret == 1 ) {
23732391 dowork = true;
23742392 } else if (ret < 0 ) {
@@ -3929,6 +3947,8 @@ drm_dp_mst_detect_port(struct drm_connector *connector,
39293947 switch (port -> pdt ) {
39303948 case DP_PEER_DEVICE_NONE :
39313949 case DP_PEER_DEVICE_MST_BRANCHING :
3950+ if (!port -> mcs )
3951+ ret = connector_status_connected ;
39323952 break ;
39333953
39343954 case DP_PEER_DEVICE_SST_SINK :
@@ -4541,7 +4561,7 @@ drm_dp_delayed_destroy_port(struct drm_dp_mst_port *port)
45414561 if (port -> connector )
45424562 port -> mgr -> cbs -> destroy_connector (port -> mgr , port -> connector );
45434563
4544- drm_dp_port_set_pdt (port , DP_PEER_DEVICE_NONE );
4564+ drm_dp_port_set_pdt (port , DP_PEER_DEVICE_NONE , port -> mcs );
45454565 drm_dp_mst_put_port_malloc (port );
45464566}
45474567
0 commit comments