fbcon-cfb32.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/video/cfb32.c -- Low level frame buffer operations for 32 bpp
  3.  *    truecolor packed pixels
  4.  *
  5.  * Created 28 Dec 1997 by Geert Uytterhoeven
  6.  *
  7.  *  This file is subject to the terms and conditions of the GNU General Public
  8.  *  License.  See the file COPYING in the main directory of this archive for
  9.  *  more details.
  10.  */
  11. #include <linux/module.h>
  12. #include <linux/tty.h>
  13. #include <linux/console.h>
  14. #include <linux/string.h>
  15. #include <linux/fb.h>
  16. #include <video/fbcon.h>
  17. #include <video/fbcon-cfb32.h>
  18.     /*
  19.      *  32 bpp packed pixels
  20.      */
  21. void fbcon_cfb32_setup(struct display *p)
  22. {
  23.     p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<2;
  24.     p->next_plane = 0;
  25. }
  26. void fbcon_cfb32_bmove(struct display *p, int sy, int sx, int dy, int dx,
  27.        int height, int width)
  28. {
  29.     int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
  30.     u8 *src, *dst;
  31.     if (sx == 0 && dx == 0 && width * fontwidth(p) * 4 == bytes) {
  32. fb_memmove(p->screen_base + dy * linesize,
  33.   p->screen_base + sy * linesize,
  34.   height * linesize);
  35. return;
  36.     }
  37.     if (fontwidthlog(p)) {
  38. sx <<= fontwidthlog(p)+2;
  39. dx <<= fontwidthlog(p)+2;
  40. width <<= fontwidthlog(p)+2;
  41.     } else {
  42. sx *= fontwidth(p)*4;
  43. dx *= fontwidth(p)*4;
  44. width *= fontwidth(p)*4;
  45.     }
  46.     if (dy < sy || (dy == sy && dx < sx)) {
  47. src = p->screen_base + sy * linesize + sx;
  48. dst = p->screen_base + dy * linesize + dx;
  49. for (rows = height * fontheight(p); rows--;) {
  50.     fb_memmove(dst, src, width);
  51.     src += bytes;
  52.     dst += bytes;
  53. }
  54.     } else {
  55. src = p->screen_base + (sy+height) * linesize + sx - bytes;
  56. dst = p->screen_base + (dy+height) * linesize + dx - bytes;
  57. for (rows = height * fontheight(p); rows--;) {
  58.     fb_memmove(dst, src, width);
  59.     src -= bytes;
  60.     dst -= bytes;
  61. }
  62.     }
  63. }
  64. static inline void rectfill(u8 *dest, int width, int height, u32 data,
  65.     int linesize)
  66. {
  67.     int i;
  68.     while (height-- > 0) {
  69. u32 *p = (u32 *)dest;
  70. for (i = 0; i < width/4; i++) {
  71.     fb_writel(data, p++);
  72.     fb_writel(data, p++);
  73.     fb_writel(data, p++);
  74.     fb_writel(data, p++);
  75. }
  76. if (width & 2) {
  77.     fb_writel(data, p++);
  78.     fb_writel(data, p++);
  79. }
  80. if (width & 1)
  81.     fb_writel(data, p++);
  82. dest += linesize;
  83.     }
  84. }
  85. void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy, int sx,
  86.        int height, int width)
  87. {
  88.     u8 *dest;
  89.     int bytes = p->next_line, lines = height * fontheight(p);
  90.     u32 bgx;
  91.     dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 4;
  92.     bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
  93.     width *= fontwidth(p)/4;
  94.     if (width * 16 == bytes)
  95. rectfill(dest, lines * width * 4, 1, bgx, bytes);
  96.     else
  97. rectfill(dest, width * 4, lines, bgx, bytes);
  98. }
  99. void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c, int yy,
  100.       int xx)
  101. {
  102.     u8 *dest, *cdat, bits;
  103.     int bytes = p->next_line, rows;
  104.     u32 eorx, fgx, bgx, *pt;
  105.     dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
  106.     if (fontwidth(p) <= 8)
  107. cdat = p->fontdata + (c & p->charmask) * fontheight(p);
  108.     else
  109. cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
  110.     fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
  111.     bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
  112.     eorx = fgx ^ bgx;
  113.     for (rows = fontheight(p); rows--; dest += bytes) {
  114. bits = *cdat++;
  115. pt = (u32 *) dest;
  116. fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
  117. fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
  118. fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
  119. fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
  120. if (fontwidth(p) < 8)
  121.     continue;
  122. fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
  123. fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
  124. fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
  125. fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
  126. if (fontwidth(p) < 12)
  127.     continue;
  128. bits = *cdat++;
  129. fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
  130. fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
  131. fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
  132. fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
  133. if (fontwidth(p) < 16)
  134.     continue;
  135. fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
  136. fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
  137. fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
  138. fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
  139.     }
  140. }
  141. void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
  142.        const unsigned short *s, int count, int yy, int xx)
  143. {
  144.     u8 *cdat, *dest, *dest0, bits;
  145.     u16 c;
  146.     int rows, bytes = p->next_line;
  147.     u32 eorx, fgx, bgx, *pt;
  148.     dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
  149.     c = scr_readw(s);
  150.     fgx = ((u32 *)p->dispsw_data)[attr_fgcol(p, c)];
  151.     bgx = ((u32 *)p->dispsw_data)[attr_bgcol(p, c)];
  152.     eorx = fgx ^ bgx;
  153.     while (count--) {
  154. c = scr_readw(s++) & p->charmask;
  155. if (fontwidth(p) <= 8)
  156.     cdat = p->fontdata + c * fontheight(p);
  157. else
  158.     cdat = p->fontdata + (c * fontheight(p) << 1);
  159. for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
  160.     bits = *cdat++;
  161.     pt = (u32 *) dest;
  162.     fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
  163.     fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
  164.     fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
  165.     fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
  166.     if (fontwidth(p) < 8)
  167. continue;
  168.     fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
  169.     fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
  170.     fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
  171.     fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
  172.     if (fontwidth(p) < 12)
  173. continue;
  174.     bits = *cdat++;
  175.     fb_writel((-(bits >> 7) & eorx) ^ bgx, pt++);
  176.     fb_writel((-(bits >> 6 & 1) & eorx) ^ bgx, pt++);
  177.     fb_writel((-(bits >> 5 & 1) & eorx) ^ bgx, pt++);
  178.     fb_writel((-(bits >> 4 & 1) & eorx) ^ bgx, pt++);
  179.     if (fontwidth(p) < 16)
  180. continue;
  181.     fb_writel((-(bits >> 3 & 1) & eorx) ^ bgx, pt++);
  182.     fb_writel((-(bits >> 2 & 1) & eorx) ^ bgx, pt++);
  183.     fb_writel((-(bits >> 1 & 1) & eorx) ^ bgx, pt++);
  184.     fb_writel((-(bits & 1) & eorx) ^ bgx, pt++);
  185. }
  186. dest0 += fontwidth(p)*4;
  187.     }
  188. }
  189. void fbcon_cfb32_revc(struct display *p, int xx, int yy)
  190. {
  191.     u8 *dest;
  192.     int bytes = p->next_line, rows;
  193.     dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 4;
  194.     for (rows = fontheight(p); rows--; dest += bytes) {
  195. switch (fontwidth(p)) {
  196. case 16:
  197.     fb_writel(fb_readl(dest+(4*12)) ^ 0xffffffff, dest+(4*12));
  198.     fb_writel(fb_readl(dest+(4*13)) ^ 0xffffffff, dest+(4*13));
  199.     fb_writel(fb_readl(dest+(4*14)) ^ 0xffffffff, dest+(4*14));
  200.     fb_writel(fb_readl(dest+(4*15)) ^ 0xffffffff, dest+(4*15));
  201.     /* FALL THROUGH */
  202. case 12:
  203.     fb_writel(fb_readl(dest+(4*8)) ^ 0xffffffff, dest+(4*8));
  204.     fb_writel(fb_readl(dest+(4*9)) ^ 0xffffffff, dest+(4*9));
  205.     fb_writel(fb_readl(dest+(4*10)) ^ 0xffffffff, dest+(4*10));
  206.     fb_writel(fb_readl(dest+(4*11)) ^ 0xffffffff, dest+(4*11));
  207.     /* FALL THROUGH */
  208. case 8:
  209.     fb_writel(fb_readl(dest+(4*4)) ^ 0xffffffff, dest+(4*4));
  210.     fb_writel(fb_readl(dest+(4*5)) ^ 0xffffffff, dest+(4*5));
  211.     fb_writel(fb_readl(dest+(4*6)) ^ 0xffffffff, dest+(4*6));
  212.     fb_writel(fb_readl(dest+(4*7)) ^ 0xffffffff, dest+(4*7));
  213.     /* FALL THROUGH */
  214. case 4:
  215.     fb_writel(fb_readl(dest+(4*0)) ^ 0xffffffff, dest+(4*0));
  216.     fb_writel(fb_readl(dest+(4*1)) ^ 0xffffffff, dest+(4*1));
  217.     fb_writel(fb_readl(dest+(4*2)) ^ 0xffffffff, dest+(4*2));
  218.     fb_writel(fb_readl(dest+(4*3)) ^ 0xffffffff, dest+(4*3));
  219.     /* FALL THROUGH */
  220. }
  221.     }
  222. }
  223. void fbcon_cfb32_clear_margins(struct vc_data *conp, struct display *p,
  224.        int bottom_only)
  225. {
  226.     int bytes = p->next_line;
  227.     u32 bgx;
  228.     unsigned int right_start = conp->vc_cols*fontwidth(p);
  229.     unsigned int bottom_start = conp->vc_rows*fontheight(p);
  230.     unsigned int right_width, bottom_width;
  231.     bgx = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
  232.     if (!bottom_only && (right_width = p->var.xres-right_start))
  233. rectfill(p->screen_base+right_start*4, right_width,
  234.  p->var.yres_virtual, bgx, bytes);
  235.     if ((bottom_width = p->var.yres-bottom_start))
  236. rectfill(p->screen_base+(p->var.yoffset+bottom_start)*bytes,
  237.  right_start, bottom_width, bgx, bytes);
  238. }
  239.     /*
  240.      *  `switch' for the low level operations
  241.      */
  242. struct display_switch fbcon_cfb32 = {
  243.     setup: fbcon_cfb32_setup,
  244.     bmove: fbcon_cfb32_bmove,
  245.     clear: fbcon_cfb32_clear,
  246.     putc: fbcon_cfb32_putc,
  247.     putcs: fbcon_cfb32_putcs,
  248.     revc: fbcon_cfb32_revc,
  249.     clear_margins: fbcon_cfb32_clear_margins,
  250.     fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
  251. };
  252. #ifdef MODULE
  253. MODULE_LICENSE("GPL");
  254. int init_module(void)
  255. {
  256.     return 0;
  257. }
  258. void cleanup_module(void)
  259. {}
  260. #endif /* MODULE */
  261.     /*
  262.      *  Visible symbols for modules
  263.      */
  264. EXPORT_SYMBOL(fbcon_cfb32);
  265. EXPORT_SYMBOL(fbcon_cfb32_setup);
  266. EXPORT_SYMBOL(fbcon_cfb32_bmove);
  267. EXPORT_SYMBOL(fbcon_cfb32_clear);
  268. EXPORT_SYMBOL(fbcon_cfb32_putc);
  269. EXPORT_SYMBOL(fbcon_cfb32_putcs);
  270. EXPORT_SYMBOL(fbcon_cfb32_revc);
  271. EXPORT_SYMBOL(fbcon_cfb32_clear_margins);