@@ -1599,7 +1599,6 @@ static int vmw_kms_check_implicit(struct drm_device *dev,
1599
1599
static int vmw_kms_check_topology (struct drm_device * dev ,
1600
1600
struct drm_atomic_state * state )
1601
1601
{
1602
- struct vmw_private * dev_priv = vmw_priv (dev );
1603
1602
struct drm_crtc_state * old_crtc_state , * new_crtc_state ;
1604
1603
struct drm_rect * rects ;
1605
1604
struct drm_crtc * crtc ;
@@ -1611,19 +1610,31 @@ static int vmw_kms_check_topology(struct drm_device *dev,
1611
1610
if (!rects )
1612
1611
return - ENOMEM ;
1613
1612
1614
- mutex_lock (& dev_priv -> requested_layout_mutex );
1615
-
1616
1613
drm_for_each_crtc (crtc , dev ) {
1617
1614
struct vmw_display_unit * du = vmw_crtc_to_du (crtc );
1618
- struct drm_crtc_state * crtc_state = crtc -> state ;
1615
+ struct drm_crtc_state * crtc_state ;
1619
1616
1620
1617
i = drm_crtc_index (crtc );
1621
1618
1622
- if (crtc_state && crtc_state -> enable ) {
1619
+ crtc_state = vmw_crtc_state_and_lock (state , crtc );
1620
+ if (IS_ERR (crtc_state )) {
1621
+ ret = PTR_ERR (crtc_state );
1622
+ goto clean ;
1623
+ }
1624
+
1625
+ if (!crtc_state )
1626
+ continue ;
1627
+
1628
+ if (crtc_state -> enable ) {
1623
1629
rects [i ].x1 = du -> gui_x ;
1624
1630
rects [i ].y1 = du -> gui_y ;
1625
1631
rects [i ].x2 = du -> gui_x + crtc_state -> mode .hdisplay ;
1626
1632
rects [i ].y2 = du -> gui_y + crtc_state -> mode .vdisplay ;
1633
+ } else {
1634
+ rects [i ].x1 = 0 ;
1635
+ rects [i ].y1 = 0 ;
1636
+ rects [i ].x2 = 0 ;
1637
+ rects [i ].y2 = 0 ;
1627
1638
}
1628
1639
}
1629
1640
@@ -1635,14 +1646,6 @@ static int vmw_kms_check_topology(struct drm_device *dev,
1635
1646
struct drm_connector_state * conn_state ;
1636
1647
struct vmw_connector_state * vmw_conn_state ;
1637
1648
1638
- if (!new_crtc_state -> enable ) {
1639
- rects [i ].x1 = 0 ;
1640
- rects [i ].y1 = 0 ;
1641
- rects [i ].x2 = 0 ;
1642
- rects [i ].y2 = 0 ;
1643
- continue ;
1644
- }
1645
-
1646
1649
if (!du -> pref_active ) {
1647
1650
ret = - EINVAL ;
1648
1651
goto clean ;
@@ -1663,18 +1666,12 @@ static int vmw_kms_check_topology(struct drm_device *dev,
1663
1666
vmw_conn_state = vmw_connector_state_to_vcs (conn_state );
1664
1667
vmw_conn_state -> gui_x = du -> gui_x ;
1665
1668
vmw_conn_state -> gui_y = du -> gui_y ;
1666
-
1667
- rects [i ].x1 = du -> gui_x ;
1668
- rects [i ].y1 = du -> gui_y ;
1669
- rects [i ].x2 = du -> gui_x + new_crtc_state -> mode .hdisplay ;
1670
- rects [i ].y2 = du -> gui_y + new_crtc_state -> mode .vdisplay ;
1671
1669
}
1672
1670
1673
1671
ret = vmw_kms_check_display_memory (dev , dev -> mode_config .num_crtc ,
1674
1672
rects );
1675
1673
1676
1674
clean :
1677
- mutex_unlock (& dev_priv -> requested_layout_mutex );
1678
1675
kfree (rects );
1679
1676
return ret ;
1680
1677
}
@@ -2031,11 +2028,25 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
2031
2028
struct vmw_display_unit * du ;
2032
2029
struct drm_connector * con ;
2033
2030
struct drm_connector_list_iter conn_iter ;
2031
+ struct drm_modeset_acquire_ctx ctx ;
2032
+ struct drm_crtc * crtc ;
2033
+ int ret ;
2034
+
2035
+ /* Currently gui_x/y is protected with the crtc mutex */
2036
+ mutex_lock (& dev -> mode_config .mutex );
2037
+ drm_modeset_acquire_init (& ctx , 0 );
2038
+ retry :
2039
+ drm_for_each_crtc (crtc , dev ) {
2040
+ ret = drm_modeset_lock (& crtc -> mutex , & ctx );
2041
+ if (ret < 0 ) {
2042
+ if (ret == - EDEADLK ) {
2043
+ drm_modeset_backoff (& ctx );
2044
+ goto retry ;
2045
+ }
2046
+ goto out_fini ;
2047
+ }
2048
+ }
2034
2049
2035
- /*
2036
- * Currently only gui_x/y is protected with requested_layout_mutex.
2037
- */
2038
- mutex_lock (& dev_priv -> requested_layout_mutex );
2039
2050
drm_connector_list_iter_begin (dev , & conn_iter );
2040
2051
drm_for_each_connector_iter (con , & conn_iter ) {
2041
2052
du = vmw_connector_to_du (con );
@@ -2054,9 +2065,7 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
2054
2065
}
2055
2066
}
2056
2067
drm_connector_list_iter_end (& conn_iter );
2057
- mutex_unlock (& dev_priv -> requested_layout_mutex );
2058
2068
2059
- mutex_lock (& dev -> mode_config .mutex );
2060
2069
list_for_each_entry (con , & dev -> mode_config .connector_list , head ) {
2061
2070
du = vmw_connector_to_du (con );
2062
2071
if (num_rects > du -> unit ) {
@@ -2076,10 +2085,13 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
2076
2085
}
2077
2086
con -> status = vmw_du_connector_detect (con , true);
2078
2087
}
2079
- mutex_unlock (& dev -> mode_config .mutex );
2080
2088
2081
2089
drm_sysfs_hotplug_event (dev );
2082
-
2090
+ out_fini :
2091
+ drm_modeset_drop_locks (& ctx );
2092
+ drm_modeset_acquire_fini (& ctx );
2093
+ mutex_unlock (& dev -> mode_config .mutex );
2094
+
2083
2095
return 0 ;
2084
2096
}
2085
2097
0 commit comments