Commit 1f9a5dce authored by Dave Airlie's avatar Dave Airlie

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

Pull request of 2018-12-05

Page flip with damage by Deepak and others,
Various vmwgfx minor fixes anc cleanups.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Thomas Hellstrom <thellstrom@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181205103554.3675-1-thellstrom@vmware.com
parents fb878d10 9a01135b
...@@ -554,6 +554,18 @@ Plane Composition Properties ...@@ -554,6 +554,18 @@ Plane Composition Properties
.. kernel-doc:: drivers/gpu/drm/drm_blend.c .. kernel-doc:: drivers/gpu/drm/drm_blend.c
:export: :export:
FB_DAMAGE_CLIPS
~~~~~~~~~~~~~~~
.. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c
:doc: overview
.. kernel-doc:: drivers/gpu/drm/drm_damage_helper.c
:export:
.. kernel-doc:: include/drm/drm_damage_helper.h
:internal:
Color Management Properties Color Management Properties
--------------------------- ---------------------------
......
...@@ -4781,10 +4781,8 @@ T: git git://anongit.freedesktop.org/drm/drm-misc ...@@ -4781,10 +4781,8 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
DRM DRIVER FOR VMWARE VIRTUAL GPU DRM DRIVER FOR VMWARE VIRTUAL GPU
M: "VMware Graphics" <linux-graphics-maintainer@vmware.com> M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
M: Sinclair Yeh <syeh@vmware.com>
M: Thomas Hellstrom <thellstrom@vmware.com> M: Thomas Hellstrom <thellstrom@vmware.com>
L: dri-devel@lists.freedesktop.org L: dri-devel@lists.freedesktop.org
T: git git://people.freedesktop.org/~syeh/repos_linux
T: git git://people.freedesktop.org/~thomash/linux T: git git://people.freedesktop.org/~thomash/linux
S: Supported S: Supported
F: drivers/gpu/drm/vmwgfx/ F: drivers/gpu/drm/vmwgfx/
......
...@@ -37,7 +37,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper ...@@ -37,7 +37,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
drm_simple_kms_helper.o drm_modeset_helper.o \ drm_simple_kms_helper.o drm_modeset_helper.o \
drm_scdc_helper.o drm_gem_framebuffer_helper.o \ drm_scdc_helper.o drm_gem_framebuffer_helper.o \
drm_atomic_state_helper.o drm_atomic_state_helper.o drm_damage_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
......
...@@ -531,6 +531,8 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, ...@@ -531,6 +531,8 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
struct drm_crtc *crtc = new_plane_state->crtc; struct drm_crtc *crtc = new_plane_state->crtc;
const struct drm_framebuffer *fb = new_plane_state->fb; const struct drm_framebuffer *fb = new_plane_state->fb;
unsigned int fb_width, fb_height; unsigned int fb_width, fb_height;
struct drm_mode_rect *clips;
uint32_t num_clips;
int ret; int ret;
/* either *both* CRTC and FB must be set, or neither */ /* either *both* CRTC and FB must be set, or neither */
...@@ -604,6 +606,26 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, ...@@ -604,6 +606,26 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
return -ENOSPC; return -ENOSPC;
} }
clips = drm_plane_get_damage_clips(new_plane_state);
num_clips = drm_plane_get_damage_clips_count(new_plane_state);
/* Make sure damage clips are valid and inside the fb. */
while (num_clips > 0) {
if (clips->x1 >= clips->x2 ||
clips->y1 >= clips->y2 ||
clips->x1 < 0 ||
clips->y1 < 0 ||
clips->x2 > fb_width ||
clips->y2 > fb_height) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
plane->base.id, plane->name, clips->x1,
clips->y1, clips->x2, clips->y2);
return -EINVAL;
}
clips++;
num_clips--;
}
if (plane_switching_crtc(old_plane_state, new_plane_state)) { if (plane_switching_crtc(old_plane_state, new_plane_state)) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n", DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
plane->base.id, plane->name); plane->base.id, plane->name);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_writeback.h> #include <drm/drm_writeback.h>
#include <drm/drm_damage_helper.h>
#include <linux/dma-fence.h> #include <linux/dma-fence.h>
#include "drm_crtc_helper_internal.h" #include "drm_crtc_helper_internal.h"
...@@ -862,6 +863,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -862,6 +863,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane); drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane);
drm_atomic_helper_check_plane_damage(state, new_plane_state);
if (!funcs || !funcs->atomic_check) if (!funcs || !funcs->atomic_check)
continue; continue;
......
...@@ -517,6 +517,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, ...@@ -517,6 +517,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
{ {
struct drm_device *dev = plane->dev; struct drm_device *dev = plane->dev;
struct drm_mode_config *config = &dev->mode_config; struct drm_mode_config *config = &dev->mode_config;
bool replaced = false;
int ret;
if (property == config->prop_fb_id) { if (property == config->prop_fb_id) {
struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
...@@ -570,6 +572,14 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, ...@@ -570,6 +572,14 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
state->color_encoding = val; state->color_encoding = val;
} else if (property == plane->color_range_property) { } else if (property == plane->color_range_property) {
state->color_range = val; state->color_range = val;
} else if (property == config->prop_fb_damage_clips) {
ret = drm_atomic_replace_property_blob_from_id(dev,
&state->fb_damage_clips,
val,
-1,
sizeof(struct drm_rect),
&replaced);
return ret;
} else if (plane->funcs->atomic_set_property) { } else if (plane->funcs->atomic_set_property) {
return plane->funcs->atomic_set_property(plane, state, return plane->funcs->atomic_set_property(plane, state,
property, val); property, val);
...@@ -625,6 +635,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane, ...@@ -625,6 +635,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
*val = state->color_encoding; *val = state->color_encoding;
} else if (property == plane->color_range_property) { } else if (property == plane->color_range_property) {
*val = state->color_range; *val = state->color_range;
} else if (property == config->prop_fb_damage_clips) {
*val = (state->fb_damage_clips) ?
state->fb_damage_clips->base.id : 0;
} else if (plane->funcs->atomic_get_property) { } else if (plane->funcs->atomic_get_property) {
return plane->funcs->atomic_get_property(plane, state, property, val); return plane->funcs->atomic_get_property(plane, state, property, val);
} else { } else {
......
This diff is collapsed.
...@@ -297,6 +297,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) ...@@ -297,6 +297,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM; return -ENOMEM;
dev->mode_config.prop_crtc_id = prop; dev->mode_config.prop_crtc_id = prop;
prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "FB_DAMAGE_CLIPS",
0);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_fb_damage_clips = prop;
prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC, prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC,
"ACTIVE"); "ACTIVE");
if (!prop) if (!prop)
......
test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
test-drm_format.o test-drm_framebuffer.o test-drm_format.o test-drm_framebuffer.o \
test-drm_damage_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
...@@ -11,3 +11,24 @@ selftest(check_drm_format_block_width, igt_check_drm_format_block_width) ...@@ -11,3 +11,24 @@ selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
selftest(check_drm_format_block_height, igt_check_drm_format_block_height) selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch) selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create)
selftest(damage_iter_no_damage, igt_damage_iter_no_damage)
selftest(damage_iter_no_damage_fractional_src, igt_damage_iter_no_damage_fractional_src)
selftest(damage_iter_no_damage_src_moved, igt_damage_iter_no_damage_src_moved)
selftest(damage_iter_no_damage_fractional_src_moved, igt_damage_iter_no_damage_fractional_src_moved)
selftest(damage_iter_no_damage_not_visible, igt_damage_iter_no_damage_not_visible)
selftest(damage_iter_no_damage_no_crtc, igt_damage_iter_no_damage_no_crtc)
selftest(damage_iter_no_damage_no_fb, igt_damage_iter_no_damage_no_fb)
selftest(damage_iter_simple_damage, igt_damage_iter_simple_damage)
selftest(damage_iter_single_damage, igt_damage_iter_single_damage)
selftest(damage_iter_single_damage_intersect_src, igt_damage_iter_single_damage_intersect_src)
selftest(damage_iter_single_damage_outside_src, igt_damage_iter_single_damage_outside_src)
selftest(damage_iter_single_damage_fractional_src, igt_damage_iter_single_damage_fractional_src)
selftest(damage_iter_single_damage_intersect_fractional_src, igt_damage_iter_single_damage_intersect_fractional_src)
selftest(damage_iter_single_damage_outside_fractional_src, igt_damage_iter_single_damage_outside_fractional_src)
selftest(damage_iter_single_damage_src_moved, igt_damage_iter_single_damage_src_moved)
selftest(damage_iter_single_damage_fractional_src_moved, igt_damage_iter_single_damage_fractional_src_moved)
selftest(damage_iter_damage, igt_damage_iter_damage)
selftest(damage_iter_damage_one_intersect, igt_damage_iter_damage_one_intersect)
selftest(damage_iter_damage_one_outside, igt_damage_iter_damage_one_outside)
selftest(damage_iter_damage_src_moved, igt_damage_iter_damage_src_moved)
selftest(damage_iter_damage_not_visible, igt_damage_iter_damage_not_visible)
This diff is collapsed.
...@@ -18,5 +18,26 @@ int igt_check_drm_format_block_width(void *ignored); ...@@ -18,5 +18,26 @@ int igt_check_drm_format_block_width(void *ignored);
int igt_check_drm_format_block_height(void *ignored); int igt_check_drm_format_block_height(void *ignored);
int igt_check_drm_format_min_pitch(void *ignored); int igt_check_drm_format_min_pitch(void *ignored);
int igt_check_drm_framebuffer_create(void *ignored); int igt_check_drm_framebuffer_create(void *ignored);
int igt_damage_iter_no_damage(void *ignored);
int igt_damage_iter_no_damage_fractional_src(void *ignored);
int igt_damage_iter_no_damage_src_moved(void *ignored);
int igt_damage_iter_no_damage_fractional_src_moved(void *ignored);
int igt_damage_iter_no_damage_not_visible(void *ignored);
int igt_damage_iter_no_damage_no_crtc(void *ignored);
int igt_damage_iter_no_damage_no_fb(void *ignored);
int igt_damage_iter_simple_damage(void *ignored);
int igt_damage_iter_single_damage(void *ignored);
int igt_damage_iter_single_damage_intersect_src(void *ignored);
int igt_damage_iter_single_damage_outside_src(void *ignored);
int igt_damage_iter_single_damage_fractional_src(void *ignored);
int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored);
int igt_damage_iter_single_damage_outside_fractional_src(void *ignored);
int igt_damage_iter_single_damage_src_moved(void *ignored);
int igt_damage_iter_single_damage_fractional_src_moved(void *ignored);
int igt_damage_iter_damage(void *ignored);
int igt_damage_iter_damage_one_intersect(void *ignored);
int igt_damage_iter_damage_one_outside(void *ignored);
int igt_damage_iter_damage_src_moved(void *ignored);
int igt_damage_iter_damage_not_visible(void *ignored);
#endif #endif
...@@ -665,7 +665,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -665,7 +665,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
mutex_init(&dev_priv->cmdbuf_mutex); mutex_init(&dev_priv->cmdbuf_mutex);
mutex_init(&dev_priv->release_mutex); mutex_init(&dev_priv->release_mutex);
mutex_init(&dev_priv->binding_mutex); mutex_init(&dev_priv->binding_mutex);
mutex_init(&dev_priv->requested_layout_mutex);
mutex_init(&dev_priv->global_kms_state_mutex); mutex_init(&dev_priv->global_kms_state_mutex);
ttm_lock_init(&dev_priv->reservation_sem); ttm_lock_init(&dev_priv->reservation_sem);
spin_lock_init(&dev_priv->resource_lock); spin_lock_init(&dev_priv->resource_lock);
......
...@@ -465,15 +465,6 @@ struct vmw_private { ...@@ -465,15 +465,6 @@ struct vmw_private {
uint32_t num_displays; uint32_t num_displays;
/*
* Currently requested_layout_mutex is used to protect the gui
* positionig state in display unit. With that use case currently this
* mutex is only taken during layout ioctl and atomic check_modeset.
* Other display unit state can be protected with this mutex but that
* needs careful consideration.
*/
struct mutex requested_layout_mutex;
/* /*
* Framebuffer info. * Framebuffer info.
*/ */
...@@ -484,8 +475,6 @@ struct vmw_private { ...@@ -484,8 +475,6 @@ struct vmw_private {
struct vmw_overlay *overlay_priv; struct vmw_overlay *overlay_priv;
struct drm_property *hotplug_mode_update_property; struct drm_property *hotplug_mode_update_property;
struct drm_property *implicit_placement_property; struct drm_property *implicit_placement_property;
unsigned num_implicit;
struct vmw_framebuffer *implicit_fb;
struct mutex global_kms_state_mutex; struct mutex global_kms_state_mutex;
spinlock_t cursor_lock; spinlock_t cursor_lock;
struct drm_atomic_state *suspend_state; struct drm_atomic_state *suspend_state;
......
...@@ -1738,7 +1738,6 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv, ...@@ -1738,7 +1738,6 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
void *buf) void *buf)
{ {
struct vmw_buffer_object *vmw_bo; struct vmw_buffer_object *vmw_bo;
int ret;
struct { struct {
uint32_t header; uint32_t header;
...@@ -1748,7 +1747,6 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv, ...@@ -1748,7 +1747,6 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
return vmw_translate_guest_ptr(dev_priv, sw_context, return vmw_translate_guest_ptr(dev_priv, sw_context,
&cmd->body.ptr, &cmd->body.ptr,
&vmw_bo); &vmw_bo);
return ret;
} }
......
...@@ -906,13 +906,10 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) ...@@ -906,13 +906,10 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
container_of(action, struct vmw_event_fence_action, action); container_of(action, struct vmw_event_fence_action, action);
struct drm_device *dev = eaction->dev; struct drm_device *dev = eaction->dev;
struct drm_pending_event *event = eaction->event; struct drm_pending_event *event = eaction->event;
struct drm_file *file_priv;
if (unlikely(event == NULL)) if (unlikely(event == NULL))
return; return;
file_priv = event->file_priv;
spin_lock_irq(&dev->event_lock); spin_lock_irq(&dev->event_lock);
if (likely(eaction->tv_sec != NULL)) { if (likely(eaction->tv_sec != NULL)) {
......
This diff is collapsed.
...@@ -33,7 +33,123 @@ ...@@ -33,7 +33,123 @@
#include <drm/drm_encoder.h> #include <drm/drm_encoder.h>
#include "vmwgfx_drv.h" #include "vmwgfx_drv.h"
/**
* struct vmw_du_update_plane - Closure structure for vmw_du_helper_plane_update
* @plane: Plane which is being updated.
* @old_state: Old state of plane.
* @dev_priv: Device private.
* @du: Display unit on which to update the plane.
* @vfb: Framebuffer which is blitted to display unit.
* @out_fence: Out fence for resource finish.
* @mutex: The mutex used to protect resource reservation.
* @cpu_blit: True if need cpu blit.
* @intr: Whether to perform waits interruptible if possible.
*
* This structure loosely represent the set of operations needed to perform a
* plane update on a display unit. Implementer will define that functionality
* according to the function callbacks for this structure. In brief it involves
* surface/buffer object validation, populate FIFO commands and command
* submission to the device.
*/
struct vmw_du_update_plane {
/**
* @calc_fifo_size: Calculate fifo size.
*
* Determine fifo size for the commands needed for update. The number of
* damage clips on display unit @num_hits will be passed to allocate
* sufficient fifo space.
*
* Return: Fifo size needed
*/
uint32_t (*calc_fifo_size)(struct vmw_du_update_plane *update,
uint32_t num_hits);
/**
* @post_prepare: Populate fifo for resource preparation.
*
* Some surface resource or buffer object need some extra cmd submission
* like update GB image for proxy surface and define a GMRFB for screen
* object. That should should be done here as this callback will be
* called after FIFO allocation with the address of command buufer.
*
* This callback is optional.
*
* Return: Size of commands populated to command buffer.
*/
uint32_t (*post_prepare)(struct vmw_du_update_plane *update, void *cmd);
/**
* @pre_clip: Populate fifo before clip.
*
* This is where pre clip related command should be populated like
* surface copy/DMA, etc.
*
* This callback is optional.
*
* Return: Size of commands populated to command buffer.
*/
uint32_t (*pre_clip)(struct vmw_du_update_plane *update, void *cmd,
uint32_t num_hits);
/**
* @clip: Populate fifo for clip.
*
* This is where to populate clips for surface copy/dma or blit commands
* if needed. This will be called times have damage in display unit,
* which is one if doing full update. @clip is the damage in destination
* coordinates which is crtc/DU and @src_x, @src_y is damage clip src in
* framebuffer coordinate.
*
* This callback is optional.
*
* Return: Size of commands populated to command buffer.
*/
uint32_t (*clip)(struct vmw_du_update_plane *update, void *cmd,
struct drm_rect *clip, uint32_t src_x, uint32_t src_y);
/**
* @post_clip: Populate fifo after clip.
*
* This is where to populate display unit update commands or blit
* commands.
*
* Return: Size of commands populated to command buffer.
*/
uint32_t (*post_clip)(struct vmw_du_update_plane *update, void *cmd,
struct drm_rect *bb);
struct drm_plane *plane;
struct drm_plane_state *old_state;
struct vmw_private *dev_priv;
struct vmw_display_unit *du;
struct vmw_framebuffer *vfb;
struct vmw_fence_obj **out_fence;
struct mutex *mutex;
bool cpu_blit;
bool intr;
};
/**
* struct vmw_du_update_plane_surface - closure structure for surface
* @base: base closure structure.
* @cmd_start: FIFO command start address (used by SOU only).
*/
struct vmw_du_update_plane_surface {
struct vmw_du_update_plane base;
/* This member is to handle special case SOU surface update */
void *cmd_start;
};
/**
* struct vmw_du_update_plane_buffer - Closure structure for buffer object
* @base: Base closure structure.
* @fb_left: x1 for fb damage bounding box.
* @fb_top: y1 for fb damage bounding box.
*/
struct vmw_du_update_plane_buffer {
struct vmw_du_update_plane base;
int fb_left, fb_top;
};
/** /**
* struct vmw_kms_dirty - closure structure for the vmw_kms_helper_dirty * struct vmw_kms_dirty - closure structure for the vmw_kms_helper_dirty
...@@ -191,8 +307,6 @@ struct vmw_plane_state { ...@@ -191,8 +307,6 @@ struct vmw_plane_state {
struct vmw_connector_state { struct vmw_connector_state {
struct drm_connector_state base; struct drm_connector_state base;
bool is_implicit;
/** /**
* @gui_x: * @gui_x:
* *
...@@ -254,7 +368,6 @@ struct vmw_display_unit { ...@@ -254,7 +368,6 @@ struct vmw_display_unit {
int gui_x; int gui_x;
int gui_y; int gui_y;
bool is_implicit; bool is_implicit;
bool active_implicit;
int set_gui_x; int set_gui_x;
int set_gui_y; int set_gui_y;
}; };
...@@ -334,17 +447,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -334,17 +447,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
struct drm_crtc **p_crtc, struct drm_crtc **p_crtc,
struct drm_display_mode **p_mode); struct drm_display_mode **p_mode);
void vmw_guess_mode_timing(struct drm_display_mode *mode); void vmw_guess_mode_timing(struct drm_display_mode *mode);
void vmw_kms_del_active(struct vmw_private *dev_priv, void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv);
struct vmw_display_unit *du); void vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv);
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);
/* Universal Plane Helpers */ /* Universal Plane Helpers */
void vmw_du_primary_plane_destroy(struct drm_plane *plane); void vmw_du_primary_plane_destroy(struct drm_plane *plane);
...@@ -456,6 +560,20 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, ...@@ -456,6 +560,20 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
bool interruptible, bool interruptible,
struct drm_crtc *crtc); struct drm_crtc *crtc);
int vmw_kms_set_config(struct drm_mode_set *set, int vmw_du_helper_plane_update(struct vmw_du_update_plane *update);
struct drm_modeset_acquire_ctx *ctx);
/**
* vmw_du_translate_to_crtc - Translate a rect from framebuffer to crtc
* @state: Plane state.
* @r: Rectangle to translate.
*/
static inline void vmw_du_translate_to_crtc(struct drm_plane_state *state,
struct drm_rect *r)
{
int translate_crtc_x = -((state->src_x >> 16) - state->crtc_x);
int translate_crtc_y = -((state->src_y >> 16) - state->crtc_y);
drm_rect_translate(r, translate_crtc_x, translate_crtc_y);
}
#endif #endif
...@@ -233,7 +233,7 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { ...@@ -233,7 +233,7 @@ static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = {
.reset = vmw_du_crtc_reset, .reset = vmw_du_crtc_reset,
.atomic_duplicate_state = vmw_du_crtc_duplicate_state, .atomic_duplicate_state = vmw_du_crtc_duplicate_state,
.atomic_destroy_state = vmw_du_crtc_destroy_state, .atomic_destroy_state = vmw_du_crtc_destroy_state,
.set_config = vmw_kms_set_config, .set_config = drm_atomic_helper_set_config,
}; };
...@@ -263,13 +263,10 @@ static const struct drm_connector_funcs vmw_legacy_connector_funcs = { ...@@ -263,13 +263,10 @@ static const struct drm_connector_funcs vmw_legacy_connector_funcs = {
.dpms = vmw_du_connector_dpms, .dpms = vmw_du_connector_dpms,
.detect = vmw_du_connector_detect, .detect = vmw_du_connector_detect,
.fill_modes = vmw_du_connector_fill_modes, .fill_modes = vmw_du_connector_fill_modes,
.set_property = vmw_du_connector_set_property,
.destroy = vmw_ldu_connector_destroy, .destroy = vmw_ldu_connector_destroy,
.reset = vmw_du_connector_reset, .reset = vmw_du_connector_reset,
.atomic_duplicate_state = vmw_du_connector_duplicate_state, .atomic_duplicate_state = vmw_du_connector_duplicate_state,
.atomic_destroy_state = vmw_du_connector_destroy_state, .atomic_destroy_state = vmw_du_connector_destroy_state,
.atomic_set_property = vmw_du_connector_atomic_set_property,
.atomic_get_property = vmw_du_connector_atomic_get_property,
}; };
static const struct static const struct
...@@ -416,7 +413,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -416,7 +413,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
drm_plane_helper_add(cursor, &vmw_ldu_cursor_plane_helper_funcs); drm_plane_helper_add(cursor, &vmw_ldu_cursor_plane_helper_funcs);
vmw_du_connector_reset(connector); vmw_du_connector_reset(connector);
ret = drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, ret = drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
DRM_MODE_CONNECTOR_VIRTUAL); DRM_MODE_CONNECTOR_VIRTUAL);
...@@ -427,8 +423,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -427,8 +423,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
drm_connector_helper_add(connector, &vmw_ldu_connector_helper_funcs); drm_connector_helper_add(connector, &vmw_ldu_connector_helper_funcs);
connector->status = vmw_du_connector_detect(connector, true); connector->status = vmw_du_connector_detect(connector, true);
vmw_connector_state_to_vcs(connector->state)->is_implicit = true;
ret = drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, ret = drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
DRM_MODE_ENCODER_VIRTUAL, NULL); DRM_MODE_ENCODER_VIRTUAL, NULL);
...@@ -447,7 +441,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -447,7 +441,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
goto err_free_encoder; goto err_free_encoder;
} }
vmw_du_crtc_reset(crtc); vmw_du_crtc_reset(crtc);
ret = drm_crtc_init_with_planes(dev, crtc, &ldu->base.primary, ret = drm_crtc_init_with_planes(dev, crtc, &ldu->base.primary,
&ldu->base.cursor, &ldu->base.cursor,
...@@ -513,7 +506,7 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv) ...@@ -513,7 +506,7 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv)
if (ret != 0) if (ret != 0)
goto err_free; goto err_free;
vmw_kms_create_implicit_placement_property(dev_priv, true); vmw_kms_create_implicit_placement_property(dev_priv);
if (dev_priv->capabilities & SVGA_CAP_MULTIMON) if (dev_priv->capabilities & SVGA_CAP_MULTIMON)
for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i)
......
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/**************************************************************************
*
* Copyright (c) 2018 VMware, Inc., Palo Alto, CA., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Deepak Rawat <drawat@vmware.com>
*
**************************************************************************/
#ifndef DRM_DAMAGE_HELPER_H_
#define DRM_DAMAGE_HELPER_H_
#include <drm/drm_atomic_helper.h>
/**
* drm_atomic_for_each_plane_damage - Iterator macro for plane damage.
* @iter: The iterator to advance.
* @rect: Return a rectangle in fb coordinate clipped to plane src.
*
* Note that if the first call to iterator macro return false then no need to do
* plane update. Iterator will return full plane src when damage is not passed
* by user-space.
*/
#define drm_atomic_for_each_plane_damage(iter, rect) \
while (drm_atomic_helper_damage_iter_next(iter, rect))
/**
* struct drm_atomic_helper_damage_iter - Closure structure for damage iterator.
*
* This structure tracks state needed to walk the list of plane damage clips.
*/
struct drm_atomic_helper_damage_iter {
/* private: Plane src in whole number. */
struct drm_rect plane_src;
/* private: Rectangles in plane damage blob. */
const struct drm_rect *clips;
/* private: Number of rectangles in plane damage blob. */
uint32_t num_clips;
/* private: Current clip iterator is advancing on. */
uint32_t curr_clip;
/* private: Whether need full plane update. */
bool full_update;
};
void drm_plane_enable_fb_damage_clips(struct drm_plane *plane);
void drm_atomic_helper_check_plane_damage(struct drm_atomic_state *state,
struct drm_plane_state *plane_state);
int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb,
struct drm_file *file_priv, unsigned int flags,
unsigned int color, struct drm_clip_rect *clips,
unsigned int num_clips);
void
drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter,
const struct drm_plane_state *old_state,
const struct drm_plane_state *new_state);
bool
drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter,
struct drm_rect *rect);
/**
* drm_helper_get_plane_damage_clips - Returns damage clips in &drm_rect.
* @state: Plane state.
*
* Returns plane damage rectangles in internal &drm_rect. Currently &drm_rect
* can be obtained by simply typecasting &drm_mode_rect. This is because both
* are signed 32 and during drm_atomic_check_only() it is verified that damage
* clips are inside fb.
*
* Return: Clips in plane fb_damage_clips blob property.
*/
static inline struct drm_rect *
drm_helper_get_plane_damage_clips(const struct drm_plane_state *state)
{
return (struct drm_rect *)drm_plane_get_damage_clips(state);
}
#endif
...@@ -633,6 +633,15 @@ struct drm_mode_config { ...@@ -633,6 +633,15 @@ struct drm_mode_config {
* &drm_crtc. * &drm_crtc.
*/ */
struct drm_property *prop_crtc_id; struct drm_property *prop_crtc_id;
/**
* @prop_fb_damage_clips: Optional plane property to mark damaged
* regions on the plane in framebuffer coordinates of the framebuffer
* attached to the plane.
*
* The layout of blob data is simply an array of &drm_mode_rect. Unlike
* plane src coordinates, damage clips are not in 16.16 fixed point.
*/
struct drm_property *prop_fb_damage_clips;
/** /**
* @prop_active: Default atomic CRTC property to control the active * @prop_active: Default atomic CRTC property to control the active
* state, which is the simplified implementation for DPMS in atomic * state, which is the simplified implementation for DPMS in atomic
......
...@@ -173,6 +173,16 @@ struct drm_plane_state { ...@@ -173,6 +173,16 @@ struct drm_plane_state {
*/ */
enum drm_color_range color_range; enum drm_color_range color_range;
/**
* @fb_damage_clips:
*
* Blob representing damage (area in plane framebuffer that changed
* since last plane update) as an array of &drm_mode_rect in framebuffer
* coodinates of the attached framebuffer. Note that unlike plane src,
* damage clips are not in 16.16 fixed point.
*/
struct drm_property_blob *fb_damage_clips;
/** @src: clipped source coordinates of the plane (in 16.16) */ /** @src: clipped source coordinates of the plane (in 16.16) */
/** @dst: clipped destination coordinates of the plane */ /** @dst: clipped destination coordinates of the plane */
struct drm_rect src, dst; struct drm_rect src, dst;
...@@ -800,5 +810,37 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev, ...@@ -800,5 +810,37 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
bool drm_any_plane_has_format(struct drm_device *dev, bool drm_any_plane_has_format(struct drm_device *dev,
u32 format, u64 modifier); u32 format, u64 modifier);
/**
* drm_plane_get_damage_clips_count - Returns damage clips count.
* @state: Plane state.
*
* Simple helper to get the number of &drm_mode_rect clips set by user-space
* during plane update.
*
* Return: Number of clips in plane fb_damage_clips blob property.
*/
static inline unsigned int
drm_plane_get_damage_clips_count(const struct drm_plane_state *state)
{
return (state && state->fb_damage_clips) ?
state->fb_damage_clips->length/sizeof(struct drm_mode_rect) : 0;
}
/**
* drm_plane_get_damage_clips - Returns damage clips.
* @state: Plane state.
*
* Note that this function returns uapi type &drm_mode_rect. Drivers might
* instead be interested in internal &drm_rect which can be obtained by calling
* drm_helper_get_plane_damage_clips().
*
* Return: Damage clips in plane fb_damage_clips blob property.
*/
static inline struct drm_mode_rect *
drm_plane_get_damage_clips(const struct drm_plane_state *state)
{
return (struct drm_mode_rect *)((state && state->fb_damage_clips) ?
state->fb_damage_clips->data : NULL);
}
#endif #endif
...@@ -888,6 +888,25 @@ struct drm_mode_revoke_lease { ...@@ -888,6 +888,25 @@ struct drm_mode_revoke_lease {
__u32 lessee_id; __u32 lessee_id;
}; };
/**
* struct drm_mode_rect - Two dimensional rectangle.
* @x1: Horizontal starting coordinate (inclusive).
* @y1: Vertical starting coordinate (inclusive).
* @x2: Horizontal ending coordinate (exclusive).
* @y2: Vertical ending coordinate (exclusive).
*
* With drm subsystem using struct drm_rect to manage rectangular area this
* export it to user-space.
*
* Currently used by drm_mode_atomic blob property FB_DAMAGE_CLIPS.
*/
struct drm_mode_rect {
__s32 x1;
__s32 y1;
__s32 x2;
__s32 y2;
};
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif
......
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