2013-06-19 15:54:11 +04:00
/*
* rcar_du_plane . c - - R - Car Display Unit Planes
*
2014-02-06 21:13:52 +04:00
* Copyright ( C ) 2013 - 2014 Renesas Electronics Corporation
2013-06-19 15:54:11 +04:00
*
* Contact : Laurent Pinchart ( laurent . pinchart @ ideasonboard . com )
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
# include <drm/drmP.h>
2015-02-20 12:30:59 +03:00
# include <drm/drm_atomic_helper.h>
2013-06-19 15:54:11 +04:00
# include <drm/drm_crtc.h>
# include <drm/drm_crtc_helper.h>
# include <drm/drm_fb_cma_helper.h>
# include <drm/drm_gem_cma_helper.h>
2015-02-18 13:18:05 +03:00
# include <drm/drm_plane_helper.h>
2013-06-19 15:54:11 +04:00
# include "rcar_du_drv.h"
# include "rcar_du_kms.h"
# include "rcar_du_plane.h"
# include "rcar_du_regs.h"
# define RCAR_DU_COLORKEY_NONE (0 << 24)
# define RCAR_DU_COLORKEY_SOURCE (1 << 24)
# define RCAR_DU_COLORKEY_MASK (1 << 24)
2013-06-16 23:01:02 +04:00
static u32 rcar_du_plane_read ( struct rcar_du_group * rgrp ,
2013-06-19 15:54:11 +04:00
unsigned int index , u32 reg )
{
2013-06-16 23:01:02 +04:00
return rcar_du_read ( rgrp - > dev ,
rgrp - > mmio_offset + index * PLANE_OFF + reg ) ;
2013-06-19 15:54:11 +04:00
}
2013-06-16 23:01:02 +04:00
static void rcar_du_plane_write ( struct rcar_du_group * rgrp ,
2013-06-19 15:54:11 +04:00
unsigned int index , u32 reg , u32 data )
{
2013-06-16 23:01:02 +04:00
rcar_du_write ( rgrp - > dev , rgrp - > mmio_offset + index * PLANE_OFF + reg ,
data ) ;
2013-06-19 15:54:11 +04:00
}
2015-02-23 02:25:19 +03:00
static void rcar_du_plane_setup_fb ( struct rcar_du_plane * plane )
2013-06-19 15:54:11 +04:00
{
2015-02-23 03:59:35 +03:00
struct rcar_du_plane_state * state =
2015-04-29 00:48:17 +03:00
to_rcar_plane_state ( plane - > plane . state ) ;
2015-02-23 02:25:19 +03:00
struct drm_framebuffer * fb = plane - > plane . state - > fb ;
2013-06-16 23:01:02 +04:00
struct rcar_du_group * rgrp = plane - > group ;
2015-02-23 03:59:35 +03:00
unsigned int src_x = state - > state . src_x > > 16 ;
unsigned int src_y = state - > state . src_y > > 16 ;
2015-02-25 19:27:19 +03:00
unsigned int index = state - > hwindex ;
2015-02-23 02:25:19 +03:00
struct drm_gem_cma_object * gem ;
2014-12-09 20:11:18 +03:00
bool interlaced ;
2013-11-13 17:26:01 +04:00
u32 mwr ;
2015-02-23 03:59:35 +03:00
interlaced = state - > state . crtc - > state - > adjusted_mode . flags
2015-02-22 20:24:59 +03:00
& DRM_MODE_FLAG_INTERLACE ;
2014-12-09 20:11:18 +03:00
/* Memory pitch (expressed in pixels). Must be doubled for interlaced
* operation with 32 bpp formats .
*/
2015-02-23 03:59:35 +03:00
if ( state - > format - > planes = = 2 )
2015-02-23 02:25:19 +03:00
mwr = fb - > pitches [ 0 ] ;
2013-11-13 17:26:01 +04:00
else
2015-02-23 03:59:35 +03:00
mwr = fb - > pitches [ 0 ] * 8 / state - > format - > bpp ;
2013-11-13 17:26:01 +04:00
2015-02-23 03:59:35 +03:00
if ( interlaced & & state - > format - > bpp = = 32 )
2014-12-09 20:11:18 +03:00
mwr * = 2 ;
2013-11-13 17:26:01 +04:00
rcar_du_plane_write ( rgrp , index , PnMWR , mwr ) ;
2013-06-19 15:54:11 +04:00
2013-06-14 22:54:16 +04:00
/* The Y position is expressed in raster line units and must be doubled
* for 32 bpp formats , according to the R8A7790 datasheet . No mention of
* doubling the Y position is found in the R8A7779 datasheet , but the
* rule seems to apply there as well .
*
2014-12-09 20:11:18 +03:00
* Despite not being documented , doubling seem not to be needed when
* operating in interlaced mode .
*
2013-06-14 22:54:16 +04:00
* Similarly , for the second plane , NV12 and NV21 formats seem to
2014-12-09 20:11:18 +03:00
* require a halved Y position value , in both progressive and interlaced
* modes .
2013-06-19 15:54:11 +04:00
*/
2015-02-20 16:58:38 +03:00
rcar_du_plane_write ( rgrp , index , PnSPXR , src_x ) ;
rcar_du_plane_write ( rgrp , index , PnSPYR , src_y *
2015-02-23 03:59:35 +03:00
( ! interlaced & & state - > format - > bpp = = 32 ? 2 : 1 ) ) ;
2015-02-23 02:25:19 +03:00
gem = drm_fb_cma_get_gem_obj ( fb , 0 ) ;
rcar_du_plane_write ( rgrp , index , PnDSA0R , gem - > paddr + fb - > offsets [ 0 ] ) ;
2013-06-19 15:54:11 +04:00
2015-02-23 03:59:35 +03:00
if ( state - > format - > planes = = 2 ) {
2013-06-19 15:54:11 +04:00
index = ( index + 1 ) % 8 ;
2015-02-23 02:25:19 +03:00
rcar_du_plane_write ( rgrp , index , PnMWR , fb - > pitches [ 0 ] ) ;
2014-12-09 23:45:11 +03:00
2015-02-20 16:58:38 +03:00
rcar_du_plane_write ( rgrp , index , PnSPXR , src_x ) ;
rcar_du_plane_write ( rgrp , index , PnSPYR , src_y *
2015-02-23 03:59:35 +03:00
( state - > format - > bpp = = 16 ? 2 : 1 ) / 2 ) ;
2013-11-13 17:26:01 +04:00
2013-06-19 15:54:11 +04:00
gem = drm_fb_cma_get_gem_obj ( fb , 1 ) ;
2015-02-23 02:25:19 +03:00
rcar_du_plane_write ( rgrp , index , PnDSA0R ,
gem - > paddr + fb - > offsets [ 1 ] ) ;
2013-06-19 15:54:11 +04:00
}
}
static void rcar_du_plane_setup_mode ( struct rcar_du_plane * plane ,
unsigned int index )
{
2015-02-23 03:36:31 +03:00
struct rcar_du_plane_state * state =
2015-04-29 00:48:17 +03:00
to_rcar_plane_state ( plane - > plane . state ) ;
2013-06-16 23:01:02 +04:00
struct rcar_du_group * rgrp = plane - > group ;
2013-06-19 15:54:11 +04:00
u32 colorkey ;
u32 pnmr ;
/* The PnALPHAR register controls alpha-blending in 16bpp formats
* ( ARGB1555 and XRGB1555 ) .
*
* For ARGB , set the alpha value to 0 , and enable alpha - blending when
* the A bit is 0. This maps A = 0 to alpha = 0 and A = 1 to alpha = 255.
*
* For XRGB , set the alpha value to the plane - wide alpha value and
* enable alpha - blending regardless of the X bit value .
*/
2015-02-23 03:59:35 +03:00
if ( state - > format - > fourcc ! = DRM_FORMAT_XRGB1555 )
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnALPHAR , PnALPHAR_ABIT_0 ) ;
2013-06-19 15:54:11 +04:00
else
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnALPHAR ,
2015-02-23 03:36:31 +03:00
PnALPHAR_ABIT_X | state - > alpha ) ;
2013-06-19 15:54:11 +04:00
2015-02-23 03:59:35 +03:00
pnmr = PnMR_BM_MD | state - > format - > pnmr ;
2013-06-19 15:54:11 +04:00
/* Disable color keying when requested. YUV formats have the
* PnMR_SPIM_TP_OFF bit set in their pnmr field , disabling color keying
* automatically .
*/
2015-02-23 03:36:31 +03:00
if ( ( state - > colorkey & RCAR_DU_COLORKEY_MASK ) = = RCAR_DU_COLORKEY_NONE )
2013-06-19 15:54:11 +04:00
pnmr | = PnMR_SPIM_TP_OFF ;
/* For packed YUV formats we need to select the U/V order. */
2015-02-23 03:59:35 +03:00
if ( state - > format - > fourcc = = DRM_FORMAT_YUYV )
2013-06-19 15:54:11 +04:00
pnmr | = PnMR_YCDF_YUYV ;
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnMR , pnmr ) ;
2013-06-19 15:54:11 +04:00
2015-02-23 03:59:35 +03:00
switch ( state - > format - > fourcc ) {
2013-06-19 15:54:11 +04:00
case DRM_FORMAT_RGB565 :
2015-02-23 03:36:31 +03:00
colorkey = ( ( state - > colorkey & 0xf80000 ) > > 8 )
| ( ( state - > colorkey & 0x00fc00 ) > > 5 )
| ( ( state - > colorkey & 0x0000f8 ) > > 3 ) ;
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnTC2R , colorkey ) ;
2013-06-19 15:54:11 +04:00
break ;
case DRM_FORMAT_ARGB1555 :
case DRM_FORMAT_XRGB1555 :
2015-02-23 03:36:31 +03:00
colorkey = ( ( state - > colorkey & 0xf80000 ) > > 9 )
| ( ( state - > colorkey & 0x00f800 ) > > 6 )
| ( ( state - > colorkey & 0x0000f8 ) > > 3 ) ;
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnTC2R , colorkey ) ;
2013-06-19 15:54:11 +04:00
break ;
case DRM_FORMAT_XRGB8888 :
case DRM_FORMAT_ARGB8888 :
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnTC3R ,
2015-02-23 03:36:31 +03:00
PnTC3R_CODE | ( state - > colorkey & 0xffffff ) ) ;
2013-06-19 15:54:11 +04:00
break ;
}
}
static void __rcar_du_plane_setup ( struct rcar_du_plane * plane ,
unsigned int index )
{
2015-02-23 03:59:35 +03:00
struct rcar_du_plane_state * state =
2015-04-29 00:48:17 +03:00
to_rcar_plane_state ( plane - > plane . state ) ;
2013-06-16 23:01:02 +04:00
struct rcar_du_group * rgrp = plane - > group ;
2013-06-19 15:54:11 +04:00
u32 ddcr2 = PnDDCR2_CODE ;
u32 ddcr4 ;
/* Data format
*
* The data format is selected by the DDDF field in PnMR and the EDF
* field in DDCR4 .
*/
2013-06-16 23:01:02 +04:00
ddcr4 = rcar_du_plane_read ( rgrp , index , PnDDCR4 ) ;
2013-06-19 15:54:11 +04:00
ddcr4 & = ~ PnDDCR4_EDF_MASK ;
2015-02-23 03:59:35 +03:00
ddcr4 | = state - > format - > edf | PnDDCR4_CODE ;
2013-06-19 15:54:11 +04:00
rcar_du_plane_setup_mode ( plane , index ) ;
2015-02-23 03:59:35 +03:00
if ( state - > format - > planes = = 2 ) {
2015-02-25 19:27:19 +03:00
if ( state - > hwindex ! = index ) {
2015-02-23 03:59:35 +03:00
if ( state - > format - > fourcc = = DRM_FORMAT_NV12 | |
state - > format - > fourcc = = DRM_FORMAT_NV21 )
2013-06-19 15:54:11 +04:00
ddcr2 | = PnDDCR2_Y420 ;
2015-02-23 03:59:35 +03:00
if ( state - > format - > fourcc = = DRM_FORMAT_NV21 )
2013-06-19 15:54:11 +04:00
ddcr2 | = PnDDCR2_NV21 ;
ddcr2 | = PnDDCR2_DIVU ;
} else {
ddcr2 | = PnDDCR2_DIVY ;
}
}
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnDDCR2 , ddcr2 ) ;
rcar_du_plane_write ( rgrp , index , PnDDCR4 , ddcr4 ) ;
2013-06-19 15:54:11 +04:00
/* Destination position and size */
2015-02-20 16:58:38 +03:00
rcar_du_plane_write ( rgrp , index , PnDSXR , plane - > plane . state - > crtc_w ) ;
rcar_du_plane_write ( rgrp , index , PnDSYR , plane - > plane . state - > crtc_h ) ;
rcar_du_plane_write ( rgrp , index , PnDPXR , plane - > plane . state - > crtc_x ) ;
rcar_du_plane_write ( rgrp , index , PnDPYR , plane - > plane . state - > crtc_y ) ;
2013-06-19 15:54:11 +04:00
/* Wrap-around and blinking, disabled */
2013-06-16 23:01:02 +04:00
rcar_du_plane_write ( rgrp , index , PnWASPR , 0 ) ;
rcar_du_plane_write ( rgrp , index , PnWAMWR , 4095 ) ;
rcar_du_plane_write ( rgrp , index , PnBTR , 0 ) ;
rcar_du_plane_write ( rgrp , index , PnMLR , 0 ) ;
2013-06-19 15:54:11 +04:00
}
void rcar_du_plane_setup ( struct rcar_du_plane * plane )
{
2015-02-23 03:59:35 +03:00
struct rcar_du_plane_state * state =
2015-04-29 00:48:17 +03:00
to_rcar_plane_state ( plane - > plane . state ) ;
2015-02-23 03:59:35 +03:00
2015-02-25 19:27:19 +03:00
__rcar_du_plane_setup ( plane , state - > hwindex ) ;
2015-02-23 03:59:35 +03:00
if ( state - > format - > planes = = 2 )
2015-02-25 19:27:19 +03:00
__rcar_du_plane_setup ( plane , ( state - > hwindex + 1 ) % 8 ) ;
2013-06-19 15:54:11 +04:00
2015-02-23 02:25:19 +03:00
rcar_du_plane_setup_fb ( plane ) ;
2013-06-19 15:54:11 +04:00
}
2015-02-18 13:18:05 +03:00
static int rcar_du_plane_atomic_check ( struct drm_plane * plane ,
struct drm_plane_state * state )
2013-06-19 15:54:11 +04:00
{
2015-04-29 00:48:17 +03:00
struct rcar_du_plane_state * rstate = to_rcar_plane_state ( state ) ;
2013-06-19 15:54:11 +04:00
struct rcar_du_plane * rplane = to_rcar_plane ( plane ) ;
2013-06-16 23:01:02 +04:00
struct rcar_du_device * rcdu = rplane - > group - > dev ;
2013-06-19 15:54:11 +04:00
2015-02-25 19:27:19 +03:00
if ( ! state - > fb | | ! state - > crtc ) {
rstate - > format = NULL ;
2015-02-18 13:18:05 +03:00
return 0 ;
2015-02-25 19:27:19 +03:00
}
2015-02-17 19:34:17 +03:00
2015-02-18 13:18:05 +03:00
if ( state - > src_w > > 16 ! = state - > crtc_w | |
state - > src_h > > 16 ! = state - > crtc_h ) {
dev_dbg ( rcdu - > dev , " %s: scaling not supported \n " , __func__ ) ;
2013-06-19 15:54:11 +04:00
return - EINVAL ;
}
2015-02-25 19:27:19 +03:00
rstate - > format = rcar_du_format_info ( state - > fb - > pixel_format ) ;
if ( rstate - > format = = NULL ) {
2015-02-18 13:18:05 +03:00
dev_dbg ( rcdu - > dev , " %s: unsupported format %08x \n " , __func__ ,
state - > fb - > pixel_format ) ;
2013-06-19 15:54:11 +04:00
return - EINVAL ;
}
return 0 ;
}
2015-02-18 13:18:05 +03:00
static void rcar_du_plane_atomic_update ( struct drm_plane * plane ,
struct drm_plane_state * old_state )
{
struct rcar_du_plane * rplane = to_rcar_plane ( plane ) ;
2015-02-23 03:59:35 +03:00
2015-02-25 19:27:19 +03:00
if ( plane - > state - > crtc )
rcar_du_plane_setup ( rplane ) ;
2013-06-19 15:54:11 +04:00
}
2015-02-18 13:18:05 +03:00
static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {
. atomic_check = rcar_du_plane_atomic_check ,
. atomic_update = rcar_du_plane_atomic_update ,
} ;
2015-02-23 03:36:31 +03:00
static void rcar_du_plane_reset ( struct drm_plane * plane )
2013-06-19 15:54:11 +04:00
{
2015-02-23 03:36:31 +03:00
struct rcar_du_plane_state * state ;
if ( plane - > state & & plane - > state - > fb )
drm_framebuffer_unreference ( plane - > state - > fb ) ;
2013-06-19 15:54:11 +04:00
2015-02-23 03:36:31 +03:00
kfree ( plane - > state ) ;
plane - > state = NULL ;
state = kzalloc ( sizeof ( * state ) , GFP_KERNEL ) ;
if ( state = = NULL )
2013-06-19 15:54:11 +04:00
return ;
2015-02-25 19:27:19 +03:00
state - > hwindex = - 1 ;
2015-02-23 03:36:31 +03:00
state - > alpha = 255 ;
state - > colorkey = RCAR_DU_COLORKEY_NONE ;
state - > zpos = plane - > type = = DRM_PLANE_TYPE_PRIMARY ? 0 : 1 ;
plane - > state = & state - > state ;
plane - > state - > plane = plane ;
2013-06-19 15:54:11 +04:00
}
2015-02-23 03:36:31 +03:00
static struct drm_plane_state *
rcar_du_plane_atomic_duplicate_state ( struct drm_plane * plane )
2013-06-19 15:54:11 +04:00
{
2015-02-23 03:36:31 +03:00
struct rcar_du_plane_state * state ;
struct rcar_du_plane_state * copy ;
2013-06-19 15:54:11 +04:00
2015-05-27 16:36:29 +03:00
if ( WARN_ON ( ! plane - > state ) )
return NULL ;
2015-04-29 00:48:17 +03:00
state = to_rcar_plane_state ( plane - > state ) ;
2015-02-23 03:36:31 +03:00
copy = kmemdup ( state , sizeof ( * state ) , GFP_KERNEL ) ;
if ( copy = = NULL )
return NULL ;
2015-05-27 16:36:29 +03:00
__drm_atomic_helper_plane_duplicate_state ( plane , & copy - > state ) ;
2013-06-19 15:54:11 +04:00
2015-02-23 03:36:31 +03:00
return & copy - > state ;
2013-06-19 15:54:11 +04:00
}
2015-02-23 03:36:31 +03:00
static void rcar_du_plane_atomic_destroy_state ( struct drm_plane * plane ,
struct drm_plane_state * state )
2013-06-19 15:54:11 +04:00
{
2015-05-27 16:36:29 +03:00
__drm_atomic_helper_plane_destroy_state ( plane , state ) ;
2015-04-29 00:48:17 +03:00
kfree ( to_rcar_plane_state ( state ) ) ;
2015-02-23 03:36:31 +03:00
}
2013-06-19 15:54:11 +04:00
2015-02-23 03:36:31 +03:00
static int rcar_du_plane_atomic_set_property ( struct drm_plane * plane ,
struct drm_plane_state * state ,
struct drm_property * property ,
uint64_t val )
{
2015-04-29 00:48:17 +03:00
struct rcar_du_plane_state * rstate = to_rcar_plane_state ( state ) ;
2015-04-28 23:59:29 +03:00
struct rcar_du_device * rcdu = to_rcar_plane ( plane ) - > group - > dev ;
2013-06-19 15:54:11 +04:00
2015-04-28 23:59:29 +03:00
if ( property = = rcdu - > props . alpha )
2015-02-23 03:36:31 +03:00
rstate - > alpha = val ;
2015-04-28 23:59:29 +03:00
else if ( property = = rcdu - > props . colorkey )
2015-02-23 03:36:31 +03:00
rstate - > colorkey = val ;
2015-04-28 23:59:29 +03:00
else if ( property = = rcdu - > props . zpos )
2015-02-23 03:36:31 +03:00
rstate - > zpos = val ;
else
return - EINVAL ;
2013-06-19 15:54:11 +04:00
2015-02-23 03:36:31 +03:00
return 0 ;
2013-06-19 15:54:11 +04:00
}
2015-02-23 03:36:31 +03:00
static int rcar_du_plane_atomic_get_property ( struct drm_plane * plane ,
const struct drm_plane_state * state , struct drm_property * property ,
uint64_t * val )
2013-06-19 15:54:11 +04:00
{
2015-02-23 03:36:31 +03:00
const struct rcar_du_plane_state * rstate =
container_of ( state , const struct rcar_du_plane_state , state ) ;
2015-04-28 23:59:29 +03:00
struct rcar_du_device * rcdu = to_rcar_plane ( plane ) - > group - > dev ;
2013-06-19 15:54:11 +04:00
2015-04-28 23:59:29 +03:00
if ( property = = rcdu - > props . alpha )
2015-02-23 03:36:31 +03:00
* val = rstate - > alpha ;
2015-04-28 23:59:29 +03:00
else if ( property = = rcdu - > props . colorkey )
2015-02-23 03:36:31 +03:00
* val = rstate - > colorkey ;
2015-04-28 23:59:29 +03:00
else if ( property = = rcdu - > props . zpos )
2015-02-23 03:36:31 +03:00
* val = rstate - > zpos ;
2013-06-19 15:54:11 +04:00
else
return - EINVAL ;
return 0 ;
}
static const struct drm_plane_funcs rcar_du_plane_funcs = {
2015-02-20 14:18:56 +03:00
. update_plane = drm_atomic_helper_update_plane ,
. disable_plane = drm_atomic_helper_disable_plane ,
2015-02-23 03:36:31 +03:00
. reset = rcar_du_plane_reset ,
. set_property = drm_atomic_helper_plane_set_property ,
2013-06-19 15:54:11 +04:00
. destroy = drm_plane_cleanup ,
2015-02-23 03:36:31 +03:00
. atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state ,
. atomic_destroy_state = rcar_du_plane_atomic_destroy_state ,
. atomic_set_property = rcar_du_plane_atomic_set_property ,
. atomic_get_property = rcar_du_plane_atomic_get_property ,
2013-06-19 15:54:11 +04:00
} ;
static const uint32_t formats [ ] = {
DRM_FORMAT_RGB565 ,
DRM_FORMAT_ARGB1555 ,
DRM_FORMAT_XRGB1555 ,
DRM_FORMAT_XRGB8888 ,
DRM_FORMAT_ARGB8888 ,
DRM_FORMAT_UYVY ,
DRM_FORMAT_YUYV ,
DRM_FORMAT_NV12 ,
DRM_FORMAT_NV21 ,
DRM_FORMAT_NV16 ,
} ;
2013-06-16 23:01:02 +04:00
int rcar_du_planes_init ( struct rcar_du_group * rgrp )
2013-06-19 15:54:11 +04:00
{
2013-06-16 23:01:02 +04:00
struct rcar_du_device * rcdu = rgrp - > dev ;
2015-02-17 19:34:17 +03:00
unsigned int crtcs ;
2013-06-19 15:54:11 +04:00
unsigned int i ;
2015-02-17 19:34:17 +03:00
int ret ;
2013-06-19 15:54:11 +04:00
2015-04-28 23:59:29 +03:00
/* Create one primary plane per CRTC in this group and seven overlay
2015-02-17 19:34:17 +03:00
* planes .
*/
2015-05-25 16:32:45 +03:00
rgrp - > num_planes = rgrp - > num_crtcs + 7 ;
2015-02-17 19:34:17 +03:00
crtcs = ( ( 1 < < rcdu - > num_crtcs ) - 1 ) & ( 3 < < ( 2 * rgrp - > index ) ) ;
2015-05-25 16:32:45 +03:00
for ( i = 0 ; i < rgrp - > num_planes ; + + i ) {
2015-04-28 17:36:33 +03:00
enum drm_plane_type type = i < rgrp - > num_crtcs
2015-02-17 19:34:17 +03:00
? DRM_PLANE_TYPE_PRIMARY
: DRM_PLANE_TYPE_OVERLAY ;
2015-04-29 00:05:56 +03:00
struct rcar_du_plane * plane = & rgrp - > planes [ i ] ;
2013-06-19 15:54:11 +04:00
2013-06-16 23:01:02 +04:00
plane - > group = rgrp ;
2013-06-19 15:54:11 +04:00
2015-02-17 19:34:17 +03:00
ret = drm_universal_plane_init ( rcdu - > ddev , & plane - > plane , crtcs ,
& rcar_du_plane_funcs , formats ,
ARRAY_SIZE ( formats ) , type ) ;
2013-06-19 15:54:11 +04:00
if ( ret < 0 )
return ret ;
2015-02-18 13:18:05 +03:00
drm_plane_helper_add ( & plane - > plane ,
& rcar_du_plane_helper_funcs ) ;
2015-02-17 19:34:17 +03:00
if ( type = = DRM_PLANE_TYPE_PRIMARY )
continue ;
2013-06-19 15:54:11 +04:00
drm_object_attach_property ( & plane - > plane . base ,
2015-04-28 23:59:29 +03:00
rcdu - > props . alpha , 255 ) ;
2013-06-19 15:54:11 +04:00
drm_object_attach_property ( & plane - > plane . base ,
2015-04-28 23:59:29 +03:00
rcdu - > props . colorkey ,
2013-06-19 15:54:11 +04:00
RCAR_DU_COLORKEY_NONE ) ;
drm_object_attach_property ( & plane - > plane . base ,
2015-04-28 23:59:29 +03:00
rcdu - > props . zpos , 1 ) ;
2013-06-19 15:54:11 +04:00
}
return 0 ;
}