Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _FB_DRAW_H
0003 #define _FB_DRAW_H
0004 
0005 #include <asm/types.h>
0006 #include <linux/fb.h>
0007 #include <linux/bug.h>
0008 
0009     /*
0010      *  Compose two values, using a bitmask as decision value
0011      *  This is equivalent to (a & mask) | (b & ~mask)
0012      */
0013 
0014 static inline unsigned long
0015 comp(unsigned long a, unsigned long b, unsigned long mask)
0016 {
0017     return ((a ^ b) & mask) ^ b;
0018 }
0019 
0020     /*
0021      *  Create a pattern with the given pixel's color
0022      */
0023 
0024 #if BITS_PER_LONG == 64
0025 static inline unsigned long
0026 pixel_to_pat( u32 bpp, u32 pixel)
0027 {
0028     switch (bpp) {
0029     case 1:
0030         return 0xfffffffffffffffful*pixel;
0031     case 2:
0032         return 0x5555555555555555ul*pixel;
0033     case 4:
0034         return 0x1111111111111111ul*pixel;
0035     case 8:
0036         return 0x0101010101010101ul*pixel;
0037     case 12:
0038         return 0x1001001001001001ul*pixel;
0039     case 16:
0040         return 0x0001000100010001ul*pixel;
0041     case 24:
0042         return 0x0001000001000001ul*pixel;
0043     case 32:
0044         return 0x0000000100000001ul*pixel;
0045     default:
0046         WARN(1, "pixel_to_pat(): unsupported pixelformat %d\n", bpp);
0047         return 0;
0048     }
0049 }
0050 #else
0051 static inline unsigned long
0052 pixel_to_pat( u32 bpp, u32 pixel)
0053 {
0054     switch (bpp) {
0055     case 1:
0056         return 0xfffffffful*pixel;
0057     case 2:
0058         return 0x55555555ul*pixel;
0059     case 4:
0060         return 0x11111111ul*pixel;
0061     case 8:
0062         return 0x01010101ul*pixel;
0063     case 12:
0064         return 0x01001001ul*pixel;
0065     case 16:
0066         return 0x00010001ul*pixel;
0067     case 24:
0068         return 0x01000001ul*pixel;
0069     case 32:
0070         return 0x00000001ul*pixel;
0071     default:
0072         WARN(1, "pixel_to_pat(): unsupported pixelformat %d\n", bpp);
0073         return 0;
0074     }
0075 }
0076 #endif
0077 
0078 #ifdef CONFIG_FB_CFB_REV_PIXELS_IN_BYTE
0079 #if BITS_PER_LONG == 64
0080 #define REV_PIXELS_MASK1 0x5555555555555555ul
0081 #define REV_PIXELS_MASK2 0x3333333333333333ul
0082 #define REV_PIXELS_MASK4 0x0f0f0f0f0f0f0f0ful
0083 #else
0084 #define REV_PIXELS_MASK1 0x55555555ul
0085 #define REV_PIXELS_MASK2 0x33333333ul
0086 #define REV_PIXELS_MASK4 0x0f0f0f0ful
0087 #endif
0088 
0089 static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
0090                           u32 bswapmask)
0091 {
0092     if (bswapmask & 1)
0093         val = comp(val >> 1, val << 1, REV_PIXELS_MASK1);
0094     if (bswapmask & 2)
0095         val = comp(val >> 2, val << 2, REV_PIXELS_MASK2);
0096     if (bswapmask & 3)
0097         val = comp(val >> 4, val << 4, REV_PIXELS_MASK4);
0098     return val;
0099 }
0100 
0101 static inline u32 fb_shifted_pixels_mask_u32(struct fb_info *p, u32 index,
0102                          u32 bswapmask)
0103 {
0104     u32 mask;
0105 
0106     if (!bswapmask) {
0107         mask = FB_SHIFT_HIGH(p, ~(u32)0, index);
0108     } else {
0109         mask = 0xff << FB_LEFT_POS(p, 8);
0110         mask = FB_SHIFT_LOW(p, mask, index & (bswapmask)) & mask;
0111         mask = FB_SHIFT_HIGH(p, mask, index & ~(bswapmask));
0112 #if defined(__i386__) || defined(__x86_64__)
0113         /* Shift argument is limited to 0 - 31 on x86 based CPU's */
0114         if(index + bswapmask < 32)
0115 #endif
0116             mask |= FB_SHIFT_HIGH(p, ~(u32)0,
0117                     (index + bswapmask) & ~(bswapmask));
0118     }
0119     return mask;
0120 }
0121 
0122 static inline unsigned long fb_shifted_pixels_mask_long(struct fb_info *p,
0123                             u32 index,
0124                             u32 bswapmask)
0125 {
0126     unsigned long mask;
0127 
0128     if (!bswapmask) {
0129         mask = FB_SHIFT_HIGH(p, ~0UL, index);
0130     } else {
0131         mask = 0xff << FB_LEFT_POS(p, 8);
0132         mask = FB_SHIFT_LOW(p, mask, index & (bswapmask)) & mask;
0133         mask = FB_SHIFT_HIGH(p, mask, index & ~(bswapmask));
0134 #if defined(__i386__) || defined(__x86_64__)
0135         /* Shift argument is limited to 0 - 31 on x86 based CPU's */
0136         if(index + bswapmask < BITS_PER_LONG)
0137 #endif
0138             mask |= FB_SHIFT_HIGH(p, ~0UL,
0139                     (index + bswapmask) & ~(bswapmask));
0140     }
0141     return mask;
0142 }
0143 
0144 
0145 static inline u32 fb_compute_bswapmask(struct fb_info *info)
0146 {
0147     u32 bswapmask = 0;
0148     unsigned bpp = info->var.bits_per_pixel;
0149 
0150     if ((bpp < 8) && (info->var.nonstd & FB_NONSTD_REV_PIX_IN_B)) {
0151         /*
0152          * Reversed order of pixel layout in bytes
0153          * works only for 1, 2 and 4 bpp
0154          */
0155         bswapmask = 7 - bpp + 1;
0156     }
0157     return bswapmask;
0158 }
0159 
0160 #else /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
0161 
0162 static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
0163                           u32 bswapmask)
0164 {
0165     return val;
0166 }
0167 
0168 #define fb_shifted_pixels_mask_u32(p, i, b) FB_SHIFT_HIGH((p), ~(u32)0, (i))
0169 #define fb_shifted_pixels_mask_long(p, i, b) FB_SHIFT_HIGH((p), ~0UL, (i))
0170 #define fb_compute_bswapmask(...) 0
0171 
0172 #endif  /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
0173 
0174 #define cpu_to_le_long _cpu_to_le_long(BITS_PER_LONG)
0175 #define _cpu_to_le_long(x) __cpu_to_le_long(x)
0176 #define __cpu_to_le_long(x) cpu_to_le##x
0177 
0178 #define le_long_to_cpu _le_long_to_cpu(BITS_PER_LONG)
0179 #define _le_long_to_cpu(x) __le_long_to_cpu(x)
0180 #define __le_long_to_cpu(x) le##x##_to_cpu
0181 
0182 static inline unsigned long rolx(unsigned long word, unsigned int shift, unsigned int x)
0183 {
0184     return (word << shift) | (word >> (x - shift));
0185 }
0186 
0187 #endif /* FB_DRAW_H */