vmwgfx: Infrastructure for explicit placement
Make it possible to use explicit placement (although not hooked up with a user-space interface yet) and relax the single framebuffer limit to only apply to implicit placement. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>hifive-unleashed-5.1
parent
1543b4dd0c
commit
6987427a39
|
@ -102,6 +102,7 @@ struct vmw_display_unit {
|
||||||
*/
|
*/
|
||||||
int gui_x;
|
int gui_x;
|
||||||
int gui_y;
|
int gui_y;
|
||||||
|
bool is_implicit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define vmw_crtc_to_du(x) \
|
#define vmw_crtc_to_du(x) \
|
||||||
|
|
|
@ -337,6 +337,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
|
||||||
ldu->base.pref_width = 800;
|
ldu->base.pref_width = 800;
|
||||||
ldu->base.pref_height = 600;
|
ldu->base.pref_height = 600;
|
||||||
ldu->base.pref_mode = NULL;
|
ldu->base.pref_mode = NULL;
|
||||||
|
ldu->base.is_implicit = true;
|
||||||
|
|
||||||
drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
|
drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_VIRTUAL);
|
DRM_MODE_CONNECTOR_VIRTUAL);
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
container_of(x, struct vmw_screen_object_unit, base.connector)
|
container_of(x, struct vmw_screen_object_unit, base.connector)
|
||||||
|
|
||||||
struct vmw_screen_object_display {
|
struct vmw_screen_object_display {
|
||||||
unsigned num_active;
|
unsigned num_implicit;
|
||||||
|
|
||||||
struct vmw_framebuffer *fb;
|
struct vmw_framebuffer *implicit_fb;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +51,7 @@ 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;
|
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)
|
||||||
|
@ -75,10 +75,10 @@ static void vmw_sou_del_active(struct vmw_private *vmw_priv,
|
||||||
{
|
{
|
||||||
struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
|
struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
|
||||||
|
|
||||||
if (sou->active) {
|
if (sou->active_implicit) {
|
||||||
if (--(ld->num_active) == 0)
|
if (--(ld->num_implicit) == 0)
|
||||||
ld->fb = NULL;
|
ld->implicit_fb = NULL;
|
||||||
sou->active = false;
|
sou->active_implicit = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ static void vmw_sou_add_active(struct vmw_private *vmw_priv,
|
||||||
{
|
{
|
||||||
struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
|
struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
|
||||||
|
|
||||||
BUG_ON(!ld->num_active && ld->fb);
|
BUG_ON(!ld->num_implicit && ld->implicit_fb);
|
||||||
|
|
||||||
if (!sou->active) {
|
if (!sou->active_implicit && sou->base.is_implicit) {
|
||||||
ld->fb = vfb;
|
ld->implicit_fb = vfb;
|
||||||
sou->active = true;
|
sou->active_implicit = true;
|
||||||
ld->num_active++;
|
ld->num_implicit++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +132,13 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv,
|
||||||
(sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0);
|
(sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0);
|
||||||
cmd->obj.size.width = mode->hdisplay;
|
cmd->obj.size.width = mode->hdisplay;
|
||||||
cmd->obj.size.height = mode->vdisplay;
|
cmd->obj.size.height = mode->vdisplay;
|
||||||
|
if (sou->base.is_implicit) {
|
||||||
cmd->obj.root.x = x;
|
cmd->obj.root.x = x;
|
||||||
cmd->obj.root.y = y;
|
cmd->obj.root.y = y;
|
||||||
|
} else {
|
||||||
|
cmd->obj.root.x = sou->base.gui_x;
|
||||||
|
cmd->obj.root.y = sou->base.gui_y;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ok to assume that buffer is pinned in vram */
|
/* Ok to assume that buffer is pinned in vram */
|
||||||
vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
|
vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
|
||||||
|
@ -280,10 +285,11 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sou only supports one fb active at the time */
|
/* sou only supports one fb active at the time */
|
||||||
if (dev_priv->sou_priv->fb && vfb &&
|
if (sou->base.is_implicit &&
|
||||||
!(dev_priv->sou_priv->num_active == 1 &&
|
dev_priv->sou_priv->implicit_fb && vfb &&
|
||||||
sou->active) &&
|
!(dev_priv->sou_priv->num_implicit == 1 &&
|
||||||
dev_priv->sou_priv->fb != vfb) {
|
sou->active_implicit) &&
|
||||||
|
dev_priv->sou_priv->implicit_fb != vfb) {
|
||||||
DRM_ERROR("Multiple framebuffers not supported\n");
|
DRM_ERROR("Multiple framebuffers not supported\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -439,12 +445,13 @@ 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 = false;
|
sou->active_implicit = false;
|
||||||
|
|
||||||
sou->base.pref_active = (unit == 0);
|
sou->base.pref_active = (unit == 0);
|
||||||
sou->base.pref_width = 800;
|
sou->base.pref_width = 800;
|
||||||
sou->base.pref_height = 600;
|
sou->base.pref_height = 600;
|
||||||
sou->base.pref_mode = NULL;
|
sou->base.pref_mode = NULL;
|
||||||
|
sou->base.is_implicit = true;
|
||||||
|
|
||||||
drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
|
drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
|
||||||
DRM_MODE_CONNECTOR_VIRTUAL);
|
DRM_MODE_CONNECTOR_VIRTUAL);
|
||||||
|
@ -488,8 +495,8 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv)
|
||||||
if (unlikely(!dev_priv->sou_priv))
|
if (unlikely(!dev_priv->sou_priv))
|
||||||
goto err_no_mem;
|
goto err_no_mem;
|
||||||
|
|
||||||
dev_priv->sou_priv->num_active = 0;
|
dev_priv->sou_priv->num_implicit = 0;
|
||||||
dev_priv->sou_priv->fb = NULL;
|
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))
|
||||||
|
@ -524,9 +531,6 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
|
||||||
|
|
||||||
drm_vblank_cleanup(dev);
|
drm_vblank_cleanup(dev);
|
||||||
|
|
||||||
if (dev_priv->sou_priv->num_active > 0)
|
|
||||||
DRM_ERROR("Still have active outputs when unloading driver");
|
|
||||||
|
|
||||||
kfree(dev_priv->sou_priv);
|
kfree(dev_priv->sou_priv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue