* better
[mascara-docs.git] / i386 / linux-2.3.21 / include / video / fbcon.h
blob1cca4c90f73e5bc357fb0d958ed1e48c81f8fcad
1 /*
2 * linux/drivers/video/fbcon.h -- Low level frame buffer based console driver
4 * Copyright (C) 1997 Geert Uytterhoeven
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
11 #ifndef _VIDEO_FBCON_H
12 #define _VIDEO_FBCON_H
14 #include <linux/config.h>
15 #include <linux/types.h>
16 #include <linux/console_struct.h>
17 #include <linux/vt_buffer.h>
19 #include <asm/io.h>
22 /*
23 * `switch' for the Low Level Operations
26 struct display_switch {
27 void (*setup)(struct display *p);
28 void (*bmove)(struct display *p, int sy, int sx, int dy, int dx,
29 int height, int width);
30 /* for clear, conp may be NULL, which means use a blanking (black) color */
31 void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
32 int height, int width);
33 void (*putc)(struct vc_data *conp, struct display *p, int c, int yy,
34 int xx);
35 void (*putcs)(struct vc_data *conp, struct display *p, const unsigned short *s,
36 int count, int yy, int xx);
37 void (*revc)(struct display *p, int xx, int yy);
38 void (*cursor)(struct display *p, int mode, int xx, int yy);
39 int (*set_font)(struct display *p, int width, int height);
40 void (*clear_margins)(struct vc_data *conp, struct display *p,
41 int bottom_only);
42 unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
43 };
45 extern struct display_switch fbcon_dummy;
47 #define fontheight(p) ((p)->_fontheight)
48 #define fontheightlog(p) ((p)->_fontheightlog)
50 #ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
52 /* fontwidth w is supported by dispsw */
53 #define FONTWIDTH(w) (1 << ((8) - 1))
54 /* fontwidths w1-w2 inclusive are supported by dispsw */
55 #define FONTWIDTHRANGE(w1,w2) FONTWIDTH(8)
57 #define fontwidth(p) (8)
58 #define fontwidthlog(p) (0)
60 #else
62 /* fontwidth w is supported by dispsw */
63 #define FONTWIDTH(w) (1 << ((w) - 1))
64 /* fontwidths w1-w2 inclusive are supported by dispsw */
65 #define FONTWIDTHRANGE(w1,w2) (FONTWIDTH(w2+1) - FONTWIDTH(w1))
67 #define fontwidth(p) ((p)->_fontwidth)
68 #define fontwidthlog(p) ((p)->_fontwidthlog)
70 #endif
73 * Attribute Decoding
76 /* Color */
77 #define attr_fgcol(p,s) \
78 (((s) >> ((p)->fgshift)) & 0x0f)
79 #define attr_bgcol(p,s) \
80 (((s) >> ((p)->bgshift)) & 0x0f)
81 #define attr_bgcol_ec(p,conp) \
82 ((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
84 /* Monochrome */
85 #define attr_bold(p,s) \
86 ((s) & 0x200)
87 #define attr_reverse(p,s) \
88 (((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
89 #define attr_underline(p,s) \
90 ((s) & 0x400)
91 #define attr_blink(p,s) \
92 ((s) & 0x8000)
95 * Scroll Method
98 /* Internal flags */
99 #define __SCROLL_YPAN 0x001
100 #define __SCROLL_YWRAP 0x002
101 #define __SCROLL_YMOVE 0x003
102 #define __SCROLL_YREDRAW 0x004
103 #define __SCROLL_YMASK 0x00f
104 #define __SCROLL_YFIXED 0x010
105 #define __SCROLL_YNOMOVE 0x020
106 #define __SCROLL_YPANREDRAW 0x040
107 #define __SCROLL_YNOPARTIAL 0x080
109 /* Only these should be used by the drivers */
110 /* Which one should you use? If you have a fast card and slow bus,
111 then probably just 0 to indicate fbcon should choose between
112 YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
113 and even better if your card can do fonting (1->8/32bit painting),
114 you should consider either SCROLL_YREDRAW (if your card is
115 able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
116 The best is to test it with some real life scrolling (usually, not
117 all lines on the screen are filled completely with non-space characters,
118 and REDRAW performs much better on such lines, so don't cat a file
119 with every line covering all screen columns, it would not be the right
120 benchmark).
122 #define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW)
123 #define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
125 /* SCROLL_YNOPARTIAL, used in combination with the above, is for video
126 cards which can not handle using panning to scroll a portion of the
127 screen without excessive flicker. Panning will only be used for
128 whole screens.
130 /* Namespace consistency */
131 #define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL
134 extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
137 /* ================================================================= */
138 /* Utility Assembler Functions */
139 /* ================================================================= */
142 #if defined(__mc68000__)
144 /* ====================================================================== */
146 /* Those of a delicate disposition might like to skip the next couple of
147 * pages.
149 * These functions are drop in replacements for memmove and
150 * memset(_, 0, _). However their five instances add at least a kilobyte
151 * to the object file. You have been warned.
153 * Not a great fan of assembler for the sake of it, but I think
154 * that these routines are at least 10 times faster than their C
155 * equivalents for large blits, and that's important to the lowest level of
156 * a graphics driver. Question is whether some scheme with the blitter
157 * would be faster. I suspect not for simple text system - not much
158 * asynchrony.
160 * Code is very simple, just gruesome expansion. Basic strategy is to
161 * increase data moved/cleared at each step to 16 bytes to reduce
162 * instruction per data move overhead. movem might be faster still
163 * For more than 15 bytes, we try to align the write direction on a
164 * longword boundary to get maximum speed. This is even more gruesome.
165 * Unaligned read/write used requires 68020+ - think this is a problem?
167 * Sorry!
171 /* ++roman: I've optimized Robert's original versions in some minor
172 * aspects, e.g. moveq instead of movel, let gcc choose the registers,
173 * use movem in some places...
174 * For other modes than 1 plane, lots of more such assembler functions
175 * were needed (e.g. the ones using movep or expanding color values).
178 /* ++andreas: more optimizations:
179 subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
180 addal is faster than addaw
181 movep is rather expensive compared to ordinary move's
182 some functions rewritten in C for clarity, no speed loss */
184 static __inline__ void *fb_memclear_small(void *s, size_t count)
186 if (!count)
187 return(0);
189 __asm__ __volatile__(
190 "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
191 "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
192 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
193 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
194 "1: subql #1,%1 ; jcs 3f\n\t"
195 "2: moveml %2/%3/%4/%5,%0@-\n\t"
196 "dbra %1,2b\n\t"
197 "3:"
198 : "=a" (s), "=d" (count)
199 : "d" (0), "d" (0), "d" (0), "d" (0),
200 "0" ((char *)s+count), "1" (count)
203 return(0);
207 static __inline__ void *fb_memclear(void *s, size_t count)
209 if (!count)
210 return(0);
212 if (count < 16) {
213 __asm__ __volatile__(
214 "lsrl #1,%1 ; jcc 1f ; clrb %0@+\n\t"
215 "1: lsrl #1,%1 ; jcc 1f ; clrw %0@+\n\t"
216 "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+\n\t"
217 "1: lsrl #1,%1 ; jcc 1f ; clrl %0@+ ; clrl %0@+\n\t"
218 "1:"
219 : "=a" (s), "=d" (count)
220 : "0" (s), "1" (count)
222 } else {
223 long tmp;
224 __asm__ __volatile__(
225 "movel %1,%2\n\t"
226 "lsrl #1,%2 ; jcc 1f ; clrb %0@+ ; subqw #1,%1\n\t"
227 "lsrl #1,%2 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
228 "clrw %0@+ ; subqw #2,%1 ; jra 2f\n\t"
229 "1: lsrl #1,%2 ; jcc 2f\n\t"
230 "clrw %0@+ ; subqw #2,%1\n\t"
231 "2: movew %1,%2; lsrl #2,%1 ; jeq 6f\n\t"
232 "lsrl #1,%1 ; jcc 3f ; clrl %0@+\n\t"
233 "3: lsrl #1,%1 ; jcc 4f ; clrl %0@+ ; clrl %0@+\n\t"
234 "4: subql #1,%1 ; jcs 6f\n\t"
235 "5: clrl %0@+; clrl %0@+ ; clrl %0@+ ; clrl %0@+\n\t"
236 "dbra %1,5b ; clrw %1; subql #1,%1; jcc 5b\n\t"
237 "6: movew %2,%1; btst #1,%1 ; jeq 7f ; clrw %0@+\n\t"
238 "7: ; btst #0,%1 ; jeq 8f ; clrb %0@+\n\t"
239 "8:"
240 : "=a" (s), "=d" (count), "=d" (tmp)
241 : "0" (s), "1" (count)
245 return(0);
249 static __inline__ void *fb_memset255(void *s, size_t count)
251 if (!count)
252 return(0);
254 __asm__ __volatile__(
255 "lsrl #1,%1 ; jcc 1f ; moveb %2,%0@-\n\t"
256 "1: lsrl #1,%1 ; jcc 1f ; movew %2,%0@-\n\t"
257 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@-\n\t"
258 "1: lsrl #1,%1 ; jcc 1f ; movel %2,%0@- ; movel %2,%0@-\n\t"
259 "1: subql #1,%1 ; jcs 3f\n\t"
260 "2: moveml %2/%3/%4/%5,%0@-\n\t"
261 "dbra %1,2b\n\t"
262 "3:"
263 : "=a" (s), "=d" (count)
264 : "d" (-1), "d" (-1), "d" (-1), "d" (-1),
265 "0" ((char *) s + count), "1" (count)
268 return(0);
272 static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
274 if (d < s) {
275 if (count < 16) {
276 __asm__ __volatile__(
277 "lsrl #1,%2 ; jcc 1f ; moveb %1@+,%0@+\n\t"
278 "1: lsrl #1,%2 ; jcc 1f ; movew %1@+,%0@+\n\t"
279 "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+\n\t"
280 "1: lsrl #1,%2 ; jcc 1f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
281 "1:"
282 : "=a" (d), "=a" (s), "=d" (count)
283 : "0" (d), "1" (s), "2" (count)
285 } else {
286 long tmp;
287 __asm__ __volatile__(
288 "movel %0,%3\n\t"
289 "lsrl #1,%3 ; jcc 1f ; moveb %1@+,%0@+ ; subqw #1,%2\n\t"
290 "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
291 "movew %1@+,%0@+ ; subqw #2,%2 ; jra 2f\n\t"
292 "1: lsrl #1,%3 ; jcc 2f\n\t"
293 "movew %1@+,%0@+ ; subqw #2,%2\n\t"
294 "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
295 "lsrl #1,%2 ; jcc 3f ; movel %1@+,%0@+\n\t"
296 "3: lsrl #1,%2 ; jcc 4f ; movel %1@+,%0@+ ; movel %1@+,%0@+\n\t"
297 "4: subql #1,%2 ; jcs 6f\n\t"
298 "5: movel %1@+,%0@+;movel %1@+,%0@+\n\t"
299 "movel %1@+,%0@+;movel %1@+,%0@+\n\t"
300 "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
301 "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@+,%0@+\n\t"
302 "7: ; btst #0,%2 ; jeq 8f ; moveb %1@+,%0@+\n\t"
303 "8:"
304 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
305 : "0" (d), "1" (s), "2" (count)
308 } else {
309 if (count < 16) {
310 __asm__ __volatile__(
311 "lsrl #1,%2 ; jcc 1f ; moveb %1@-,%0@-\n\t"
312 "1: lsrl #1,%2 ; jcc 1f ; movew %1@-,%0@-\n\t"
313 "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@-\n\t"
314 "1: lsrl #1,%2 ; jcc 1f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
315 "1:"
316 : "=a" (d), "=a" (s), "=d" (count)
317 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
319 } else {
320 long tmp;
321 __asm__ __volatile__(
322 "movel %0,%3\n\t"
323 "lsrl #1,%3 ; jcc 1f ; moveb %1@-,%0@- ; subqw #1,%2\n\t"
324 "lsrl #1,%3 ; jcs 2f\n\t" /* %0 increased=>bit 2 switched*/
325 "movew %1@-,%0@- ; subqw #2,%2 ; jra 2f\n\t"
326 "1: lsrl #1,%3 ; jcc 2f\n\t"
327 "movew %1@-,%0@- ; subqw #2,%2\n\t"
328 "2: movew %2,%-; lsrl #2,%2 ; jeq 6f\n\t"
329 "lsrl #1,%2 ; jcc 3f ; movel %1@-,%0@-\n\t"
330 "3: lsrl #1,%2 ; jcc 4f ; movel %1@-,%0@- ; movel %1@-,%0@-\n\t"
331 "4: subql #1,%2 ; jcs 6f\n\t"
332 "5: movel %1@-,%0@-;movel %1@-,%0@-\n\t"
333 "movel %1@-,%0@-;movel %1@-,%0@-\n\t"
334 "dbra %2,5b ; clrw %2; subql #1,%2; jcc 5b\n\t"
335 "6: movew %+,%2; btst #1,%2 ; jeq 7f ; movew %1@-,%0@-\n\t"
336 "7: ; btst #0,%2 ; jeq 8f ; moveb %1@-,%0@-\n\t"
337 "8:"
338 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
339 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count)
344 return(0);
348 /* ++andreas: Simple and fast version of memmove, assumes size is
349 divisible by 16, suitable for moving the whole screen bitplane */
350 static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
352 if (!size)
353 return;
354 if (dst < src)
355 __asm__ __volatile__
356 ("1:"
357 " moveml %0@+,%/d0/%/d1/%/a0/%/a1\n"
358 " moveml %/d0/%/d1/%/a0/%/a1,%1@\n"
359 " addql #8,%1; addql #8,%1\n"
360 " dbra %2,1b\n"
361 " clrw %2; subql #1,%2\n"
362 " jcc 1b"
363 : "=a" (src), "=a" (dst), "=d" (size)
364 : "0" (src), "1" (dst), "2" (size / 16 - 1)
365 : "d0", "d1", "a0", "a1", "memory");
366 else
367 __asm__ __volatile__
368 ("1:"
369 " subql #8,%0; subql #8,%0\n"
370 " moveml %0@,%/d0/%/d1/%/a0/%/a1\n"
371 " moveml %/d0/%/d1/%/a0/%/a1,%1@-\n"
372 " dbra %2,1b\n"
373 " clrw %2; subql #1,%2\n"
374 " jcc 1b"
375 : "=a" (src), "=a" (dst), "=d" (size)
376 : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
377 : "d0", "d1", "a0", "a1", "memory");
380 #elif defined(CONFIG_SUN4)
382 /* You may think that I'm crazy and that I should use generic
383 routines. No, I'm not: sun4's framebuffer crashes if we std
384 into it, so we cannot use memset. */
386 static __inline__ void *sun4_memset(void *s, char val, size_t count)
388 int i;
389 for(i=0; i<count;i++)
390 ((char *) s) [i] = val;
391 return s;
394 static __inline__ void *fb_memset255(void *s, size_t count)
396 return sun4_memset(s, 255, count);
399 static __inline__ void *fb_memclear(void *s, size_t count)
401 return sun4_memset(s, 0, count);
404 static __inline__ void *fb_memclear_small(void *s, size_t count)
406 return sun4_memset(s, 0, count);
409 /* To be honest, this is slow_memmove :). But sun4 is crappy, so what we can do. */
410 static __inline__ void fast_memmove(void *d, const void *s, size_t count)
412 int i;
413 if (d<s) {
414 for (i=0; i<count; i++)
415 ((char *) d)[i] = ((char *) s)[i];
416 } else
417 for (i=0; i<count; i++)
418 ((char *) d)[count-i-1] = ((char *) s)[count-i-1];
421 static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
423 fast_memmove(dst, src, size);
424 return dst;
427 #else
429 static __inline__ void *fb_memclear_small(void *s, size_t count)
431 return(memset(s, 0, count));
434 static __inline__ void *fb_memclear(void *s, size_t count)
436 return(memset(s, 0, count));
439 static __inline__ void *fb_memset255(void *s, size_t count)
441 return(memset(s, 255, count));
444 #if defined(__i386__)
446 static __inline__ void fast_memmove(void *d, const void *s, size_t count)
448 int d0, d1, d2, d3;
449 if (d < s) {
450 __asm__ __volatile__ (
451 "cld\n\t"
452 "shrl $1,%%ecx\n\t"
453 "jnc 1f\n\t"
454 "movsb\n"
455 "1:\tshrl $1,%%ecx\n\t"
456 "jnc 2f\n\t"
457 "movsw\n"
458 "2:\trep\n\t"
459 "movsl"
460 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
461 :"0"(count),"1"((long)d),"2"((long)s)
462 :"memory");
463 } else {
464 __asm__ __volatile__ (
465 "std\n\t"
466 "shrl $1,%%ecx\n\t"
467 "jnc 1f\n\t"
468 "movb 3(%%esi),%%al\n\t"
469 "movb %%al,3(%%edi)\n\t"
470 "decl %%esi\n\t"
471 "decl %%edi\n"
472 "1:\tshrl $1,%%ecx\n\t"
473 "jnc 2f\n\t"
474 "movw 2(%%esi),%%ax\n\t"
475 "movw %%ax,2(%%edi)\n\t"
476 "decl %%esi\n\t"
477 "decl %%edi\n\t"
478 "decl %%esi\n\t"
479 "decl %%edi\n"
480 "2:\trep\n\t"
481 "movsl\n\t"
482 "cld"
483 : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3)
484 :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s)
485 :"memory");
489 static __inline__ void *fb_memmove(char *dst, const char *src, size_t size)
491 fast_memmove(dst, src, size);
492 return dst;
495 #else /* !i386 */
498 * Anyone who'd like to write asm functions for other CPUs?
499 * (Why are these functions better than those from include/asm/string.h?)
502 static __inline__ void *fb_memmove(void *d, const void *s, size_t count)
504 return(memmove(d, s, count));
507 static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
509 memmove(dst, src, size);
512 #endif /* !i386 */
514 #endif
517 #if defined(__sparc__)
519 /* We map all of our framebuffers such that big-endian accesses
520 * are what we want, so the following is sufficient.
523 #define fb_readb sbus_readb
524 #define fb_readw sbus_readw
525 #define fb_readl sbus_readl
526 #define fb_writeb sbus_writeb
527 #define fb_writew sbus_writew
528 #define fb_writel sbus_writel
529 #define fb_memset sbus_memset_io
531 #elif defined(__i386__) || defined(__alpha__)
533 #define fb_readb __raw_readb
534 #define fb_readw __raw_readw
535 #define fb_readl __raw_readl
536 #define fb_writeb __raw_writeb
537 #define fb_writew __raw_writew
538 #define fb_writel __raw_writel
539 #define fb_memset memset_io
541 #else
543 #define fb_readb(addr) (*(volatile u8 *) (addr))
544 #define fb_readw(addr) (*(volatile u16 *) (addr))
545 #define fb_readl(addr) (*(volatile u32 *) (addr))
546 #define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
547 #define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
548 #define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
549 #define fb_memset memset
551 #endif
553 #endif /* _VIDEO_FBCON_H */