18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  linux/drivers/video/vgacon.c -- Low level VGA based console driver
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *	Created 28 Sep 1997 by Geert Uytterhoeven
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *	Rewritten by Martin Mares <mj@ucw.cz>, July 1998
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *  This file is based on the old console.c, vga.c and vesa_blank.c drivers.
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci *	Copyright (C) 1991, 1992  Linus Torvalds
118c2ecf20Sopenharmony_ci *			    1995  Jay Estabrook
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci *	User definable mapping table and font loading by Eugene G. Crosser,
148c2ecf20Sopenharmony_ci *	<crosser@average.org>
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *	Improved loadable font/UTF-8 support by H. Peter Anvin
178c2ecf20Sopenharmony_ci *	Feb-Sep 1995 <peter.anvin@linux.org>
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci *	Colour palette handling, by Simon Tatham
208c2ecf20Sopenharmony_ci *	17-Jun-95 <sgt20@cam.ac.uk>
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci *	if 512 char mode is already enabled don't re-enable it,
238c2ecf20Sopenharmony_ci *	because it causes screen to flicker, by Mitja Horvat
248c2ecf20Sopenharmony_ci *	5-May-96 <mitja.horvat@guest.arnes.si>
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci *	Use 2 outw instead of 4 outb_p to reduce erroneous text
278c2ecf20Sopenharmony_ci *	flashing on RHS of screen during heavy console scrolling .
288c2ecf20Sopenharmony_ci *	Oct 1996, Paul Gortmaker.
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci *
318c2ecf20Sopenharmony_ci *  This file is subject to the terms and conditions of the GNU General Public
328c2ecf20Sopenharmony_ci *  License.  See the file COPYING in the main directory of this archive for
338c2ecf20Sopenharmony_ci *  more details.
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#include <linux/module.h>
378c2ecf20Sopenharmony_ci#include <linux/types.h>
388c2ecf20Sopenharmony_ci#include <linux/fs.h>
398c2ecf20Sopenharmony_ci#include <linux/kernel.h>
408c2ecf20Sopenharmony_ci#include <linux/console.h>
418c2ecf20Sopenharmony_ci#include <linux/string.h>
428c2ecf20Sopenharmony_ci#include <linux/kd.h>
438c2ecf20Sopenharmony_ci#include <linux/slab.h>
448c2ecf20Sopenharmony_ci#include <linux/vt_kern.h>
458c2ecf20Sopenharmony_ci#include <linux/sched.h>
468c2ecf20Sopenharmony_ci#include <linux/selection.h>
478c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
488c2ecf20Sopenharmony_ci#include <linux/ioport.h>
498c2ecf20Sopenharmony_ci#include <linux/init.h>
508c2ecf20Sopenharmony_ci#include <linux/screen_info.h>
518c2ecf20Sopenharmony_ci#include <video/vga.h>
528c2ecf20Sopenharmony_ci#include <asm/io.h>
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(vga_lock);
558c2ecf20Sopenharmony_cistatic int cursor_size_lastfrom;
568c2ecf20Sopenharmony_cistatic int cursor_size_lastto;
578c2ecf20Sopenharmony_cistatic u32 vgacon_xres;
588c2ecf20Sopenharmony_cistatic u32 vgacon_yres;
598c2ecf20Sopenharmony_cistatic struct vgastate vgastate;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci#define BLANK 0x0020
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci#define VGA_FONTWIDTH       8   /* VGA does not support fontwidths != 8 */
648c2ecf20Sopenharmony_ci/*
658c2ecf20Sopenharmony_ci *  Interface used by the world
668c2ecf20Sopenharmony_ci */
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic const char *vgacon_startup(void);
698c2ecf20Sopenharmony_cistatic void vgacon_init(struct vc_data *c, int init);
708c2ecf20Sopenharmony_cistatic void vgacon_deinit(struct vc_data *c);
718c2ecf20Sopenharmony_cistatic void vgacon_cursor(struct vc_data *c, int mode);
728c2ecf20Sopenharmony_cistatic int vgacon_switch(struct vc_data *c);
738c2ecf20Sopenharmony_cistatic int vgacon_blank(struct vc_data *c, int blank, int mode_switch);
748c2ecf20Sopenharmony_cistatic void vgacon_scrolldelta(struct vc_data *c, int lines);
758c2ecf20Sopenharmony_cistatic int vgacon_set_origin(struct vc_data *c);
768c2ecf20Sopenharmony_cistatic void vgacon_save_screen(struct vc_data *c);
778c2ecf20Sopenharmony_cistatic void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
788c2ecf20Sopenharmony_cistatic struct uni_pagedir *vgacon_uni_pagedir;
798c2ecf20Sopenharmony_cistatic int vgacon_refcount;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/* Description of the hardware situation */
828c2ecf20Sopenharmony_cistatic bool		vga_init_done;
838c2ecf20Sopenharmony_cistatic unsigned long	vga_vram_base		__read_mostly;	/* Base of video memory */
848c2ecf20Sopenharmony_cistatic unsigned long	vga_vram_end		__read_mostly;	/* End of video memory */
858c2ecf20Sopenharmony_cistatic unsigned int	vga_vram_size		__read_mostly;	/* Size of video memory */
868c2ecf20Sopenharmony_cistatic u16		vga_video_port_reg	__read_mostly;	/* Video register select port */
878c2ecf20Sopenharmony_cistatic u16		vga_video_port_val	__read_mostly;	/* Video register value port */
888c2ecf20Sopenharmony_cistatic unsigned int	vga_video_num_columns;			/* Number of text columns */
898c2ecf20Sopenharmony_cistatic unsigned int	vga_video_num_lines;			/* Number of text lines */
908c2ecf20Sopenharmony_cistatic bool		vga_can_do_color;			/* Do we support colors? */
918c2ecf20Sopenharmony_cistatic unsigned int	vga_default_font_height __read_mostly;	/* Height of default screen font */
928c2ecf20Sopenharmony_cistatic unsigned char	vga_video_type		__read_mostly;	/* Card type */
938c2ecf20Sopenharmony_cistatic bool		vga_font_is_default = true;
948c2ecf20Sopenharmony_cistatic int		vga_vesa_blanked;
958c2ecf20Sopenharmony_cistatic bool 		vga_palette_blanked;
968c2ecf20Sopenharmony_cistatic bool 		vga_is_gfx;
978c2ecf20Sopenharmony_cistatic bool 		vga_512_chars;
988c2ecf20Sopenharmony_cistatic int 		vga_video_font_height;
998c2ecf20Sopenharmony_cistatic int 		vga_scan_lines		__read_mostly;
1008c2ecf20Sopenharmony_cistatic unsigned int 	vga_rolled_over;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic bool vgacon_text_mode_force;
1038c2ecf20Sopenharmony_cistatic bool vga_hardscroll_enabled;
1048c2ecf20Sopenharmony_cistatic bool vga_hardscroll_user_enable = true;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cibool vgacon_text_force(void)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	return vgacon_text_mode_force;
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(vgacon_text_force);
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_cistatic int __init text_mode(char *str)
1138c2ecf20Sopenharmony_ci{
1148c2ecf20Sopenharmony_ci	vgacon_text_mode_force = true;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	pr_warn("You have booted with nomodeset. This means your GPU drivers are DISABLED\n");
1178c2ecf20Sopenharmony_ci	pr_warn("Any video related functionality will be severely degraded, and you may not even be able to suspend the system properly\n");
1188c2ecf20Sopenharmony_ci	pr_warn("Unless you actually understand what nomodeset does, you should reboot without enabling it\n");
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	return 1;
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/* force text mode - used by kernel modesetting */
1248c2ecf20Sopenharmony_ci__setup("nomodeset", text_mode);
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic int __init no_scroll(char *str)
1278c2ecf20Sopenharmony_ci{
1288c2ecf20Sopenharmony_ci	/*
1298c2ecf20Sopenharmony_ci	 * Disabling scrollback is required for the Braillex ib80-piezo
1308c2ecf20Sopenharmony_ci	 * Braille reader made by F.H. Papenmeier (Germany).
1318c2ecf20Sopenharmony_ci	 * Use the "no-scroll" bootflag.
1328c2ecf20Sopenharmony_ci	 */
1338c2ecf20Sopenharmony_ci	vga_hardscroll_user_enable = vga_hardscroll_enabled = false;
1348c2ecf20Sopenharmony_ci	return 1;
1358c2ecf20Sopenharmony_ci}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci__setup("no-scroll", no_scroll);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci/*
1408c2ecf20Sopenharmony_ci * By replacing the four outb_p with two back to back outw, we can reduce
1418c2ecf20Sopenharmony_ci * the window of opportunity to see text mislocated to the RHS of the
1428c2ecf20Sopenharmony_ci * console during heavy scrolling activity. However there is the remote
1438c2ecf20Sopenharmony_ci * possibility that some pre-dinosaur hardware won't like the back to back
1448c2ecf20Sopenharmony_ci * I/O. Since the Xservers get away with it, we should be able to as well.
1458c2ecf20Sopenharmony_ci */
1468c2ecf20Sopenharmony_cistatic inline void write_vga(unsigned char reg, unsigned int val)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	unsigned int v1, v2;
1498c2ecf20Sopenharmony_ci	unsigned long flags;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	/*
1528c2ecf20Sopenharmony_ci	 * ddprintk might set the console position from interrupt
1538c2ecf20Sopenharmony_ci	 * handlers, thus the write has to be IRQ-atomic.
1548c2ecf20Sopenharmony_ci	 */
1558c2ecf20Sopenharmony_ci	raw_spin_lock_irqsave(&vga_lock, flags);
1568c2ecf20Sopenharmony_ci	v1 = reg + (val & 0xff00);
1578c2ecf20Sopenharmony_ci	v2 = reg + 1 + ((val << 8) & 0xff00);
1588c2ecf20Sopenharmony_ci	outw(v1, vga_video_port_reg);
1598c2ecf20Sopenharmony_ci	outw(v2, vga_video_port_reg);
1608c2ecf20Sopenharmony_ci	raw_spin_unlock_irqrestore(&vga_lock, flags);
1618c2ecf20Sopenharmony_ci}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic inline void vga_set_mem_top(struct vc_data *c)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic void vgacon_restore_screen(struct vc_data *c)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	if (c->vc_origin != c->vc_visible_origin)
1718c2ecf20Sopenharmony_ci		vgacon_scrolldelta(c, 0);
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_cistatic void vgacon_scrolldelta(struct vc_data *c, int lines)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	vc_scrolldelta_helper(c, lines, vga_rolled_over, (void *)vga_vram_base,
1778c2ecf20Sopenharmony_ci			vga_vram_size);
1788c2ecf20Sopenharmony_ci	vga_set_mem_top(c);
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cistatic const char *vgacon_startup(void)
1828c2ecf20Sopenharmony_ci{
1838c2ecf20Sopenharmony_ci	const char *display_desc = NULL;
1848c2ecf20Sopenharmony_ci	u16 saved1, saved2;
1858c2ecf20Sopenharmony_ci	volatile u16 *p;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB ||
1888c2ecf20Sopenharmony_ci	    screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) {
1898c2ecf20Sopenharmony_ci	      no_vga:
1908c2ecf20Sopenharmony_ci#ifdef CONFIG_DUMMY_CONSOLE
1918c2ecf20Sopenharmony_ci		conswitchp = &dummy_con;
1928c2ecf20Sopenharmony_ci		return conswitchp->con_startup();
1938c2ecf20Sopenharmony_ci#else
1948c2ecf20Sopenharmony_ci		return NULL;
1958c2ecf20Sopenharmony_ci#endif
1968c2ecf20Sopenharmony_ci	}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	/* boot_params.screen_info reasonably initialized? */
1998c2ecf20Sopenharmony_ci	if ((screen_info.orig_video_lines == 0) ||
2008c2ecf20Sopenharmony_ci	    (screen_info.orig_video_cols  == 0))
2018c2ecf20Sopenharmony_ci		goto no_vga;
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	/* VGA16 modes are not handled by VGACON */
2048c2ecf20Sopenharmony_ci	if ((screen_info.orig_video_mode == 0x0D) ||	/* 320x200/4 */
2058c2ecf20Sopenharmony_ci	    (screen_info.orig_video_mode == 0x0E) ||	/* 640x200/4 */
2068c2ecf20Sopenharmony_ci	    (screen_info.orig_video_mode == 0x10) ||	/* 640x350/4 */
2078c2ecf20Sopenharmony_ci	    (screen_info.orig_video_mode == 0x12) ||	/* 640x480/4 */
2088c2ecf20Sopenharmony_ci	    (screen_info.orig_video_mode == 0x6A))	/* 800x600/4 (VESA) */
2098c2ecf20Sopenharmony_ci		goto no_vga;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	vga_video_num_lines = screen_info.orig_video_lines;
2128c2ecf20Sopenharmony_ci	vga_video_num_columns = screen_info.orig_video_cols;
2138c2ecf20Sopenharmony_ci	vgastate.vgabase = NULL;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	if (screen_info.orig_video_mode == 7) {
2168c2ecf20Sopenharmony_ci		/* Monochrome display */
2178c2ecf20Sopenharmony_ci		vga_vram_base = 0xb0000;
2188c2ecf20Sopenharmony_ci		vga_video_port_reg = VGA_CRT_IM;
2198c2ecf20Sopenharmony_ci		vga_video_port_val = VGA_CRT_DM;
2208c2ecf20Sopenharmony_ci		if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
2218c2ecf20Sopenharmony_ci			static struct resource ega_console_resource =
2228c2ecf20Sopenharmony_ci			    { .name	= "ega",
2238c2ecf20Sopenharmony_ci			      .flags	= IORESOURCE_IO,
2248c2ecf20Sopenharmony_ci			      .start	= 0x3B0,
2258c2ecf20Sopenharmony_ci			      .end	= 0x3BF };
2268c2ecf20Sopenharmony_ci			vga_video_type = VIDEO_TYPE_EGAM;
2278c2ecf20Sopenharmony_ci			vga_vram_size = 0x8000;
2288c2ecf20Sopenharmony_ci			display_desc = "EGA+";
2298c2ecf20Sopenharmony_ci			request_resource(&ioport_resource,
2308c2ecf20Sopenharmony_ci					 &ega_console_resource);
2318c2ecf20Sopenharmony_ci		} else {
2328c2ecf20Sopenharmony_ci			static struct resource mda1_console_resource =
2338c2ecf20Sopenharmony_ci			    { .name	= "mda",
2348c2ecf20Sopenharmony_ci			      .flags	= IORESOURCE_IO,
2358c2ecf20Sopenharmony_ci			      .start	= 0x3B0,
2368c2ecf20Sopenharmony_ci			      .end	= 0x3BB };
2378c2ecf20Sopenharmony_ci			static struct resource mda2_console_resource =
2388c2ecf20Sopenharmony_ci			    { .name	= "mda",
2398c2ecf20Sopenharmony_ci			      .flags	= IORESOURCE_IO,
2408c2ecf20Sopenharmony_ci			      .start	= 0x3BF,
2418c2ecf20Sopenharmony_ci			      .end	= 0x3BF };
2428c2ecf20Sopenharmony_ci			vga_video_type = VIDEO_TYPE_MDA;
2438c2ecf20Sopenharmony_ci			vga_vram_size = 0x2000;
2448c2ecf20Sopenharmony_ci			display_desc = "*MDA";
2458c2ecf20Sopenharmony_ci			request_resource(&ioport_resource,
2468c2ecf20Sopenharmony_ci					 &mda1_console_resource);
2478c2ecf20Sopenharmony_ci			request_resource(&ioport_resource,
2488c2ecf20Sopenharmony_ci					 &mda2_console_resource);
2498c2ecf20Sopenharmony_ci			vga_video_font_height = 14;
2508c2ecf20Sopenharmony_ci		}
2518c2ecf20Sopenharmony_ci	} else {
2528c2ecf20Sopenharmony_ci		/* If not, it is color. */
2538c2ecf20Sopenharmony_ci		vga_can_do_color = true;
2548c2ecf20Sopenharmony_ci		vga_vram_base = 0xb8000;
2558c2ecf20Sopenharmony_ci		vga_video_port_reg = VGA_CRT_IC;
2568c2ecf20Sopenharmony_ci		vga_video_port_val = VGA_CRT_DC;
2578c2ecf20Sopenharmony_ci		if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
2588c2ecf20Sopenharmony_ci			int i;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci			vga_vram_size = 0x8000;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci			if (!screen_info.orig_video_isVGA) {
2638c2ecf20Sopenharmony_ci				static struct resource ega_console_resource =
2648c2ecf20Sopenharmony_ci				    { .name	= "ega",
2658c2ecf20Sopenharmony_ci				      .flags	= IORESOURCE_IO,
2668c2ecf20Sopenharmony_ci				      .start	= 0x3C0,
2678c2ecf20Sopenharmony_ci				      .end	= 0x3DF };
2688c2ecf20Sopenharmony_ci				vga_video_type = VIDEO_TYPE_EGAC;
2698c2ecf20Sopenharmony_ci				display_desc = "EGA";
2708c2ecf20Sopenharmony_ci				request_resource(&ioport_resource,
2718c2ecf20Sopenharmony_ci						 &ega_console_resource);
2728c2ecf20Sopenharmony_ci			} else {
2738c2ecf20Sopenharmony_ci				static struct resource vga_console_resource =
2748c2ecf20Sopenharmony_ci				    { .name	= "vga+",
2758c2ecf20Sopenharmony_ci				      .flags	= IORESOURCE_IO,
2768c2ecf20Sopenharmony_ci				      .start	= 0x3C0,
2778c2ecf20Sopenharmony_ci				      .end	= 0x3DF };
2788c2ecf20Sopenharmony_ci				vga_video_type = VIDEO_TYPE_VGAC;
2798c2ecf20Sopenharmony_ci				display_desc = "VGA+";
2808c2ecf20Sopenharmony_ci				request_resource(&ioport_resource,
2818c2ecf20Sopenharmony_ci						 &vga_console_resource);
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci				/*
2848c2ecf20Sopenharmony_ci				 * Normalise the palette registers, to point
2858c2ecf20Sopenharmony_ci				 * the 16 screen colours to the first 16
2868c2ecf20Sopenharmony_ci				 * DAC entries.
2878c2ecf20Sopenharmony_ci				 */
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci				for (i = 0; i < 16; i++) {
2908c2ecf20Sopenharmony_ci					inb_p(VGA_IS1_RC);
2918c2ecf20Sopenharmony_ci					outb_p(i, VGA_ATT_W);
2928c2ecf20Sopenharmony_ci					outb_p(i, VGA_ATT_W);
2938c2ecf20Sopenharmony_ci				}
2948c2ecf20Sopenharmony_ci				outb_p(0x20, VGA_ATT_W);
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci				/*
2978c2ecf20Sopenharmony_ci				 * Now set the DAC registers back to their
2988c2ecf20Sopenharmony_ci				 * default values
2998c2ecf20Sopenharmony_ci				 */
3008c2ecf20Sopenharmony_ci				for (i = 0; i < 16; i++) {
3018c2ecf20Sopenharmony_ci					outb_p(color_table[i], VGA_PEL_IW);
3028c2ecf20Sopenharmony_ci					outb_p(default_red[i], VGA_PEL_D);
3038c2ecf20Sopenharmony_ci					outb_p(default_grn[i], VGA_PEL_D);
3048c2ecf20Sopenharmony_ci					outb_p(default_blu[i], VGA_PEL_D);
3058c2ecf20Sopenharmony_ci				}
3068c2ecf20Sopenharmony_ci			}
3078c2ecf20Sopenharmony_ci		} else {
3088c2ecf20Sopenharmony_ci			static struct resource cga_console_resource =
3098c2ecf20Sopenharmony_ci			    { .name	= "cga",
3108c2ecf20Sopenharmony_ci			      .flags	= IORESOURCE_IO,
3118c2ecf20Sopenharmony_ci			      .start	= 0x3D4,
3128c2ecf20Sopenharmony_ci			      .end	= 0x3D5 };
3138c2ecf20Sopenharmony_ci			vga_video_type = VIDEO_TYPE_CGA;
3148c2ecf20Sopenharmony_ci			vga_vram_size = 0x2000;
3158c2ecf20Sopenharmony_ci			display_desc = "*CGA";
3168c2ecf20Sopenharmony_ci			request_resource(&ioport_resource,
3178c2ecf20Sopenharmony_ci					 &cga_console_resource);
3188c2ecf20Sopenharmony_ci			vga_video_font_height = 8;
3198c2ecf20Sopenharmony_ci		}
3208c2ecf20Sopenharmony_ci	}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	vga_vram_base = VGA_MAP_MEM(vga_vram_base, vga_vram_size);
3238c2ecf20Sopenharmony_ci	vga_vram_end = vga_vram_base + vga_vram_size;
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_ci	/*
3268c2ecf20Sopenharmony_ci	 *      Find out if there is a graphics card present.
3278c2ecf20Sopenharmony_ci	 *      Are there smarter methods around?
3288c2ecf20Sopenharmony_ci	 */
3298c2ecf20Sopenharmony_ci	p = (volatile u16 *) vga_vram_base;
3308c2ecf20Sopenharmony_ci	saved1 = scr_readw(p);
3318c2ecf20Sopenharmony_ci	saved2 = scr_readw(p + 1);
3328c2ecf20Sopenharmony_ci	scr_writew(0xAA55, p);
3338c2ecf20Sopenharmony_ci	scr_writew(0x55AA, p + 1);
3348c2ecf20Sopenharmony_ci	if (scr_readw(p) != 0xAA55 || scr_readw(p + 1) != 0x55AA) {
3358c2ecf20Sopenharmony_ci		scr_writew(saved1, p);
3368c2ecf20Sopenharmony_ci		scr_writew(saved2, p + 1);
3378c2ecf20Sopenharmony_ci		goto no_vga;
3388c2ecf20Sopenharmony_ci	}
3398c2ecf20Sopenharmony_ci	scr_writew(0x55AA, p);
3408c2ecf20Sopenharmony_ci	scr_writew(0xAA55, p + 1);
3418c2ecf20Sopenharmony_ci	if (scr_readw(p) != 0x55AA || scr_readw(p + 1) != 0xAA55) {
3428c2ecf20Sopenharmony_ci		scr_writew(saved1, p);
3438c2ecf20Sopenharmony_ci		scr_writew(saved2, p + 1);
3448c2ecf20Sopenharmony_ci		goto no_vga;
3458c2ecf20Sopenharmony_ci	}
3468c2ecf20Sopenharmony_ci	scr_writew(saved1, p);
3478c2ecf20Sopenharmony_ci	scr_writew(saved2, p + 1);
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	if (vga_video_type == VIDEO_TYPE_EGAC
3508c2ecf20Sopenharmony_ci	    || vga_video_type == VIDEO_TYPE_VGAC
3518c2ecf20Sopenharmony_ci	    || vga_video_type == VIDEO_TYPE_EGAM) {
3528c2ecf20Sopenharmony_ci		vga_hardscroll_enabled = vga_hardscroll_user_enable;
3538c2ecf20Sopenharmony_ci		vga_default_font_height = screen_info.orig_video_points;
3548c2ecf20Sopenharmony_ci		vga_video_font_height = screen_info.orig_video_points;
3558c2ecf20Sopenharmony_ci		/* This may be suboptimal but is a safe bet - go with it */
3568c2ecf20Sopenharmony_ci		vga_scan_lines =
3578c2ecf20Sopenharmony_ci		    vga_video_font_height * vga_video_num_lines;
3588c2ecf20Sopenharmony_ci	}
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH;
3618c2ecf20Sopenharmony_ci	vgacon_yres = vga_scan_lines;
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci	vga_init_done = true;
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	return display_desc;
3668c2ecf20Sopenharmony_ci}
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_cistatic void vgacon_init(struct vc_data *c, int init)
3698c2ecf20Sopenharmony_ci{
3708c2ecf20Sopenharmony_ci	struct uni_pagedir *p;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	/*
3738c2ecf20Sopenharmony_ci	 * We cannot be loaded as a module, therefore init will be 1
3748c2ecf20Sopenharmony_ci	 * if we are the default console, however if we are a fallback
3758c2ecf20Sopenharmony_ci	 * console, for example if fbcon has failed registration, then
3768c2ecf20Sopenharmony_ci	 * init will be 0, so we need to make sure our boot parameters
3778c2ecf20Sopenharmony_ci	 * have been copied to the console structure for vgacon_resize
3788c2ecf20Sopenharmony_ci	 * ultimately called by vc_resize.  Any subsequent calls to
3798c2ecf20Sopenharmony_ci	 * vgacon_init init will have init set to 0 too.
3808c2ecf20Sopenharmony_ci	 */
3818c2ecf20Sopenharmony_ci	c->vc_can_do_color = vga_can_do_color;
3828c2ecf20Sopenharmony_ci	c->vc_scan_lines = vga_scan_lines;
3838c2ecf20Sopenharmony_ci	c->vc_font.height = c->vc_cell_height = vga_video_font_height;
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	/* set dimensions manually if init != 0 since vc_resize() will fail */
3868c2ecf20Sopenharmony_ci	if (init) {
3878c2ecf20Sopenharmony_ci		c->vc_cols = vga_video_num_columns;
3888c2ecf20Sopenharmony_ci		c->vc_rows = vga_video_num_lines;
3898c2ecf20Sopenharmony_ci	} else
3908c2ecf20Sopenharmony_ci		vc_resize(c, vga_video_num_columns, vga_video_num_lines);
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	c->vc_complement_mask = 0x7700;
3938c2ecf20Sopenharmony_ci	if (vga_512_chars)
3948c2ecf20Sopenharmony_ci		c->vc_hi_font_mask = 0x0800;
3958c2ecf20Sopenharmony_ci	p = *c->vc_uni_pagedir_loc;
3968c2ecf20Sopenharmony_ci	if (c->vc_uni_pagedir_loc != &vgacon_uni_pagedir) {
3978c2ecf20Sopenharmony_ci		con_free_unimap(c);
3988c2ecf20Sopenharmony_ci		c->vc_uni_pagedir_loc = &vgacon_uni_pagedir;
3998c2ecf20Sopenharmony_ci		vgacon_refcount++;
4008c2ecf20Sopenharmony_ci	}
4018c2ecf20Sopenharmony_ci	if (!vgacon_uni_pagedir && p)
4028c2ecf20Sopenharmony_ci		con_set_default_unimap(c);
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	/* Only set the default if the user didn't deliberately override it */
4058c2ecf20Sopenharmony_ci	if (global_cursor_default == -1)
4068c2ecf20Sopenharmony_ci		global_cursor_default =
4078c2ecf20Sopenharmony_ci			!(screen_info.flags & VIDEO_FLAGS_NOCURSOR);
4088c2ecf20Sopenharmony_ci}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_cistatic void vgacon_deinit(struct vc_data *c)
4118c2ecf20Sopenharmony_ci{
4128c2ecf20Sopenharmony_ci	/* When closing the active console, reset video origin */
4138c2ecf20Sopenharmony_ci	if (con_is_visible(c)) {
4148c2ecf20Sopenharmony_ci		c->vc_visible_origin = vga_vram_base;
4158c2ecf20Sopenharmony_ci		vga_set_mem_top(c);
4168c2ecf20Sopenharmony_ci	}
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci	if (!--vgacon_refcount)
4198c2ecf20Sopenharmony_ci		con_free_unimap(c);
4208c2ecf20Sopenharmony_ci	c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;
4218c2ecf20Sopenharmony_ci	con_set_default_unimap(c);
4228c2ecf20Sopenharmony_ci}
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_cistatic u8 vgacon_build_attr(struct vc_data *c, u8 color,
4258c2ecf20Sopenharmony_ci			    enum vc_intensity intensity,
4268c2ecf20Sopenharmony_ci			    bool blink, bool underline, bool reverse,
4278c2ecf20Sopenharmony_ci			    bool italic)
4288c2ecf20Sopenharmony_ci{
4298c2ecf20Sopenharmony_ci	u8 attr = color;
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	if (vga_can_do_color) {
4328c2ecf20Sopenharmony_ci		if (italic)
4338c2ecf20Sopenharmony_ci			attr = (attr & 0xF0) | c->vc_itcolor;
4348c2ecf20Sopenharmony_ci		else if (underline)
4358c2ecf20Sopenharmony_ci			attr = (attr & 0xf0) | c->vc_ulcolor;
4368c2ecf20Sopenharmony_ci		else if (intensity == VCI_HALF_BRIGHT)
4378c2ecf20Sopenharmony_ci			attr = (attr & 0xf0) | c->vc_halfcolor;
4388c2ecf20Sopenharmony_ci	}
4398c2ecf20Sopenharmony_ci	if (reverse)
4408c2ecf20Sopenharmony_ci		attr =
4418c2ecf20Sopenharmony_ci		    ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) &
4428c2ecf20Sopenharmony_ci				       0x77);
4438c2ecf20Sopenharmony_ci	if (blink)
4448c2ecf20Sopenharmony_ci		attr ^= 0x80;
4458c2ecf20Sopenharmony_ci	if (intensity == VCI_BOLD)
4468c2ecf20Sopenharmony_ci		attr ^= 0x08;
4478c2ecf20Sopenharmony_ci	if (!vga_can_do_color) {
4488c2ecf20Sopenharmony_ci		if (italic)
4498c2ecf20Sopenharmony_ci			attr = (attr & 0xF8) | 0x02;
4508c2ecf20Sopenharmony_ci		else if (underline)
4518c2ecf20Sopenharmony_ci			attr = (attr & 0xf8) | 0x01;
4528c2ecf20Sopenharmony_ci		else if (intensity == VCI_HALF_BRIGHT)
4538c2ecf20Sopenharmony_ci			attr = (attr & 0xf0) | 0x08;
4548c2ecf20Sopenharmony_ci	}
4558c2ecf20Sopenharmony_ci	return attr;
4568c2ecf20Sopenharmony_ci}
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_cistatic void vgacon_invert_region(struct vc_data *c, u16 * p, int count)
4598c2ecf20Sopenharmony_ci{
4608c2ecf20Sopenharmony_ci	const bool col = vga_can_do_color;
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	while (count--) {
4638c2ecf20Sopenharmony_ci		u16 a = scr_readw(p);
4648c2ecf20Sopenharmony_ci		if (col)
4658c2ecf20Sopenharmony_ci			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
4668c2ecf20Sopenharmony_ci			    (((a) & 0x0700) << 4);
4678c2ecf20Sopenharmony_ci		else
4688c2ecf20Sopenharmony_ci			a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
4698c2ecf20Sopenharmony_ci		scr_writew(a, p++);
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci}
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_cistatic void vgacon_set_cursor_size(int xpos, int from, int to)
4748c2ecf20Sopenharmony_ci{
4758c2ecf20Sopenharmony_ci	unsigned long flags;
4768c2ecf20Sopenharmony_ci	int curs, cure;
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	if ((from == cursor_size_lastfrom) && (to == cursor_size_lastto))
4798c2ecf20Sopenharmony_ci		return;
4808c2ecf20Sopenharmony_ci	cursor_size_lastfrom = from;
4818c2ecf20Sopenharmony_ci	cursor_size_lastto = to;
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci	raw_spin_lock_irqsave(&vga_lock, flags);
4848c2ecf20Sopenharmony_ci	if (vga_video_type >= VIDEO_TYPE_VGAC) {
4858c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
4868c2ecf20Sopenharmony_ci		curs = inb_p(vga_video_port_val);
4878c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
4888c2ecf20Sopenharmony_ci		cure = inb_p(vga_video_port_val);
4898c2ecf20Sopenharmony_ci	} else {
4908c2ecf20Sopenharmony_ci		curs = 0;
4918c2ecf20Sopenharmony_ci		cure = 0;
4928c2ecf20Sopenharmony_ci	}
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	curs = (curs & 0xc0) | from;
4958c2ecf20Sopenharmony_ci	cure = (cure & 0xe0) | to;
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_ci	outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
4988c2ecf20Sopenharmony_ci	outb_p(curs, vga_video_port_val);
4998c2ecf20Sopenharmony_ci	outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
5008c2ecf20Sopenharmony_ci	outb_p(cure, vga_video_port_val);
5018c2ecf20Sopenharmony_ci	raw_spin_unlock_irqrestore(&vga_lock, flags);
5028c2ecf20Sopenharmony_ci}
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_cistatic void vgacon_cursor(struct vc_data *c, int mode)
5058c2ecf20Sopenharmony_ci{
5068c2ecf20Sopenharmony_ci	if (c->vc_mode != KD_TEXT)
5078c2ecf20Sopenharmony_ci		return;
5088c2ecf20Sopenharmony_ci
5098c2ecf20Sopenharmony_ci	vgacon_restore_screen(c);
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	switch (mode) {
5128c2ecf20Sopenharmony_ci	case CM_ERASE:
5138c2ecf20Sopenharmony_ci		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
5148c2ecf20Sopenharmony_ci	        if (vga_video_type >= VIDEO_TYPE_VGAC)
5158c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x, 31, 30);
5168c2ecf20Sopenharmony_ci		else
5178c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x, 31, 31);
5188c2ecf20Sopenharmony_ci		break;
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	case CM_MOVE:
5218c2ecf20Sopenharmony_ci	case CM_DRAW:
5228c2ecf20Sopenharmony_ci		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
5238c2ecf20Sopenharmony_ci		switch (CUR_SIZE(c->vc_cursor_type)) {
5248c2ecf20Sopenharmony_ci		case CUR_UNDERLINE:
5258c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x,
5268c2ecf20Sopenharmony_ci					       c->vc_cell_height -
5278c2ecf20Sopenharmony_ci					       (c->vc_cell_height <
5288c2ecf20Sopenharmony_ci						10 ? 2 : 3),
5298c2ecf20Sopenharmony_ci					       c->vc_cell_height -
5308c2ecf20Sopenharmony_ci					       (c->vc_cell_height <
5318c2ecf20Sopenharmony_ci						10 ? 1 : 2));
5328c2ecf20Sopenharmony_ci			break;
5338c2ecf20Sopenharmony_ci		case CUR_TWO_THIRDS:
5348c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x,
5358c2ecf20Sopenharmony_ci					       c->vc_cell_height / 3,
5368c2ecf20Sopenharmony_ci					       c->vc_cell_height -
5378c2ecf20Sopenharmony_ci					       (c->vc_cell_height <
5388c2ecf20Sopenharmony_ci						10 ? 1 : 2));
5398c2ecf20Sopenharmony_ci			break;
5408c2ecf20Sopenharmony_ci		case CUR_LOWER_THIRD:
5418c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x,
5428c2ecf20Sopenharmony_ci					       (c->vc_cell_height * 2) / 3,
5438c2ecf20Sopenharmony_ci					       c->vc_cell_height -
5448c2ecf20Sopenharmony_ci					       (c->vc_cell_height <
5458c2ecf20Sopenharmony_ci						10 ? 1 : 2));
5468c2ecf20Sopenharmony_ci			break;
5478c2ecf20Sopenharmony_ci		case CUR_LOWER_HALF:
5488c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x,
5498c2ecf20Sopenharmony_ci					       c->vc_cell_height / 2,
5508c2ecf20Sopenharmony_ci					       c->vc_cell_height -
5518c2ecf20Sopenharmony_ci					       (c->vc_cell_height <
5528c2ecf20Sopenharmony_ci						10 ? 1 : 2));
5538c2ecf20Sopenharmony_ci			break;
5548c2ecf20Sopenharmony_ci		case CUR_NONE:
5558c2ecf20Sopenharmony_ci			if (vga_video_type >= VIDEO_TYPE_VGAC)
5568c2ecf20Sopenharmony_ci				vgacon_set_cursor_size(c->state.x, 31, 30);
5578c2ecf20Sopenharmony_ci			else
5588c2ecf20Sopenharmony_ci				vgacon_set_cursor_size(c->state.x, 31, 31);
5598c2ecf20Sopenharmony_ci			break;
5608c2ecf20Sopenharmony_ci		default:
5618c2ecf20Sopenharmony_ci			vgacon_set_cursor_size(c->state.x, 1,
5628c2ecf20Sopenharmony_ci					       c->vc_cell_height);
5638c2ecf20Sopenharmony_ci			break;
5648c2ecf20Sopenharmony_ci		}
5658c2ecf20Sopenharmony_ci		break;
5668c2ecf20Sopenharmony_ci	}
5678c2ecf20Sopenharmony_ci}
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_cistatic int vgacon_doresize(struct vc_data *c,
5708c2ecf20Sopenharmony_ci		unsigned int width, unsigned int height)
5718c2ecf20Sopenharmony_ci{
5728c2ecf20Sopenharmony_ci	unsigned long flags;
5738c2ecf20Sopenharmony_ci	unsigned int scanlines = height * c->vc_cell_height;
5748c2ecf20Sopenharmony_ci	u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan;
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci	raw_spin_lock_irqsave(&vga_lock, flags);
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	vgacon_xres = width * VGA_FONTWIDTH;
5798c2ecf20Sopenharmony_ci	vgacon_yres = height * c->vc_cell_height;
5808c2ecf20Sopenharmony_ci	if (vga_video_type >= VIDEO_TYPE_VGAC) {
5818c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
5828c2ecf20Sopenharmony_ci		max_scan = inb_p(vga_video_port_val);
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci		if (max_scan & 0x80)
5858c2ecf20Sopenharmony_ci			scanlines <<= 1;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_MODE, vga_video_port_reg);
5888c2ecf20Sopenharmony_ci		mode = inb_p(vga_video_port_val);
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci		if (mode & 0x04)
5918c2ecf20Sopenharmony_ci			scanlines >>= 1;
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci		scanlines -= 1;
5948c2ecf20Sopenharmony_ci		scanlines_lo = scanlines & 0xff;
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
5978c2ecf20Sopenharmony_ci		r7 = inb_p(vga_video_port_val) & ~0x42;
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci		if (scanlines & 0x100)
6008c2ecf20Sopenharmony_ci			r7 |= 0x02;
6018c2ecf20Sopenharmony_ci		if (scanlines & 0x200)
6028c2ecf20Sopenharmony_ci			r7 |= 0x40;
6038c2ecf20Sopenharmony_ci
6048c2ecf20Sopenharmony_ci		/* deprotect registers */
6058c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
6068c2ecf20Sopenharmony_ci		vsync_end = inb_p(vga_video_port_val);
6078c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
6088c2ecf20Sopenharmony_ci		outb_p(vsync_end & ~0x80, vga_video_port_val);
6098c2ecf20Sopenharmony_ci	}
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci	outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);
6128c2ecf20Sopenharmony_ci	outb_p(width - 1, vga_video_port_val);
6138c2ecf20Sopenharmony_ci	outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);
6148c2ecf20Sopenharmony_ci	outb_p(width >> 1, vga_video_port_val);
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_ci	if (vga_video_type >= VIDEO_TYPE_VGAC) {
6178c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
6188c2ecf20Sopenharmony_ci		outb_p(scanlines_lo, vga_video_port_val);
6198c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
6208c2ecf20Sopenharmony_ci		outb_p(r7,vga_video_port_val);
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci		/* reprotect registers */
6238c2ecf20Sopenharmony_ci		outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
6248c2ecf20Sopenharmony_ci		outb_p(vsync_end, vga_video_port_val);
6258c2ecf20Sopenharmony_ci	}
6268c2ecf20Sopenharmony_ci
6278c2ecf20Sopenharmony_ci	raw_spin_unlock_irqrestore(&vga_lock, flags);
6288c2ecf20Sopenharmony_ci	return 0;
6298c2ecf20Sopenharmony_ci}
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_cistatic int vgacon_switch(struct vc_data *c)
6328c2ecf20Sopenharmony_ci{
6338c2ecf20Sopenharmony_ci	int x = c->vc_cols * VGA_FONTWIDTH;
6348c2ecf20Sopenharmony_ci	int y = c->vc_rows * c->vc_cell_height;
6358c2ecf20Sopenharmony_ci	int rows = screen_info.orig_video_lines * vga_default_font_height/
6368c2ecf20Sopenharmony_ci		c->vc_cell_height;
6378c2ecf20Sopenharmony_ci	/*
6388c2ecf20Sopenharmony_ci	 * We need to save screen size here as it's the only way
6398c2ecf20Sopenharmony_ci	 * we can spot the screen has been resized and we need to
6408c2ecf20Sopenharmony_ci	 * set size of freshly allocated screens ourselves.
6418c2ecf20Sopenharmony_ci	 */
6428c2ecf20Sopenharmony_ci	vga_video_num_columns = c->vc_cols;
6438c2ecf20Sopenharmony_ci	vga_video_num_lines = c->vc_rows;
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci	/* We can only copy out the size of the video buffer here,
6468c2ecf20Sopenharmony_ci	 * otherwise we get into VGA BIOS */
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	if (!vga_is_gfx) {
6498c2ecf20Sopenharmony_ci		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
6508c2ecf20Sopenharmony_ci			    c->vc_screenbuf_size > vga_vram_size ?
6518c2ecf20Sopenharmony_ci				vga_vram_size : c->vc_screenbuf_size);
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci		if ((vgacon_xres != x || vgacon_yres != y) &&
6548c2ecf20Sopenharmony_ci		    (!(vga_video_num_columns % 2) &&
6558c2ecf20Sopenharmony_ci		     vga_video_num_columns <= screen_info.orig_video_cols &&
6568c2ecf20Sopenharmony_ci		     vga_video_num_lines <= rows))
6578c2ecf20Sopenharmony_ci			vgacon_doresize(c, c->vc_cols, c->vc_rows);
6588c2ecf20Sopenharmony_ci	}
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_ci	return 0;		/* Redrawing not needed */
6618c2ecf20Sopenharmony_ci}
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_cistatic void vga_set_palette(struct vc_data *vc, const unsigned char *table)
6648c2ecf20Sopenharmony_ci{
6658c2ecf20Sopenharmony_ci	int i, j;
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_ci	vga_w(vgastate.vgabase, VGA_PEL_MSK, 0xff);
6688c2ecf20Sopenharmony_ci	for (i = j = 0; i < 16; i++) {
6698c2ecf20Sopenharmony_ci		vga_w(vgastate.vgabase, VGA_PEL_IW, table[i]);
6708c2ecf20Sopenharmony_ci		vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
6718c2ecf20Sopenharmony_ci		vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
6728c2ecf20Sopenharmony_ci		vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
6738c2ecf20Sopenharmony_ci	}
6748c2ecf20Sopenharmony_ci}
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_cistatic void vgacon_set_palette(struct vc_data *vc, const unsigned char *table)
6778c2ecf20Sopenharmony_ci{
6788c2ecf20Sopenharmony_ci	if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked
6798c2ecf20Sopenharmony_ci	    || !con_is_visible(vc))
6808c2ecf20Sopenharmony_ci		return;
6818c2ecf20Sopenharmony_ci	vga_set_palette(vc, table);
6828c2ecf20Sopenharmony_ci}
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci/* structure holding original VGA register settings */
6858c2ecf20Sopenharmony_cistatic struct {
6868c2ecf20Sopenharmony_ci	unsigned char SeqCtrlIndex;	/* Sequencer Index reg.   */
6878c2ecf20Sopenharmony_ci	unsigned char CrtCtrlIndex;	/* CRT-Contr. Index reg.  */
6888c2ecf20Sopenharmony_ci	unsigned char CrtMiscIO;	/* Miscellaneous register */
6898c2ecf20Sopenharmony_ci	unsigned char HorizontalTotal;	/* CRT-Controller:00h */
6908c2ecf20Sopenharmony_ci	unsigned char HorizDisplayEnd;	/* CRT-Controller:01h */
6918c2ecf20Sopenharmony_ci	unsigned char StartHorizRetrace;	/* CRT-Controller:04h */
6928c2ecf20Sopenharmony_ci	unsigned char EndHorizRetrace;	/* CRT-Controller:05h */
6938c2ecf20Sopenharmony_ci	unsigned char Overflow;	/* CRT-Controller:07h */
6948c2ecf20Sopenharmony_ci	unsigned char StartVertRetrace;	/* CRT-Controller:10h */
6958c2ecf20Sopenharmony_ci	unsigned char EndVertRetrace;	/* CRT-Controller:11h */
6968c2ecf20Sopenharmony_ci	unsigned char ModeControl;	/* CRT-Controller:17h */
6978c2ecf20Sopenharmony_ci	unsigned char ClockingMode;	/* Seq-Controller:01h */
6988c2ecf20Sopenharmony_ci} vga_state;
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_cistatic void vga_vesa_blank(struct vgastate *state, int mode)
7018c2ecf20Sopenharmony_ci{
7028c2ecf20Sopenharmony_ci	/* save original values of VGA controller registers */
7038c2ecf20Sopenharmony_ci	if (!vga_vesa_blanked) {
7048c2ecf20Sopenharmony_ci		raw_spin_lock_irq(&vga_lock);
7058c2ecf20Sopenharmony_ci		vga_state.SeqCtrlIndex = vga_r(state->vgabase, VGA_SEQ_I);
7068c2ecf20Sopenharmony_ci		vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
7078c2ecf20Sopenharmony_ci		vga_state.CrtMiscIO = vga_r(state->vgabase, VGA_MIS_R);
7088c2ecf20Sopenharmony_ci		raw_spin_unlock_irq(&vga_lock);
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_ci		outb_p(0x00, vga_video_port_reg);	/* HorizontalTotal */
7118c2ecf20Sopenharmony_ci		vga_state.HorizontalTotal = inb_p(vga_video_port_val);
7128c2ecf20Sopenharmony_ci		outb_p(0x01, vga_video_port_reg);	/* HorizDisplayEnd */
7138c2ecf20Sopenharmony_ci		vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
7148c2ecf20Sopenharmony_ci		outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */
7158c2ecf20Sopenharmony_ci		vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
7168c2ecf20Sopenharmony_ci		outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */
7178c2ecf20Sopenharmony_ci		vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
7188c2ecf20Sopenharmony_ci		outb_p(0x07, vga_video_port_reg);	/* Overflow */
7198c2ecf20Sopenharmony_ci		vga_state.Overflow = inb_p(vga_video_port_val);
7208c2ecf20Sopenharmony_ci		outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */
7218c2ecf20Sopenharmony_ci		vga_state.StartVertRetrace = inb_p(vga_video_port_val);
7228c2ecf20Sopenharmony_ci		outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */
7238c2ecf20Sopenharmony_ci		vga_state.EndVertRetrace = inb_p(vga_video_port_val);
7248c2ecf20Sopenharmony_ci		outb_p(0x17, vga_video_port_reg);	/* ModeControl */
7258c2ecf20Sopenharmony_ci		vga_state.ModeControl = inb_p(vga_video_port_val);
7268c2ecf20Sopenharmony_ci		vga_state.ClockingMode = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
7278c2ecf20Sopenharmony_ci	}
7288c2ecf20Sopenharmony_ci
7298c2ecf20Sopenharmony_ci	/* assure that video is enabled */
7308c2ecf20Sopenharmony_ci	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
7318c2ecf20Sopenharmony_ci	raw_spin_lock_irq(&vga_lock);
7328c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode | 0x20);
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci	/* test for vertical retrace in process.... */
7358c2ecf20Sopenharmony_ci	if ((vga_state.CrtMiscIO & 0x80) == 0x80)
7368c2ecf20Sopenharmony_ci		vga_w(state->vgabase, VGA_MIS_W, vga_state.CrtMiscIO & 0xEF);
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci	/*
7398c2ecf20Sopenharmony_ci	 * Set <End of vertical retrace> to minimum (0) and
7408c2ecf20Sopenharmony_ci	 * <Start of vertical Retrace> to maximum (incl. overflow)
7418c2ecf20Sopenharmony_ci	 * Result: turn off vertical sync (VSync) pulse.
7428c2ecf20Sopenharmony_ci	 */
7438c2ecf20Sopenharmony_ci	if (mode & VESA_VSYNC_SUSPEND) {
7448c2ecf20Sopenharmony_ci		outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */
7458c2ecf20Sopenharmony_ci		outb_p(0xff, vga_video_port_val);	/* maximum value */
7468c2ecf20Sopenharmony_ci		outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */
7478c2ecf20Sopenharmony_ci		outb_p(0x40, vga_video_port_val);	/* minimum (bits 0..3)  */
7488c2ecf20Sopenharmony_ci		outb_p(0x07, vga_video_port_reg);	/* Overflow */
7498c2ecf20Sopenharmony_ci		outb_p(vga_state.Overflow | 0x84, vga_video_port_val);	/* bits 9,10 of vert. retrace */
7508c2ecf20Sopenharmony_ci	}
7518c2ecf20Sopenharmony_ci
7528c2ecf20Sopenharmony_ci	if (mode & VESA_HSYNC_SUSPEND) {
7538c2ecf20Sopenharmony_ci		/*
7548c2ecf20Sopenharmony_ci		 * Set <End of horizontal retrace> to minimum (0) and
7558c2ecf20Sopenharmony_ci		 *  <Start of horizontal Retrace> to maximum
7568c2ecf20Sopenharmony_ci		 * Result: turn off horizontal sync (HSync) pulse.
7578c2ecf20Sopenharmony_ci		 */
7588c2ecf20Sopenharmony_ci		outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */
7598c2ecf20Sopenharmony_ci		outb_p(0xff, vga_video_port_val);	/* maximum */
7608c2ecf20Sopenharmony_ci		outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */
7618c2ecf20Sopenharmony_ci		outb_p(0x00, vga_video_port_val);	/* minimum (0) */
7628c2ecf20Sopenharmony_ci	}
7638c2ecf20Sopenharmony_ci
7648c2ecf20Sopenharmony_ci	/* restore both index registers */
7658c2ecf20Sopenharmony_ci	vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex);
7668c2ecf20Sopenharmony_ci	outb_p(vga_state.CrtCtrlIndex, vga_video_port_reg);
7678c2ecf20Sopenharmony_ci	raw_spin_unlock_irq(&vga_lock);
7688c2ecf20Sopenharmony_ci}
7698c2ecf20Sopenharmony_ci
7708c2ecf20Sopenharmony_cistatic void vga_vesa_unblank(struct vgastate *state)
7718c2ecf20Sopenharmony_ci{
7728c2ecf20Sopenharmony_ci	/* restore original values of VGA controller registers */
7738c2ecf20Sopenharmony_ci	raw_spin_lock_irq(&vga_lock);
7748c2ecf20Sopenharmony_ci	vga_w(state->vgabase, VGA_MIS_W, vga_state.CrtMiscIO);
7758c2ecf20Sopenharmony_ci
7768c2ecf20Sopenharmony_ci	outb_p(0x00, vga_video_port_reg);	/* HorizontalTotal */
7778c2ecf20Sopenharmony_ci	outb_p(vga_state.HorizontalTotal, vga_video_port_val);
7788c2ecf20Sopenharmony_ci	outb_p(0x01, vga_video_port_reg);	/* HorizDisplayEnd */
7798c2ecf20Sopenharmony_ci	outb_p(vga_state.HorizDisplayEnd, vga_video_port_val);
7808c2ecf20Sopenharmony_ci	outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */
7818c2ecf20Sopenharmony_ci	outb_p(vga_state.StartHorizRetrace, vga_video_port_val);
7828c2ecf20Sopenharmony_ci	outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */
7838c2ecf20Sopenharmony_ci	outb_p(vga_state.EndHorizRetrace, vga_video_port_val);
7848c2ecf20Sopenharmony_ci	outb_p(0x07, vga_video_port_reg);	/* Overflow */
7858c2ecf20Sopenharmony_ci	outb_p(vga_state.Overflow, vga_video_port_val);
7868c2ecf20Sopenharmony_ci	outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */
7878c2ecf20Sopenharmony_ci	outb_p(vga_state.StartVertRetrace, vga_video_port_val);
7888c2ecf20Sopenharmony_ci	outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */
7898c2ecf20Sopenharmony_ci	outb_p(vga_state.EndVertRetrace, vga_video_port_val);
7908c2ecf20Sopenharmony_ci	outb_p(0x17, vga_video_port_reg);	/* ModeControl */
7918c2ecf20Sopenharmony_ci	outb_p(vga_state.ModeControl, vga_video_port_val);
7928c2ecf20Sopenharmony_ci	/* ClockingMode */
7938c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode);
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci	/* restore index/control registers */
7968c2ecf20Sopenharmony_ci	vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex);
7978c2ecf20Sopenharmony_ci	outb_p(vga_state.CrtCtrlIndex, vga_video_port_reg);
7988c2ecf20Sopenharmony_ci	raw_spin_unlock_irq(&vga_lock);
7998c2ecf20Sopenharmony_ci}
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_cistatic void vga_pal_blank(struct vgastate *state)
8028c2ecf20Sopenharmony_ci{
8038c2ecf20Sopenharmony_ci	int i;
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_ci	vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
8068c2ecf20Sopenharmony_ci	for (i = 0; i < 16; i++) {
8078c2ecf20Sopenharmony_ci		vga_w(state->vgabase, VGA_PEL_IW, i);
8088c2ecf20Sopenharmony_ci		vga_w(state->vgabase, VGA_PEL_D, 0);
8098c2ecf20Sopenharmony_ci		vga_w(state->vgabase, VGA_PEL_D, 0);
8108c2ecf20Sopenharmony_ci		vga_w(state->vgabase, VGA_PEL_D, 0);
8118c2ecf20Sopenharmony_ci	}
8128c2ecf20Sopenharmony_ci}
8138c2ecf20Sopenharmony_ci
8148c2ecf20Sopenharmony_cistatic int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
8158c2ecf20Sopenharmony_ci{
8168c2ecf20Sopenharmony_ci	switch (blank) {
8178c2ecf20Sopenharmony_ci	case 0:		/* Unblank */
8188c2ecf20Sopenharmony_ci		if (vga_vesa_blanked) {
8198c2ecf20Sopenharmony_ci			vga_vesa_unblank(&vgastate);
8208c2ecf20Sopenharmony_ci			vga_vesa_blanked = 0;
8218c2ecf20Sopenharmony_ci		}
8228c2ecf20Sopenharmony_ci		if (vga_palette_blanked) {
8238c2ecf20Sopenharmony_ci			vga_set_palette(c, color_table);
8248c2ecf20Sopenharmony_ci			vga_palette_blanked = false;
8258c2ecf20Sopenharmony_ci			return 0;
8268c2ecf20Sopenharmony_ci		}
8278c2ecf20Sopenharmony_ci		vga_is_gfx = false;
8288c2ecf20Sopenharmony_ci		/* Tell console.c that it has to restore the screen itself */
8298c2ecf20Sopenharmony_ci		return 1;
8308c2ecf20Sopenharmony_ci	case 1:		/* Normal blanking */
8318c2ecf20Sopenharmony_ci	case -1:	/* Obsolete */
8328c2ecf20Sopenharmony_ci		if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) {
8338c2ecf20Sopenharmony_ci			vga_pal_blank(&vgastate);
8348c2ecf20Sopenharmony_ci			vga_palette_blanked = true;
8358c2ecf20Sopenharmony_ci			return 0;
8368c2ecf20Sopenharmony_ci		}
8378c2ecf20Sopenharmony_ci		vgacon_set_origin(c);
8388c2ecf20Sopenharmony_ci		scr_memsetw((void *) vga_vram_base, BLANK,
8398c2ecf20Sopenharmony_ci			    c->vc_screenbuf_size);
8408c2ecf20Sopenharmony_ci		if (mode_switch)
8418c2ecf20Sopenharmony_ci			vga_is_gfx = true;
8428c2ecf20Sopenharmony_ci		return 1;
8438c2ecf20Sopenharmony_ci	default:		/* VESA blanking */
8448c2ecf20Sopenharmony_ci		if (vga_video_type == VIDEO_TYPE_VGAC) {
8458c2ecf20Sopenharmony_ci			vga_vesa_blank(&vgastate, blank - 1);
8468c2ecf20Sopenharmony_ci			vga_vesa_blanked = blank;
8478c2ecf20Sopenharmony_ci		}
8488c2ecf20Sopenharmony_ci		return 0;
8498c2ecf20Sopenharmony_ci	}
8508c2ecf20Sopenharmony_ci}
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci/*
8538c2ecf20Sopenharmony_ci * PIO_FONT support.
8548c2ecf20Sopenharmony_ci *
8558c2ecf20Sopenharmony_ci * The font loading code goes back to the codepage package by
8568c2ecf20Sopenharmony_ci * Joel Hoffman (joel@wam.umd.edu). (He reports that the original
8578c2ecf20Sopenharmony_ci * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
8588c2ecf20Sopenharmony_ci * Video Systems_ by Richard Wilton. 1987.  Microsoft Press".)
8598c2ecf20Sopenharmony_ci *
8608c2ecf20Sopenharmony_ci * Change for certain monochrome monitors by Yury Shevchuck
8618c2ecf20Sopenharmony_ci * (sizif@botik.yaroslavl.su).
8628c2ecf20Sopenharmony_ci */
8638c2ecf20Sopenharmony_ci
8648c2ecf20Sopenharmony_ci#define colourmap 0xa0000
8658c2ecf20Sopenharmony_ci/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
8668c2ecf20Sopenharmony_ci   should use 0xA0000 for the bwmap as well.. */
8678c2ecf20Sopenharmony_ci#define blackwmap 0xa0000
8688c2ecf20Sopenharmony_ci#define cmapsz 8192
8698c2ecf20Sopenharmony_ci
8708c2ecf20Sopenharmony_cistatic int vgacon_do_font_op(struct vgastate *state, char *arg, int set,
8718c2ecf20Sopenharmony_ci		bool ch512)
8728c2ecf20Sopenharmony_ci{
8738c2ecf20Sopenharmony_ci	unsigned short video_port_status = vga_video_port_reg + 6;
8748c2ecf20Sopenharmony_ci	int font_select = 0x00, beg, i;
8758c2ecf20Sopenharmony_ci	char *charmap;
8768c2ecf20Sopenharmony_ci	bool clear_attribs = false;
8778c2ecf20Sopenharmony_ci	if (vga_video_type != VIDEO_TYPE_EGAM) {
8788c2ecf20Sopenharmony_ci		charmap = (char *) VGA_MAP_MEM(colourmap, 0);
8798c2ecf20Sopenharmony_ci		beg = 0x0e;
8808c2ecf20Sopenharmony_ci	} else {
8818c2ecf20Sopenharmony_ci		charmap = (char *) VGA_MAP_MEM(blackwmap, 0);
8828c2ecf20Sopenharmony_ci		beg = 0x0a;
8838c2ecf20Sopenharmony_ci	}
8848c2ecf20Sopenharmony_ci
8858c2ecf20Sopenharmony_ci#ifdef BROKEN_GRAPHICS_PROGRAMS
8868c2ecf20Sopenharmony_ci	/*
8878c2ecf20Sopenharmony_ci	 * All fonts are loaded in slot 0 (0:1 for 512 ch)
8888c2ecf20Sopenharmony_ci	 */
8898c2ecf20Sopenharmony_ci
8908c2ecf20Sopenharmony_ci	if (!arg)
8918c2ecf20Sopenharmony_ci		return -EINVAL;	/* Return to default font not supported */
8928c2ecf20Sopenharmony_ci
8938c2ecf20Sopenharmony_ci	vga_font_is_default = false;
8948c2ecf20Sopenharmony_ci	font_select = ch512 ? 0x04 : 0x00;
8958c2ecf20Sopenharmony_ci#else
8968c2ecf20Sopenharmony_ci	/*
8978c2ecf20Sopenharmony_ci	 * The default font is kept in slot 0 and is never touched.
8988c2ecf20Sopenharmony_ci	 * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)
8998c2ecf20Sopenharmony_ci	 */
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	if (set) {
9028c2ecf20Sopenharmony_ci		vga_font_is_default = !arg;
9038c2ecf20Sopenharmony_ci		if (!arg)
9048c2ecf20Sopenharmony_ci			ch512 = false;	/* Default font is always 256 */
9058c2ecf20Sopenharmony_ci		font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;
9068c2ecf20Sopenharmony_ci	}
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci	if (!vga_font_is_default)
9098c2ecf20Sopenharmony_ci		charmap += 4 * cmapsz;
9108c2ecf20Sopenharmony_ci#endif
9118c2ecf20Sopenharmony_ci
9128c2ecf20Sopenharmony_ci	raw_spin_lock_irq(&vga_lock);
9138c2ecf20Sopenharmony_ci	/* First, the Sequencer */
9148c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
9158c2ecf20Sopenharmony_ci	/* CPU writes only to map 2 */
9168c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x04);
9178c2ecf20Sopenharmony_ci	/* Sequential addressing */
9188c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x07);
9198c2ecf20Sopenharmony_ci	/* Clear synchronous reset */
9208c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_ci	/* Now, the graphics controller, select map 2 */
9238c2ecf20Sopenharmony_ci	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x02);
9248c2ecf20Sopenharmony_ci	/* disable odd-even addressing */
9258c2ecf20Sopenharmony_ci	vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x00);
9268c2ecf20Sopenharmony_ci	/* map start at A000:0000 */
9278c2ecf20Sopenharmony_ci	vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x00);
9288c2ecf20Sopenharmony_ci	raw_spin_unlock_irq(&vga_lock);
9298c2ecf20Sopenharmony_ci
9308c2ecf20Sopenharmony_ci	if (arg) {
9318c2ecf20Sopenharmony_ci		if (set)
9328c2ecf20Sopenharmony_ci			for (i = 0; i < cmapsz; i++) {
9338c2ecf20Sopenharmony_ci				vga_writeb(arg[i], charmap + i);
9348c2ecf20Sopenharmony_ci				cond_resched();
9358c2ecf20Sopenharmony_ci			}
9368c2ecf20Sopenharmony_ci		else
9378c2ecf20Sopenharmony_ci			for (i = 0; i < cmapsz; i++) {
9388c2ecf20Sopenharmony_ci				arg[i] = vga_readb(charmap + i);
9398c2ecf20Sopenharmony_ci				cond_resched();
9408c2ecf20Sopenharmony_ci			}
9418c2ecf20Sopenharmony_ci
9428c2ecf20Sopenharmony_ci		/*
9438c2ecf20Sopenharmony_ci		 * In 512-character mode, the character map is not contiguous if
9448c2ecf20Sopenharmony_ci		 * we want to remain EGA compatible -- which we do
9458c2ecf20Sopenharmony_ci		 */
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ci		if (ch512) {
9488c2ecf20Sopenharmony_ci			charmap += 2 * cmapsz;
9498c2ecf20Sopenharmony_ci			arg += cmapsz;
9508c2ecf20Sopenharmony_ci			if (set)
9518c2ecf20Sopenharmony_ci				for (i = 0; i < cmapsz; i++) {
9528c2ecf20Sopenharmony_ci					vga_writeb(arg[i], charmap + i);
9538c2ecf20Sopenharmony_ci					cond_resched();
9548c2ecf20Sopenharmony_ci				}
9558c2ecf20Sopenharmony_ci			else
9568c2ecf20Sopenharmony_ci				for (i = 0; i < cmapsz; i++) {
9578c2ecf20Sopenharmony_ci					arg[i] = vga_readb(charmap + i);
9588c2ecf20Sopenharmony_ci					cond_resched();
9598c2ecf20Sopenharmony_ci				}
9608c2ecf20Sopenharmony_ci		}
9618c2ecf20Sopenharmony_ci	}
9628c2ecf20Sopenharmony_ci
9638c2ecf20Sopenharmony_ci	raw_spin_lock_irq(&vga_lock);
9648c2ecf20Sopenharmony_ci	/* First, the sequencer, Synchronous reset */
9658c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);
9668c2ecf20Sopenharmony_ci	/* CPU writes to maps 0 and 1 */
9678c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x03);
9688c2ecf20Sopenharmony_ci	/* odd-even addressing */
9698c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x03);
9708c2ecf20Sopenharmony_ci	/* Character Map Select */
9718c2ecf20Sopenharmony_ci	if (set)
9728c2ecf20Sopenharmony_ci		vga_wseq(state->vgabase, VGA_SEQ_CHARACTER_MAP, font_select);
9738c2ecf20Sopenharmony_ci	/* clear synchronous reset */
9748c2ecf20Sopenharmony_ci	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
9758c2ecf20Sopenharmony_ci
9768c2ecf20Sopenharmony_ci	/* Now, the graphics controller, select map 0 for CPU */
9778c2ecf20Sopenharmony_ci	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x00);
9788c2ecf20Sopenharmony_ci	/* enable even-odd addressing */
9798c2ecf20Sopenharmony_ci	vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x10);
9808c2ecf20Sopenharmony_ci	/* map starts at b800:0 or b000:0 */
9818c2ecf20Sopenharmony_ci	vga_wgfx(state->vgabase, VGA_GFX_MISC, beg);
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci	/* if 512 char mode is already enabled don't re-enable it. */
9848c2ecf20Sopenharmony_ci	if ((set) && (ch512 != vga_512_chars)) {
9858c2ecf20Sopenharmony_ci		vga_512_chars = ch512;
9868c2ecf20Sopenharmony_ci		/* 256-char: enable intensity bit
9878c2ecf20Sopenharmony_ci		   512-char: disable intensity bit */
9888c2ecf20Sopenharmony_ci		inb_p(video_port_status);	/* clear address flip-flop */
9898c2ecf20Sopenharmony_ci		/* color plane enable register */
9908c2ecf20Sopenharmony_ci		vga_wattr(state->vgabase, VGA_ATC_PLANE_ENABLE, ch512 ? 0x07 : 0x0f);
9918c2ecf20Sopenharmony_ci		/* Wilton (1987) mentions the following; I don't know what
9928c2ecf20Sopenharmony_ci		   it means, but it works, and it appears necessary */
9938c2ecf20Sopenharmony_ci		inb_p(video_port_status);
9948c2ecf20Sopenharmony_ci		vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
9958c2ecf20Sopenharmony_ci		clear_attribs = true;
9968c2ecf20Sopenharmony_ci	}
9978c2ecf20Sopenharmony_ci	raw_spin_unlock_irq(&vga_lock);
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci	if (clear_attribs) {
10008c2ecf20Sopenharmony_ci		for (i = 0; i < MAX_NR_CONSOLES; i++) {
10018c2ecf20Sopenharmony_ci			struct vc_data *c = vc_cons[i].d;
10028c2ecf20Sopenharmony_ci			if (c && c->vc_sw == &vga_con) {
10038c2ecf20Sopenharmony_ci				/* force hi font mask to 0, so we always clear
10048c2ecf20Sopenharmony_ci				   the bit on either transition */
10058c2ecf20Sopenharmony_ci				c->vc_hi_font_mask = 0x00;
10068c2ecf20Sopenharmony_ci				clear_buffer_attributes(c);
10078c2ecf20Sopenharmony_ci				c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
10088c2ecf20Sopenharmony_ci			}
10098c2ecf20Sopenharmony_ci		}
10108c2ecf20Sopenharmony_ci	}
10118c2ecf20Sopenharmony_ci	return 0;
10128c2ecf20Sopenharmony_ci}
10138c2ecf20Sopenharmony_ci
10148c2ecf20Sopenharmony_ci/*
10158c2ecf20Sopenharmony_ci * Adjust the screen to fit a font of a certain height
10168c2ecf20Sopenharmony_ci */
10178c2ecf20Sopenharmony_cistatic int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
10188c2ecf20Sopenharmony_ci{
10198c2ecf20Sopenharmony_ci	unsigned char ovr, vde, fsr;
10208c2ecf20Sopenharmony_ci	int rows, maxscan, i;
10218c2ecf20Sopenharmony_ci
10228c2ecf20Sopenharmony_ci	rows = vc->vc_scan_lines / fontheight;	/* Number of video rows we end up with */
10238c2ecf20Sopenharmony_ci	maxscan = rows * fontheight - 1;	/* Scan lines to actually display-1 */
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_ci	/* Reprogram the CRTC for the new font size
10268c2ecf20Sopenharmony_ci	   Note: the attempt to read the overflow register will fail
10278c2ecf20Sopenharmony_ci	   on an EGA, but using 0xff for the previous value appears to
10288c2ecf20Sopenharmony_ci	   be OK for EGA text modes in the range 257-512 scan lines, so I
10298c2ecf20Sopenharmony_ci	   guess we don't need to worry about it.
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci	   The same applies for the spill bits in the font size and cursor
10328c2ecf20Sopenharmony_ci	   registers; they are write-only on EGA, but it appears that they
10338c2ecf20Sopenharmony_ci	   are all don't care bits on EGA, so I guess it doesn't matter. */
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci	raw_spin_lock_irq(&vga_lock);
10368c2ecf20Sopenharmony_ci	outb_p(0x07, vga_video_port_reg);	/* CRTC overflow register */
10378c2ecf20Sopenharmony_ci	ovr = inb_p(vga_video_port_val);
10388c2ecf20Sopenharmony_ci	outb_p(0x09, vga_video_port_reg);	/* Font size register */
10398c2ecf20Sopenharmony_ci	fsr = inb_p(vga_video_port_val);
10408c2ecf20Sopenharmony_ci	raw_spin_unlock_irq(&vga_lock);
10418c2ecf20Sopenharmony_ci
10428c2ecf20Sopenharmony_ci	vde = maxscan & 0xff;	/* Vertical display end reg */
10438c2ecf20Sopenharmony_ci	ovr = (ovr & 0xbd) +	/* Overflow register */
10448c2ecf20Sopenharmony_ci	    ((maxscan & 0x100) >> 7) + ((maxscan & 0x200) >> 3);
10458c2ecf20Sopenharmony_ci	fsr = (fsr & 0xe0) + (fontheight - 1);	/*  Font size register */
10468c2ecf20Sopenharmony_ci
10478c2ecf20Sopenharmony_ci	raw_spin_lock_irq(&vga_lock);
10488c2ecf20Sopenharmony_ci	outb_p(0x07, vga_video_port_reg);	/* CRTC overflow register */
10498c2ecf20Sopenharmony_ci	outb_p(ovr, vga_video_port_val);
10508c2ecf20Sopenharmony_ci	outb_p(0x09, vga_video_port_reg);	/* Font size */
10518c2ecf20Sopenharmony_ci	outb_p(fsr, vga_video_port_val);
10528c2ecf20Sopenharmony_ci	outb_p(0x12, vga_video_port_reg);	/* Vertical display limit */
10538c2ecf20Sopenharmony_ci	outb_p(vde, vga_video_port_val);
10548c2ecf20Sopenharmony_ci	raw_spin_unlock_irq(&vga_lock);
10558c2ecf20Sopenharmony_ci	vga_video_font_height = fontheight;
10568c2ecf20Sopenharmony_ci
10578c2ecf20Sopenharmony_ci	for (i = 0; i < MAX_NR_CONSOLES; i++) {
10588c2ecf20Sopenharmony_ci		struct vc_data *c = vc_cons[i].d;
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci		if (c && c->vc_sw == &vga_con) {
10618c2ecf20Sopenharmony_ci			if (con_is_visible(c)) {
10628c2ecf20Sopenharmony_ci			        /* void size to cause regs to be rewritten */
10638c2ecf20Sopenharmony_ci				cursor_size_lastfrom = 0;
10648c2ecf20Sopenharmony_ci				cursor_size_lastto = 0;
10658c2ecf20Sopenharmony_ci				c->vc_sw->con_cursor(c, CM_DRAW);
10668c2ecf20Sopenharmony_ci			}
10678c2ecf20Sopenharmony_ci			c->vc_font.height = c->vc_cell_height = fontheight;
10688c2ecf20Sopenharmony_ci			vc_resize(c, 0, rows);	/* Adjust console size */
10698c2ecf20Sopenharmony_ci		}
10708c2ecf20Sopenharmony_ci	}
10718c2ecf20Sopenharmony_ci	return 0;
10728c2ecf20Sopenharmony_ci}
10738c2ecf20Sopenharmony_ci
10748c2ecf20Sopenharmony_cistatic int vgacon_font_set(struct vc_data *c, struct console_font *font,
10758c2ecf20Sopenharmony_ci			   unsigned int flags)
10768c2ecf20Sopenharmony_ci{
10778c2ecf20Sopenharmony_ci	unsigned charcount = font->charcount;
10788c2ecf20Sopenharmony_ci	int rc;
10798c2ecf20Sopenharmony_ci
10808c2ecf20Sopenharmony_ci	if (vga_video_type < VIDEO_TYPE_EGAM)
10818c2ecf20Sopenharmony_ci		return -EINVAL;
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	if (font->width != VGA_FONTWIDTH ||
10848c2ecf20Sopenharmony_ci	    (charcount != 256 && charcount != 512))
10858c2ecf20Sopenharmony_ci		return -EINVAL;
10868c2ecf20Sopenharmony_ci
10878c2ecf20Sopenharmony_ci	rc = vgacon_do_font_op(&vgastate, font->data, 1, charcount == 512);
10888c2ecf20Sopenharmony_ci	if (rc)
10898c2ecf20Sopenharmony_ci		return rc;
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_ci	if (!(flags & KD_FONT_FLAG_DONT_RECALC))
10928c2ecf20Sopenharmony_ci		rc = vgacon_adjust_height(c, font->height);
10938c2ecf20Sopenharmony_ci	return rc;
10948c2ecf20Sopenharmony_ci}
10958c2ecf20Sopenharmony_ci
10968c2ecf20Sopenharmony_cistatic int vgacon_font_get(struct vc_data *c, struct console_font *font)
10978c2ecf20Sopenharmony_ci{
10988c2ecf20Sopenharmony_ci	if (vga_video_type < VIDEO_TYPE_EGAM)
10998c2ecf20Sopenharmony_ci		return -EINVAL;
11008c2ecf20Sopenharmony_ci
11018c2ecf20Sopenharmony_ci	font->width = VGA_FONTWIDTH;
11028c2ecf20Sopenharmony_ci	font->height = c->vc_font.height;
11038c2ecf20Sopenharmony_ci	font->charcount = vga_512_chars ? 512 : 256;
11048c2ecf20Sopenharmony_ci	if (!font->data)
11058c2ecf20Sopenharmony_ci		return 0;
11068c2ecf20Sopenharmony_ci	return vgacon_do_font_op(&vgastate, font->data, 0, vga_512_chars);
11078c2ecf20Sopenharmony_ci}
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_cistatic int vgacon_resize(struct vc_data *c, unsigned int width,
11108c2ecf20Sopenharmony_ci			 unsigned int height, unsigned int user)
11118c2ecf20Sopenharmony_ci{
11128c2ecf20Sopenharmony_ci	if ((width << 1) * height > vga_vram_size)
11138c2ecf20Sopenharmony_ci		return -EINVAL;
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	if (user) {
11168c2ecf20Sopenharmony_ci		/*
11178c2ecf20Sopenharmony_ci		 * Ho ho!  Someone (svgatextmode, eh?) may have reprogrammed
11188c2ecf20Sopenharmony_ci		 * the video mode!  Set the new defaults then and go away.
11198c2ecf20Sopenharmony_ci		 */
11208c2ecf20Sopenharmony_ci		screen_info.orig_video_cols = width;
11218c2ecf20Sopenharmony_ci		screen_info.orig_video_lines = height;
11228c2ecf20Sopenharmony_ci		vga_default_font_height = c->vc_cell_height;
11238c2ecf20Sopenharmony_ci		return 0;
11248c2ecf20Sopenharmony_ci	}
11258c2ecf20Sopenharmony_ci	if (width % 2 || width > screen_info.orig_video_cols ||
11268c2ecf20Sopenharmony_ci	    height > (screen_info.orig_video_lines * vga_default_font_height)/
11278c2ecf20Sopenharmony_ci	    c->vc_cell_height)
11288c2ecf20Sopenharmony_ci		return -EINVAL;
11298c2ecf20Sopenharmony_ci
11308c2ecf20Sopenharmony_ci	if (con_is_visible(c) && !vga_is_gfx) /* who knows */
11318c2ecf20Sopenharmony_ci		vgacon_doresize(c, width, height);
11328c2ecf20Sopenharmony_ci	return 0;
11338c2ecf20Sopenharmony_ci}
11348c2ecf20Sopenharmony_ci
11358c2ecf20Sopenharmony_cistatic int vgacon_set_origin(struct vc_data *c)
11368c2ecf20Sopenharmony_ci{
11378c2ecf20Sopenharmony_ci	if (vga_is_gfx ||	/* We don't play origin tricks in graphic modes */
11388c2ecf20Sopenharmony_ci	    (console_blanked && !vga_palette_blanked))	/* Nor we write to blanked screens */
11398c2ecf20Sopenharmony_ci		return 0;
11408c2ecf20Sopenharmony_ci	c->vc_origin = c->vc_visible_origin = vga_vram_base;
11418c2ecf20Sopenharmony_ci	vga_set_mem_top(c);
11428c2ecf20Sopenharmony_ci	vga_rolled_over = 0;
11438c2ecf20Sopenharmony_ci	return 1;
11448c2ecf20Sopenharmony_ci}
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_cistatic void vgacon_save_screen(struct vc_data *c)
11478c2ecf20Sopenharmony_ci{
11488c2ecf20Sopenharmony_ci	static int vga_bootup_console = 0;
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_ci	if (!vga_bootup_console) {
11518c2ecf20Sopenharmony_ci		/* This is a gross hack, but here is the only place we can
11528c2ecf20Sopenharmony_ci		 * set bootup console parameters without messing up generic
11538c2ecf20Sopenharmony_ci		 * console initialization routines.
11548c2ecf20Sopenharmony_ci		 */
11558c2ecf20Sopenharmony_ci		vga_bootup_console = 1;
11568c2ecf20Sopenharmony_ci		c->state.x = screen_info.orig_x;
11578c2ecf20Sopenharmony_ci		c->state.y = screen_info.orig_y;
11588c2ecf20Sopenharmony_ci	}
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_ci	/* We can't copy in more than the size of the video buffer,
11618c2ecf20Sopenharmony_ci	 * or we'll be copying in VGA BIOS */
11628c2ecf20Sopenharmony_ci
11638c2ecf20Sopenharmony_ci	if (!vga_is_gfx)
11648c2ecf20Sopenharmony_ci		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin,
11658c2ecf20Sopenharmony_ci			    c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size);
11668c2ecf20Sopenharmony_ci}
11678c2ecf20Sopenharmony_ci
11688c2ecf20Sopenharmony_cistatic bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
11698c2ecf20Sopenharmony_ci		enum con_scroll dir, unsigned int lines)
11708c2ecf20Sopenharmony_ci{
11718c2ecf20Sopenharmony_ci	unsigned long oldo;
11728c2ecf20Sopenharmony_ci	unsigned int delta;
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_ci	if (t || b != c->vc_rows || vga_is_gfx || c->vc_mode != KD_TEXT)
11758c2ecf20Sopenharmony_ci		return false;
11768c2ecf20Sopenharmony_ci
11778c2ecf20Sopenharmony_ci	if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
11788c2ecf20Sopenharmony_ci		return false;
11798c2ecf20Sopenharmony_ci
11808c2ecf20Sopenharmony_ci	vgacon_restore_screen(c);
11818c2ecf20Sopenharmony_ci	oldo = c->vc_origin;
11828c2ecf20Sopenharmony_ci	delta = lines * c->vc_size_row;
11838c2ecf20Sopenharmony_ci	if (dir == SM_UP) {
11848c2ecf20Sopenharmony_ci		if (c->vc_scr_end + delta >= vga_vram_end) {
11858c2ecf20Sopenharmony_ci			scr_memcpyw((u16 *) vga_vram_base,
11868c2ecf20Sopenharmony_ci				    (u16 *) (oldo + delta),
11878c2ecf20Sopenharmony_ci				    c->vc_screenbuf_size - delta);
11888c2ecf20Sopenharmony_ci			c->vc_origin = vga_vram_base;
11898c2ecf20Sopenharmony_ci			vga_rolled_over = oldo - vga_vram_base;
11908c2ecf20Sopenharmony_ci		} else
11918c2ecf20Sopenharmony_ci			c->vc_origin += delta;
11928c2ecf20Sopenharmony_ci		scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size -
11938c2ecf20Sopenharmony_ci				     delta), c->vc_video_erase_char,
11948c2ecf20Sopenharmony_ci			    delta);
11958c2ecf20Sopenharmony_ci	} else {
11968c2ecf20Sopenharmony_ci		if (oldo - delta < vga_vram_base) {
11978c2ecf20Sopenharmony_ci			scr_memmovew((u16 *) (vga_vram_end -
11988c2ecf20Sopenharmony_ci					      c->vc_screenbuf_size +
11998c2ecf20Sopenharmony_ci					      delta), (u16 *) oldo,
12008c2ecf20Sopenharmony_ci				     c->vc_screenbuf_size - delta);
12018c2ecf20Sopenharmony_ci			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
12028c2ecf20Sopenharmony_ci			vga_rolled_over = 0;
12038c2ecf20Sopenharmony_ci		} else
12048c2ecf20Sopenharmony_ci			c->vc_origin -= delta;
12058c2ecf20Sopenharmony_ci		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
12068c2ecf20Sopenharmony_ci		scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char,
12078c2ecf20Sopenharmony_ci			    delta);
12088c2ecf20Sopenharmony_ci	}
12098c2ecf20Sopenharmony_ci	c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
12108c2ecf20Sopenharmony_ci	c->vc_visible_origin = c->vc_origin;
12118c2ecf20Sopenharmony_ci	vga_set_mem_top(c);
12128c2ecf20Sopenharmony_ci	c->vc_pos = (c->vc_pos - oldo) + c->vc_origin;
12138c2ecf20Sopenharmony_ci	return true;
12148c2ecf20Sopenharmony_ci}
12158c2ecf20Sopenharmony_ci
12168c2ecf20Sopenharmony_ci/*
12178c2ecf20Sopenharmony_ci *  The console `switch' structure for the VGA based console
12188c2ecf20Sopenharmony_ci */
12198c2ecf20Sopenharmony_ci
12208c2ecf20Sopenharmony_cistatic void vgacon_clear(struct vc_data *vc, int sy, int sx, int height,
12218c2ecf20Sopenharmony_ci			 int width) { }
12228c2ecf20Sopenharmony_cistatic void vgacon_putc(struct vc_data *vc, int c, int ypos, int xpos) { }
12238c2ecf20Sopenharmony_cistatic void vgacon_putcs(struct vc_data *vc, const unsigned short *s,
12248c2ecf20Sopenharmony_ci			 int count, int ypos, int xpos) { }
12258c2ecf20Sopenharmony_ci
12268c2ecf20Sopenharmony_ciconst struct consw vga_con = {
12278c2ecf20Sopenharmony_ci	.owner = THIS_MODULE,
12288c2ecf20Sopenharmony_ci	.con_startup = vgacon_startup,
12298c2ecf20Sopenharmony_ci	.con_init = vgacon_init,
12308c2ecf20Sopenharmony_ci	.con_deinit = vgacon_deinit,
12318c2ecf20Sopenharmony_ci	.con_clear = vgacon_clear,
12328c2ecf20Sopenharmony_ci	.con_putc = vgacon_putc,
12338c2ecf20Sopenharmony_ci	.con_putcs = vgacon_putcs,
12348c2ecf20Sopenharmony_ci	.con_cursor = vgacon_cursor,
12358c2ecf20Sopenharmony_ci	.con_scroll = vgacon_scroll,
12368c2ecf20Sopenharmony_ci	.con_switch = vgacon_switch,
12378c2ecf20Sopenharmony_ci	.con_blank = vgacon_blank,
12388c2ecf20Sopenharmony_ci	.con_font_set = vgacon_font_set,
12398c2ecf20Sopenharmony_ci	.con_font_get = vgacon_font_get,
12408c2ecf20Sopenharmony_ci	.con_resize = vgacon_resize,
12418c2ecf20Sopenharmony_ci	.con_set_palette = vgacon_set_palette,
12428c2ecf20Sopenharmony_ci	.con_scrolldelta = vgacon_scrolldelta,
12438c2ecf20Sopenharmony_ci	.con_set_origin = vgacon_set_origin,
12448c2ecf20Sopenharmony_ci	.con_save_screen = vgacon_save_screen,
12458c2ecf20Sopenharmony_ci	.con_build_attr = vgacon_build_attr,
12468c2ecf20Sopenharmony_ci	.con_invert_region = vgacon_invert_region,
12478c2ecf20Sopenharmony_ci};
12488c2ecf20Sopenharmony_ciEXPORT_SYMBOL(vga_con);
12498c2ecf20Sopenharmony_ci
12508c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
1251