2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2012-08-15 13:59:49 +01:00
/*
* Copyright ( C ) 2012 Russell King
*/
2019-08-04 11:41:31 +02:00
2019-01-17 22:03:34 +01:00
# include <drm/drm_modeset_helper.h>
2012-08-15 13:59:49 +01:00
# include <drm/drm_fb_helper.h>
2019-08-04 11:41:31 +02:00
# include <drm/drm_fourcc.h>
2018-03-30 15:11:33 +01:00
# include <drm/drm_gem_framebuffer_helper.h>
2019-08-04 11:41:31 +02:00
2012-08-15 13:59:49 +01:00
# include "armada_drm.h"
# include "armada_fb.h"
# include "armada_gem.h"
# include "armada_hw.h"
static const struct drm_framebuffer_funcs armada_fb_funcs = {
2018-03-30 15:11:33 +01:00
. destroy = drm_gem_fb_destroy ,
. create_handle = drm_gem_fb_create_handle ,
2012-08-15 13:59:49 +01:00
} ;
struct armada_framebuffer * armada_framebuffer_create ( struct drm_device * dev ,
2015-11-11 19:11:29 +02:00
const struct drm_mode_fb_cmd2 * mode , struct armada_gem_object * obj )
2012-08-15 13:59:49 +01:00
{
struct armada_framebuffer * dfb ;
uint8_t format , config ;
int ret ;
switch ( mode - > pixel_format ) {
# define FMT(drm, fmt, mod) \
case DRM_FORMAT_ # # drm : \
format = CFG_ # # fmt ; \
config = mod ; \
break
FMT ( RGB565 , 565 , CFG_SWAPRB ) ;
FMT ( BGR565 , 565 , 0 ) ;
FMT ( ARGB1555 , 1555 , CFG_SWAPRB ) ;
FMT ( ABGR1555 , 1555 , 0 ) ;
FMT ( RGB888 , 888 PACK , CFG_SWAPRB ) ;
FMT ( BGR888 , 888 PACK , 0 ) ;
FMT ( XRGB8888 , X888 , CFG_SWAPRB ) ;
FMT ( XBGR8888 , X888 , 0 ) ;
FMT ( ARGB8888 , 8888 , CFG_SWAPRB ) ;
FMT ( ABGR8888 , 8888 , 0 ) ;
FMT ( YUYV , 422 PACK , CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV ) ;
FMT ( UYVY , 422 PACK , CFG_YUV2RGB ) ;
FMT ( VYUY , 422 PACK , CFG_YUV2RGB | CFG_SWAPUV ) ;
FMT ( YVYU , 422 PACK , CFG_YUV2RGB | CFG_SWAPYU ) ;
FMT ( YUV422 , 422 , CFG_YUV2RGB ) ;
FMT ( YVU422 , 422 , CFG_YUV2RGB | CFG_SWAPUV ) ;
FMT ( YUV420 , 420 , CFG_YUV2RGB ) ;
FMT ( YVU420 , 420 , CFG_YUV2RGB | CFG_SWAPUV ) ;
FMT ( C8 , PSEUDO8 , 0 ) ;
# undef FMT
default :
return ERR_PTR ( - EINVAL ) ;
}
dfb = kzalloc ( sizeof ( * dfb ) , GFP_KERNEL ) ;
if ( ! dfb ) {
DRM_ERROR ( " failed to allocate Armada fb object \n " ) ;
return ERR_PTR ( - ENOMEM ) ;
}
dfb - > fmt = format ;
dfb - > mod = config ;
2018-03-30 15:11:33 +01:00
dfb - > fb . obj [ 0 ] = & obj - > obj ;
2012-08-15 13:59:49 +01:00
drm: Pass 'dev' to drm_helper_mode_fill_fb_struct()
Pass the drm_device to drm_helper_mode_fill_fb_struct() so that we can
populate fb->dev early. Will make it easier to use the fb before we
register it.
@@
identifier fb, mode_cmd;
@@
void drm_helper_mode_fill_fb_struct(
+ struct drm_device *dev,
struct drm_framebuffer *fb,
const struct drm_mode_fb_cmd2 *mode_cmd
);
@@
identifier fb, mode_cmd;
@@
void drm_helper_mode_fill_fb_struct(
+ struct drm_device *dev,
struct drm_framebuffer *fb,
const struct drm_mode_fb_cmd2 *mode_cmd
)
{ ... }
@@
function func;
identifier dev;
expression E1, E2;
@@
func(struct drm_device *dev, ...)
{
...
drm_helper_mode_fill_fb_struct(
+ dev,
E1, E2);
...
}
@@
expression E1, E2;
@@
drm_helper_mode_fill_fb_struct(
+ dev,
E1, E2);
v2: Rerun spatch due to code changes
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1481748539-18283-1-git-send-email-ville.syrjala@linux.intel.com
2016-12-14 22:48:59 +02:00
drm_helper_mode_fill_fb_struct ( dev , & dfb - > fb , mode ) ;
2012-08-15 13:59:49 +01:00
ret = drm_framebuffer_init ( dev , & dfb - > fb , & armada_fb_funcs ) ;
if ( ret ) {
kfree ( dfb ) ;
return ERR_PTR ( ret ) ;
}
/*
* Take a reference on our object as we ' re successful - the
* caller already holds a reference , which keeps us safe for
* the above call , but the caller will drop their reference
* to it . Hence we need to take our own reference .
*/
2017-09-20 12:54:48 -06:00
drm_gem_object_get ( & obj - > obj ) ;
2012-08-15 13:59:49 +01:00
return dfb ;
}
2018-07-30 11:52:34 +01:00
struct drm_framebuffer * armada_fb_create ( struct drm_device * dev ,
2015-11-11 19:11:29 +02:00
struct drm_file * dfile , const struct drm_mode_fb_cmd2 * mode )
2012-08-15 13:59:49 +01:00
{
2019-05-16 12:31:47 +02:00
const struct drm_format_info * info = drm_get_format_info ( dev , mode ) ;
2012-08-15 13:59:49 +01:00
struct armada_gem_object * obj ;
struct armada_framebuffer * dfb ;
int ret ;
DRM_DEBUG_DRIVER ( " w%u h%u pf%08x f%u p%u,%u,%u \n " ,
mode - > width , mode - > height , mode - > pixel_format ,
mode - > flags , mode - > pitches [ 0 ] , mode - > pitches [ 1 ] ,
mode - > pitches [ 2 ] ) ;
/* We can only handle a single plane at the moment */
2019-05-16 12:31:47 +02:00
if ( info - > num_planes > 1 & &
2012-08-15 13:59:49 +01:00
( mode - > handles [ 0 ] ! = mode - > handles [ 1 ] | |
mode - > handles [ 0 ] ! = mode - > handles [ 2 ] ) ) {
ret = - EINVAL ;
goto err ;
}
2016-05-09 11:04:54 +01:00
obj = armada_gem_object_lookup ( dfile , mode - > handles [ 0 ] ) ;
2012-08-15 13:59:49 +01:00
if ( ! obj ) {
ret = - ENOENT ;
goto err ;
}
if ( obj - > obj . import_attach & & ! obj - > sgt ) {
ret = armada_gem_map_import ( obj ) ;
if ( ret )
goto err_unref ;
}
/* Framebuffer objects must have a valid device address for scanout */
2017-05-22 10:46:22 +02:00
if ( ! obj - > mapped ) {
2012-08-15 13:59:49 +01:00
ret = - EINVAL ;
goto err_unref ;
}
dfb = armada_framebuffer_create ( dev , mode , obj ) ;
if ( IS_ERR ( dfb ) ) {
ret = PTR_ERR ( dfb ) ;
goto err ;
}
2020-05-15 10:50:56 +01:00
drm_gem_object_put ( & obj - > obj ) ;
2012-08-15 13:59:49 +01:00
return & dfb - > fb ;
err_unref :
2020-05-15 10:50:56 +01:00
drm_gem_object_put ( & obj - > obj ) ;
2012-08-15 13:59:49 +01:00
err :
DRM_ERROR ( " failed to initialize framebuffer: %d \n " , ret ) ;
return ERR_PTR ( ret ) ;
}