2012-08-15 13:59:49 +01:00
/*
* Copyright ( C ) 2012 Russell King
* Rewritten from the dovefb driver , and Armada510 manuals .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <drm/drmP.h>
2018-07-30 11:52:34 +01:00
# include <drm/drm_atomic.h>
2018-09-05 15:57:11 +02:00
# include <drm/drm_atomic_uapi.h>
2018-01-05 09:43:46 +10:00
# include <drm/drm_atomic_helper.h>
2018-07-30 11:52:34 +01:00
# include <drm/drm_plane_helper.h>
2018-07-30 11:52:34 +01:00
# include <drm/armada_drm.h>
2012-08-15 13:59:49 +01:00
# include "armada_crtc.h"
# include "armada_drm.h"
# include "armada_fb.h"
# include "armada_gem.h"
# include "armada_hw.h"
# include "armada_ioctlP.h"
2018-07-30 11:52:34 +01:00
# include "armada_plane.h"
2016-05-17 13:51:08 +01:00
# include "armada_trace.h"
2012-08-15 13:59:49 +01:00
2018-07-30 11:52:34 +01:00
# define DEFAULT_BRIGHTNESS 0
# define DEFAULT_CONTRAST 0x4000
# define DEFAULT_SATURATION 0x4000
2018-07-30 11:52:34 +01:00
# define DEFAULT_ENCODING DRM_COLOR_YCBCR_BT601
2018-07-30 11:52:34 +01:00
struct armada_overlay_state {
struct drm_plane_state base ;
2018-07-30 11:52:34 +01:00
u32 colorkey_yr ;
u32 colorkey_ug ;
u32 colorkey_vb ;
u32 colorkey_mode ;
u32 colorkey_enable ;
2018-07-30 11:52:34 +01:00
s16 brightness ;
u16 contrast ;
u16 saturation ;
} ;
# define drm_to_overlay_state(s) \
container_of ( s , struct armada_overlay_state , base )
static inline u32 armada_spu_contrast ( struct drm_plane_state * state )
{
return drm_to_overlay_state ( state ) - > brightness < < 16 |
drm_to_overlay_state ( state ) - > contrast ;
}
static inline u32 armada_spu_saturation ( struct drm_plane_state * state )
{
/* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
return drm_to_overlay_state ( state ) - > saturation < < 16 ;
}
2012-08-15 13:59:49 +01:00
2018-07-30 11:52:34 +01:00
static inline u32 armada_csc ( struct drm_plane_state * state )
{
/*
* The CFG_CSC_RGB_ * settings control the output of the colour space
* converter , setting the range of output values it produces . Since
* we will be blending with the full - range graphics , we need to
* produce full - range RGB output from the conversion .
*/
return CFG_CSC_RGB_COMPUTER |
( state - > color_encoding = = DRM_COLOR_YCBCR_BT709 ?
CFG_CSC_YUV_CCIR709 : CFG_CSC_YUV_CCIR601 ) ;
}
2012-08-15 13:59:49 +01:00
/* === Plane support === */
2018-07-30 11:52:34 +01:00
static void armada_drm_overlay_plane_atomic_update ( struct drm_plane * plane ,
struct drm_plane_state * old_state )
2012-08-15 13:59:49 +01:00
{
2018-07-30 11:52:34 +01:00
struct drm_plane_state * state = plane - > state ;
struct armada_crtc * dcrtc ;
struct armada_regs * regs ;
unsigned int idx ;
u32 cfg , cfg_mask , val ;
2012-08-15 13:59:49 +01:00
2018-07-30 11:52:34 +01:00
DRM_DEBUG_KMS ( " [PLANE:%d:%s] \n " , plane - > base . id , plane - > name ) ;
2012-08-15 13:59:49 +01:00
2018-07-30 11:52:34 +01:00
if ( ! state - > fb | | WARN_ON ( ! state - > crtc ) )
return ;
2015-06-15 10:18:02 +01:00
2018-07-30 11:52:34 +01:00
DRM_DEBUG_KMS ( " [PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u \n " ,
plane - > base . id , plane - > name ,
state - > crtc - > base . id , state - > crtc - > name ,
state - > fb - > base . id ,
old_state - > visible , state - > visible ) ;
dcrtc = drm_to_armada_crtc ( state - > crtc ) ;
regs = dcrtc - > regs + dcrtc - > regs_idx ;
idx = 0 ;
if ( ! old_state - > visible & & state - > visible )
armada_reg_queue_mod ( regs , idx ,
0 , CFG_PDWN16x66 | CFG_PDWN32x66 ,
LCD_SPU_SRAM_PARA1 ) ;
val = armada_rect_hw_fp ( & state - > src ) ;
if ( armada_rect_hw_fp ( & old_state - > src ) ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_DMA_HPXL_VLN ) ;
val = armada_rect_yx ( & state - > dst ) ;
if ( armada_rect_yx ( & old_state - > dst ) ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_DMA_OVSA_HPXL_VLN ) ;
val = armada_rect_hw ( & state - > dst ) ;
if ( armada_rect_hw ( & old_state - > dst ) ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_DZM_HPXL_VLN ) ;
2017-07-08 10:22:31 +01:00
/* FIXME: overlay on an interlaced display */
2018-07-30 11:52:34 +01:00
if ( old_state - > src . x1 ! = state - > src . x1 | |
old_state - > src . y1 ! = state - > src . y1 | |
old_state - > fb ! = state - > fb ) {
const struct drm_format_info * format ;
2018-07-30 11:52:34 +01:00
u16 src_x , pitches [ 3 ] ;
2018-07-30 11:52:34 +01:00
u32 addrs [ 2 ] [ 3 ] ;
2016-08-16 22:09:11 +01:00
2018-07-30 11:52:34 +01:00
armada_drm_plane_calc ( state , addrs , pitches , false ) ;
2015-06-15 10:18:02 +01:00
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , addrs [ 0 ] [ 0 ] ,
2012-08-15 13:59:49 +01:00
LCD_SPU_DMA_START_ADDR_Y0 ) ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , addrs [ 0 ] [ 1 ] ,
2012-08-15 13:59:49 +01:00
LCD_SPU_DMA_START_ADDR_U0 ) ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , addrs [ 0 ] [ 2 ] ,
2012-08-15 13:59:49 +01:00
LCD_SPU_DMA_START_ADDR_V0 ) ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , addrs [ 1 ] [ 0 ] ,
2012-08-15 13:59:49 +01:00
LCD_SPU_DMA_START_ADDR_Y1 ) ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , addrs [ 1 ] [ 1 ] ,
2012-08-15 13:59:49 +01:00
LCD_SPU_DMA_START_ADDR_U1 ) ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , addrs [ 1 ] [ 2 ] ,
2012-08-15 13:59:49 +01:00
LCD_SPU_DMA_START_ADDR_V1 ) ;
2018-07-30 11:52:34 +01:00
val = pitches [ 0 ] < < 16 | pitches [ 0 ] ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , val , LCD_SPU_DMA_PITCH_YC ) ;
2018-07-30 11:52:34 +01:00
val = pitches [ 1 ] < < 16 | pitches [ 2 ] ;
2018-07-30 11:52:34 +01:00
armada_reg_queue_set ( regs , idx , val , LCD_SPU_DMA_PITCH_UV ) ;
2015-06-15 10:17:57 +01:00
2018-07-30 11:52:34 +01:00
cfg = CFG_DMA_FMT ( drm_fb_to_armada_fb ( state - > fb ) - > fmt ) |
CFG_DMA_MOD ( drm_fb_to_armada_fb ( state - > fb ) - > mod ) |
CFG_CBSH_ENA ;
if ( state - > visible )
cfg | = CFG_DMA_ENA ;
2015-06-15 10:17:57 +01:00
2018-07-30 11:52:34 +01:00
/*
* Shifting a YUV packed format image by one pixel causes the
* U / V planes to swap . Compensate for it by also toggling
* the UV swap .
*/
format = state - > fb - > format ;
2018-07-30 11:52:34 +01:00
src_x = state - > src . x1 > > 16 ;
2018-07-30 11:52:34 +01:00
if ( format - > num_planes = = 1 & & src_x & ( format - > hsub - 1 ) )
cfg ^ = CFG_DMA_MOD ( CFG_SWAPUV ) ;
cfg_mask = CFG_CBSH_ENA | CFG_DMAFORMAT |
CFG_DMA_MOD ( CFG_SWAPRB | CFG_SWAPUV |
CFG_SWAPYU | CFG_YUV2RGB ) |
CFG_DMA_FTOGGLE | CFG_DMA_TSTMODE |
CFG_DMA_ENA ;
} else if ( old_state - > visible ! = state - > visible ) {
cfg = state - > visible ? CFG_DMA_ENA : 0 ;
cfg_mask = CFG_DMA_ENA ;
} else {
cfg = cfg_mask = 0 ;
2012-08-15 13:59:49 +01:00
}
2018-07-30 11:52:34 +01:00
if ( drm_rect_width ( & old_state - > src ) ! = drm_rect_width ( & state - > src ) | |
drm_rect_width ( & old_state - > dst ) ! = drm_rect_width ( & state - > dst ) ) {
cfg_mask | = CFG_DMA_HSMOOTH ;
if ( drm_rect_width ( & state - > src ) > > 16 ! =
drm_rect_width ( & state - > dst ) )
cfg | = CFG_DMA_HSMOOTH ;
2012-08-15 13:59:49 +01:00
}
2017-07-08 10:22:31 +01:00
2018-07-30 11:52:34 +01:00
if ( cfg_mask )
armada_reg_queue_mod ( regs , idx , cfg , cfg_mask ,
LCD_SPU_DMA_CTRL0 ) ;
2018-07-30 11:52:34 +01:00
2018-07-30 11:52:34 +01:00
val = armada_spu_contrast ( state ) ;
if ( ( ! old_state - > visible & & state - > visible ) | |
armada_spu_contrast ( old_state ) ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_CONTRAST ) ;
val = armada_spu_saturation ( state ) ;
if ( ( ! old_state - > visible & & state - > visible ) | |
armada_spu_saturation ( old_state ) ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_SATURATION ) ;
if ( ! old_state - > visible & & state - > visible )
armada_reg_queue_set ( regs , idx , 0x00002000 , LCD_SPU_CBSH_HUE ) ;
2018-07-30 11:52:34 +01:00
val = armada_csc ( state ) ;
if ( ( ! old_state - > visible & & state - > visible ) | |
armada_csc ( old_state ) ! = val )
armada_reg_queue_mod ( regs , idx , val , CFG_CSC_MASK ,
LCD_SPU_IOPAD_CONTROL ) ;
2018-07-30 11:52:34 +01:00
val = drm_to_overlay_state ( state ) - > colorkey_yr ;
if ( ( ! old_state - > visible & & state - > visible ) | |
drm_to_overlay_state ( old_state ) - > colorkey_yr ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_COLORKEY_Y ) ;
val = drm_to_overlay_state ( state ) - > colorkey_ug ;
if ( ( ! old_state - > visible & & state - > visible ) | |
drm_to_overlay_state ( old_state ) - > colorkey_ug ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_COLORKEY_U ) ;
val = drm_to_overlay_state ( state ) - > colorkey_vb ;
if ( ( ! old_state - > visible & & state - > visible ) | |
drm_to_overlay_state ( old_state ) - > colorkey_vb ! = val )
armada_reg_queue_set ( regs , idx , val , LCD_SPU_COLORKEY_V ) ;
val = drm_to_overlay_state ( state ) - > colorkey_mode ;
if ( ( ! old_state - > visible & & state - > visible ) | |
drm_to_overlay_state ( old_state ) - > colorkey_mode ! = val )
armada_reg_queue_mod ( regs , idx , val , CFG_CKMODE_MASK |
CFG_ALPHAM_MASK | CFG_ALPHA_MASK ,
LCD_SPU_DMA_CTRL1 ) ;
val = drm_to_overlay_state ( state ) - > colorkey_enable ;
if ( ( ( ! old_state - > visible & & state - > visible ) | |
drm_to_overlay_state ( old_state ) - > colorkey_enable ! = val ) & &
dcrtc - > variant - > has_spu_adv_reg )
armada_reg_queue_mod ( regs , idx , val , ADV_GRACOLORKEY |
ADV_VIDCOLORKEY , LCD_SPU_ADV_REG ) ;
2018-07-30 11:52:34 +01:00
2018-07-30 11:52:34 +01:00
dcrtc - > regs_idx + = idx ;
2018-07-30 11:52:34 +01:00
}
static void armada_drm_overlay_plane_atomic_disable ( struct drm_plane * plane ,
struct drm_plane_state * old_state )
{
struct armada_crtc * dcrtc ;
struct armada_regs * regs ;
unsigned int idx = 0 ;
DRM_DEBUG_KMS ( " [PLANE:%d:%s] \n " , plane - > base . id , plane - > name ) ;
if ( ! old_state - > crtc )
return ;
DRM_DEBUG_KMS ( " [PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d] \n " ,
plane - > base . id , plane - > name ,
old_state - > crtc - > base . id , old_state - > crtc - > name ,
old_state - > fb - > base . id ) ;
dcrtc = drm_to_armada_crtc ( old_state - > crtc ) ;
regs = dcrtc - > regs + dcrtc - > regs_idx ;
/* Disable plane and power down the YUV FIFOs */
armada_reg_queue_mod ( regs , idx , 0 , CFG_DMA_ENA , LCD_SPU_DMA_CTRL0 ) ;
armada_reg_queue_mod ( regs , idx , CFG_PDWN16x66 | CFG_PDWN32x66 , 0 ,
LCD_SPU_SRAM_PARA1 ) ;
dcrtc - > regs_idx + = idx ;
}
static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs = {
. prepare_fb = armada_drm_plane_prepare_fb ,
. cleanup_fb = armada_drm_plane_cleanup_fb ,
. atomic_check = armada_drm_plane_atomic_check ,
. atomic_update = armada_drm_overlay_plane_atomic_update ,
. atomic_disable = armada_drm_overlay_plane_atomic_disable ,
} ;
static int
2018-07-30 11:53:06 +01:00
armada_overlay_plane_update ( struct drm_plane * plane , struct drm_crtc * crtc ,
2018-07-30 11:52:34 +01:00
struct drm_framebuffer * fb ,
int crtc_x , int crtc_y , unsigned crtc_w , unsigned crtc_h ,
uint32_t src_x , uint32_t src_y , uint32_t src_w , uint32_t src_h ,
struct drm_modeset_acquire_ctx * ctx )
{
2018-07-30 11:53:06 +01:00
struct drm_atomic_state * state ;
struct drm_plane_state * plane_state ;
int ret = 0 ;
2018-07-30 11:52:34 +01:00
trace_armada_ovl_plane_update ( plane , crtc , fb ,
crtc_x , crtc_y , crtc_w , crtc_h ,
src_x , src_y , src_w , src_h ) ;
2018-07-30 11:53:06 +01:00
state = drm_atomic_state_alloc ( plane - > dev ) ;
2018-07-30 11:52:34 +01:00
if ( ! state )
return - ENOMEM ;
2018-07-30 11:53:06 +01:00
state - > acquire_ctx = ctx ;
plane_state = drm_atomic_get_plane_state ( state , plane ) ;
if ( IS_ERR ( plane_state ) ) {
ret = PTR_ERR ( plane_state ) ;
goto fail ;
}
ret = drm_atomic_set_crtc_for_plane ( plane_state , crtc ) ;
if ( ret ! = 0 )
goto fail ;
drm_atomic_set_fb_for_plane ( plane_state , fb ) ;
plane_state - > crtc_x = crtc_x ;
plane_state - > crtc_y = crtc_y ;
plane_state - > crtc_h = crtc_h ;
plane_state - > crtc_w = crtc_w ;
plane_state - > src_x = src_x ;
plane_state - > src_y = src_y ;
plane_state - > src_h = src_h ;
plane_state - > src_w = src_w ;
ret = drm_atomic_nonblocking_commit ( state ) ;
fail :
drm_atomic_state_put ( state ) ;
return ret ;
2012-08-15 13:59:49 +01:00
}
2015-07-15 18:11:23 +01:00
static void armada_ovl_plane_destroy ( struct drm_plane * plane )
2012-08-15 13:59:49 +01:00
{
2015-06-15 10:13:30 +01:00
drm_plane_cleanup ( plane ) ;
2018-07-30 11:53:06 +01:00
kfree ( plane ) ;
2012-08-15 13:59:49 +01:00
}
2018-07-30 11:52:34 +01:00
static void armada_overlay_reset ( struct drm_plane * plane )
{
struct armada_overlay_state * state ;
if ( plane - > state )
__drm_atomic_helper_plane_destroy_state ( plane - > state ) ;
kfree ( plane - > state ) ;
state = kzalloc ( sizeof ( * state ) , GFP_KERNEL ) ;
if ( state ) {
state - > base . plane = plane ;
2018-07-30 11:52:34 +01:00
state - > base . color_encoding = DEFAULT_ENCODING ;
state - > base . color_range = DRM_COLOR_YCBCR_LIMITED_RANGE ;
2018-07-30 11:52:34 +01:00
state - > base . rotation = DRM_MODE_ROTATE_0 ;
2018-07-30 11:52:34 +01:00
state - > colorkey_yr = 0xfefefe00 ;
state - > colorkey_ug = 0x01010100 ;
state - > colorkey_vb = 0x01010100 ;
state - > colorkey_mode = CFG_CKMODE ( CKMODE_RGB ) |
CFG_ALPHAM_GRA | CFG_ALPHA ( 0 ) ;
state - > colorkey_enable = ADV_GRACOLORKEY ;
2018-07-30 11:52:34 +01:00
state - > brightness = DEFAULT_BRIGHTNESS ;
state - > contrast = DEFAULT_CONTRAST ;
state - > saturation = DEFAULT_SATURATION ;
}
plane - > state = & state - > base ;
}
struct drm_plane_state *
armada_overlay_duplicate_state ( struct drm_plane * plane )
{
struct armada_overlay_state * state ;
if ( WARN_ON ( ! plane - > state ) )
return NULL ;
state = kmemdup ( plane - > state , sizeof ( * state ) , GFP_KERNEL ) ;
if ( state )
__drm_atomic_helper_plane_duplicate_state ( plane , & state - > base ) ;
return & state - > base ;
}
static int armada_overlay_set_property ( struct drm_plane * plane ,
struct drm_plane_state * state , struct drm_property * property ,
uint64_t val )
{
struct armada_private * priv = plane - > dev - > dev_private ;
2018-07-30 11:52:34 +01:00
# define K2R(val) (((val) >> 0) & 0xff)
# define K2G(val) (((val) >> 8) & 0xff)
# define K2B(val) (((val) >> 16) & 0xff)
if ( property = = priv - > colorkey_prop ) {
# define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
drm_to_overlay_state ( state ) - > colorkey_yr = CCC ( K2R ( val ) ) ;
drm_to_overlay_state ( state ) - > colorkey_ug = CCC ( K2G ( val ) ) ;
drm_to_overlay_state ( state ) - > colorkey_vb = CCC ( K2B ( val ) ) ;
# undef CCC
} else if ( property = = priv - > colorkey_min_prop ) {
drm_to_overlay_state ( state ) - > colorkey_yr & = ~ 0x00ff0000 ;
drm_to_overlay_state ( state ) - > colorkey_yr | = K2R ( val ) < < 16 ;
drm_to_overlay_state ( state ) - > colorkey_ug & = ~ 0x00ff0000 ;
drm_to_overlay_state ( state ) - > colorkey_ug | = K2G ( val ) < < 16 ;
drm_to_overlay_state ( state ) - > colorkey_vb & = ~ 0x00ff0000 ;
drm_to_overlay_state ( state ) - > colorkey_vb | = K2B ( val ) < < 16 ;
} else if ( property = = priv - > colorkey_max_prop ) {
drm_to_overlay_state ( state ) - > colorkey_yr & = ~ 0xff000000 ;
drm_to_overlay_state ( state ) - > colorkey_yr | = K2R ( val ) < < 24 ;
drm_to_overlay_state ( state ) - > colorkey_ug & = ~ 0xff000000 ;
drm_to_overlay_state ( state ) - > colorkey_ug | = K2G ( val ) < < 24 ;
drm_to_overlay_state ( state ) - > colorkey_vb & = ~ 0xff000000 ;
drm_to_overlay_state ( state ) - > colorkey_vb | = K2B ( val ) < < 24 ;
} else if ( property = = priv - > colorkey_val_prop ) {
drm_to_overlay_state ( state ) - > colorkey_yr & = ~ 0x0000ff00 ;
drm_to_overlay_state ( state ) - > colorkey_yr | = K2R ( val ) < < 8 ;
drm_to_overlay_state ( state ) - > colorkey_ug & = ~ 0x0000ff00 ;
drm_to_overlay_state ( state ) - > colorkey_ug | = K2G ( val ) < < 8 ;
drm_to_overlay_state ( state ) - > colorkey_vb & = ~ 0x0000ff00 ;
drm_to_overlay_state ( state ) - > colorkey_vb | = K2B ( val ) < < 8 ;
} else if ( property = = priv - > colorkey_alpha_prop ) {
drm_to_overlay_state ( state ) - > colorkey_yr & = ~ 0x000000ff ;
drm_to_overlay_state ( state ) - > colorkey_yr | = K2R ( val ) ;
drm_to_overlay_state ( state ) - > colorkey_ug & = ~ 0x000000ff ;
drm_to_overlay_state ( state ) - > colorkey_ug | = K2G ( val ) ;
drm_to_overlay_state ( state ) - > colorkey_vb & = ~ 0x000000ff ;
drm_to_overlay_state ( state ) - > colorkey_vb | = K2B ( val ) ;
} else if ( property = = priv - > colorkey_mode_prop ) {
if ( val = = CKMODE_DISABLE ) {
drm_to_overlay_state ( state ) - > colorkey_mode =
CFG_CKMODE ( CKMODE_DISABLE ) |
CFG_ALPHAM_CFG | CFG_ALPHA ( 255 ) ;
drm_to_overlay_state ( state ) - > colorkey_enable = 0 ;
} else {
drm_to_overlay_state ( state ) - > colorkey_mode =
CFG_CKMODE ( val ) |
CFG_ALPHAM_GRA | CFG_ALPHA ( 0 ) ;
drm_to_overlay_state ( state ) - > colorkey_enable =
ADV_GRACOLORKEY ;
}
} else if ( property = = priv - > brightness_prop ) {
2018-07-30 11:52:34 +01:00
drm_to_overlay_state ( state ) - > brightness = val - 256 ;
} else if ( property = = priv - > contrast_prop ) {
drm_to_overlay_state ( state ) - > contrast = val ;
} else if ( property = = priv - > saturation_prop ) {
drm_to_overlay_state ( state ) - > saturation = val ;
} else {
return - EINVAL ;
}
return 0 ;
}
static int armada_overlay_get_property ( struct drm_plane * plane ,
const struct drm_plane_state * state , struct drm_property * property ,
uint64_t * val )
{
struct armada_private * priv = plane - > dev - > dev_private ;
2018-07-30 11:52:34 +01:00
# define C2K(c,s) (((c) >> (s)) & 0xff)
# define R2BGR(r,g,b,s) (C2K(r,s) << 0 | C2K(g,s) << 8 | C2K(b,s) << 16)
if ( property = = priv - > colorkey_prop ) {
/* Do best-efforts here for this property */
* val = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 16 ) ;
/* If min != max, or min != val, error out */
if ( * val ! = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 24 ) | |
* val ! = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 8 ) )
return - EINVAL ;
} else if ( property = = priv - > colorkey_min_prop ) {
* val = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 16 ) ;
} else if ( property = = priv - > colorkey_max_prop ) {
* val = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 24 ) ;
} else if ( property = = priv - > colorkey_val_prop ) {
* val = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 8 ) ;
} else if ( property = = priv - > colorkey_alpha_prop ) {
* val = R2BGR ( drm_to_overlay_state ( state ) - > colorkey_yr ,
drm_to_overlay_state ( state ) - > colorkey_ug ,
drm_to_overlay_state ( state ) - > colorkey_vb , 0 ) ;
} else if ( property = = priv - > colorkey_mode_prop ) {
* val = ( drm_to_overlay_state ( state ) - > colorkey_mode &
CFG_CKMODE_MASK ) > > ffs ( CFG_CKMODE_MASK ) ;
} else if ( property = = priv - > brightness_prop ) {
2018-07-30 11:52:34 +01:00
* val = drm_to_overlay_state ( state ) - > brightness + 256 ;
} else if ( property = = priv - > contrast_prop ) {
* val = drm_to_overlay_state ( state ) - > contrast ;
} else if ( property = = priv - > saturation_prop ) {
* val = drm_to_overlay_state ( state ) - > saturation ;
} else {
return - EINVAL ;
}
return 0 ;
}
2015-07-15 18:11:23 +01:00
static const struct drm_plane_funcs armada_ovl_plane_funcs = {
2018-07-30 11:53:06 +01:00
. update_plane = armada_overlay_plane_update ,
. disable_plane = drm_atomic_helper_disable_plane ,
2015-07-15 18:11:23 +01:00
. destroy = armada_ovl_plane_destroy ,
2018-07-30 11:52:34 +01:00
. reset = armada_overlay_reset ,
. atomic_duplicate_state = armada_overlay_duplicate_state ,
. atomic_destroy_state = drm_atomic_helper_plane_destroy_state ,
. atomic_set_property = armada_overlay_set_property ,
. atomic_get_property = armada_overlay_get_property ,
2012-08-15 13:59:49 +01:00
} ;
2015-07-15 18:11:23 +01:00
static const uint32_t armada_ovl_formats [ ] = {
2012-08-15 13:59:49 +01:00
DRM_FORMAT_UYVY ,
DRM_FORMAT_YUYV ,
DRM_FORMAT_YUV420 ,
DRM_FORMAT_YVU420 ,
DRM_FORMAT_YUV422 ,
DRM_FORMAT_YVU422 ,
DRM_FORMAT_VYUY ,
DRM_FORMAT_YVYU ,
DRM_FORMAT_ARGB8888 ,
DRM_FORMAT_ABGR8888 ,
DRM_FORMAT_XRGB8888 ,
DRM_FORMAT_XBGR8888 ,
DRM_FORMAT_RGB888 ,
DRM_FORMAT_BGR888 ,
DRM_FORMAT_ARGB1555 ,
DRM_FORMAT_ABGR1555 ,
DRM_FORMAT_RGB565 ,
DRM_FORMAT_BGR565 ,
} ;
2017-07-01 16:24:42 +05:30
static const struct drm_prop_enum_list armada_drm_colorkey_enum_list [ ] = {
2012-08-15 13:59:49 +01:00
{ CKMODE_DISABLE , " disabled " } ,
{ CKMODE_Y , " Y component " } ,
{ CKMODE_U , " U component " } ,
{ CKMODE_V , " V component " } ,
{ CKMODE_RGB , " RGB " } ,
{ CKMODE_R , " R component " } ,
{ CKMODE_G , " G component " } ,
{ CKMODE_B , " B component " } ,
} ;
static int armada_overlay_create_properties ( struct drm_device * dev )
{
struct armada_private * priv = dev - > dev_private ;
if ( priv - > colorkey_prop )
return 0 ;
priv - > colorkey_prop = drm_property_create_range ( dev , 0 ,
" colorkey " , 0 , 0xffffff ) ;
priv - > colorkey_min_prop = drm_property_create_range ( dev , 0 ,
" colorkey_min " , 0 , 0xffffff ) ;
priv - > colorkey_max_prop = drm_property_create_range ( dev , 0 ,
" colorkey_max " , 0 , 0xffffff ) ;
priv - > colorkey_val_prop = drm_property_create_range ( dev , 0 ,
" colorkey_val " , 0 , 0xffffff ) ;
priv - > colorkey_alpha_prop = drm_property_create_range ( dev , 0 ,
" colorkey_alpha " , 0 , 0xffffff ) ;
priv - > colorkey_mode_prop = drm_property_create_enum ( dev , 0 ,
" colorkey_mode " ,
armada_drm_colorkey_enum_list ,
ARRAY_SIZE ( armada_drm_colorkey_enum_list ) ) ;
priv - > brightness_prop = drm_property_create_range ( dev , 0 ,
" brightness " , 0 , 256 + 255 ) ;
priv - > contrast_prop = drm_property_create_range ( dev , 0 ,
" contrast " , 0 , 0x7fff ) ;
priv - > saturation_prop = drm_property_create_range ( dev , 0 ,
" saturation " , 0 , 0x7fff ) ;
if ( ! priv - > colorkey_prop )
return - ENOMEM ;
return 0 ;
}
int armada_overlay_plane_create ( struct drm_device * dev , unsigned long crtcs )
{
struct armada_private * priv = dev - > dev_private ;
struct drm_mode_object * mobj ;
2018-07-30 11:53:06 +01:00
struct drm_plane * overlay ;
2012-08-15 13:59:49 +01:00
int ret ;
ret = armada_overlay_create_properties ( dev ) ;
if ( ret )
return ret ;
2018-07-30 11:53:06 +01:00
overlay = kzalloc ( sizeof ( * overlay ) , GFP_KERNEL ) ;
if ( ! overlay )
2012-08-15 13:59:49 +01:00
return - ENOMEM ;
2018-07-30 11:53:06 +01:00
drm_plane_helper_add ( overlay , & armada_overlay_plane_helper_funcs ) ;
2018-07-30 11:52:34 +01:00
2018-07-30 11:53:06 +01:00
ret = drm_universal_plane_init ( dev , overlay , crtcs ,
2015-07-15 18:11:24 +01:00
& armada_ovl_plane_funcs ,
armada_ovl_formats ,
ARRAY_SIZE ( armada_ovl_formats ) ,
2017-07-23 20:46:38 -07:00
NULL ,
drm: Pass 'name' to drm_universal_plane_init()
Done with coccinelle for the most part. It choked on
msm/mdp/mdp5/mdp5_plane.c like so:
"BAD:!!!!! enum drm_plane_type type;"
No idea how to deal with that, so I just fixed that up
by hand.
Also it thinks '...' is part of the semantic patch, so I put an
'int DOTDOTDOT' placeholder in its place and got rid of it with
sed afterwards.
I didn't convert drm_plane_init() since passing the varargs through
would mean either cpp macros or va_list, and I figured we don't
care about these legacy functions enough to warrant the extra pain.
@@
typedef uint32_t;
identifier dev, plane, possible_crtcs, funcs, formats, format_count, type;
@@
int drm_universal_plane_init(struct drm_device *dev,
struct drm_plane *plane,
unsigned long possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats,
unsigned int format_count,
enum drm_plane_type type
+ ,const char *name, int DOTDOTDOT
)
{ ... }
@@
identifier dev, plane, possible_crtcs, funcs, formats, format_count, type;
@@
int drm_universal_plane_init(struct drm_device *dev,
struct drm_plane *plane,
unsigned long possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats,
unsigned int format_count,
enum drm_plane_type type
+ ,const char *name, int DOTDOTDOT
);
@@
expression E1, E2, E3, E4, E5, E6, E7;
@@
drm_universal_plane_init(E1, E2, E3, E4, E5, E6, E7
+ ,NULL
)
v2: Split crtc and plane changes apart
Pass NUL for no-name instead of ""
Leave drm_plane_init() alone
v3: Add ', or NULL...' to @name kernel doc (Jani)
Annotate the function with __printf() attribute (Jani)
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1449670795-2853-1-git-send-email-ville.syrjala@linux.intel.com
2015-12-09 16:19:55 +02:00
DRM_PLANE_TYPE_OVERLAY , NULL ) ;
2015-07-15 18:11:23 +01:00
if ( ret ) {
2018-07-30 11:53:06 +01:00
kfree ( overlay ) ;
2015-07-15 18:11:23 +01:00
return ret ;
}
2012-08-15 13:59:49 +01:00
2018-07-30 11:53:06 +01:00
mobj = & overlay - > base ;
2012-08-15 13:59:49 +01:00
drm_object_attach_property ( mobj , priv - > colorkey_prop ,
0x0101fe ) ;
drm_object_attach_property ( mobj , priv - > colorkey_min_prop ,
0x0101fe ) ;
drm_object_attach_property ( mobj , priv - > colorkey_max_prop ,
0x0101fe ) ;
drm_object_attach_property ( mobj , priv - > colorkey_val_prop ,
0x0101fe ) ;
drm_object_attach_property ( mobj , priv - > colorkey_alpha_prop ,
0x000000 ) ;
drm_object_attach_property ( mobj , priv - > colorkey_mode_prop ,
CKMODE_RGB ) ;
2018-07-30 11:52:34 +01:00
drm_object_attach_property ( mobj , priv - > brightness_prop ,
256 + DEFAULT_BRIGHTNESS ) ;
2012-08-15 13:59:49 +01:00
drm_object_attach_property ( mobj , priv - > contrast_prop ,
2018-07-30 11:52:34 +01:00
DEFAULT_CONTRAST ) ;
2012-08-15 13:59:49 +01:00
drm_object_attach_property ( mobj , priv - > saturation_prop ,
2018-07-30 11:52:34 +01:00
DEFAULT_SATURATION ) ;
2012-08-15 13:59:49 +01:00
2018-07-30 11:53:06 +01:00
ret = drm_plane_create_color_properties ( overlay ,
2018-07-30 11:52:34 +01:00
BIT ( DRM_COLOR_YCBCR_BT601 ) |
BIT ( DRM_COLOR_YCBCR_BT709 ) ,
BIT ( DRM_COLOR_YCBCR_LIMITED_RANGE ) ,
DEFAULT_ENCODING ,
DRM_COLOR_YCBCR_LIMITED_RANGE ) ;
return ret ;
2012-08-15 13:59:49 +01:00
}