aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/console/vgacon.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d27fa91e5886..0705cd741411 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -497,6 +497,57 @@ static void vgacon_cursor(struct vc_data *c, int mode)
497 } 497 }
498} 498}
499 499
500static int vgacon_doresize(struct vc_data *c,
501 unsigned int width, unsigned int height)
502{
503 unsigned long flags;
504 unsigned int scanlines = height * c->vc_font.height;
505 u8 scanlines_lo, r7, vsync_end, mode;
506
507 spin_lock_irqsave(&vga_lock, flags);
508
509 outb_p(VGA_CRTC_MODE, vga_video_port_reg);
510 mode = inb_p(vga_video_port_val);
511
512 if (mode & 0x04)
513 scanlines >>= 1;
514
515 scanlines -= 1;
516 scanlines_lo = scanlines & 0xff;
517
518 outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
519 r7 = inb_p(vga_video_port_val) & ~0x42;
520
521 if (scanlines & 0x100)
522 r7 |= 0x02;
523 if (scanlines & 0x200)
524 r7 |= 0x40;
525
526 /* deprotect registers */
527 outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
528 vsync_end = inb_p(vga_video_port_val);
529 outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
530 outb_p(vsync_end & ~0x80, vga_video_port_val);
531
532 outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);
533 outb_p(width - 1, vga_video_port_val);
534 outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);
535 outb_p(width >> 1, vga_video_port_val);
536
537 outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
538 outb_p(scanlines_lo, vga_video_port_val);
539 outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
540 outb_p(r7,vga_video_port_val);
541
542 /* reprotect registers */
543 outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
544 outb_p(vsync_end, vga_video_port_val);
545
546 spin_unlock_irqrestore(&vga_lock, flags);
547
548 return 0;
549}
550
500static int vgacon_switch(struct vc_data *c) 551static int vgacon_switch(struct vc_data *c)
501{ 552{
502 /* 553 /*
@@ -510,9 +561,13 @@ static int vgacon_switch(struct vc_data *c)
510 /* We can only copy out the size of the video buffer here, 561 /* We can only copy out the size of the video buffer here,
511 * otherwise we get into VGA BIOS */ 562 * otherwise we get into VGA BIOS */
512 563
513 if (!vga_is_gfx) 564 if (!vga_is_gfx) {
514 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, 565 scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
515 c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); 566 c->vc_screenbuf_size > vga_vram_size ?
567 vga_vram_size : c->vc_screenbuf_size);
568 vgacon_doresize(c, c->vc_cols, c->vc_rows);
569 }
570
516 return 0; /* Redrawing not needed */ 571 return 0; /* Redrawing not needed */
517} 572}
518 573
@@ -962,6 +1017,17 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
962 1017
963#endif 1018#endif
964 1019
1020static int vgacon_resize(struct vc_data *c, unsigned int width,
1021 unsigned int height)
1022{
1023 if (width % 2 || width > ORIG_VIDEO_COLS || height > ORIG_VIDEO_LINES)
1024 return -EINVAL;
1025
1026 if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
1027 vgacon_doresize(c, width, height);
1028 return 0;
1029}
1030
965static int vgacon_scrolldelta(struct vc_data *c, int lines) 1031static int vgacon_scrolldelta(struct vc_data *c, int lines)
966{ 1032{
967 if (!lines) /* Turn scrollback off */ 1033 if (!lines) /* Turn scrollback off */
@@ -1103,6 +1169,7 @@ const struct consw vga_con = {
1103 .con_blank = vgacon_blank, 1169 .con_blank = vgacon_blank,
1104 .con_font_set = vgacon_font_set, 1170 .con_font_set = vgacon_font_set,
1105 .con_font_get = vgacon_font_get, 1171 .con_font_get = vgacon_font_get,
1172 .con_resize = vgacon_resize,
1106 .con_set_palette = vgacon_set_palette, 1173 .con_set_palette = vgacon_set_palette,
1107 .con_scrolldelta = vgacon_scrolldelta, 1174 .con_scrolldelta = vgacon_scrolldelta,
1108 .con_set_origin = vgacon_set_origin, 1175 .con_set_origin = vgacon_set_origin,