16104c370SDaniel Vetter /*
26104c370SDaniel Vetter * linux/drivers/video/console/fbcon.h -- Low level frame buffer based console driver
36104c370SDaniel Vetter *
46104c370SDaniel Vetter * Copyright (C) 1997 Geert Uytterhoeven
56104c370SDaniel Vetter *
66104c370SDaniel Vetter * This file is subject to the terms and conditions of the GNU General Public
76104c370SDaniel Vetter * License. See the file COPYING in the main directory of this archive
86104c370SDaniel Vetter * for more details.
96104c370SDaniel Vetter */
106104c370SDaniel Vetter
116104c370SDaniel Vetter #ifndef _VIDEO_FBCON_H
126104c370SDaniel Vetter #define _VIDEO_FBCON_H
136104c370SDaniel Vetter
146104c370SDaniel Vetter #include <linux/types.h>
156104c370SDaniel Vetter #include <linux/vt_buffer.h>
166104c370SDaniel Vetter #include <linux/vt_kern.h>
173b0fb6abSDaniel Vetter #include <linux/workqueue.h>
186104c370SDaniel Vetter
196104c370SDaniel Vetter #include <asm/io.h>
206104c370SDaniel Vetter
216104c370SDaniel Vetter /*
226104c370SDaniel Vetter * This is the interface between the low-level console driver and the
236104c370SDaniel Vetter * low-level frame buffer device
246104c370SDaniel Vetter */
256104c370SDaniel Vetter
2650233393SDaniel Vetter struct fbcon_display {
276104c370SDaniel Vetter /* Filled in by the low-level console driver */
286104c370SDaniel Vetter const u_char *fontdata;
296104c370SDaniel Vetter int userfont; /* != 0 if fontdata kmalloc()ed */
30a3f781a9SHelge Deller #ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
31a3f781a9SHelge Deller u_short scrollmode; /* Scroll Method, use fb_scrollmode() */
32a3f781a9SHelge Deller #endif
336104c370SDaniel Vetter u_short inverse; /* != 0 text black on white as default */
346104c370SDaniel Vetter short yscroll; /* Hardware scrolling */
356104c370SDaniel Vetter int vrows; /* number of virtual rows */
366104c370SDaniel Vetter int cursor_shape;
376104c370SDaniel Vetter int con_rotate;
386104c370SDaniel Vetter u32 xres_virtual;
396104c370SDaniel Vetter u32 yres_virtual;
406104c370SDaniel Vetter u32 height;
416104c370SDaniel Vetter u32 width;
426104c370SDaniel Vetter u32 bits_per_pixel;
436104c370SDaniel Vetter u32 grayscale;
446104c370SDaniel Vetter u32 nonstd;
456104c370SDaniel Vetter u32 accel_flags;
466104c370SDaniel Vetter u32 rotate;
476104c370SDaniel Vetter struct fb_bitfield red;
486104c370SDaniel Vetter struct fb_bitfield green;
496104c370SDaniel Vetter struct fb_bitfield blue;
506104c370SDaniel Vetter struct fb_bitfield transp;
516104c370SDaniel Vetter const struct fb_videomode *mode;
526104c370SDaniel Vetter };
536104c370SDaniel Vetter
546104c370SDaniel Vetter struct fbcon_ops {
551148836fSHelge Deller void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
561148836fSHelge Deller int sx, int dy, int dx, int height, int width);
576104c370SDaniel Vetter void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
586104c370SDaniel Vetter int sx, int height, int width);
596104c370SDaniel Vetter void (*putcs)(struct vc_data *vc, struct fb_info *info,
606104c370SDaniel Vetter const unsigned short *s, int count, int yy, int xx,
616104c370SDaniel Vetter int fg, int bg);
626104c370SDaniel Vetter void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
6374c1c8b3SDavid Lechner int color, int bottom_only);
646104c370SDaniel Vetter void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode,
6506a0df4dSLinus Torvalds int fg, int bg);
666104c370SDaniel Vetter int (*update_start)(struct fb_info *info);
676104c370SDaniel Vetter int (*rotate_font)(struct fb_info *info, struct vc_data *vc);
686104c370SDaniel Vetter struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
693b0fb6abSDaniel Vetter struct delayed_work cursor_work; /* Cursor timer */
706104c370SDaniel Vetter struct fb_cursor cursor_state;
7150233393SDaniel Vetter struct fbcon_display *p;
726c789357SKees Cook struct fb_info *info;
736104c370SDaniel Vetter int currcon; /* Current VC. */
746104c370SDaniel Vetter int cur_blink_jiffies;
756104c370SDaniel Vetter int cursor_flash;
766104c370SDaniel Vetter int cursor_reset;
776104c370SDaniel Vetter int blank_state;
786104c370SDaniel Vetter int graphics;
796104c370SDaniel Vetter int save_graphics; /* for debug enter/leave */
80*cae69e45SDaniel Vetter bool initialized;
816104c370SDaniel Vetter int rotate;
826104c370SDaniel Vetter int cur_rotate;
836104c370SDaniel Vetter char *cursor_data;
846104c370SDaniel Vetter u8 *fontbuffer;
856104c370SDaniel Vetter u8 *fontdata;
866104c370SDaniel Vetter u8 *cursor_src;
876104c370SDaniel Vetter u32 cursor_size;
886104c370SDaniel Vetter u32 fd_size;
896104c370SDaniel Vetter };
906104c370SDaniel Vetter /*
916104c370SDaniel Vetter * Attribute Decoding
926104c370SDaniel Vetter */
936104c370SDaniel Vetter
946104c370SDaniel Vetter /* Color */
956104c370SDaniel Vetter #define attr_fgcol(fgshift,s) \
966104c370SDaniel Vetter (((s) >> (fgshift)) & 0x0f)
976104c370SDaniel Vetter #define attr_bgcol(bgshift,s) \
986104c370SDaniel Vetter (((s) >> (bgshift)) & 0x0f)
996104c370SDaniel Vetter
1006104c370SDaniel Vetter /* Monochrome */
1016104c370SDaniel Vetter #define attr_bold(s) \
1026104c370SDaniel Vetter ((s) & 0x200)
1036104c370SDaniel Vetter #define attr_reverse(s) \
1046104c370SDaniel Vetter ((s) & 0x800)
1056104c370SDaniel Vetter #define attr_underline(s) \
1066104c370SDaniel Vetter ((s) & 0x400)
1076104c370SDaniel Vetter #define attr_blink(s) \
1086104c370SDaniel Vetter ((s) & 0x8000)
1096104c370SDaniel Vetter
1106104c370SDaniel Vetter
mono_col(const struct fb_info * info)1116104c370SDaniel Vetter static inline int mono_col(const struct fb_info *info)
1126104c370SDaniel Vetter {
1136104c370SDaniel Vetter __u32 max_len;
1146104c370SDaniel Vetter max_len = max(info->var.green.length, info->var.red.length);
1156104c370SDaniel Vetter max_len = max(info->var.blue.length, max_len);
1166104c370SDaniel Vetter return (~(0xfff << max_len)) & 0xff;
1176104c370SDaniel Vetter }
1186104c370SDaniel Vetter
attr_col_ec(int shift,struct vc_data * vc,struct fb_info * info,int is_fg)1196104c370SDaniel Vetter static inline int attr_col_ec(int shift, struct vc_data *vc,
1206104c370SDaniel Vetter struct fb_info *info, int is_fg)
1216104c370SDaniel Vetter {
1226104c370SDaniel Vetter int is_mono01;
1236104c370SDaniel Vetter int col;
1246104c370SDaniel Vetter int fg;
1256104c370SDaniel Vetter int bg;
1266104c370SDaniel Vetter
1276104c370SDaniel Vetter if (!vc)
1286104c370SDaniel Vetter return 0;
1296104c370SDaniel Vetter
1306104c370SDaniel Vetter if (vc->vc_can_do_color)
1316104c370SDaniel Vetter return is_fg ? attr_fgcol(shift,vc->vc_video_erase_char)
1326104c370SDaniel Vetter : attr_bgcol(shift,vc->vc_video_erase_char);
1336104c370SDaniel Vetter
1346104c370SDaniel Vetter if (!info)
1356104c370SDaniel Vetter return 0;
1366104c370SDaniel Vetter
1376104c370SDaniel Vetter col = mono_col(info);
1386104c370SDaniel Vetter is_mono01 = info->fix.visual == FB_VISUAL_MONO01;
1396104c370SDaniel Vetter
1406104c370SDaniel Vetter if (attr_reverse(vc->vc_video_erase_char)) {
1416104c370SDaniel Vetter fg = is_mono01 ? col : 0;
1426104c370SDaniel Vetter bg = is_mono01 ? 0 : col;
1436104c370SDaniel Vetter }
1446104c370SDaniel Vetter else {
1456104c370SDaniel Vetter fg = is_mono01 ? 0 : col;
1466104c370SDaniel Vetter bg = is_mono01 ? col : 0;
1476104c370SDaniel Vetter }
1486104c370SDaniel Vetter
1496104c370SDaniel Vetter return is_fg ? fg : bg;
1506104c370SDaniel Vetter }
1516104c370SDaniel Vetter
1526104c370SDaniel Vetter #define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0)
1536104c370SDaniel Vetter #define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1)
1546104c370SDaniel Vetter
1551148836fSHelge Deller /*
1561148836fSHelge Deller * Scroll Method
1571148836fSHelge Deller */
1581148836fSHelge Deller
1591148836fSHelge Deller /* There are several methods fbcon can use to move text around the screen:
1601148836fSHelge Deller *
1611148836fSHelge Deller * Operation Pan Wrap
1621148836fSHelge Deller *---------------------------------------------
1631148836fSHelge Deller * SCROLL_MOVE copyarea No No
1641148836fSHelge Deller * SCROLL_PAN_MOVE copyarea Yes No
1651148836fSHelge Deller * SCROLL_WRAP_MOVE copyarea No Yes
1661148836fSHelge Deller * SCROLL_REDRAW imageblit No No
1671148836fSHelge Deller * SCROLL_PAN_REDRAW imageblit Yes No
1681148836fSHelge Deller * SCROLL_WRAP_REDRAW imageblit No Yes
1691148836fSHelge Deller *
1701148836fSHelge Deller * (SCROLL_WRAP_REDRAW is not implemented yet)
1711148836fSHelge Deller *
1721148836fSHelge Deller * In general, fbcon will choose the best scrolling
1731148836fSHelge Deller * method based on the rule below:
1741148836fSHelge Deller *
1751148836fSHelge Deller * Pan/Wrap > accel imageblit > accel copyarea >
1761148836fSHelge Deller * soft imageblit > (soft copyarea)
1771148836fSHelge Deller *
1781148836fSHelge Deller * Exception to the rule: Pan + accel copyarea is
1791148836fSHelge Deller * preferred over Pan + accel imageblit.
1801148836fSHelge Deller *
1811148836fSHelge Deller * The above is typical for PCI/AGP cards. Unless
1821148836fSHelge Deller * overridden, fbcon will never use soft copyarea.
1831148836fSHelge Deller *
1841148836fSHelge Deller * If you need to override the above rule, set the
1851148836fSHelge Deller * appropriate flags in fb_info->flags. For example,
1861148836fSHelge Deller * to prefer copyarea over imageblit, set
1871148836fSHelge Deller * FBINFO_READS_FAST.
1881148836fSHelge Deller *
1891148836fSHelge Deller * Other notes:
1901148836fSHelge Deller * + use the hardware engine to move the text
1911148836fSHelge Deller * (hw-accelerated copyarea() and fillrect())
1921148836fSHelge Deller * + use hardware-supported panning on a large virtual screen
1931148836fSHelge Deller * + amifb can not only pan, but also wrap the display by N lines
1941148836fSHelge Deller * (i.e. visible line i = physical line (i+N) % yres).
1951148836fSHelge Deller * + read what's already rendered on the screen and
1961148836fSHelge Deller * write it in a different place (this is cfb_copyarea())
1971148836fSHelge Deller * + re-render the text to the screen
1981148836fSHelge Deller *
1991148836fSHelge Deller * Whether to use wrapping or panning can only be figured out at
2001148836fSHelge Deller * runtime (when we know whether our font height is a multiple
2011148836fSHelge Deller * of the pan/wrap step)
2021148836fSHelge Deller *
2031148836fSHelge Deller */
2041148836fSHelge Deller
2051148836fSHelge Deller #define SCROLL_MOVE 0x001
2061148836fSHelge Deller #define SCROLL_PAN_MOVE 0x002
2071148836fSHelge Deller #define SCROLL_WRAP_MOVE 0x003
2081148836fSHelge Deller #define SCROLL_REDRAW 0x004
2091148836fSHelge Deller #define SCROLL_PAN_REDRAW 0x005
2101148836fSHelge Deller
fb_scrollmode(struct fbcon_display * fb)211a3f781a9SHelge Deller static inline u_short fb_scrollmode(struct fbcon_display *fb)
212a3f781a9SHelge Deller {
213a3f781a9SHelge Deller #ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
214a3f781a9SHelge Deller return fb->scrollmode;
215a3f781a9SHelge Deller #else
216a3f781a9SHelge Deller /* hardcoded to SCROLL_REDRAW if acceleration was disabled. */
217a3f781a9SHelge Deller return SCROLL_REDRAW;
218a3f781a9SHelge Deller #endif
219a3f781a9SHelge Deller }
220a3f781a9SHelge Deller
221a3f781a9SHelge Deller
2226104c370SDaniel Vetter #ifdef CONFIG_FB_TILEBLITTING
2236104c370SDaniel Vetter extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
2246104c370SDaniel Vetter #endif
2256104c370SDaniel Vetter extern void fbcon_set_bitops(struct fbcon_ops *ops);
2266104c370SDaniel Vetter extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
2276104c370SDaniel Vetter
2286104c370SDaniel Vetter #define FBCON_ATTRIBUTE_UNDERLINE 1
2296104c370SDaniel Vetter #define FBCON_ATTRIBUTE_REVERSE 2
2306104c370SDaniel Vetter #define FBCON_ATTRIBUTE_BOLD 4
2316104c370SDaniel Vetter
real_y(struct fbcon_display * p,int ypos)23250233393SDaniel Vetter static inline int real_y(struct fbcon_display *p, int ypos)
2336104c370SDaniel Vetter {
2346104c370SDaniel Vetter int rows = p->vrows;
2356104c370SDaniel Vetter
2366104c370SDaniel Vetter ypos += p->yscroll;
2376104c370SDaniel Vetter return ypos < rows ? ypos : ypos - rows;
2386104c370SDaniel Vetter }
2396104c370SDaniel Vetter
2406104c370SDaniel Vetter
get_attribute(struct fb_info * info,u16 c)2416104c370SDaniel Vetter static inline int get_attribute(struct fb_info *info, u16 c)
2426104c370SDaniel Vetter {
2436104c370SDaniel Vetter int attribute = 0;
2446104c370SDaniel Vetter
2456104c370SDaniel Vetter if (fb_get_color_depth(&info->var, &info->fix) == 1) {
2466104c370SDaniel Vetter if (attr_underline(c))
2476104c370SDaniel Vetter attribute |= FBCON_ATTRIBUTE_UNDERLINE;
2486104c370SDaniel Vetter if (attr_reverse(c))
2496104c370SDaniel Vetter attribute |= FBCON_ATTRIBUTE_REVERSE;
2506104c370SDaniel Vetter if (attr_bold(c))
2516104c370SDaniel Vetter attribute |= FBCON_ATTRIBUTE_BOLD;
2526104c370SDaniel Vetter }
2536104c370SDaniel Vetter
2546104c370SDaniel Vetter return attribute;
2556104c370SDaniel Vetter }
2566104c370SDaniel Vetter
2576104c370SDaniel Vetter #define FBCON_SWAP(i,r,v) ({ \
2586104c370SDaniel Vetter typeof(r) _r = (r); \
2596104c370SDaniel Vetter typeof(v) _v = (v); \
2606104c370SDaniel Vetter (void) (&_r == &_v); \
2616104c370SDaniel Vetter (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
2626104c370SDaniel Vetter
2636104c370SDaniel Vetter #ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
2646104c370SDaniel Vetter extern void fbcon_set_rotate(struct fbcon_ops *ops);
2656104c370SDaniel Vetter #else
2666104c370SDaniel Vetter #define fbcon_set_rotate(x) do {} while(0)
2676104c370SDaniel Vetter #endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
2686104c370SDaniel Vetter
269b0d8e409SHans de Goede #endif /* _VIDEO_FBCON_H */
270