2009-06-05 14:42:42 +02:00
/*
* Copyright 2009 Red Hat Inc .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDER ( S ) OR AUTHOR ( S ) BE LIABLE FOR ANY CLAIM , DAMAGES OR
* OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE ,
* ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE .
*
* Authors : Dave Airlie
*/
2010-04-28 11:46:42 +10:00
# ifndef DRM_FIXED_H
# define DRM_FIXED_H
2009-06-05 14:42:42 +02:00
2010-04-28 11:46:42 +10:00
typedef union dfixed {
2009-06-05 14:42:42 +02:00
u32 full ;
} fixed20_12 ;
2010-04-28 11:46:42 +10:00
# define dfixed_const(A) (u32)(((A) << 12)) /* + ((B + 0.000122)*4096)) */
# define dfixed_const_half(A) (u32)(((A) << 12) + 2048)
# define dfixed_const_666(A) (u32)(((A) << 12) + 2731)
# define dfixed_const_8(A) (u32)(((A) << 12) + 3277)
# define dfixed_mul(A, B) ((u64)((u64)(A).full * (B).full + 2048) >> 12)
# define dfixed_init(A) { .full = dfixed_const((A)) }
# define dfixed_init_half(A) { .full = dfixed_const_half((A)) }
# define dfixed_trunc(A) ((A).full >> 12)
2012-04-25 11:45:01 +02:00
# define dfixed_frac(A) ((A).full & ((1 << 12) - 1))
2009-06-05 14:42:42 +02:00
2010-04-28 11:46:42 +10:00
static inline u32 dfixed_floor ( fixed20_12 A )
2009-12-09 14:40:06 -05:00
{
2010-04-28 11:46:42 +10:00
u32 non_frac = dfixed_trunc ( A ) ;
2009-12-09 14:40:06 -05:00
2010-04-28 11:46:42 +10:00
return dfixed_const ( non_frac ) ;
2009-12-09 14:40:06 -05:00
}
2010-04-28 11:46:42 +10:00
static inline u32 dfixed_ceil ( fixed20_12 A )
2009-12-09 14:40:06 -05:00
{
2010-04-28 11:46:42 +10:00
u32 non_frac = dfixed_trunc ( A ) ;
2009-12-09 14:40:06 -05:00
2010-04-28 11:46:42 +10:00
if ( A . full > dfixed_const ( non_frac ) )
return dfixed_const ( non_frac + 1 ) ;
2009-12-09 14:40:06 -05:00
else
2010-04-28 11:46:42 +10:00
return dfixed_const ( non_frac ) ;
2009-12-09 14:40:06 -05:00
}
2010-04-28 11:46:42 +10:00
static inline u32 dfixed_div ( fixed20_12 A , fixed20_12 B )
2009-06-05 14:42:42 +02:00
{
u64 tmp = ( ( u64 ) A . full < < 13 ) ;
do_div ( tmp , B . full ) ;
tmp + = 1 ;
tmp / = 2 ;
return lower_32_bits ( tmp ) ;
}
# endif