Home | History | Annotate | Line # | Download | only in boot
vreset.c revision 1.3.8.1
      1  1.3.8.1    elad /* $NetBSD: vreset.c,v 1.3.8.1 2006/04/19 02:33:39 elad Exp $ */
      2  1.3.8.1    elad /*-
      3  1.3.8.1    elad  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      4      1.1  nonaka  * All rights reserved.
      5      1.1  nonaka  *
      6  1.3.8.1    elad  * This code is derived from software contributed to The NetBSD Foundation
      7  1.3.8.1    elad  * by Tim Rightnour
      8      1.1  nonaka  *
      9      1.1  nonaka  * Redistribution and use in source and binary forms, with or without
     10      1.1  nonaka  * modification, are permitted provided that the following conditions
     11      1.1  nonaka  * are met:
     12      1.1  nonaka  * 1. Redistributions of source code must retain the above copyright
     13      1.1  nonaka  *    notice, this list of conditions and the following disclaimer.
     14      1.1  nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     15      1.1  nonaka  *    notice, this list of conditions and the following disclaimer in the
     16      1.1  nonaka  *    documentation and/or other materials provided with the distribution.
     17      1.1  nonaka  * 3. All advertising materials mentioning features or use of this software
     18      1.1  nonaka  *    must display the following acknowledgement:
     19  1.3.8.1    elad  *        This product includes software developed by the NetBSD
     20  1.3.8.1    elad  *        Foundation, Inc. and its contributors.
     21  1.3.8.1    elad  * 4. Neither the name of The NetBSD Foundation nor the names of its
     22  1.3.8.1    elad  *    contributors may be used to endorse or promote products derived
     23  1.3.8.1    elad  *    from this software without specific prior written permission.
     24      1.1  nonaka  *
     25  1.3.8.1    elad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     26  1.3.8.1    elad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  1.3.8.1    elad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  1.3.8.1    elad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     29  1.3.8.1    elad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  1.3.8.1    elad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  1.3.8.1    elad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  1.3.8.1    elad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  1.3.8.1    elad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  1.3.8.1    elad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  1.3.8.1    elad  * POSSIBILITY OF SUCH DAMAGE.
     36      1.1  nonaka  */
     37      1.1  nonaka 
     38  1.3.8.1    elad #ifdef VGA_RESET
     39      1.1  nonaka #include <lib/libsa/stand.h>
     40      1.1  nonaka #include "boot.h"
     41      1.1  nonaka #include "iso_font.h"
     42      1.1  nonaka 
     43  1.3.8.1    elad #define VGA_SR_PORT	0x3c4
     44  1.3.8.1    elad #define VGA_CR_PORT	0x3d4
     45  1.3.8.1    elad #define VGA_CR_DATA	0x3d5
     46  1.3.8.1    elad #define VGA_GR_PORT	0x3ce
     47  1.3.8.1    elad #define VGA_GR_DATA	0x3cf
     48  1.3.8.1    elad #define SRREGS	4
     49  1.3.8.1    elad #define CRREGS	24
     50  1.3.8.1    elad #define GRREGS	9
     51  1.3.8.1    elad #define LINES 25
     52  1.3.8.1    elad #define COLS 80
     53  1.3.8.1    elad #define PCI_VENDOR_S3		0x5333
     54  1.3.8.1    elad #define PCI_VENDOR_CIRRUS	0x1013
     55  1.3.8.1    elad #define PCI_VENDOR_DIAMOND	0x100E
     56  1.3.8.1    elad #define PCI_VENDOR_MATROX	0x102B
     57  1.3.8.1    elad #define PCI_VENDOR_PARADISE	0x101C
     58  1.3.8.1    elad 
     59  1.3.8.1    elad static void write_attr(u_int8_t, u_int8_t, u_int8_t);
     60  1.3.8.1    elad static void set_text_regs(void);
     61  1.3.8.1    elad static void set_text_clut(int);
     62  1.3.8.1    elad static void load_font(u_int8_t *);
     63  1.3.8.1    elad static void unlock_S3(void);
     64  1.3.8.1    elad static void clear_video_memory(void);
     65  1.3.8.1    elad 
     66  1.3.8.1    elad extern char *videomem;
     67  1.3.8.1    elad 
     68  1.3.8.1    elad typedef struct vga_reg {
     69  1.3.8.1    elad 	u_int8_t idx;
     70  1.3.8.1    elad 	u_int8_t val;
     71  1.3.8.1    elad } vga_reg_t;
     72  1.3.8.1    elad 
     73  1.3.8.1    elad static vga_reg_t SR_regs[SRREGS] = {
     74  1.3.8.1    elad 	/* idx  val */
     75  1.3.8.1    elad 	{ 0x1,	0x0 },	/* 01: clocking mode */
     76  1.3.8.1    elad 	{ 0x2,	0x3 },	/* 02: map mask */
     77  1.3.8.1    elad 	{ 0x3,	0x0 },	/* 03: character map select */
     78  1.3.8.1    elad 	{ 0x4,	0x2 }	/* 04: memory mode */
     79      1.1  nonaka };
     80      1.1  nonaka 
     81  1.3.8.1    elad static vga_reg_t CR_regs[CRREGS] = {
     82  1.3.8.1    elad 	/* idx  val */
     83  1.3.8.1    elad 	{ 0x0,	0x61 }, /* 00: horizontal total */
     84  1.3.8.1    elad 	{ 0x1,	0x4f }, /* 01: horizontal display-enable end */
     85  1.3.8.1    elad 	{ 0x2,	0x50 }, /* 02: start horizontal blanking */
     86  1.3.8.1    elad 	{ 0x3,	0x82 }, /* 03: display skew control / end horizontal blanking */	{ 0x4,	0x55 }, /* 04: start horizontal retrace pulse */
     87  1.3.8.1    elad 	{ 0x5,	0x81 }, /* 05: horizontal retrace delay / end horiz. retrace */
     88  1.3.8.1    elad 	{ 0x6,	0xf0 }, /* 06: vertical total */
     89  1.3.8.1    elad 	{ 0x7,	0x1f }, /* 07: overflow register */
     90  1.3.8.1    elad 	{ 0x8,	0x00 }, /* 08: preset row scan */
     91  1.3.8.1    elad 	{ 0x9,	0x4f }, /* 09: overflow / maximum scan line */
     92  1.3.8.1    elad 	{ 0xa,	0x0d }, /* 0A: cursor off / cursor start */
     93  1.3.8.1    elad 	{ 0xb,	0x0e }, /* 0B: cursor skew / cursor end */
     94  1.3.8.1    elad 	{ 0xc,	0x00 }, /* 0C: start regenerative buffer address high */
     95  1.3.8.1    elad 	{ 0xd,	0x00 }, /* 0D: start regenerative buffer address low */
     96  1.3.8.1    elad 	{ 0xe,	0x00 }, /* 0E: cursor location high */
     97  1.3.8.1    elad 	{ 0xf,	0x00 }, /* 0F: cursor location low */
     98  1.3.8.1    elad 	{ 0x10, 0x9a }, /* 10: vertical retrace start */
     99  1.3.8.1    elad 	{ 0x11, 0x8c }, /* 11: vertical interrupt / vertical retrace end */
    100  1.3.8.1    elad 	{ 0x12, 0x8f }, /* 12: vertical display enable end */
    101  1.3.8.1    elad 	{ 0x13, 0x28 }, /* 13: logical line width */
    102  1.3.8.1    elad 	{ 0x14, 0x1f }, /* 14: underline location */
    103  1.3.8.1    elad 	{ 0x15, 0x97 }, /* 15: start vertical blanking */
    104  1.3.8.1    elad 	{ 0x16, 0x00 }, /* 16: end vertical blanking */
    105  1.3.8.1    elad 	{ 0x17, 0xa3 }, /* 17: CRT mode control */
    106      1.1  nonaka };
    107      1.1  nonaka 
    108  1.3.8.1    elad static vga_reg_t GR_regs[GRREGS] = {
    109  1.3.8.1    elad 	/* idx  val */
    110  1.3.8.1    elad 	{ 0x0,	0x00 }, /* 00: set/reset map */
    111  1.3.8.1    elad 	{ 0x1,	0x00 }, /* 01: enable set/reset */
    112  1.3.8.1    elad 	{ 0x2,	0x00 }, /* 02: color compare */
    113  1.3.8.1    elad 	{ 0x3,	0x00 }, /* 03: data rotate */
    114  1.3.8.1    elad 	{ 0x4,	0x00 }, /* 04: read map select */
    115  1.3.8.1    elad 	{ 0x5,	0x10 }, /* 05: graphics mode */
    116  1.3.8.1    elad 	{ 0x6,	0x0e }, /* 06: miscellaneous */
    117  1.3.8.1    elad 	{ 0x7,	0x00 }, /* 07: color don't care */
    118  1.3.8.1    elad 	{ 0x8,	0xff }, /* 08: bit mask */
    119      1.1  nonaka };
    120      1.1  nonaka 
    121  1.3.8.1    elad /* video DAC palette registers */
    122  1.3.8.1    elad /* XXX only set up 16 colors used by internal palette in ATC regsters */
    123  1.3.8.1    elad static const u_int8_t vga_dacpal[] = {
    124  1.3.8.1    elad 	/* R     G     B */
    125  1.3.8.1    elad 	0x00, 0x00, 0x00,	/* BLACK        */
    126  1.3.8.1    elad 	0x00, 0x00, 0x2a,	/* BLUE         */
    127  1.3.8.1    elad 	0x00, 0x2a, 0x00,	/* GREEN        */
    128  1.3.8.1    elad 	0x00, 0x2a, 0x2a,	/* CYAN         */
    129  1.3.8.1    elad 	0x2a, 0x00, 0x00,	/* RED          */
    130  1.3.8.1    elad 	0x2a, 0x00, 0x2a,	/* MAGENTA      */
    131  1.3.8.1    elad 	0x2a, 0x15, 0x00,	/* BROWN        */
    132  1.3.8.1    elad 	0x2a, 0x2a, 0x2a,	/* LIGHTGREY    */
    133  1.3.8.1    elad 	0x15, 0x15, 0x15,	/* DARKGREY     */
    134  1.3.8.1    elad 	0x15, 0x15, 0x3f,	/* LIGHTBLUE    */
    135  1.3.8.1    elad 	0x15, 0x3f, 0x15,	/* LIGHTGREEN   */
    136  1.3.8.1    elad 	0x15, 0x3f, 0x3f,	/* LIGHTCYAN    */
    137  1.3.8.1    elad 	0x3f, 0x15, 0x15,	/* LIGHTRED     */
    138  1.3.8.1    elad 	0x3f, 0x15, 0x3f,	/* LIGHTMAGENTA */
    139  1.3.8.1    elad 	0x3f, 0x3f, 0x15,	/* YELLOW       */
    140  1.3.8.1    elad 	0x3f, 0x3f, 0x3f	/* WHITE        */
    141      1.1  nonaka };
    142      1.1  nonaka 
    143  1.3.8.1    elad static const u_int8_t vga_atc[] = {
    144  1.3.8.1    elad 	0x00,	/* 00: internal palette  0 */
    145  1.3.8.1    elad 	0x01,	/* 01: internal palette  1 */
    146  1.3.8.1    elad 	0x02,	/* 02: internal palette  2 */
    147  1.3.8.1    elad 	0x03,	/* 03: internal palette  3 */
    148  1.3.8.1    elad 	0x04,	/* 04: internal palette  4 */
    149  1.3.8.1    elad 	0x05,	/* 05: internal palette  5 */
    150  1.3.8.1    elad 	0x14,	/* 06: internal palette  6 */
    151  1.3.8.1    elad 	0x07,	/* 07: internal palette  7 */
    152  1.3.8.1    elad 	0x38,	/* 08: internal palette  8 */
    153  1.3.8.1    elad 	0x39,	/* 09: internal palette  9 */
    154  1.3.8.1    elad 	0x3a,	/* 0A: internal palette 10 */
    155  1.3.8.1    elad 	0x3b,	/* 0B: internal palette 11 */
    156  1.3.8.1    elad 	0x3c,	/* 0C: internal palette 12 */
    157  1.3.8.1    elad 	0x3d,	/* 0D: internal palette 13 */
    158  1.3.8.1    elad 	0x3e,	/* 0E: internal palette 14 */
    159  1.3.8.1    elad 	0x3f,	/* 0F: internal palette 15 */
    160  1.3.8.1    elad 	0x0c,	/* 10: attribute mode control */
    161  1.3.8.1    elad 	0x00,	/* 11: overscan color */
    162  1.3.8.1    elad 	0x0f,	/* 12: color plane enable */
    163  1.3.8.1    elad 	0x08,	/* 13: horizontal PEL panning */
    164  1.3.8.1    elad 	0x00	/* 14: color select */
    165      1.1  nonaka };
    166      1.1  nonaka 
    167      1.1  nonaka void
    168  1.3.8.1    elad vga_reset(u_char *ISA_mem)
    169      1.1  nonaka {
    170      1.1  nonaka 	int slot;
    171      1.1  nonaka 
    172  1.3.8.1    elad 	/* check if we are in text mode, if so, punt */
    173  1.3.8.1    elad 	outb(VGA_GR_PORT, 0x06);
    174  1.3.8.1    elad 	if ((inb(VGA_GR_DATA) & 0x01) == 0)
    175  1.3.8.1    elad 		return;
    176  1.3.8.1    elad 
    177  1.3.8.1    elad 	/* guess not, we lose. */
    178  1.3.8.1    elad 	slot = -1;
    179  1.3.8.1    elad 	while ((slot = scan_PCI(slot)) > -1) {
    180  1.3.8.1    elad 		unlockVideo(slot);
    181  1.3.8.1    elad 		switch (PCI_vendor(slot)) {
    182  1.3.8.1    elad 		case PCI_VENDOR_CIRRUS:
    183  1.3.8.1    elad 			outw(VGA_SR_PORT, 0x0612); /* unlock ext regs */
    184  1.3.8.1    elad 			outw(VGA_SR_PORT, 0x0700); /* reset ext sequence mode */
    185  1.3.8.1    elad 			break;
    186  1.3.8.1    elad 		case PCI_VENDOR_PARADISE:
    187  1.3.8.1    elad 			outw(VGA_GR_PORT, 0x0f05); /* unlock registers */
    188  1.3.8.1    elad 			outw(VGA_SR_PORT, 0x0648);
    189  1.3.8.1    elad 			outw(VGA_CR_PORT, 0x2985);
    190  1.3.8.1    elad 			outw(VGA_CR_PORT, 0x34a6);
    191  1.3.8.1    elad 			outb(VGA_GR_PORT, 0x0b); /* disable linear addressing */
    192  1.3.8.1    elad 			outb(VGA_GR_DATA, inb(VGA_GR_DATA) & ~0x30);
    193  1.3.8.1    elad 			outw(VGA_SR_PORT, 0x1400);
    194  1.3.8.1    elad 			outb(VGA_GR_PORT, 0x0e); /* disable 256 color mode */
    195  1.3.8.1    elad 			outb(VGA_GR_DATA, inb(VGA_GR_DATA) & ~0x01);
    196  1.3.8.1    elad 			outb(0xd00, 0xff); /* enable auto-centering */
    197  1.3.8.1    elad 			if (!(inb(0xd01) & 0x03)) {
    198  1.3.8.1    elad 				outb(VGA_CR_PORT, 0x33);
    199  1.3.8.1    elad 				outb(VGA_CR_DATA, inb(VGA_CR_DATA) & ~0x90);
    200  1.3.8.1    elad 				outb(VGA_CR_PORT, 0x32);
    201  1.3.8.1    elad 				outb(VGA_CR_DATA, inb(VGA_CR_DATA) | 0x04);
    202  1.3.8.1    elad 				outw(VGA_CR_PORT, 0x0250);
    203  1.3.8.1    elad 				outw(VGA_CR_PORT, 0x07ba);
    204  1.3.8.1    elad 				outw(VGA_CR_PORT, 0x0900);
    205  1.3.8.1    elad 				outw(VGA_CR_PORT, 0x15e7);
    206  1.3.8.1    elad 				outw(VGA_CR_PORT, 0x2a95);
    207  1.3.8.1    elad 			}
    208  1.3.8.1    elad 			outw(VGA_CR_PORT, 0x34a0);
    209  1.3.8.1    elad 			break;
    210  1.3.8.1    elad 		case PCI_VENDOR_S3:
    211  1.3.8.1    elad 			unlock_S3();
    212  1.3.8.1    elad 			break;
    213  1.3.8.1    elad 		default:
    214  1.3.8.1    elad 			break;
    215  1.3.8.1    elad 		}
    216  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x0120); /* disable video */
    217  1.3.8.1    elad 		set_text_regs();
    218  1.3.8.1    elad 		set_text_clut(0);
    219  1.3.8.1    elad 		load_font(ISA_mem);
    220  1.3.8.1    elad 		set_text_regs();
    221  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x0100); /* re-enable video */
    222  1.3.8.1    elad 		clear_video_memory();
    223  1.3.8.1    elad 
    224  1.3.8.1    elad 		if (PCI_vendor(slot) == PCI_VENDOR_S3)
    225  1.3.8.1    elad 			outb(0x3c2, 0x63);	/* ??? */
    226  1.3.8.1    elad 		delay(1000);
    227  1.3.8.1    elad 	}
    228  1.3.8.1    elad 	return;
    229      1.1  nonaka }
    230      1.1  nonaka 
    231  1.3.8.1    elad /* write something to a VGA attribute register */
    232  1.3.8.1    elad static void
    233  1.3.8.1    elad write_attr(u_int8_t index, u_int8_t data, u_int8_t videoOn)
    234      1.1  nonaka {
    235  1.3.8.1    elad 	u_int8_t v;
    236  1.3.8.1    elad 
    237  1.3.8.1    elad 	v = inb(0x3da);		/* reset attr addr toggle */
    238      1.1  nonaka 	if (videoOn)
    239      1.1  nonaka 		outb(0x3c0, (index & 0x1F) | 0x20);
    240      1.1  nonaka 	else
    241      1.1  nonaka 		outb(0x3c0, (index & 0x1F));
    242      1.1  nonaka 	outb(0x3c0, data);
    243      1.1  nonaka }
    244      1.1  nonaka 
    245  1.3.8.1    elad static void
    246  1.3.8.1    elad set_text_regs(void)
    247      1.1  nonaka {
    248      1.1  nonaka 	int i;
    249      1.1  nonaka 
    250  1.3.8.1    elad 	for (i = 0; i < SRREGS; i++) {
    251  1.3.8.1    elad 		outb(VGA_SR_PORT, SR_regs[i].idx);
    252  1.3.8.1    elad 		outb(VGA_SR_PORT + 1, SR_regs[i].val);
    253  1.3.8.1    elad 	}
    254  1.3.8.1    elad 	for (i = 0; i < CRREGS; i++) {
    255  1.3.8.1    elad 		outb(VGA_CR_PORT, CR_regs[i].idx);
    256  1.3.8.1    elad 		outb(VGA_CR_PORT + 1, CR_regs[i].val);
    257  1.3.8.1    elad 	}
    258  1.3.8.1    elad 	for (i = 0; i < GRREGS; i++) {
    259  1.3.8.1    elad 		outb(VGA_GR_PORT, GR_regs[i].idx);
    260  1.3.8.1    elad 		outb(VGA_GR_PORT + 1, GR_regs[i].val);
    261      1.1  nonaka 	}
    262      1.1  nonaka 
    263      1.1  nonaka 	outb(0x3c2, 0x67);  /* MISC */
    264      1.1  nonaka 	outb(0x3c6, 0xff);  /* MASK */
    265      1.1  nonaka 
    266  1.3.8.1    elad 	for (i = 0; i < 0x14; i++)
    267  1.3.8.1    elad 		write_attr(i, vga_atc[i], 0);
    268  1.3.8.1    elad 	write_attr(0x14, 0x00, 1); /* color select; video on  */
    269      1.1  nonaka }
    270      1.1  nonaka 
    271  1.3.8.1    elad static void
    272  1.3.8.1    elad set_text_clut(int shift)
    273      1.1  nonaka {
    274      1.1  nonaka 	int i;
    275      1.1  nonaka 
    276  1.3.8.1    elad 	outb(0x3C6, 0xFF);
    277  1.3.8.1    elad 	inb(0x3C7);
    278  1.3.8.1    elad 	outb(0x3C8, 0);
    279  1.3.8.1    elad 	inb(0x3C7);
    280  1.3.8.1    elad 
    281  1.3.8.1    elad 	for (i = 0; i < (16 * 3); ) {
    282  1.3.8.1    elad 		outb(0x3c9, vga_dacpal[i++] << shift);
    283  1.3.8.1    elad 		outb(0x3c9, vga_dacpal[i++] << shift);
    284  1.3.8.1    elad 		outb(0x3c9, vga_dacpal[i++] << shift);
    285      1.1  nonaka 	}
    286      1.1  nonaka }
    287      1.1  nonaka 
    288  1.3.8.1    elad static void
    289  1.3.8.1    elad load_font(u_int8_t *ISA_mem)
    290      1.1  nonaka {
    291      1.1  nonaka 	int i, j;
    292  1.3.8.1    elad 	u_int8_t *font_page = (u_int8_t *)&ISA_mem[0xA0000];
    293  1.3.8.1    elad 
    294      1.1  nonaka 	outb(0x3C2, 0x67);
    295  1.3.8.1    elad 	inb(0x3DA);  /* Reset Attr toggle */
    296  1.3.8.1    elad 
    297  1.3.8.1    elad 	outb(0x3C0, 0x30);
    298  1.3.8.1    elad 	outb(0x3C0, 0x01);	/* graphics mode */
    299  1.3.8.1    elad 	outw(0x3C4, 0x0001);	/* reset sequencer */
    300  1.3.8.1    elad 	outw(0x3C4, 0x0204);	/* write to plane 2 */
    301  1.3.8.1    elad 	outw(0x3C4, 0x0406);	/* enable plane graphics */
    302  1.3.8.1    elad 	outw(0x3C4, 0x0003);	/* reset sequencer */
    303  1.3.8.1    elad 	outw(0x3CE, 0x0402);	/* read plane 2 */
    304  1.3.8.1    elad 	outw(0x3CE, 0x0500);	/* write mode 0, read mode 0 */
    305  1.3.8.1    elad 	outw(0x3CE, 0x0605);	/* set graphics mode */
    306      1.1  nonaka 
    307      1.1  nonaka 	for (i = 0;  i < sizeof(font);  i += 16) {
    308      1.1  nonaka 		for (j = 0;  j < 16;  j++) {
    309  1.3.8.1    elad 			__asm__ volatile("eieio");
    310      1.1  nonaka 			font_page[(2*i)+j] = font[i+j];
    311      1.1  nonaka 		}
    312      1.1  nonaka 	}
    313      1.1  nonaka }
    314      1.1  nonaka 
    315  1.3.8.1    elad static void
    316  1.3.8.1    elad unlock_S3(void)
    317      1.1  nonaka {
    318  1.3.8.1    elad 	int s3_devid;
    319      1.1  nonaka 
    320  1.3.8.1    elad 	outw(VGA_CR_PORT, 0x3848);
    321  1.3.8.1    elad 	outw(VGA_CR_PORT, 0x39a5);
    322  1.3.8.1    elad 	outb(VGA_CR_PORT, 0x2d);
    323  1.3.8.1    elad 	s3_devid = inb(VGA_CR_DATA) << 8;
    324  1.3.8.1    elad 	outb(VGA_CR_PORT, 0x2e);
    325  1.3.8.1    elad 	s3_devid |= inb(VGA_CR_DATA);
    326  1.3.8.1    elad 
    327  1.3.8.1    elad 	if (s3_devid != 0x8812) {
    328  1.3.8.1    elad 		/* from the S3 manual */
    329  1.3.8.1    elad 		outb(0x46E8, 0x10);  /* Put into setup mode */
    330  1.3.8.1    elad 		outb(0x3C3, 0x10);
    331  1.3.8.1    elad 		outb(0x102, 0x01);   /* Enable registers */
    332  1.3.8.1    elad 		outb(0x46E8, 0x08);  /* Enable video */
    333  1.3.8.1    elad 		outb(0x3C3, 0x08);
    334  1.3.8.1    elad 		outb(0x4AE8, 0x00);
    335  1.3.8.1    elad                 outb(VGA_CR_PORT, 0x38);  /* Unlock all registers */
    336  1.3.8.1    elad 		outb(VGA_CR_DATA, 0x48);
    337  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x39);
    338  1.3.8.1    elad 		outb(VGA_CR_DATA, 0xA5);
    339  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x40);
    340  1.3.8.1    elad 		outb(VGA_CR_DATA, inb(0x3D5)|0x01);
    341  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x33);
    342  1.3.8.1    elad 		outb(VGA_CR_DATA, inb(0x3D5)&~0x52);
    343  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x35);
    344  1.3.8.1    elad 		outb(VGA_CR_DATA, inb(0x3D5)&~0x30);
    345  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x3A);
    346  1.3.8.1    elad 		outb(VGA_CR_DATA, 0x00);
    347  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x53);
    348  1.3.8.1    elad 		outb(VGA_CR_DATA, 0x00);
    349  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x31);
    350  1.3.8.1    elad 		outb(VGA_CR_DATA, inb(0x3D5)&~0x4B);
    351  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x58);
    352  1.3.8.1    elad 
    353  1.3.8.1    elad 		outb(VGA_CR_DATA, 0);
    354  1.3.8.1    elad 
    355  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x54);
    356  1.3.8.1    elad 		outb(VGA_CR_DATA, 0x38);
    357  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x60);
    358  1.3.8.1    elad 		outb(VGA_CR_DATA, 0x07);
    359  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x61);
    360  1.3.8.1    elad 		outb(VGA_CR_DATA, 0x80);
    361  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x62);
    362  1.3.8.1    elad 		outb(VGA_CR_DATA, 0xA1);
    363  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x69);  /* High order bits for cursor address */
    364  1.3.8.1    elad 		outb(VGA_CR_DATA, 0);
    365  1.3.8.1    elad 
    366  1.3.8.1    elad 		outb(VGA_CR_PORT, 0x32);
    367  1.3.8.1    elad 		outb(VGA_CR_DATA, inb(0x3D5)&~0x10);
    368  1.3.8.1    elad 	} else {
    369  1.3.8.1    elad 		/* IBM Portable 860 */
    370  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x0806);
    371  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x1041);
    372  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x1128);
    373  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x4000);
    374  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x3100);
    375  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x3a05);
    376  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x6688);
    377  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x5800); /* disable linear addressing */
    378  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x4500); /* disable H/W cursor */
    379  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x5410); /* enable auto-centering */
    380  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x561f);
    381  1.3.8.1    elad 		outw(VGA_SR_PORT, 0x1b80); /* lock DCLK selection */
    382  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x3900); /* lock S3 registers */
    383  1.3.8.1    elad 		outw(VGA_CR_PORT, 0x3800);
    384  1.3.8.1    elad 	}
    385      1.1  nonaka }
    386      1.1  nonaka 
    387  1.3.8.1    elad static void
    388  1.3.8.1    elad clear_video_memory(void)
    389      1.1  nonaka {
    390  1.3.8.1    elad 	int i, j;
    391      1.1  nonaka 
    392  1.3.8.1    elad 	for (i = 0;  i < LINES; i++) {
    393  1.3.8.1    elad 		for (j = 0; j < COLS; j++) {
    394  1.3.8.1    elad 			videomem[((i * COLS)+j) * 2] = 0x20; /* space */
    395  1.3.8.1    elad 			videomem[((i * COLS)+j) * 2 + 1] = 0x07; /* fg/bg */
    396      1.1  nonaka 		}
    397      1.1  nonaka 	}
    398      1.1  nonaka }
    399      1.1  nonaka 
    400  1.3.8.1    elad #endif /* VGA_RESET */
    401