Commit 70a09f36 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'vmwgfx-next-160316' of git://people.freedesktop.org/~thomash/linux into drm-next

Pull request of 2016-03-16

* tag 'vmwgfx-next-160316' of git://people.freedesktop.org/~thomash/linux:
  drm/vmwgfx: Bump driver minor
  drm/vmwgfx: Allow the UPDATE_LAYOUT ioctl from control nodes
  drm/vmwgfx: Send a hotplug event at master_set
  drm/vmwgfx: Default to explicit crtc placement for screen targets and screen objects
  drm/vmwgfx: Calculate the cursor position based on the crtc gui origin
  drm/vmwgfx: Add connector properties to switch between explicit and implicit placement
  drm/vmwgfx: Add suggested screen x and y connector properties
  drm/vmwgfx: Add implicit framebuffer checks to the screen target code
  drm/vmwgfx: Break out implicit fb code
  drm/vmwgfx: Rework screen target page flips v2
  drm/vmwgfx: Fix screen object page flips for large framebuffers
  drm/vmwgfx: Fix a screen object framebuffer dirty corner case
  drm/vmwgfx: Add DXGenMips support
parents 189df01d 5476aa46
......@@ -195,7 +195,7 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
DRM_MASTER | DRM_AUTH),
VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT,
vmw_kms_update_layout_ioctl,
DRM_MASTER),
DRM_MASTER | DRM_CONTROL_ALLOW),
VMW_IOCTL_DEF(VMW_CREATE_SHADER,
vmw_shader_define_ioctl,
DRM_AUTH | DRM_RENDER_ALLOW),
......@@ -1204,6 +1204,7 @@ static int vmw_master_set(struct drm_device *dev,
}
dev_priv->active_master = vmaster;
drm_sysfs_hotplug_event(dev);
return 0;
}
......
......@@ -40,9 +40,9 @@
#include <drm/ttm/ttm_module.h>
#include "vmwgfx_fence.h"
#define VMWGFX_DRIVER_DATE "20150810"
#define VMWGFX_DRIVER_DATE "20160210"
#define VMWGFX_DRIVER_MAJOR 2
#define VMWGFX_DRIVER_MINOR 9
#define VMWGFX_DRIVER_MINOR 10
#define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
......@@ -407,8 +407,11 @@ struct vmw_private {
void *fb_info;
enum vmw_display_unit_type active_display_unit;
struct vmw_legacy_display *ldu_priv;
struct vmw_screen_object_display *sou_priv;
struct vmw_overlay *overlay_priv;
struct drm_property *hotplug_mode_update_property;
struct drm_property *implicit_placement_property;
unsigned num_implicit;
struct vmw_framebuffer *implicit_fb;
/*
* Context and surface management.
......
......@@ -3009,6 +3009,26 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv,
return ret;
}
/**
* vmw_cmd_dx_genmips - Validate an SVGA_3D_CMD_DX_GENMIPS command
*
* @dev_priv: Pointer to a device private struct.
* @sw_context: The software context being used for this batch.
* @header: Pointer to the command header in the command stream.
*/
static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
SVGA3dCmdHeader *header)
{
struct {
SVGA3dCmdHeader header;
SVGA3dCmdDXGenMips body;
} *cmd = container_of(header, typeof(*cmd), header);
return vmw_view_id_val_add(sw_context, vmw_view_sr,
cmd->body.shaderResourceViewId);
}
static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
void *buf, uint32_t *size)
......@@ -3297,7 +3317,7 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
&vmw_cmd_dx_clear_depthstencil_view, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_PRED_COPY, &vmw_cmd_invalid,
true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_GENMIPS, &vmw_cmd_invalid,
VMW_CMD_DEF(SVGA_3D_CMD_DX_GENMIPS, &vmw_cmd_dx_genmips,
true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE,
&vmw_cmd_dx_check_subresource, true, false, true),
......
......@@ -236,8 +236,8 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
bool shown = du->cursor_surface || du->cursor_dmabuf ? true : false;
du->cursor_x = x + crtc->x;
du->cursor_y = y + crtc->y;
du->cursor_x = x + du->set_gui_x;
du->cursor_y = y + du->set_gui_y;
/*
* FIXME: Unclear whether there's any global state touched by the
......@@ -663,9 +663,8 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
break;
case vmw_du_screen_object:
ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base,
clips, num_clips, increment,
true,
NULL);
clips, NULL, num_clips,
increment, true, NULL);
break;
case vmw_du_legacy:
ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0,
......@@ -1109,6 +1108,22 @@ int vmw_kms_present(struct vmw_private *dev_priv,
return 0;
}
static void
vmw_kms_create_hotplug_mode_update_property(struct vmw_private *dev_priv)
{
if (dev_priv->hotplug_mode_update_property)
return;
dev_priv->hotplug_mode_update_property =
drm_property_create_range(dev_priv->dev,
DRM_MODE_PROP_IMMUTABLE,
"hotplug_mode_update", 0, 1);
if (!dev_priv->hotplug_mode_update_property)
return;
}
int vmw_kms_init(struct vmw_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
......@@ -1121,6 +1136,9 @@ int vmw_kms_init(struct vmw_private *dev_priv)
dev->mode_config.max_width = dev_priv->texture_max_width;
dev->mode_config.max_height = dev_priv->texture_max_height;
drm_mode_create_suggested_offset_properties(dev);
vmw_kms_create_hotplug_mode_update_property(dev_priv);
ret = vmw_kms_stdu_init_display(dev_priv);
if (ret) {
ret = vmw_kms_sou_init_display(dev_priv);
......@@ -1360,15 +1378,28 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
du->pref_active = true;
du->gui_x = rects[du->unit].x;
du->gui_y = rects[du->unit].y;
drm_object_property_set_value
(&con->base, dev->mode_config.suggested_x_property,
du->gui_x);
drm_object_property_set_value
(&con->base, dev->mode_config.suggested_y_property,
du->gui_y);
} else {
du->pref_width = 800;
du->pref_height = 600;
du->pref_active = false;
drm_object_property_set_value
(&con->base, dev->mode_config.suggested_x_property,
0);
drm_object_property_set_value
(&con->base, dev->mode_config.suggested_y_property,
0);
}
con->status = vmw_du_connector_detect(con, true);
}
mutex_unlock(&dev->mode_config.mutex);
drm_sysfs_hotplug_event(dev);
return 0;
}
......@@ -1591,6 +1622,12 @@ int vmw_du_connector_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t val)
{
struct vmw_display_unit *du = vmw_connector_to_du(connector);
struct vmw_private *dev_priv = vmw_priv(connector->dev);
if (property == dev_priv->implicit_placement_property)
du->is_implicit = val;
return 0;
}
......@@ -2096,3 +2133,119 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
return 0;
}
/**
* vmw_kms_del_active - unregister a crtc binding to the implicit framebuffer
*
* @dev_priv: Pointer to a device private struct.
* @du: The display unit of the crtc.
*/
void vmw_kms_del_active(struct vmw_private *dev_priv,
struct vmw_display_unit *du)
{
lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
if (du->active_implicit) {
if (--(dev_priv->num_implicit) == 0)
dev_priv->implicit_fb = NULL;
du->active_implicit = false;
}
}
/**
* vmw_kms_add_active - register a crtc binding to an implicit framebuffer
*
* @vmw_priv: Pointer to a device private struct.
* @du: The display unit of the crtc.
* @vfb: The implicit framebuffer
*
* Registers a binding to an implicit framebuffer.
*/
void vmw_kms_add_active(struct vmw_private *dev_priv,
struct vmw_display_unit *du,
struct vmw_framebuffer *vfb)
{
lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
WARN_ON_ONCE(!dev_priv->num_implicit && dev_priv->implicit_fb);
if (!du->active_implicit && du->is_implicit) {
dev_priv->implicit_fb = vfb;
du->active_implicit = true;
dev_priv->num_implicit++;
}
}
/**
* vmw_kms_screen_object_flippable - Check whether we can page-flip a crtc.
*
* @dev_priv: Pointer to device-private struct.
* @crtc: The crtc we want to flip.
*
* Returns true or false depending whether it's OK to flip this crtc
* based on the criterion that we must not have more than one implicit
* frame-buffer at any one time.
*/
bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv,
struct drm_crtc *crtc)
{
struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
if (!du->is_implicit)
return true;
if (dev_priv->num_implicit != 1)
return false;
return true;
}
/**
* vmw_kms_update_implicit_fb - Update the implicit fb.
*
* @dev_priv: Pointer to device-private struct.
* @crtc: The crtc the new implicit frame-buffer is bound to.
*/
void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv,
struct drm_crtc *crtc)
{
struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
struct vmw_framebuffer *vfb;
lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
if (!du->is_implicit)
return;
vfb = vmw_framebuffer_to_vfb(crtc->primary->fb);
WARN_ON_ONCE(dev_priv->num_implicit != 1 &&
dev_priv->implicit_fb != vfb);
dev_priv->implicit_fb = vfb;
}
/**
* vmw_kms_create_implicit_placement_proparty - Set up the implicit placement
* property.
*
* @dev_priv: Pointer to a device private struct.
* @immutable: Whether the property is immutable.
*
* Sets up the implicit placement property unless it's already set up.
*/
void
vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv,
bool immutable)
{
if (dev_priv->implicit_placement_property)
return;
dev_priv->implicit_placement_property =
drm_property_create_range(dev_priv->dev,
immutable ?
DRM_MODE_PROP_IMMUTABLE : 0,
"implicit_placement", 0, 1);
}
......@@ -178,6 +178,9 @@ struct vmw_display_unit {
int gui_x;
int gui_y;
bool is_implicit;
bool active_implicit;
int set_gui_x;
int set_gui_y;
};
#define vmw_crtc_to_du(x) \
......@@ -254,6 +257,18 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
struct drm_crtc **p_crtc,
struct drm_display_mode **p_mode);
void vmw_guess_mode_timing(struct drm_display_mode *mode);
void vmw_kms_del_active(struct vmw_private *dev_priv,
struct vmw_display_unit *du);
void vmw_kms_add_active(struct vmw_private *dev_priv,
struct vmw_display_unit *du,
struct vmw_framebuffer *vfb);
bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv,
struct drm_crtc *crtc);
void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv,
struct drm_crtc *crtc);
void vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv,
bool immutable);
/*
* Legacy display unit functions - vmwgfx_ldu.c
......@@ -287,6 +302,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips,
struct drm_vmw_rect *vclips,
unsigned num_clips, int increment,
bool interruptible,
struct vmw_fence_obj **out_fence);
......
......@@ -288,6 +288,8 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
crtc->y = set->y;
crtc->mode = *mode;
crtc->enabled = true;
ldu->base.set_gui_x = set->x;
ldu->base.set_gui_y = set->y;
vmw_ldu_add_active(dev_priv, ldu, vfb);
......@@ -375,8 +377,19 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
drm_mode_crtc_set_gamma_size(crtc, 256);
drm_object_attach_property(&connector->base,
dev->mode_config.dirty_info_property,
1);
dev->mode_config.dirty_info_property,
1);
drm_object_attach_property(&connector->base,
dev_priv->hotplug_mode_update_property, 1);
drm_object_attach_property(&connector->base,
dev->mode_config.suggested_x_property, 0);
drm_object_attach_property(&connector->base,
dev->mode_config.suggested_y_property, 0);
if (dev_priv->implicit_placement_property)
drm_object_attach_property
(&connector->base,
dev_priv->implicit_placement_property,
1);
return 0;
}
......@@ -412,6 +425,8 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv)
if (ret != 0)
goto err_vblank_cleanup;
vmw_kms_create_implicit_placement_property(dev_priv, true);
if (dev_priv->capabilities & SVGA_CAP_MULTIMON)
for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i)
vmw_ldu_init(dev_priv, i);
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment