[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
(Looping linux-media in) On Thursday 09 June 2011 13:55:13 Alan Cox wrote: > > > You also don't need a headwer with a complete list of fourcc names in > > > it, that is the half the point of FourCC. > > > > #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 > > RGB-3-3-2 */ > > > > See that V4L2 and v4l2? I'd rather not have them used in the drm > > They are just helpers. The only thing that fourcc is is a 4 byte packed > value of four symbols. > > > interface, either a DRM_ variant or a FOURCC_ variant that removes the > > V4L2. Also having it in a different include file to "videodev2.h", so > > yes we can pass FOURCC values but I'd rather we gave people a drm > > specific way to generate them or make a generic set of macros that don't > > include the V4L2 headers. > > You need a macro to assemble fourcc codes and that seems to be about it - > so just an equivalent of the v4l2_fourcc macro. Given that I plan to use the V4L2 FOURCCs in fbdev as well, it might indeed be a good idea to split them from videodev2.h into their own header file. Renaming the macros to make them V4L2-agnostic is a no-go, as that would break the API. Manually maintaining separate sets of identical FOURCCs accross subsystems also doesn't sound like a very good idea to me. We could create a header that contains V4L2-agnostic FOURCC #define's, and generate a V4L2 header with the V4L2_ prefix, but I'm not sure it would be a good idea either. -- Regards, Laurent Pinchart
Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
(Looping linux-media in) On Thursday 09 June 2011 13:55:13 Alan Cox wrote: You also don't need a headwer with a complete list of fourcc names in it, that is the half the point of FourCC. #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ See that V4L2 and v4l2? I'd rather not have them used in the drm They are just helpers. The only thing that fourcc is is a 4 byte packed value of four symbols. interface, either a DRM_ variant or a FOURCC_ variant that removes the V4L2. Also having it in a different include file to videodev2.h, so yes we can pass FOURCC values but I'd rather we gave people a drm specific way to generate them or make a generic set of macros that don't include the V4L2 headers. You need a macro to assemble fourcc codes and that seems to be about it - so just an equivalent of the v4l2_fourcc macro. Given that I plan to use the V4L2 FOURCCs in fbdev as well, it might indeed be a good idea to split them from videodev2.h into their own header file. Renaming the macros to make them V4L2-agnostic is a no-go, as that would break the API. Manually maintaining separate sets of identical FOURCCs accross subsystems also doesn't sound like a very good idea to me. We could create a header that contains V4L2-agnostic FOURCC #define's, and generate a V4L2 header with the V4L2_ prefix, but I'm not sure it would be a good idea either. -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/drm_crtc.c| 71 - drivers/gpu/drm/drm_crtc_helper.c |3 +- drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/i915/intel_display.c |9 ++-- drivers/gpu/drm/i915/intel_drv.h |2 +- drivers/gpu/drm/i915/intel_fb.c |3 +- drivers/gpu/drm/nouveau/nouveau_display.c |4 +- drivers/gpu/drm/radeon/radeon_display.c |4 +- drivers/gpu/drm/radeon/radeon_fb.c|5 +- drivers/gpu/drm/radeon/radeon_mode.h |2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |2 +- drivers/staging/gma500/psb_fb.c |2 +- include/drm/drm.h |1 + include/drm/drm_crtc.h|6 ++- include/drm/drm_crtc_helper.h |2 +- include/drm/drm_mode.h| 14 ++ 16 files changed, 112 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9be36a5..f963cf5 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1909,7 +1909,76 @@ out: 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 = >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.pitch = or->pitch; + r.bpp = or->bpp; + r.depth = or->depth; + r.pixel_format = 0; + r.handle = 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(>mode_config.mutex); + + /* TODO check buffer is sufficiently large */ + /* TODO setup destructor callback */ + + fb = dev->mode_config.funcs->fb_create(dev, file_priv, ); + 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(>filp_head, _priv->fbs); + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); + +out: + mutex_unlock(>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 = >mode_config; struct drm_framebuffer *fb; int ret = 0; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9236965..5adab04 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode) EXPORT_SYMBOL(drm_helper_connector_dpms); 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->pixel_format = mode_cmd->pixel_format; return 0; } diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 15da618..f24b9b6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -152,6 +152,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,
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/drm_crtc.c| 71 - drivers/gpu/drm/drm_crtc_helper.c |3 +- drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/i915/intel_display.c |9 ++-- drivers/gpu/drm/i915/intel_drv.h |2 +- drivers/gpu/drm/i915/intel_fb.c |3 +- drivers/gpu/drm/nouveau/nouveau_display.c |4 +- drivers/gpu/drm/radeon/radeon_display.c |4 +- drivers/gpu/drm/radeon/radeon_fb.c|5 +- drivers/gpu/drm/radeon/radeon_mode.h |2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |2 +- drivers/staging/gma500/psb_fb.c |2 +- include/drm/drm.h |1 + include/drm/drm_crtc.h|6 ++- include/drm/drm_crtc_helper.h |2 +- include/drm/drm_mode.h| 14 ++ 16 files changed, 112 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9be36a5..f963cf5 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1909,7 +1909,76 @@ out: 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.pitch = or-pitch; + r.bpp = or-bpp; + r.depth = or-depth; + r.pixel_format = 0; + r.handle = 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; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9236965..5adab04 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode) EXPORT_SYMBOL(drm_helper_connector_dpms); 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-pixel_format = mode_cmd-pixel_format; return 0; } diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 15da618..f24b9b6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -152,6 +152,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,
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
On Thu, 2011-06-09 at 09:21 +0100, Alan Cox wrote: > On Thu, 09 Jun 2011 14:05:59 +1000 > Dave Airlie wrote: > > > On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote: > > > To properly support the various plane formats supported by different > > > hardware, the kernel must know the pixel format of a framebuffer object. > > > So add a new ioctl taking a format argument corresponding to a fourcc > > > name from videodev2.h. > > > > I'd rather we don't directly tie things like that, either create a > > fourcc header that isn't V4L2 or DRM related and use that or generate > > two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can > > keep the DRM interface in some way OS agnostic. > > It *is* OS agnostic (it started on the Amiga) > > You also don't need a headwer with a complete list of fourcc names in it, > that is the half the point of FourCC. #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ See that V4L2 and v4l2? I'd rather not have them used in the drm interface, either a DRM_ variant or a FOURCC_ variant that removes the V4L2. Also having it in a different include file to "videodev2.h", so yes we can pass FOURCC values but I'd rather we gave people a drm specific way to generate them or make a generic set of macros that don't include the V4L2 headers. Dave.
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote: > To properly support the various plane formats supported by different > hardware, the kernel must know the pixel format of a framebuffer object. > So add a new ioctl taking a format argument corresponding to a fourcc > name from videodev2.h. I'd rather we don't directly tie things like that, either create a fourcc header that isn't V4L2 or DRM related and use that or generate two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can keep the DRM interface in some way OS agnostic. Dave.
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
> > You also don't need a headwer with a complete list of fourcc names in it, > > that is the half the point of FourCC. > > #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 > RGB-3-3-2 */ > > See that V4L2 and v4l2? I'd rather not have them used in the drm They are just helpers. The only thing that fourcc is is a 4 byte packed value of four symbols. > interface, either a DRM_ variant or a FOURCC_ variant that removes the > V4L2. Also having it in a different include file to "videodev2.h", so > yes we can pass FOURCC values but I'd rather we gave people a drm > specific way to generate them or make a generic set of macros that don't > include the V4L2 headers. You need a macro to assemble fourcc codes and that seems to be about it - so just an equivalent of the v4l2_fourcc macro. Alan
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
On Thu, 09 Jun 2011 14:05:59 +1000 Dave Airlie wrote: > On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote: > > To properly support the various plane formats supported by different > > hardware, the kernel must know the pixel format of a framebuffer object. > > So add a new ioctl taking a format argument corresponding to a fourcc > > name from videodev2.h. > > I'd rather we don't directly tie things like that, either create a > fourcc header that isn't V4L2 or DRM related and use that or generate > two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can > keep the DRM interface in some way OS agnostic. It *is* OS agnostic (it started on the Amiga) You also don't need a headwer with a complete list of fourcc names in it, that is the half the point of FourCC. Alan
Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
On Thu, 09 Jun 2011 14:05:59 +1000 Dave Airlie airl...@redhat.com wrote: On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote: To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. I'd rather we don't directly tie things like that, either create a fourcc header that isn't V4L2 or DRM related and use that or generate two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can keep the DRM interface in some way OS agnostic. It *is* OS agnostic (it started on the Amiga) You also don't need a headwer with a complete list of fourcc names in it, that is the half the point of FourCC. Alan ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
On Thu, 2011-06-09 at 09:21 +0100, Alan Cox wrote: On Thu, 09 Jun 2011 14:05:59 +1000 Dave Airlie airl...@redhat.com wrote: On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote: To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. I'd rather we don't directly tie things like that, either create a fourcc header that isn't V4L2 or DRM related and use that or generate two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can keep the DRM interface in some way OS agnostic. It *is* OS agnostic (it started on the Amiga) You also don't need a headwer with a complete list of fourcc names in it, that is the half the point of FourCC. #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ See that V4L2 and v4l2? I'd rather not have them used in the drm interface, either a DRM_ variant or a FOURCC_ variant that removes the V4L2. Also having it in a different include file to videodev2.h, so yes we can pass FOURCC values but I'd rather we gave people a drm specific way to generate them or make a generic set of macros that don't include the V4L2 headers. Dave. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
You also don't need a headwer with a complete list of fourcc names in it, that is the half the point of FourCC. #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ See that V4L2 and v4l2? I'd rather not have them used in the drm They are just helpers. The only thing that fourcc is is a 4 byte packed value of four symbols. interface, either a DRM_ variant or a FOURCC_ variant that removes the V4L2. Also having it in a different include file to videodev2.h, so yes we can pass FOURCC values but I'd rather we gave people a drm specific way to generate them or make a generic set of macros that don't include the V4L2 headers. You need a macro to assemble fourcc codes and that seems to be about it - so just an equivalent of the v4l2_fourcc macro. Alan ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
On Tue, 2011-06-07 at 13:07 -0700, Jesse Barnes wrote: To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. I'd rather we don't directly tie things like that, either create a fourcc header that isn't V4L2 or DRM related and use that or generate two headers one with DRM_ and one with V4L2 prefixes. Mainly so we can keep the DRM interface in some way OS agnostic. Dave. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/drm_crtc.c| 71 - drivers/gpu/drm/drm_crtc_helper.c |3 +- drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/i915/intel_display.c |9 ++-- drivers/gpu/drm/i915/intel_drv.h |2 +- drivers/gpu/drm/i915/intel_fb.c |3 +- drivers/gpu/drm/nouveau/nouveau_display.c |4 +- drivers/gpu/drm/radeon/radeon_display.c |4 +- drivers/gpu/drm/radeon/radeon_fb.c|5 +- drivers/gpu/drm/radeon/radeon_mode.h |2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |2 +- drivers/staging/gma500/psb_fb.c |2 +- include/drm/drm.h |1 + include/drm/drm_crtc.h|6 ++- include/drm/drm_crtc_helper.h |2 +- include/drm/drm_mode.h| 14 ++ 16 files changed, 112 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index dd6d149..b499cbf 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1910,7 +1910,76 @@ out: 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 = >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.pitch = or->pitch; + r.bpp = or->bpp; + r.depth = or->depth; + r.pixel_format = 0; + r.handle = 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(>mode_config.mutex); + + /* TODO check buffer is sufficiently large */ + /* TODO setup destructor callback */ + + fb = dev->mode_config.funcs->fb_create(dev, file_priv, ); + 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(>filp_head, _priv->fbs); + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); + +out: + mutex_unlock(>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 = >mode_config; struct drm_framebuffer *fb; int ret = 0; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9236965..5adab04 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode) EXPORT_SYMBOL(drm_helper_connector_dpms); 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->pixel_format = mode_cmd->pixel_format; return 0; } diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 15da618..f24b9b6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -152,6 +152,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,
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/drm_crtc.c| 105 - drivers/gpu/drm/drm_crtc_helper.c | 50 +- drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/i915/intel_display.c | 34 +- drivers/gpu/drm/i915/intel_drv.h |2 +- drivers/gpu/drm/i915/intel_fb.c | 11 ++-- drivers/gpu/drm/nouveau/nouveau_display.c |4 +- drivers/gpu/drm/radeon/radeon_display.c |4 +- drivers/gpu/drm/radeon/radeon_fb.c| 18 +++-- drivers/gpu/drm/radeon/radeon_mode.h |2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |2 +- drivers/staging/gma500/framebuffer.c |2 +- include/drm/drm.h |1 + include/drm/drm_crtc.h|7 ++- include/drm/drm_crtc_helper.h |4 +- include/drm/drm_mode.h| 26 +++ include/linux/videodev2.h |1 + 17 files changed, 231 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index cea209a..869e177 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1894,6 +1894,42 @@ out: 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 = V4L2_PIX_FMT_RGB332; + break; + case 16: + if (depth == 15) + fmt = V4L2_PIX_FMT_RGB555; + else + fmt = V4L2_PIX_FMT_RGB565; + break; + case 24: + fmt = V4L2_PIX_FMT_RGB24; + break; + case 32: + if (depth == 24) + fmt = V4L2_PIX_FMT_RGB24; + else if (depth == 30) + fmt = V4L2_PIX_FMT_INTC_RGB30; + else + fmt = V4L2_PIX_FMT_RGB32; + break; + default: + DRM_ERROR("bad bpp, assuming RGB24 pixel format\n"); + fmt = V4L2_PIX_FMT_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 @@ -1914,7 +1950,74 @@ out: 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 = >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.handle = 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(>mode_config.mutex); + + /* TODO check buffer is sufficiently large */ + /* TODO setup destructor callback */ + + fb = dev->mode_config.funcs->fb_create(dev, file_priv, ); + 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(>filp_head, _priv->fbs); + DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); + +out: + mutex_unlock(>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 = >mode_config;
[PATCH 2/4] drm: add an fb creation ioctl that takes a pixel format
To properly support the various plane formats supported by different hardware, the kernel must know the pixel format of a framebuffer object. So add a new ioctl taking a format argument corresponding to a fourcc name from videodev2.h. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/drm_crtc.c| 71 - drivers/gpu/drm/drm_crtc_helper.c |3 +- drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/i915/intel_display.c |9 ++-- drivers/gpu/drm/i915/intel_drv.h |2 +- drivers/gpu/drm/i915/intel_fb.c |3 +- drivers/gpu/drm/nouveau/nouveau_display.c |4 +- drivers/gpu/drm/radeon/radeon_display.c |4 +- drivers/gpu/drm/radeon/radeon_fb.c|5 +- drivers/gpu/drm/radeon/radeon_mode.h |2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |2 +- drivers/staging/gma500/psb_fb.c |2 +- include/drm/drm.h |1 + include/drm/drm_crtc.h|6 ++- include/drm/drm_crtc_helper.h |2 +- include/drm/drm_mode.h| 14 ++ 16 files changed, 112 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index dd6d149..b499cbf 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1910,7 +1910,76 @@ out: 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.pitch = or-pitch; + r.bpp = or-bpp; + r.depth = or-depth; + r.pixel_format = 0; + r.handle = 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; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 9236965..5adab04 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -801,13 +801,14 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode) EXPORT_SYMBOL(drm_helper_connector_dpms); 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-pixel_format = mode_cmd-pixel_format; return 0; } diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 15da618..f24b9b6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -152,6 +152,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,