Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 282429
b: refs/heads/master
c: 308e5bc
h: refs/heads/master
i:
  282427: 531b94a
v: v3
  • Loading branch information
Jesse Barnes authored and Dave Airlie committed Nov 15, 2011
1 parent 0d82d8e commit 6900339
Show file tree
Hide file tree
Showing 21 changed files with 328 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8cf5c9177151537e73ff1816540e4ba24b174391
refs/heads/master: 308e5bcbdb10452e8aba31aa21432fb67ee46d72
111 changes: 106 additions & 5 deletions trunk/drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "drmP.h"
#include "drm_crtc.h"
#include "drm_edid.h"
#include "drm_fourcc.h"

struct drm_prop_enum_list {
int type;
Expand Down Expand Up @@ -568,7 +569,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
return -ENOMEM;
}

memcpy(plane->format_types, formats, format_count);
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
plane->format_count = format_count;
plane->possible_crtcs = possible_crtcs;

Expand Down Expand Up @@ -1915,6 +1916,42 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
return ret;
}

/* Original addfb only supported RGB formats, so figure out which one */
uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
{
uint32_t fmt;

switch (bpp) {
case 8:
fmt = DRM_FOURCC_RGB332;
break;
case 16:
if (depth == 15)
fmt = DRM_FOURCC_RGB555;
else
fmt = DRM_FOURCC_RGB565;
break;
case 24:
fmt = DRM_FOURCC_RGB24;
break;
case 32:
if (depth == 24)
fmt = DRM_FOURCC_RGB24;
else if (depth == 30)
fmt = DRM_INTEL_RGB30;
else
fmt = DRM_FOURCC_RGB32;
break;
default:
DRM_ERROR("bad bpp, assuming RGB24 pixel format\n");
fmt = DRM_FOURCC_RGB24;
break;
}

return fmt;
}
EXPORT_SYMBOL(drm_mode_legacy_fb_format);

/**
* drm_mode_addfb - add an FB to the graphics configuration
* @inode: inode from the ioctl
Expand All @@ -1935,7 +1972,74 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
int drm_mode_addfb(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_mode_fb_cmd *r = data;
struct drm_mode_fb_cmd *or = data;
struct drm_mode_fb_cmd2 r = {};
struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb;
int ret = 0;

/* Use new struct with format internally */
r.fb_id = or->fb_id;
r.width = or->width;
r.height = or->height;
r.pitches[0] = or->pitch;
r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
r.handles[0] = or->handle;

if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

if ((config->min_width > r.width) || (r.width > config->max_width)) {
DRM_ERROR("mode new framebuffer width not within limits\n");
return -EINVAL;
}
if ((config->min_height > r.height) || (r.height > config->max_height)) {
DRM_ERROR("mode new framebuffer height not within limits\n");
return -EINVAL;
}

mutex_lock(&dev->mode_config.mutex);

/* TODO check buffer is sufficiently large */
/* TODO setup destructor callback */

fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
if (IS_ERR(fb)) {
DRM_ERROR("could not create framebuffer\n");
ret = PTR_ERR(fb);
goto out;
}

or->fb_id = fb->base.id;
list_add(&fb->filp_head, &file_priv->fbs);
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);

out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
}

/**
* drm_mode_addfb2 - add an FB to the graphics configuration
* @inode: inode from the ioctl
* @filp: file * from the ioctl
* @cmd: cmd from ioctl
* @arg: arg from ioctl
*
* LOCKING:
* Takes mode config lock.
*
* Add a new FB to the specified CRTC, given a user request with format.
*
* Called by the user via ioctl.
*
* RETURNS:
* Zero on success, errno on failure.
*/
int drm_mode_addfb2(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_mode_fb_cmd2 *r = data;
struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb;
int ret = 0;
Expand All @@ -1956,9 +2060,6 @@ int drm_mode_addfb(struct drm_device *dev,

mutex_lock(&dev->mode_config.mutex);

/* TODO check buffer is sufficiently large */
/* TODO setup destructor callback */

fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) {
DRM_ERROR("could not create framebuffer\n");
Expand Down
51 changes: 47 additions & 4 deletions trunk/drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "drmP.h"
#include "drm_crtc.h"
#include "drm_fourcc.h"
#include "drm_crtc_helper.h"
#include "drm_fb_helper.h"

Expand Down Expand Up @@ -810,14 +811,56 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
}
EXPORT_SYMBOL(drm_helper_connector_dpms);

/*
* Just need to support RGB formats here for compat with code that doesn't
* use pixel formats directly yet.
*/
void drm_helper_get_fb_bpp_depth(uint32_t format, unsigned int *depth,
int *bpp)
{
switch (format) {
case DRM_FOURCC_RGB332:
*depth = 8;
*bpp = 8;
break;
case DRM_FOURCC_RGB555:
*depth = 15;
*bpp = 16;
break;
case DRM_FOURCC_RGB565:
*depth = 16;
*bpp = 16;
break;
case DRM_FOURCC_RGB24:
*depth = 24;
*bpp = 32;
break;
case DRM_INTEL_RGB30:
*depth = 30;
*bpp = 32;
break;
case DRM_FOURCC_RGB32:
*depth = 32;
*bpp = 32;
break;
default:
DRM_DEBUG_KMS("unsupported pixel format\n");
*depth = 0;
*bpp = 0;
break;
}
}
EXPORT_SYMBOL(drm_helper_get_fb_bpp_depth);

int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
struct drm_mode_fb_cmd *mode_cmd)
struct drm_mode_fb_cmd2 *mode_cmd)
{
fb->width = mode_cmd->width;
fb->height = mode_cmd->height;
fb->pitch = mode_cmd->pitch;
fb->bits_per_pixel = mode_cmd->bpp;
fb->depth = mode_cmd->depth;
fb->pitch = mode_cmd->pitches[0];
drm_helper_get_fb_bpp_depth(mode_cmd->pixel_format, &fb->depth,
&fb->bits_per_pixel);
fb->pixel_format = mode_cmd->pixel_format;

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
Expand Down
39 changes: 21 additions & 18 deletions trunk/drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -6279,7 +6279,7 @@ static struct drm_display_mode load_detect_mode = {

static struct drm_framebuffer *
intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
struct intel_framebuffer *intel_fb;
Expand Down Expand Up @@ -6321,7 +6321,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
int depth, int bpp)
{
struct drm_i915_gem_object *obj;
struct drm_mode_fb_cmd mode_cmd;
struct drm_mode_fb_cmd2 mode_cmd;

obj = i915_gem_alloc_object(dev,
intel_framebuffer_size_for_mode(mode, bpp));
Expand All @@ -6330,9 +6330,9 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,

mode_cmd.width = mode->hdisplay;
mode_cmd.height = mode->vdisplay;
mode_cmd.depth = depth;
mode_cmd.bpp = bpp;
mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp);
mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
bpp);
mode_cmd.pixel_format = 0;

return intel_framebuffer_create(dev, &mode_cmd, obj);
}
Expand Down Expand Up @@ -7573,29 +7573,31 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = {

int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *intel_fb,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj)
{
int ret;

if (obj->tiling_mode == I915_TILING_Y)
return -EINVAL;

if (mode_cmd->pitch & 63)
if (mode_cmd->pitches[0] & 63)
return -EINVAL;

switch (mode_cmd->bpp) {
case 8:
case 16:
/* Only pre-ILK can handle 5:5:5 */
if (mode_cmd->depth == 15 && !HAS_PCH_SPLIT(dev))
return -EINVAL;
switch (mode_cmd->pixel_format) {
case DRM_FOURCC_RGB332:
case DRM_FOURCC_RGB565:
case DRM_FOURCC_RGB24:
case DRM_INTEL_RGB30:
/* RGB formats are common across chipsets */
break;

case 24:
case 32:
case DRM_FOURCC_YUYV:
case DRM_FOURCC_UYVY:
case DRM_FOURCC_YVYU:
case DRM_FOURCC_VYUY:
break;
default:
DRM_ERROR("unsupported pixel format\n");
return -EINVAL;
}

Expand All @@ -7613,11 +7615,12 @@ int intel_framebuffer_init(struct drm_device *dev,
static struct drm_framebuffer *
intel_user_framebuffer_create(struct drm_device *dev,
struct drm_file *filp,
struct drm_mode_fb_cmd *mode_cmd)
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_i915_gem_object *obj;

obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle));
obj = to_intel_bo(drm_gem_object_lookup(dev, filp,
mode_cmd->handles[0]));
if (&obj->base == NULL)
return ERR_PTR(-ENOENT);

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,

extern int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *ifb,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_i915_gem_object *obj);
extern int intel_fbdev_init(struct drm_device *dev);
extern void intel_fbdev_fini(struct drm_device *dev);
Expand Down
11 changes: 6 additions & 5 deletions trunk/drivers/gpu/drm/i915/intel_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
struct drm_i915_private *dev_priv = dev->dev_private;
struct fb_info *info;
struct drm_framebuffer *fb;
struct drm_mode_fb_cmd mode_cmd;
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_i915_gem_object *obj;
struct device *device = &dev->pdev->dev;
int size, ret;
Expand All @@ -77,11 +77,12 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;

mode_cmd.bpp = sizes->surface_bpp;
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
mode_cmd.depth = sizes->surface_depth;
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) /
8), 64);
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
sizes->surface_depth);

size = mode_cmd.pitch * mode_cmd.height;
size = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);
obj = i915_gem_alloc_object(dev, size);
if (!obj) {
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
int
nouveau_framebuffer_init(struct drm_device *dev,
struct nouveau_framebuffer *nv_fb,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_mode_fb_cmd2 *mode_cmd,
struct nouveau_bo *nvbo)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -124,13 +124,13 @@ nouveau_framebuffer_init(struct drm_device *dev,
static struct drm_framebuffer *
nouveau_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv,
struct drm_mode_fb_cmd *mode_cmd)
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct nouveau_framebuffer *nouveau_fb;
struct drm_gem_object *gem;
int ret;

gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
if (!gem)
return ERR_PTR(-ENOENT);

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/gpu/drm/nouveau/nouveau_fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ nouveau_framebuffer(struct drm_framebuffer *fb)
extern const struct drm_mode_config_funcs nouveau_mode_config_funcs;

int nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo);
struct drm_mode_fb_cmd2 *mode_cmd, struct nouveau_bo *nvbo);
#endif /* __NOUVEAU_FB_H__ */
Loading

0 comments on commit 6900339

Please sign in to comment.