2007-05-08 11:39:08 +04:00
# ifndef _FB_DRAW_H
# define _FB_DRAW_H
# include <asm/types.h>
2007-10-16 12:29:21 +04:00
# include <linux/fb.h>
2007-05-08 11:39:08 +04:00
/*
* Compose two values , using a bitmask as decision value
* This is equivalent to ( a & mask ) | ( b & ~ mask )
*/
static inline unsigned long
comp ( unsigned long a , unsigned long b , unsigned long mask )
{
return ( ( a ^ b ) & mask ) ^ b ;
}
/*
* Create a pattern with the given pixel ' s color
*/
# if BITS_PER_LONG == 64
static inline unsigned long
pixel_to_pat ( u32 bpp , u32 pixel )
{
switch ( bpp ) {
case 1 :
return 0xfffffffffffffffful * pixel ;
case 2 :
return 0x5555555555555555ul * pixel ;
case 4 :
return 0x1111111111111111ul * pixel ;
case 8 :
return 0x0101010101010101ul * pixel ;
case 12 :
2009-05-07 03:02:56 +04:00
return 0x1001001001001001ul * pixel ;
2007-05-08 11:39:08 +04:00
case 16 :
return 0x0001000100010001ul * pixel ;
case 24 :
2009-05-07 03:02:56 +04:00
return 0x0001000001000001ul * pixel ;
2007-05-08 11:39:08 +04:00
case 32 :
return 0x0000000100000001ul * pixel ;
default :
panic ( " pixel_to_pat(): unsupported pixelformat \n " ) ;
}
}
# else
static inline unsigned long
pixel_to_pat ( u32 bpp , u32 pixel )
{
switch ( bpp ) {
case 1 :
return 0xfffffffful * pixel ;
case 2 :
return 0x55555555ul * pixel ;
case 4 :
return 0x11111111ul * pixel ;
case 8 :
return 0x01010101ul * pixel ;
case 12 :
2009-05-07 03:02:56 +04:00
return 0x01001001ul * pixel ;
2007-05-08 11:39:08 +04:00
case 16 :
return 0x00010001ul * pixel ;
case 24 :
2009-05-07 03:02:56 +04:00
return 0x01000001ul * pixel ;
2007-05-08 11:39:08 +04:00
case 32 :
return 0x00000001ul * pixel ;
default :
panic ( " pixel_to_pat(): unsupported pixelformat \n " ) ;
}
}
# endif
2007-10-16 12:29:21 +04:00
# ifdef CONFIG_FB_CFB_REV_PIXELS_IN_BYTE
2007-10-16 12:29:55 +04:00
# if BITS_PER_LONG == 64
# define REV_PIXELS_MASK1 0x5555555555555555ul
# define REV_PIXELS_MASK2 0x3333333333333333ul
# define REV_PIXELS_MASK4 0x0f0f0f0f0f0f0f0ful
# else
# define REV_PIXELS_MASK1 0x55555555ul
# define REV_PIXELS_MASK2 0x33333333ul
# define REV_PIXELS_MASK4 0x0f0f0f0ful
# endif
static inline unsigned long fb_rev_pixels_in_long ( unsigned long val ,
u32 bswapmask )
{
if ( bswapmask & 1 )
val = comp ( val > > 1 , val < < 1 , REV_PIXELS_MASK1 ) ;
if ( bswapmask & 2 )
val = comp ( val > > 2 , val < < 2 , REV_PIXELS_MASK2 ) ;
if ( bswapmask & 3 )
val = comp ( val > > 4 , val < < 4 , REV_PIXELS_MASK4 ) ;
2008-02-06 12:40:23 +03:00
return val ;
2007-10-16 12:29:55 +04:00
}
2007-10-16 12:29:21 +04:00
2008-04-28 13:14:49 +04:00
static inline u32 fb_shifted_pixels_mask_u32 ( struct fb_info * p , u32 index ,
u32 bswapmask )
2007-10-16 12:29:21 +04:00
{
u32 mask ;
if ( ! bswapmask ) {
2008-04-28 13:14:49 +04:00
mask = FB_SHIFT_HIGH ( p , ~ ( u32 ) 0 , index ) ;
2007-10-16 12:29:21 +04:00
} else {
2008-04-28 13:14:49 +04:00
mask = 0xff < < FB_LEFT_POS ( p , 8 ) ;
mask = FB_SHIFT_LOW ( p , mask , index & ( bswapmask ) ) & mask ;
mask = FB_SHIFT_HIGH ( p , mask , index & ~ ( bswapmask ) ) ;
2007-10-16 12:29:21 +04:00
# if defined(__i386__) || defined(__x86_64__)
/* Shift argument is limited to 0 - 31 on x86 based CPU's */
if ( index + bswapmask < 32 )
# endif
2008-04-28 13:14:49 +04:00
mask | = FB_SHIFT_HIGH ( p , ~ ( u32 ) 0 ,
2007-10-16 12:29:21 +04:00
( index + bswapmask ) & ~ ( bswapmask ) ) ;
}
return mask ;
}
2008-04-28 13:14:49 +04:00
static inline unsigned long fb_shifted_pixels_mask_long ( struct fb_info * p ,
u32 index ,
u32 bswapmask )
2007-10-16 12:29:21 +04:00
{
unsigned long mask ;
if ( ! bswapmask ) {
2008-04-28 13:14:49 +04:00
mask = FB_SHIFT_HIGH ( p , ~ 0UL , index ) ;
2007-10-16 12:29:21 +04:00
} else {
2008-04-28 13:14:49 +04:00
mask = 0xff < < FB_LEFT_POS ( p , 8 ) ;
mask = FB_SHIFT_LOW ( p , mask , index & ( bswapmask ) ) & mask ;
mask = FB_SHIFT_HIGH ( p , mask , index & ~ ( bswapmask ) ) ;
2007-10-16 12:29:21 +04:00
# if defined(__i386__) || defined(__x86_64__)
/* Shift argument is limited to 0 - 31 on x86 based CPU's */
if ( index + bswapmask < BITS_PER_LONG )
# endif
2008-04-28 13:14:49 +04:00
mask | = FB_SHIFT_HIGH ( p , ~ 0UL ,
2007-10-16 12:29:21 +04:00
( index + bswapmask ) & ~ ( bswapmask ) ) ;
}
return mask ;
}
static inline u32 fb_compute_bswapmask ( struct fb_info * info )
{
u32 bswapmask = 0 ;
unsigned bpp = info - > var . bits_per_pixel ;
if ( ( bpp < 8 ) & & ( info - > var . nonstd & FB_NONSTD_REV_PIX_IN_B ) ) {
/*
* Reversed order of pixel layout in bytes
* works only for 1 , 2 and 4 bpp
*/
bswapmask = 7 - bpp + 1 ;
}
return bswapmask ;
}
# else /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
2007-10-16 12:29:55 +04:00
static inline unsigned long fb_rev_pixels_in_long ( unsigned long val ,
u32 bswapmask )
{
return val ;
}
2008-04-28 13:14:49 +04:00
# define fb_shifted_pixels_mask_u32(p, i, b) FB_SHIFT_HIGH((p), ~(u32)0, (i))
# define fb_shifted_pixels_mask_long(p, i, b) FB_SHIFT_HIGH((p), ~0UL, (i))
2007-10-16 12:29:21 +04:00
# define fb_compute_bswapmask(...) 0
# endif /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
2009-05-07 03:02:56 +04:00
# define cpu_to_le_long _cpu_to_le_long(BITS_PER_LONG)
# define _cpu_to_le_long(x) __cpu_to_le_long(x)
# define __cpu_to_le_long(x) cpu_to_le##x
# define le_long_to_cpu _le_long_to_cpu(BITS_PER_LONG)
# define _le_long_to_cpu(x) __le_long_to_cpu(x)
# define __le_long_to_cpu(x) le##x##_to_cpu
static inline unsigned long rolx ( unsigned long word , unsigned int shift , unsigned int x )
{
return ( word < < shift ) | ( word > > ( x - shift ) ) ;
}
2007-05-08 11:39:08 +04:00
# endif /* FB_DRAW_H */