xref: /openbmc/linux/drivers/video/fbdev/core/fbcon.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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