aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h9
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c66
3 files changed, 39 insertions, 37 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index b9c078860a7c..9fd8b4e75a8c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -665,7 +665,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
665 mutex_init(&dev_priv->cmdbuf_mutex); 665 mutex_init(&dev_priv->cmdbuf_mutex);
666 mutex_init(&dev_priv->release_mutex); 666 mutex_init(&dev_priv->release_mutex);
667 mutex_init(&dev_priv->binding_mutex); 667 mutex_init(&dev_priv->binding_mutex);
668 mutex_init(&dev_priv->requested_layout_mutex);
669 mutex_init(&dev_priv->global_kms_state_mutex); 668 mutex_init(&dev_priv->global_kms_state_mutex);
670 ttm_lock_init(&dev_priv->reservation_sem); 669 ttm_lock_init(&dev_priv->reservation_sem);
671 spin_lock_init(&dev_priv->resource_lock); 670 spin_lock_init(&dev_priv->resource_lock);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 5fbe47a52609..d7f6cb9331de 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -466,15 +466,6 @@ struct vmw_private {
466 uint32_t num_displays; 466 uint32_t num_displays;
467 467
468 /* 468 /*
469 * Currently requested_layout_mutex is used to protect the gui
470 * positionig state in display unit. With that use case currently this
471 * mutex is only taken during layout ioctl and atomic check_modeset.
472 * Other display unit state can be protected with this mutex but that
473 * needs careful consideration.
474 */
475 struct mutex requested_layout_mutex;
476
477 /*
478 * Framebuffer info. 469 * Framebuffer info.
479 */ 470 */
480 471
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 43ee7ccca418..b351fb5214d3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1599,7 +1599,6 @@ static int vmw_kms_check_implicit(struct drm_device *dev,
1599static int vmw_kms_check_topology(struct drm_device *dev, 1599static int vmw_kms_check_topology(struct drm_device *dev,
1600 struct drm_atomic_state *state) 1600 struct drm_atomic_state *state)
1601{ 1601{
1602 struct vmw_private *dev_priv = vmw_priv(dev);
1603 struct drm_crtc_state *old_crtc_state, *new_crtc_state; 1602 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1604 struct drm_rect *rects; 1603 struct drm_rect *rects;
1605 struct drm_crtc *crtc; 1604 struct drm_crtc *crtc;
@@ -1611,19 +1610,31 @@ static int vmw_kms_check_topology(struct drm_device *dev,
1611 if (!rects) 1610 if (!rects)
1612 return -ENOMEM; 1611 return -ENOMEM;
1613 1612
1614 mutex_lock(&dev_priv->requested_layout_mutex);
1615
1616 drm_for_each_crtc(crtc, dev) { 1613 drm_for_each_crtc(crtc, dev) {
1617 struct vmw_display_unit *du = vmw_crtc_to_du(crtc); 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 i = drm_crtc_index(crtc); 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 rects[i].x1 = du->gui_x; 1629 rects[i].x1 = du->gui_x;
1624 rects[i].y1 = du->gui_y; 1630 rects[i].y1 = du->gui_y;
1625 rects[i].x2 = du->gui_x + crtc_state->mode.hdisplay; 1631 rects[i].x2 = du->gui_x + crtc_state->mode.hdisplay;
1626 rects[i].y2 = du->gui_y + crtc_state->mode.vdisplay; 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 struct drm_connector_state *conn_state; 1646 struct drm_connector_state *conn_state;
1636 struct vmw_connector_state *vmw_conn_state; 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 if (!du->pref_active) { 1649 if (!du->pref_active) {
1647 ret = -EINVAL; 1650 ret = -EINVAL;
1648 goto clean; 1651 goto clean;
@@ -1663,18 +1666,12 @@ static int vmw_kms_check_topology(struct drm_device *dev,
1663 vmw_conn_state = vmw_connector_state_to_vcs(conn_state); 1666 vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
1664 vmw_conn_state->gui_x = du->gui_x; 1667 vmw_conn_state->gui_x = du->gui_x;
1665 vmw_conn_state->gui_y = du->gui_y; 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 ret = vmw_kms_check_display_memory(dev, dev->mode_config.num_crtc, 1671 ret = vmw_kms_check_display_memory(dev, dev->mode_config.num_crtc,
1674 rects); 1672 rects);
1675 1673
1676clean: 1674clean:
1677 mutex_unlock(&dev_priv->requested_layout_mutex);
1678 kfree(rects); 1675 kfree(rects);
1679 return ret; 1676 return ret;
1680} 1677}
@@ -2031,11 +2028,25 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
2031 struct vmw_display_unit *du; 2028 struct vmw_display_unit *du;
2032 struct drm_connector *con; 2029 struct drm_connector *con;
2033 struct drm_connector_list_iter conn_iter; 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);
2038retry:
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 drm_connector_list_iter_begin(dev, &conn_iter); 2050 drm_connector_list_iter_begin(dev, &conn_iter);
2040 drm_for_each_connector_iter(con, &conn_iter) { 2051 drm_for_each_connector_iter(con, &conn_iter) {
2041 du = vmw_connector_to_du(con); 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 drm_connector_list_iter_end(&conn_iter); 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 list_for_each_entry(con, &dev->mode_config.connector_list, head) { 2069 list_for_each_entry(con, &dev->mode_config.connector_list, head) {
2061 du = vmw_connector_to_du(con); 2070 du = vmw_connector_to_du(con);
2062 if (num_rects > du->unit) { 2071 if (num_rects > du->unit) {
@@ -2076,10 +2085,13 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
2076 } 2085 }
2077 con->status = vmw_du_connector_detect(con, true); 2086 con->status = vmw_du_connector_detect(con, true);
2078 } 2087 }
2079 mutex_unlock(&dev->mode_config.mutex);
2080 2088
2081 drm_sysfs_hotplug_event(dev); 2089 drm_sysfs_hotplug_event(dev);
2082 2090out_fini:
2091 drm_modeset_drop_locks(&ctx);
2092 drm_modeset_acquire_fini(&ctx);
2093 mutex_unlock(&dev->mode_config.mutex);
2094
2083 return 0; 2095 return 0;
2084} 2096}
2085 2097