forked from Minki/linux
drm/vmwgfx: Switch to mode_cmd2
Surprisingly few changes needed to make it happen. Compile-tested only. The idea is that this replaces the 2 patches from Ville's big fb->format patch series as a prep patch. Only impact to later patches should be the one instace added in this patch where we look at fb->pixel_format (instead of fb->bpp and fb->depth), so minor adjustements in the cocci-generated patches needed. v2: Restore pitch computation in vmw_fb_kms_framebuffer (Sinclair). Cc: ville.syrjala@linux.intel.com Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: linux-graphics-maintainer@vmware.com Cc: Sinclair Yeh <syeh@vmware.com> Cc: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com> Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161202070740.31689-1-daniel.vetter@ffwll.ch
This commit is contained in:
parent
ad1231080b
commit
dabdcdc982
@ -465,33 +465,34 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
|
|||||||
|
|
||||||
static int vmw_fb_kms_framebuffer(struct fb_info *info)
|
static int vmw_fb_kms_framebuffer(struct fb_info *info)
|
||||||
{
|
{
|
||||||
struct drm_mode_fb_cmd mode_cmd;
|
struct drm_mode_fb_cmd2 mode_cmd;
|
||||||
struct vmw_fb_par *par = info->par;
|
struct vmw_fb_par *par = info->par;
|
||||||
struct fb_var_screeninfo *var = &info->var;
|
struct fb_var_screeninfo *var = &info->var;
|
||||||
struct drm_framebuffer *cur_fb;
|
struct drm_framebuffer *cur_fb;
|
||||||
struct vmw_framebuffer *vfb;
|
struct vmw_framebuffer *vfb;
|
||||||
int ret = 0;
|
int ret = 0, depth;
|
||||||
size_t new_bo_size;
|
size_t new_bo_size;
|
||||||
|
|
||||||
ret = vmw_fb_compute_depth(var, &mode_cmd.depth);
|
ret = vmw_fb_compute_depth(var, &depth);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mode_cmd.width = var->xres;
|
mode_cmd.width = var->xres;
|
||||||
mode_cmd.height = var->yres;
|
mode_cmd.height = var->yres;
|
||||||
mode_cmd.bpp = var->bits_per_pixel;
|
mode_cmd.pitches[0] = ((var->bits_per_pixel + 7) / 8) * mode_cmd.width;
|
||||||
mode_cmd.pitch = ((mode_cmd.bpp + 7) / 8) * mode_cmd.width;
|
mode_cmd.pixel_format =
|
||||||
|
drm_mode_legacy_fb_format(var->bits_per_pixel,
|
||||||
|
((var->bits_per_pixel + 7) / 8) * mode_cmd.width);
|
||||||
|
|
||||||
cur_fb = par->set_fb;
|
cur_fb = par->set_fb;
|
||||||
if (cur_fb && cur_fb->width == mode_cmd.width &&
|
if (cur_fb && cur_fb->width == mode_cmd.width &&
|
||||||
cur_fb->height == mode_cmd.height &&
|
cur_fb->height == mode_cmd.height &&
|
||||||
cur_fb->bits_per_pixel == mode_cmd.bpp &&
|
cur_fb->pixel_format == mode_cmd.pixel_format &&
|
||||||
cur_fb->depth == mode_cmd.depth &&
|
cur_fb->pitches[0] == mode_cmd.pitches[0])
|
||||||
cur_fb->pitches[0] == mode_cmd.pitch)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Need new buffer object ? */
|
/* Need new buffer object ? */
|
||||||
new_bo_size = (size_t) mode_cmd.pitch * (size_t) mode_cmd.height;
|
new_bo_size = (size_t) mode_cmd.pitches[0] * (size_t) mode_cmd.height;
|
||||||
ret = vmw_fb_kms_detach(par,
|
ret = vmw_fb_kms_detach(par,
|
||||||
par->bo_size < new_bo_size ||
|
par->bo_size < new_bo_size ||
|
||||||
par->bo_size > 2*new_bo_size,
|
par->bo_size > 2*new_bo_size,
|
||||||
|
@ -516,7 +516,7 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
|
|||||||
static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
|
static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
|
||||||
struct vmw_surface *surface,
|
struct vmw_surface *surface,
|
||||||
struct vmw_framebuffer **out,
|
struct vmw_framebuffer **out,
|
||||||
const struct drm_mode_fb_cmd
|
const struct drm_mode_fb_cmd2
|
||||||
*mode_cmd,
|
*mode_cmd,
|
||||||
bool is_dmabuf_proxy)
|
bool is_dmabuf_proxy)
|
||||||
|
|
||||||
@ -525,6 +525,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
|
|||||||
struct vmw_framebuffer_surface *vfbs;
|
struct vmw_framebuffer_surface *vfbs;
|
||||||
enum SVGA3dSurfaceFormat format;
|
enum SVGA3dSurfaceFormat format;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct drm_format_name_buf format_name;
|
||||||
|
|
||||||
/* 3D is only supported on HWv8 and newer hosts */
|
/* 3D is only supported on HWv8 and newer hosts */
|
||||||
if (dev_priv->active_display_unit == vmw_du_legacy)
|
if (dev_priv->active_display_unit == vmw_du_legacy)
|
||||||
@ -548,21 +549,22 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mode_cmd->depth) {
|
switch (mode_cmd->pixel_format) {
|
||||||
case 32:
|
case DRM_FORMAT_ARGB8888:
|
||||||
format = SVGA3D_A8R8G8B8;
|
format = SVGA3D_A8R8G8B8;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case DRM_FORMAT_XRGB8888:
|
||||||
format = SVGA3D_X8R8G8B8;
|
format = SVGA3D_X8R8G8B8;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case DRM_FORMAT_RGB565:
|
||||||
format = SVGA3D_R5G6B5;
|
format = SVGA3D_R5G6B5;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case DRM_FORMAT_XRGB1555:
|
||||||
format = SVGA3D_A1R5G5B5;
|
format = SVGA3D_A1R5G5B5;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth);
|
DRM_ERROR("Invalid pixel format: %s\n",
|
||||||
|
drm_get_format_name(mode_cmd->pixel_format, &format_name));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,14 +583,9 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
|
|||||||
goto out_err1;
|
goto out_err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX get the first 3 from the surface info */
|
drm_helper_mode_fill_fb_struct(&vfbs->base.base, mode_cmd);
|
||||||
vfbs->base.base.bits_per_pixel = mode_cmd->bpp;
|
|
||||||
vfbs->base.base.pitches[0] = mode_cmd->pitch;
|
|
||||||
vfbs->base.base.depth = mode_cmd->depth;
|
|
||||||
vfbs->base.base.width = mode_cmd->width;
|
|
||||||
vfbs->base.base.height = mode_cmd->height;
|
|
||||||
vfbs->surface = vmw_surface_reference(surface);
|
vfbs->surface = vmw_surface_reference(surface);
|
||||||
vfbs->base.user_handle = mode_cmd->handle;
|
vfbs->base.user_handle = mode_cmd->handles[0];
|
||||||
vfbs->is_dmabuf_proxy = is_dmabuf_proxy;
|
vfbs->is_dmabuf_proxy = is_dmabuf_proxy;
|
||||||
|
|
||||||
*out = &vfbs->base;
|
*out = &vfbs->base;
|
||||||
@ -755,7 +752,7 @@ static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
|
|||||||
* 0 on success, error code otherwise
|
* 0 on success, error code otherwise
|
||||||
*/
|
*/
|
||||||
static int vmw_create_dmabuf_proxy(struct drm_device *dev,
|
static int vmw_create_dmabuf_proxy(struct drm_device *dev,
|
||||||
const struct drm_mode_fb_cmd *mode_cmd,
|
const struct drm_mode_fb_cmd2 *mode_cmd,
|
||||||
struct vmw_dma_buffer *dmabuf_mob,
|
struct vmw_dma_buffer *dmabuf_mob,
|
||||||
struct vmw_surface **srf_out)
|
struct vmw_surface **srf_out)
|
||||||
{
|
{
|
||||||
@ -763,17 +760,18 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
|
|||||||
struct drm_vmw_size content_base_size;
|
struct drm_vmw_size content_base_size;
|
||||||
struct vmw_resource *res;
|
struct vmw_resource *res;
|
||||||
unsigned int bytes_pp;
|
unsigned int bytes_pp;
|
||||||
|
struct drm_format_name_buf format_name;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (mode_cmd->depth) {
|
switch (mode_cmd->pixel_format) {
|
||||||
case 32:
|
case DRM_FORMAT_ARGB8888:
|
||||||
case 24:
|
case DRM_FORMAT_XRGB8888:
|
||||||
format = SVGA3D_X8R8G8B8;
|
format = SVGA3D_X8R8G8B8;
|
||||||
bytes_pp = 4;
|
bytes_pp = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case DRM_FORMAT_RGB565:
|
||||||
case 15:
|
case DRM_FORMAT_XRGB1555:
|
||||||
format = SVGA3D_R5G6B5;
|
format = SVGA3D_R5G6B5;
|
||||||
bytes_pp = 2;
|
bytes_pp = 2;
|
||||||
break;
|
break;
|
||||||
@ -784,11 +782,12 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("Invalid framebuffer format %d\n", mode_cmd->depth);
|
DRM_ERROR("Invalid framebuffer format %s\n",
|
||||||
|
drm_get_format_name(mode_cmd->pixel_format, &format_name));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
content_base_size.width = mode_cmd->pitch / bytes_pp;
|
content_base_size.width = mode_cmd->pitches[0] / bytes_pp;
|
||||||
content_base_size.height = mode_cmd->height;
|
content_base_size.height = mode_cmd->height;
|
||||||
content_base_size.depth = 1;
|
content_base_size.depth = 1;
|
||||||
|
|
||||||
@ -826,16 +825,17 @@ static int vmw_create_dmabuf_proxy(struct drm_device *dev,
|
|||||||
static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
|
static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
|
||||||
struct vmw_dma_buffer *dmabuf,
|
struct vmw_dma_buffer *dmabuf,
|
||||||
struct vmw_framebuffer **out,
|
struct vmw_framebuffer **out,
|
||||||
const struct drm_mode_fb_cmd
|
const struct drm_mode_fb_cmd2
|
||||||
*mode_cmd)
|
*mode_cmd)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct drm_device *dev = dev_priv->dev;
|
struct drm_device *dev = dev_priv->dev;
|
||||||
struct vmw_framebuffer_dmabuf *vfbd;
|
struct vmw_framebuffer_dmabuf *vfbd;
|
||||||
unsigned int requested_size;
|
unsigned int requested_size;
|
||||||
|
struct drm_format_name_buf format_name;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
requested_size = mode_cmd->height * mode_cmd->pitch;
|
requested_size = mode_cmd->height * mode_cmd->pitches[0];
|
||||||
if (unlikely(requested_size > dmabuf->base.num_pages * PAGE_SIZE)) {
|
if (unlikely(requested_size > dmabuf->base.num_pages * PAGE_SIZE)) {
|
||||||
DRM_ERROR("Screen buffer object size is too small "
|
DRM_ERROR("Screen buffer object size is too small "
|
||||||
"for requested mode.\n");
|
"for requested mode.\n");
|
||||||
@ -844,27 +844,16 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
|
|||||||
|
|
||||||
/* Limited framebuffer color depth support for screen objects */
|
/* Limited framebuffer color depth support for screen objects */
|
||||||
if (dev_priv->active_display_unit == vmw_du_screen_object) {
|
if (dev_priv->active_display_unit == vmw_du_screen_object) {
|
||||||
switch (mode_cmd->depth) {
|
switch (mode_cmd->pixel_format) {
|
||||||
case 32:
|
case DRM_FORMAT_XRGB8888:
|
||||||
case 24:
|
case DRM_FORMAT_ARGB8888:
|
||||||
/* Only support 32 bpp for 32 and 24 depth fbs */
|
break;
|
||||||
if (mode_cmd->bpp == 32)
|
case DRM_FORMAT_XRGB1555:
|
||||||
break;
|
case DRM_FORMAT_RGB565:
|
||||||
|
break;
|
||||||
DRM_ERROR("Invalid color depth/bbp: %d %d\n",
|
|
||||||
mode_cmd->depth, mode_cmd->bpp);
|
|
||||||
return -EINVAL;
|
|
||||||
case 16:
|
|
||||||
case 15:
|
|
||||||
/* Only support 16 bpp for 16 and 15 depth fbs */
|
|
||||||
if (mode_cmd->bpp == 16)
|
|
||||||
break;
|
|
||||||
|
|
||||||
DRM_ERROR("Invalid color depth/bbp: %d %d\n",
|
|
||||||
mode_cmd->depth, mode_cmd->bpp);
|
|
||||||
return -EINVAL;
|
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth);
|
DRM_ERROR("Invalid pixel format: %s\n",
|
||||||
|
drm_get_format_name(mode_cmd->pixel_format, &format_name));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -875,14 +864,10 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
|
|||||||
goto out_err1;
|
goto out_err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfbd->base.base.bits_per_pixel = mode_cmd->bpp;
|
drm_helper_mode_fill_fb_struct(&vfbd->base.base, mode_cmd);
|
||||||
vfbd->base.base.pitches[0] = mode_cmd->pitch;
|
|
||||||
vfbd->base.base.depth = mode_cmd->depth;
|
|
||||||
vfbd->base.base.width = mode_cmd->width;
|
|
||||||
vfbd->base.base.height = mode_cmd->height;
|
|
||||||
vfbd->base.dmabuf = true;
|
vfbd->base.dmabuf = true;
|
||||||
vfbd->buffer = vmw_dmabuf_reference(dmabuf);
|
vfbd->buffer = vmw_dmabuf_reference(dmabuf);
|
||||||
vfbd->base.user_handle = mode_cmd->handle;
|
vfbd->base.user_handle = mode_cmd->handles[0];
|
||||||
*out = &vfbd->base;
|
*out = &vfbd->base;
|
||||||
|
|
||||||
ret = drm_framebuffer_init(dev, &vfbd->base.base,
|
ret = drm_framebuffer_init(dev, &vfbd->base.base,
|
||||||
@ -916,7 +901,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
|
|||||||
struct vmw_dma_buffer *dmabuf,
|
struct vmw_dma_buffer *dmabuf,
|
||||||
struct vmw_surface *surface,
|
struct vmw_surface *surface,
|
||||||
bool only_2d,
|
bool only_2d,
|
||||||
const struct drm_mode_fb_cmd *mode_cmd)
|
const struct drm_mode_fb_cmd2 *mode_cmd)
|
||||||
{
|
{
|
||||||
struct vmw_framebuffer *vfb = NULL;
|
struct vmw_framebuffer *vfb = NULL;
|
||||||
bool is_dmabuf_proxy = false;
|
bool is_dmabuf_proxy = false;
|
||||||
@ -971,7 +956,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
|
|||||||
|
|
||||||
static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
||||||
struct drm_file *file_priv,
|
struct drm_file *file_priv,
|
||||||
const struct drm_mode_fb_cmd2 *mode_cmd2)
|
const struct drm_mode_fb_cmd2 *mode_cmd)
|
||||||
{
|
{
|
||||||
struct vmw_private *dev_priv = vmw_priv(dev);
|
struct vmw_private *dev_priv = vmw_priv(dev);
|
||||||
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
||||||
@ -979,25 +964,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
|||||||
struct vmw_surface *surface = NULL;
|
struct vmw_surface *surface = NULL;
|
||||||
struct vmw_dma_buffer *bo = NULL;
|
struct vmw_dma_buffer *bo = NULL;
|
||||||
struct ttm_base_object *user_obj;
|
struct ttm_base_object *user_obj;
|
||||||
struct drm_mode_fb_cmd mode_cmd;
|
|
||||||
const struct drm_format_info *info;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
info = drm_format_info(mode_cmd2->pixel_format);
|
|
||||||
if (!info || !info->depth) {
|
|
||||||
struct drm_format_name_buf format_name;
|
|
||||||
DRM_ERROR("Unsupported framebuffer format %s\n",
|
|
||||||
drm_get_format_name(mode_cmd2->pixel_format, &format_name));
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
mode_cmd.width = mode_cmd2->width;
|
|
||||||
mode_cmd.height = mode_cmd2->height;
|
|
||||||
mode_cmd.pitch = mode_cmd2->pitches[0];
|
|
||||||
mode_cmd.handle = mode_cmd2->handles[0];
|
|
||||||
mode_cmd.depth = info->depth;
|
|
||||||
mode_cmd.bpp = info->cpp[0] * 8;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This code should be conditioned on Screen Objects not being used.
|
* This code should be conditioned on Screen Objects not being used.
|
||||||
* If screen objects are used, we can allocate a GMR to hold the
|
* If screen objects are used, we can allocate a GMR to hold the
|
||||||
@ -1005,8 +973,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (!vmw_kms_validate_mode_vram(dev_priv,
|
if (!vmw_kms_validate_mode_vram(dev_priv,
|
||||||
mode_cmd.pitch,
|
mode_cmd->pitches[0],
|
||||||
mode_cmd.height)) {
|
mode_cmd->height)) {
|
||||||
DRM_ERROR("Requested mode exceed bounding box limit.\n");
|
DRM_ERROR("Requested mode exceed bounding box limit.\n");
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
@ -1020,7 +988,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
|||||||
* command stream using user-space handles.
|
* command stream using user-space handles.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
user_obj = ttm_base_object_lookup(tfile, mode_cmd.handle);
|
user_obj = ttm_base_object_lookup(tfile, mode_cmd->handles[0]);
|
||||||
if (unlikely(user_obj == NULL)) {
|
if (unlikely(user_obj == NULL)) {
|
||||||
DRM_ERROR("Could not locate requested kms frame buffer.\n");
|
DRM_ERROR("Could not locate requested kms frame buffer.\n");
|
||||||
return ERR_PTR(-ENOENT);
|
return ERR_PTR(-ENOENT);
|
||||||
@ -1032,14 +1000,14 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
|||||||
|
|
||||||
/* returns either a dmabuf or surface */
|
/* returns either a dmabuf or surface */
|
||||||
ret = vmw_user_lookup_handle(dev_priv, tfile,
|
ret = vmw_user_lookup_handle(dev_priv, tfile,
|
||||||
mode_cmd.handle,
|
mode_cmd->handles[0],
|
||||||
&surface, &bo);
|
&surface, &bo);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
|
vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
|
||||||
!(dev_priv->capabilities & SVGA_CAP_3D),
|
!(dev_priv->capabilities & SVGA_CAP_3D),
|
||||||
&mode_cmd);
|
mode_cmd);
|
||||||
if (IS_ERR(vfb)) {
|
if (IS_ERR(vfb)) {
|
||||||
ret = PTR_ERR(vfb);
|
ret = PTR_ERR(vfb);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
@ -248,7 +248,7 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
|
|||||||
struct vmw_dma_buffer *dmabuf,
|
struct vmw_dma_buffer *dmabuf,
|
||||||
struct vmw_surface *surface,
|
struct vmw_surface *surface,
|
||||||
bool only_2d,
|
bool only_2d,
|
||||||
const struct drm_mode_fb_cmd *mode_cmd);
|
const struct drm_mode_fb_cmd2 *mode_cmd);
|
||||||
int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
|
int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
|
||||||
unsigned unit,
|
unsigned unit,
|
||||||
u32 max_width,
|
u32 max_width,
|
||||||
|
Loading…
Reference in New Issue
Block a user