Commit 75c06855 authored by Thomas Hellstrom's avatar Thomas Hellstrom

drm/vmwgfx: Break out implicit fb code

Preparation for supporting explicit fbs for screen objects and screen
targets.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarSinclair Yeh <syeh@vmware.com>
parent b1097aeb
...@@ -407,8 +407,9 @@ struct vmw_private { ...@@ -407,8 +407,9 @@ struct vmw_private {
void *fb_info; void *fb_info;
enum vmw_display_unit_type active_display_unit; enum vmw_display_unit_type active_display_unit;
struct vmw_legacy_display *ldu_priv; struct vmw_legacy_display *ldu_priv;
struct vmw_screen_object_display *sou_priv;
struct vmw_overlay *overlay_priv; struct vmw_overlay *overlay_priv;
unsigned num_implicit;
struct vmw_framebuffer *implicit_fb;
/* /*
* Context and surface management. * Context and surface management.
......
...@@ -2095,3 +2095,95 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -2095,3 +2095,95 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
return 0; 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;
}
...@@ -178,6 +178,7 @@ struct vmw_display_unit { ...@@ -178,6 +178,7 @@ 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;
}; };
#define vmw_crtc_to_du(x) \ #define vmw_crtc_to_du(x) \
...@@ -254,6 +255,17 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -254,6 +255,17 @@ 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,
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);
/* /*
* Legacy display unit functions - vmwgfx_ldu.c * Legacy display unit functions - vmwgfx_ldu.c
......
...@@ -74,19 +74,6 @@ struct vmw_kms_sou_dirty_cmd { ...@@ -74,19 +74,6 @@ struct vmw_kms_sou_dirty_cmd {
SVGA3dCmdBlitSurfaceToScreen body; SVGA3dCmdBlitSurfaceToScreen body;
}; };
/*
* Other structs.
*/
struct vmw_screen_object_display {
unsigned num_implicit;
struct vmw_framebuffer *implicit_fb;
SVGAFifoCmdDefineGMRFB cur;
struct vmw_dma_buffer *pinned_gmrfb;
};
/** /**
* Display unit using screen objects. * Display unit using screen objects.
*/ */
...@@ -97,7 +84,6 @@ struct vmw_screen_object_unit { ...@@ -97,7 +84,6 @@ struct vmw_screen_object_unit {
struct vmw_dma_buffer *buffer; /**< Backing store buffer */ struct vmw_dma_buffer *buffer; /**< Backing store buffer */
bool defined; bool defined;
bool active_implicit;
}; };
static void vmw_sou_destroy(struct vmw_screen_object_unit *sou) static void vmw_sou_destroy(struct vmw_screen_object_unit *sou)
...@@ -116,33 +102,6 @@ static void vmw_sou_crtc_destroy(struct drm_crtc *crtc) ...@@ -116,33 +102,6 @@ static void vmw_sou_crtc_destroy(struct drm_crtc *crtc)
vmw_sou_destroy(vmw_crtc_to_sou(crtc)); vmw_sou_destroy(vmw_crtc_to_sou(crtc));
} }
static void vmw_sou_del_active(struct vmw_private *vmw_priv,
struct vmw_screen_object_unit *sou)
{
struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
if (sou->active_implicit) {
if (--(ld->num_implicit) == 0)
ld->implicit_fb = NULL;
sou->active_implicit = false;
}
}
static void vmw_sou_add_active(struct vmw_private *vmw_priv,
struct vmw_screen_object_unit *sou,
struct vmw_framebuffer *vfb)
{
struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
BUG_ON(!ld->num_implicit && ld->implicit_fb);
if (!sou->active_implicit && sou->base.is_implicit) {
ld->implicit_fb = vfb;
sou->active_implicit = true;
ld->num_implicit++;
}
}
/** /**
* Send the fifo command to create a screen. * Send the fifo command to create a screen.
*/ */
...@@ -323,13 +282,13 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) ...@@ -323,13 +282,13 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
return -EINVAL; return -EINVAL;
} }
/* sou only supports one fb active at the time */ /* Only one active implicit frame-buffer at a time. */
if (sou->base.is_implicit && if (sou->base.is_implicit &&
dev_priv->sou_priv->implicit_fb && vfb && dev_priv->implicit_fb && vfb &&
!(dev_priv->sou_priv->num_implicit == 1 && !(dev_priv->num_implicit == 1 &&
sou->active_implicit) && sou->base.active_implicit) &&
dev_priv->sou_priv->implicit_fb != vfb) { dev_priv->implicit_fb != vfb) {
DRM_ERROR("Multiple framebuffers not supported\n"); DRM_ERROR("Multiple implicit framebuffers not supported.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -351,7 +310,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) ...@@ -351,7 +310,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
crtc->y = 0; crtc->y = 0;
crtc->enabled = false; crtc->enabled = false;
vmw_sou_del_active(dev_priv, sou); vmw_kms_del_active(dev_priv, &sou->base);
vmw_sou_backing_free(dev_priv, sou); vmw_sou_backing_free(dev_priv, sou);
...@@ -415,7 +374,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) ...@@ -415,7 +374,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
return ret; return ret;
} }
vmw_sou_add_active(dev_priv, sou, vfb); vmw_kms_add_active(dev_priv, &sou->base, vfb);
connector->encoder = encoder; connector->encoder = encoder;
encoder->crtc = crtc; encoder->crtc = crtc;
...@@ -428,39 +387,6 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) ...@@ -428,39 +387,6 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
return 0; return 0;
} }
/**
* Returns if this unit can be page flipped.
* Must be called with the mode_config mutex held.
*/
static bool vmw_sou_screen_object_flippable(struct vmw_private *dev_priv,
struct drm_crtc *crtc)
{
struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
if (!sou->base.is_implicit)
return true;
if (dev_priv->sou_priv->num_implicit != 1)
return false;
return true;
}
/**
* Update the implicit fb to the current fb of this crtc.
* Must be called with the mode_config mutex held.
*/
static void vmw_sou_update_implicit_fb(struct vmw_private *dev_priv,
struct drm_crtc *crtc)
{
struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
BUG_ON(!sou->base.is_implicit);
dev_priv->sou_priv->implicit_fb =
vmw_framebuffer_to_vfb(sou->base.crtc.primary->fb);
}
static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, struct drm_pending_vblank_event *event,
...@@ -473,11 +399,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, ...@@ -473,11 +399,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
struct drm_vmw_rect vclips; struct drm_vmw_rect vclips;
int ret; int ret;
/* require ScreenObject support for page flipping */ if (!vmw_kms_crtc_flippable(dev_priv, crtc))
if (!dev_priv->sou_priv)
return -ENOSYS;
if (!vmw_sou_screen_object_flippable(dev_priv, crtc))
return -EINVAL; return -EINVAL;
crtc->primary->fb = fb; crtc->primary->fb = fb;
...@@ -522,7 +444,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, ...@@ -522,7 +444,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
vmw_fence_obj_unreference(&fence); vmw_fence_obj_unreference(&fence);
if (vmw_crtc_to_du(crtc)->is_implicit) if (vmw_crtc_to_du(crtc)->is_implicit)
vmw_sou_update_implicit_fb(dev_priv, crtc); vmw_kms_update_implicit_fb(dev_priv, crtc);
return ret; return ret;
...@@ -587,8 +509,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -587,8 +509,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
encoder = &sou->base.encoder; encoder = &sou->base.encoder;
connector = &sou->base.connector; connector = &sou->base.connector;
sou->active_implicit = false; sou->base.active_implicit = false;
sou->base.pref_active = (unit == 0); sou->base.pref_active = (unit == 0);
sou->base.pref_width = dev_priv->initial_width; sou->base.pref_width = dev_priv->initial_width;
sou->base.pref_height = dev_priv->initial_height; sou->base.pref_height = dev_priv->initial_height;
...@@ -623,11 +544,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv) ...@@ -623,11 +544,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
int i, ret; int i, ret;
if (dev_priv->sou_priv) {
DRM_INFO("sou system already on\n");
return -EINVAL;
}
if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) { if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) {
DRM_INFO("Not using screen objects," DRM_INFO("Not using screen objects,"
" missing cap SCREEN_OBJECT_2\n"); " missing cap SCREEN_OBJECT_2\n");
...@@ -635,16 +551,12 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv) ...@@ -635,16 +551,12 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
} }
ret = -ENOMEM; ret = -ENOMEM;
dev_priv->sou_priv = kmalloc(sizeof(*dev_priv->sou_priv), GFP_KERNEL); dev_priv->num_implicit = 0;
if (unlikely(!dev_priv->sou_priv)) dev_priv->implicit_fb = NULL;
goto err_no_mem;
dev_priv->sou_priv->num_implicit = 0;
dev_priv->sou_priv->implicit_fb = NULL;
ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS); ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto err_free; return ret;
ret = drm_mode_create_dirty_info_property(dev); ret = drm_mode_create_dirty_info_property(dev);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
...@@ -661,10 +573,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv) ...@@ -661,10 +573,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
err_vblank_cleanup: err_vblank_cleanup:
drm_vblank_cleanup(dev); drm_vblank_cleanup(dev);
err_free:
kfree(dev_priv->sou_priv);
dev_priv->sou_priv = NULL;
err_no_mem:
return ret; return ret;
} }
...@@ -672,13 +580,8 @@ int vmw_kms_sou_close_display(struct vmw_private *dev_priv) ...@@ -672,13 +580,8 @@ int vmw_kms_sou_close_display(struct vmw_private *dev_priv)
{ {
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
if (!dev_priv->sou_priv)
return -ENOSYS;
drm_vblank_cleanup(dev); drm_vblank_cleanup(dev);
kfree(dev_priv->sou_priv);
return 0; return 0;
} }
......
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