diff options
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 66 |
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, | |||
| 1599 | static int vmw_kms_check_topology(struct drm_device *dev, | 1599 | static 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 | ||
| 1676 | clean: | 1674 | clean: |
| 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); | ||
| 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 | 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 | 2090 | out_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 | ||
