1/* $NetBSD: vreset.c,v 1.12 2010/10/14 06:12:54 kiyohara Exp $ */ 2 3/* 4 * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org) 5 * All rights reserved. 6 * 7 * Initialize the VGA control registers to 80x25 text mode. 8 * 9 * Adapted from a program by: 10 * Steve Sellgren 11 * San Francisco Indigo Company 12 * sfindigo!sellgren@uunet.uu.net 13 * Adapted for Moto boxes by: 14 * Pat Kane & Mark Scott, 1996 15 * Fixed for IBM/PowerStack II Pat Kane 1997 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 3. All advertising materials mentioning features or use of this software 26 * must display the following acknowledgement: 27 * This product includes software developed by Gary Thomas. 28 * 4. The name of the author may not be used to endorse or promote products 29 * derived from this software without specific prior written permission. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43#ifdef CONS_VGA 44#include <lib/libsa/stand.h> 45#include "boot.h" 46#include "iso_font.h" 47 48/* 49 * VGA Register 50 */ 51struct VgaRegs 52{ 53 u_short io_port; 54 u_char io_index; 55 u_char io_value; 56}; 57 58/* 59 * Default console text mode registers used to reset 60 * graphics adapter. 61 */ 62#define NREGS 54 63#define ENDMK 0xFFFF /* End marker */ 64 65#define S3Vendor 0x5333 66#define CirrusVendor 0x1013 67#define DiamondVendor 0x100E 68#define MatroxVendor 0x102B 69 70struct VgaRegs GenVgaTextRegs[NREGS+1] = { 71/* port index value */ 72 /* SR Regs */ 73 { 0x3c4, 0x1, 0x0 }, 74 { 0x3c4, 0x2, 0x3 }, 75 { 0x3c4, 0x3, 0x0 }, 76 { 0x3c4, 0x4, 0x2 }, 77 /* CR Regs */ 78 { 0x3d4, 0x0, 0x5f }, 79 { 0x3d4, 0x1, 0x4f }, 80 { 0x3d4, 0x2, 0x50 }, 81 { 0x3d4, 0x3, 0x82 }, 82 { 0x3d4, 0x4, 0x55 }, 83 { 0x3d4, 0x5, 0x81 }, 84 { 0x3d4, 0x6, 0xbf }, 85 { 0x3d4, 0x7, 0x1f }, 86 { 0x3d4, 0x8, 0x00 }, 87 { 0x3d4, 0x9, 0x4f }, 88 { 0x3d4, 0xa, 0x0d }, 89 { 0x3d4, 0xb, 0x0e }, 90 { 0x3d4, 0xc, 0x00 }, 91 { 0x3d4, 0xd, 0x00 }, 92 { 0x3d4, 0xe, 0x00 }, 93 { 0x3d4, 0xf, 0x00 }, 94 { 0x3d4, 0x10, 0x9c }, 95 { 0x3d4, 0x11, 0x8e }, 96 { 0x3d4, 0x12, 0x8f }, 97 { 0x3d4, 0x13, 0x28 }, 98 { 0x3d4, 0x14, 0x1f }, 99 { 0x3d4, 0x15, 0x96 }, 100 { 0x3d4, 0x16, 0xb9 }, 101 { 0x3d4, 0x17, 0xa3 }, 102 /* GR Regs */ 103 { 0x3ce, 0x0, 0x0 }, 104 { 0x3ce, 0x1, 0x0 }, 105 { 0x3ce, 0x2, 0x0 }, 106 { 0x3ce, 0x3, 0x0 }, 107 { 0x3ce, 0x4, 0x0 }, 108 { 0x3ce, 0x5, 0x10 }, 109 { 0x3ce, 0x6, 0xe }, 110 { 0x3ce, 0x7, 0x0 }, 111 { 0x3ce, 0x8, 0xff }, 112 { ENDMK }, 113}; 114 115struct VgaRegs S3TextRegs[NREGS+1] = { 116/* port index value */ 117 /* SR Regs */ 118 { 0x3c4, 0x1, 0x0 }, 119 { 0x3c4, 0x2, 0x3 }, 120 { 0x3c4, 0x3, 0x0 }, 121 { 0x3c4, 0x4, 0x2 }, 122 /* CR Regs */ 123 { 0x3d4, 0x0, 0x5f }, 124 { 0x3d4, 0x1, 0x4f }, 125 { 0x3d4, 0x2, 0x50 }, 126 { 0x3d4, 0x3, 0x82 }, 127 { 0x3d4, 0x4, 0x55 }, 128 { 0x3d4, 0x5, 0x81 }, 129 { 0x3d4, 0x6, 0xbf }, 130 { 0x3d4, 0x7, 0x1f }, 131 { 0x3d4, 0x8, 0x00 }, 132 { 0x3d4, 0x9, 0x4f }, 133 { 0x3d4, 0xa, 0x0d }, 134 { 0x3d4, 0xb, 0x0e }, 135 { 0x3d4, 0xc, 0x00 }, 136 { 0x3d4, 0xd, 0x00 }, 137 { 0x3d4, 0xe, 0x00 }, 138 { 0x3d4, 0xf, 0x00 }, 139 { 0x3d4, 0x10, 0x9c }, 140 { 0x3d4, 0x11, 0x8e }, 141 { 0x3d4, 0x12, 0x8f }, 142 { 0x3d4, 0x13, 0x28 }, 143 { 0x3d4, 0x14, 0x1f }, 144 { 0x3d4, 0x15, 0x96 }, 145 { 0x3d4, 0x16, 0xb9 }, 146 { 0x3d4, 0x17, 0xa3 }, 147 /* GR Regs */ 148 { 0x3ce, 0x0, 0x0 }, 149 { 0x3ce, 0x1, 0x0 }, 150 { 0x3ce, 0x2, 0x0 }, 151 { 0x3ce, 0x3, 0x0 }, 152 { 0x3ce, 0x4, 0x0 }, 153 { 0x3ce, 0x5, 0x10 }, 154 { 0x3ce, 0x6, 0xe }, 155 { 0x3ce, 0x7, 0x0 }, 156 { 0x3ce, 0x8, 0xff }, 157 { ENDMK } 158}; 159 160struct RGBColors { 161 u_char r, g, b; 162}; 163 164/* 165 * Default console text mode color table. 166 * These values were obtained by booting Linux with 167 * text mode firmware & then dumping the registers. 168 */ 169struct RGBColors TextCLUT[256] = { 170/* red green blue */ 171 { 0x0, 0x0, 0x0 }, 172 { 0x0, 0x0, 0x2a }, 173 { 0x0, 0x2a, 0x0 }, 174 { 0x0, 0x2a, 0x2a }, 175 { 0x2a, 0x0, 0x0 }, 176 { 0x2a, 0x0, 0x2a }, 177 { 0x2a, 0x2a, 0x0 }, 178 { 0x2a, 0x2a, 0x2a }, 179 { 0x0, 0x0, 0x15 }, 180 { 0x0, 0x0, 0x3f }, 181 { 0x0, 0x2a, 0x15 }, 182 { 0x0, 0x2a, 0x3f }, 183 { 0x2a, 0x0, 0x15 }, 184 { 0x2a, 0x0, 0x3f }, 185 { 0x2a, 0x2a, 0x15 }, 186 { 0x2a, 0x2a, 0x3f }, 187 { 0x0, 0x15, 0x0 }, 188 { 0x0, 0x15, 0x2a }, 189 { 0x0, 0x3f, 0x0 }, 190 { 0x0, 0x3f, 0x2a }, 191 { 0x2a, 0x15, 0x0 }, 192 { 0x2a, 0x15, 0x2a }, 193 { 0x2a, 0x3f, 0x0 }, 194 { 0x2a, 0x3f, 0x2a }, 195 { 0x0, 0x15, 0x15 }, 196 { 0x0, 0x15, 0x3f }, 197 { 0x0, 0x3f, 0x15 }, 198 { 0x0, 0x3f, 0x3f }, 199 { 0x2a, 0x15, 0x15 }, 200 { 0x2a, 0x15, 0x3f }, 201 { 0x2a, 0x3f, 0x15 }, 202 { 0x2a, 0x3f, 0x3f }, 203 { 0x15, 0x0, 0x0 }, 204 { 0x15, 0x0, 0x2a }, 205 { 0x15, 0x2a, 0x0 }, 206 { 0x15, 0x2a, 0x2a }, 207 { 0x3f, 0x0, 0x0 }, 208 { 0x3f, 0x0, 0x2a }, 209 { 0x3f, 0x2a, 0x0 }, 210 { 0x3f, 0x2a, 0x2a }, 211 { 0x15, 0x0, 0x15 }, 212 { 0x15, 0x0, 0x3f }, 213 { 0x15, 0x2a, 0x15 }, 214 { 0x15, 0x2a, 0x3f }, 215 { 0x3f, 0x0, 0x15 }, 216 { 0x3f, 0x0, 0x3f }, 217 { 0x3f, 0x2a, 0x15 }, 218 { 0x3f, 0x2a, 0x3f }, 219 { 0x15, 0x15, 0x0 }, 220 { 0x15, 0x15, 0x2a }, 221 { 0x15, 0x3f, 0x0 }, 222 { 0x15, 0x3f, 0x2a }, 223 { 0x3f, 0x15, 0x0 }, 224 { 0x3f, 0x15, 0x2a }, 225 { 0x3f, 0x3f, 0x0 }, 226 { 0x3f, 0x3f, 0x2a }, 227 { 0x15, 0x15, 0x15 }, 228 { 0x15, 0x15, 0x3f }, 229 { 0x15, 0x3f, 0x15 }, 230 { 0x15, 0x3f, 0x3f }, 231 { 0x3f, 0x15, 0x15 }, 232 { 0x3f, 0x15, 0x3f }, 233 { 0x3f, 0x3f, 0x15 }, 234 { 0x3f, 0x3f, 0x3f }, 235 { 0x39, 0xc, 0x5 }, 236 { 0x15, 0x2c, 0xf }, 237 { 0x26, 0x10, 0x3d }, 238 { 0x29, 0x29, 0x38 }, 239 { 0x4, 0x1a, 0xe }, 240 { 0x2, 0x1e, 0x3a }, 241 { 0x3c, 0x25, 0x33 }, 242 { 0x3c, 0xc, 0x2c }, 243 { 0x3f, 0x3, 0x2b }, 244 { 0x1c, 0x9, 0x13 }, 245 { 0x25, 0x2a, 0x35 }, 246 { 0x1e, 0xa, 0x38 }, 247 { 0x24, 0x8, 0x3 }, 248 { 0x3, 0xe, 0x36 }, 249 { 0xc, 0x6, 0x2a }, 250 { 0x26, 0x3, 0x32 }, 251 { 0x5, 0x2f, 0x33 }, 252 { 0x3c, 0x35, 0x2f }, 253 { 0x2d, 0x26, 0x3e }, 254 { 0xd, 0xa, 0x10 }, 255 { 0x25, 0x3c, 0x11 }, 256 { 0xd, 0x4, 0x2e }, 257 { 0x5, 0x19, 0x3e }, 258 { 0xc, 0x13, 0x34 }, 259 { 0x2b, 0x6, 0x24 }, 260 { 0x4, 0x3, 0xd }, 261 { 0x2f, 0x3c, 0xc }, 262 { 0x2a, 0x37, 0x1f }, 263 { 0xf, 0x12, 0x38 }, 264 { 0x38, 0xe, 0x2a }, 265 { 0x12, 0x2f, 0x19 }, 266 { 0x29, 0x2e, 0x31 }, 267 { 0x25, 0x13, 0x3e }, 268 { 0x33, 0x3e, 0x33 }, 269 { 0x1d, 0x2c, 0x25 }, 270 { 0x15, 0x15, 0x5 }, 271 { 0x32, 0x25, 0x39 }, 272 { 0x1a, 0x7, 0x1f }, 273 { 0x13, 0xe, 0x1d }, 274 { 0x36, 0x17, 0x34 }, 275 { 0xf, 0x15, 0x23 }, 276 { 0x2, 0x35, 0xd }, 277 { 0x15, 0x3f, 0xc }, 278 { 0x14, 0x2f, 0xf }, 279 { 0x19, 0x21, 0x3e }, 280 { 0x27, 0x11, 0x2f }, 281 { 0x38, 0x3f, 0x3c }, 282 { 0x36, 0x2d, 0x15 }, 283 { 0x16, 0x17, 0x2 }, 284 { 0x1, 0xa, 0x3d }, 285 { 0x1b, 0x11, 0x3f }, 286 { 0x21, 0x3c, 0xd }, 287 { 0x1a, 0x39, 0x3d }, 288 { 0x8, 0xe, 0xe }, 289 { 0x22, 0x21, 0x23 }, 290 { 0x1e, 0x30, 0x5 }, 291 { 0x1f, 0x22, 0x3d }, 292 { 0x1e, 0x2f, 0xa }, 293 { 0x0, 0x1c, 0xe }, 294 { 0x0, 0x1c, 0x15 }, 295 { 0x0, 0x1c, 0x1c }, 296 { 0x0, 0x15, 0x1c }, 297 { 0x0, 0xe, 0x1c }, 298 { 0x0, 0x7, 0x1c }, 299 { 0xe, 0xe, 0x1c }, 300 { 0x11, 0xe, 0x1c }, 301 { 0x15, 0xe, 0x1c }, 302 { 0x18, 0xe, 0x1c }, 303 { 0x1c, 0xe, 0x1c }, 304 { 0x1c, 0xe, 0x18 }, 305 { 0x1c, 0xe, 0x15 }, 306 { 0x1c, 0xe, 0x11 }, 307 { 0x1c, 0xe, 0xe }, 308 { 0x1c, 0x11, 0xe }, 309 { 0x1c, 0x15, 0xe }, 310 { 0x1c, 0x18, 0xe }, 311 { 0x1c, 0x1c, 0xe }, 312 { 0x18, 0x1c, 0xe }, 313 { 0x15, 0x1c, 0xe }, 314 { 0x11, 0x1c, 0xe }, 315 { 0xe, 0x1c, 0xe }, 316 { 0xe, 0x1c, 0x11 }, 317 { 0xe, 0x1c, 0x15 }, 318 { 0xe, 0x1c, 0x18 }, 319 { 0xe, 0x1c, 0x1c }, 320 { 0xe, 0x18, 0x1c }, 321 { 0xe, 0x15, 0x1c }, 322 { 0xe, 0x11, 0x1c }, 323 { 0x14, 0x14, 0x1c }, 324 { 0x16, 0x14, 0x1c }, 325 { 0x18, 0x14, 0x1c }, 326 { 0x1a, 0x14, 0x1c }, 327 { 0x1c, 0x14, 0x1c }, 328 { 0x1c, 0x14, 0x1a }, 329 { 0x1c, 0x14, 0x18 }, 330 { 0x1c, 0x14, 0x16 }, 331 { 0x1c, 0x14, 0x14 }, 332 { 0x1c, 0x16, 0x14 }, 333 { 0x1c, 0x18, 0x14 }, 334 { 0x1c, 0x1a, 0x14 }, 335 { 0x1c, 0x1c, 0x14 }, 336 { 0x1a, 0x1c, 0x14 }, 337 { 0x18, 0x1c, 0x14 }, 338 { 0x16, 0x1c, 0x14 }, 339 { 0x14, 0x1c, 0x14 }, 340 { 0x14, 0x1c, 0x16 }, 341 { 0x14, 0x1c, 0x18 }, 342 { 0x14, 0x1c, 0x1a }, 343 { 0x14, 0x1c, 0x1c }, 344 { 0x14, 0x1a, 0x1c }, 345 { 0x14, 0x18, 0x1c }, 346 { 0x14, 0x16, 0x1c }, 347 { 0x0, 0x0, 0x10 }, 348 { 0x4, 0x0, 0x10 }, 349 { 0x8, 0x0, 0x10 }, 350 { 0xc, 0x0, 0x10 }, 351 { 0x10, 0x0, 0x10 }, 352 { 0x10, 0x0, 0xc }, 353 { 0x10, 0x0, 0x8 }, 354 { 0x10, 0x0, 0x4 }, 355 { 0x10, 0x0, 0x0 }, 356 { 0x10, 0x4, 0x0 }, 357 { 0x10, 0x8, 0x0 }, 358 { 0x10, 0xc, 0x0 }, 359 { 0x10, 0x10, 0x0 }, 360 { 0xc, 0x10, 0x0 }, 361 { 0x8, 0x10, 0x0 }, 362 { 0x4, 0x10, 0x0 }, 363 { 0x0, 0x10, 0x0 }, 364 { 0x0, 0x10, 0x4 }, 365 { 0x0, 0x10, 0x8 }, 366 { 0x0, 0x10, 0xc }, 367 { 0x0, 0x10, 0x10 }, 368 { 0x0, 0xc, 0x10 }, 369 { 0x0, 0x8, 0x10 }, 370 { 0x0, 0x4, 0x10 }, 371 { 0x8, 0x8, 0x10 }, 372 { 0xa, 0x8, 0x10 }, 373 { 0xc, 0x8, 0x10 }, 374 { 0xe, 0x8, 0x10 }, 375 { 0x10, 0x8, 0x10 }, 376 { 0x10, 0x8, 0xe }, 377 { 0x10, 0x8, 0xc }, 378 { 0x10, 0x8, 0xa }, 379 { 0x10, 0x8, 0x8 }, 380 { 0x10, 0xa, 0x8 }, 381 { 0x10, 0xc, 0x8 }, 382 { 0x10, 0xe, 0x8 }, 383 { 0x10, 0x10, 0x8 }, 384 { 0xe, 0x10, 0x8 }, 385 { 0xc, 0x10, 0x8 }, 386 { 0xa, 0x10, 0x8 }, 387 { 0x8, 0x10, 0x8 }, 388 { 0x8, 0x10, 0xa }, 389 { 0x8, 0x10, 0xc }, 390 { 0x8, 0x10, 0xe }, 391 { 0x8, 0x10, 0x10 }, 392 { 0x8, 0xe, 0x10 }, 393 { 0x8, 0xc, 0x10 }, 394 { 0x8, 0xa, 0x10 }, 395 { 0xb, 0xb, 0x10 }, 396 { 0xc, 0xb, 0x10 }, 397 { 0xd, 0xb, 0x10 }, 398 { 0xf, 0xb, 0x10 }, 399 { 0x10, 0xb, 0x10 }, 400 { 0x10, 0xb, 0xf }, 401 { 0x10, 0xb, 0xd }, 402 { 0x10, 0xb, 0xc }, 403 { 0x10, 0xb, 0xb }, 404 { 0x10, 0xc, 0xb }, 405 { 0x10, 0xd, 0xb }, 406 { 0x10, 0xf, 0xb }, 407 { 0x10, 0x10, 0xb }, 408 { 0xf, 0x10, 0xb }, 409 { 0xd, 0x10, 0xb }, 410 { 0xc, 0x10, 0xb }, 411 { 0xb, 0x10, 0xb }, 412 { 0xb, 0x10, 0xc }, 413 { 0xb, 0x10, 0xd }, 414 { 0xb, 0x10, 0xf }, 415 { 0xb, 0x10, 0x10 }, 416 { 0xb, 0xf, 0x10 }, 417 { 0xb, 0xd, 0x10 }, 418 { 0xb, 0xc, 0x10 }, 419 { 0x0, 0x0, 0x0 }, 420 { 0x0, 0x0, 0x0 }, 421 { 0x0, 0x0, 0x0 }, 422 { 0x0, 0x0, 0x0 }, 423 { 0x0, 0x0, 0x0 }, 424 { 0x0, 0x0, 0x0 }, 425 { 0x0, 0x0, 0x0 }, 426}; 427 428u_char AC[21] = { 429 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 430 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 431 0x0C, 0x00, 0x0F, 0x08, 0x00 432}; 433 434 435static int delayLoop(int); 436static void writeAttr(u_char, u_char, u_char); 437static void setTextRegs(struct VgaRegs *); 438static void setTextCLUT(void); 439static void loadFont(u_char *); 440static void unlockS3(void); 441static void enablePCIvideo(int); 442 443void 444vga_reset(u_char *ISA_mem) 445{ 446 int slot; 447 struct VgaRegs *VgaTextRegs; 448 449 /* See if VGA already in TEXT mode - exit if so! */ 450 outb(0x3CE, 0x06); 451 if ((inb(0x3CF) & 0x01) == 0) 452 return; 453 454 /* If no VGA responding in text mode, then we have some work to do... */ 455 slot = findPCIVga(); /* find video card in use */ 456 enablePCIvideo(slot); /* enable I/O to card */ 457 458 /* 459 * Note: the PCI scanning code does not yet work correctly 460 * for non-Moto boxes, so the switch below only 461 * defaults to using an S3 card if it does not 462 * find a Cirrus card. 463 * 464 * The only reason we need to scan the bus looking for 465 * a graphics card is so we could do the "enablePCIvideo(slot)" 466 * call above; it is needed because Moto's OpenFirmware 467 * disables I/O to the graphics adapter before it gives 468 * us control. PEK'97 469 */ 470 471 switch (PCIVendor(slot)) { 472 default: /* Assume S3 */ 473#if 0 474 case S3Vendor: 475#endif 476 unlockS3(); 477 VgaTextRegs = S3TextRegs; 478 outw(0x3C4, 0x0120); /* disable video */ 479 setTextRegs(VgaTextRegs); /* initial register setup */ 480 setTextCLUT(); /* load color lookup table */ 481 loadFont(ISA_mem); /* load font */ 482 setTextRegs(VgaTextRegs); /* reload registers */ 483 outw(0x3C4, 0x0100); /* re-enable video */ 484 outb(0x3c2, 0x63); /* MISC */ 485 outb(0x3c2, 0x67); /* MISC */ 486 break; 487 488 case CirrusVendor: 489 VgaTextRegs = GenVgaTextRegs; 490 outw(0x3C4, 0x0612); /* unlock ext regs */ 491 outw(0x3C4, 0x0700); /* reset ext sequence mode */ 492 outw(0x3C4, 0x0120); /* disable video */ 493 setTextRegs(VgaTextRegs); /* initial register setup */ 494 setTextCLUT(); /* load color lookup table */ 495 loadFont(ISA_mem); /* load font */ 496 setTextRegs(VgaTextRegs); /* reload registers */ 497 outw(0x3C4, 0x0100); /* re-enable video */ 498 outb(0x3c2, 0x63); /* MISC */ 499 break; 500 501 case DiamondVendor: 502 case MatroxVendor: 503 /* 504 * The following code is almost enuf to get the Matrox 505 * working (on a Moto box) but the video is not stable. 506 * We probably need to tweak the TVP3026 Video PLL regs. PEK'97 507 */ 508 VgaTextRegs = GenVgaTextRegs; 509 outw(0x3C4, 0x0120); /* disable video */ 510 setTextRegs(VgaTextRegs); /* initial register setup */ 511 setTextCLUT(); /* load color lookup table */ 512 loadFont(ISA_mem); /* load font */ 513 setTextRegs(VgaTextRegs); /* reload registers */ 514 outw(0x3C4, 0x0100); /* re-enable video */ 515 outb(0x3c2, 0x63); /* MISC */ 516 delayLoop(1); 517 break; 518 }; 519 520#ifdef DEBUG 521 printPCIslots(); 522 delayLoop(5); 523#endif 524 delayLoop(2); /* give time for the video monitor to come up */ 525} 526 527static int 528delayLoop(int k) 529{ 530 volatile int a, b; 531 volatile int i, j; 532 a = 0; 533 do { 534 for (i = 0; i < 500; i++) { 535 b = i; 536 for (j = 0; j < 200; j++) { 537 a = b+j; 538 } 539 } 540 } while (k--); 541 return a; 542} 543 544/* 545 * Write to VGA Attribute registers. 546 */ 547static void 548writeAttr(u_char index, u_char data, u_char videoOn) 549{ 550 u_char v; 551 v = inb(0x3da); /* reset attr. address toggle */ 552 if (videoOn) 553 outb(0x3c0, (index & 0x1F) | 0x20); 554 else 555 outb(0x3c0, (index & 0x1F)); 556 outb(0x3c0, data); 557} 558 559static void 560setTextRegs(struct VgaRegs *svp) 561{ 562 int i; 563 564 /* 565 * saved settings 566 */ 567 while (svp->io_port != ENDMK) { 568 outb(svp->io_port, svp->io_index); 569 outb(svp->io_port+1, svp->io_value); 570 svp++; 571 } 572 573 outb(0x3c2, 0x67); /* MISC */ 574 outb(0x3c6, 0xff); /* MASK */ 575 576 for (i = 0; i < 0x10; i++) 577 writeAttr(i, AC[i], 0); /* pallete */ 578 writeAttr(0x10, 0x0c, 0); /* text mode */ 579 writeAttr(0x11, 0x00, 0); /* overscan color (border) */ 580 writeAttr(0x12, 0x0f, 0); /* plane enable */ 581 writeAttr(0x13, 0x08, 0); /* pixel panning */ 582 writeAttr(0x14, 0x00, 1); /* color select; video on */ 583} 584 585static void 586setTextCLUT(void) 587{ 588 int i; 589 590 outb(0x3C6, 0xFF); 591 i = inb(0x3C7); 592 outb(0x3C8, 0); 593 i = inb(0x3C7); 594 595 for (i = 0; i < 256; i++) { 596 outb(0x3C9, TextCLUT[i].r); 597 outb(0x3C9, TextCLUT[i].g); 598 outb(0x3C9, TextCLUT[i].b); 599 } 600} 601 602static void 603loadFont(u_char *ISA_mem) 604{ 605 int i, j; 606 u_char *font_page = (u_char *)&ISA_mem[0xA0000]; 607 608 outb(0x3C2, 0x67); 609 /* 610 * Load font 611 */ 612 i = inb(0x3DA); /* Reset Attr toggle */ 613 614 outb(0x3C0, 0x30); 615 outb(0x3C0, 0x01); /* graphics mode */ 616 617 outw(0x3C4, 0x0001); /* reset sequencer */ 618 outw(0x3C4, 0x0204); /* write to plane 2 */ 619 outw(0x3C4, 0x0406); /* enable plane graphics */ 620 outw(0x3C4, 0x0003); /* reset sequencer */ 621 outw(0x3CE, 0x0402); /* read plane 2 */ 622 outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */ 623 outw(0x3CE, 0x0605); /* set graphics mode */ 624 625 for (i = 0; i < sizeof(font); i += 16) { 626 for (j = 0; j < 16; j++) { 627 __asm volatile("eieio"); 628 font_page[(2*i)+j] = font[i+j]; 629 } 630 } 631} 632 633static void 634unlockS3(void) 635{ 636 /* From the S3 manual */ 637 outb(0x46E8, 0x10); /* Put into setup mode */ 638 outb(0x3C3, 0x10); 639 outb(0x102, 0x01); /* Enable registers */ 640 outb(0x46E8, 0x08); /* Enable video */ 641 outb(0x3C3, 0x08); 642 outb(0x4AE8, 0x00); 643 644 outb(0x42E8, 0x80); /* Reset graphics engine? */ 645 646 outb(0x3D4, 0x38); /* Unlock all registers */ 647 outb(0x3D5, 0x48); 648 outb(0x3D4, 0x39); 649 outb(0x3D5, 0xA5); 650 outb(0x3D4, 0x40); 651 outb(0x3D5, inb(0x3D5)|0x01); 652 outb(0x3D4, 0x33); 653 outb(0x3D5, inb(0x3D5)&~0x52); 654 outb(0x3D4, 0x35); 655 outb(0x3D5, inb(0x3D5)&~0x30); 656 outb(0x3D4, 0x3A); 657 outb(0x3D5, 0x00); 658 outb(0x3D4, 0x53); 659 outb(0x3D5, 0x00); 660 outb(0x3D4, 0x31); 661 outb(0x3D5, inb(0x3D5)&~0x4B); 662 outb(0x3D4, 0x58); 663 664 outb(0x3D5, 0); 665 666 outb(0x3D4, 0x54); 667 outb(0x3D5, 0x38); 668 outb(0x3D4, 0x60); 669 outb(0x3D5, 0x07); 670 outb(0x3D4, 0x61); 671 outb(0x3D5, 0x80); 672 outb(0x3D4, 0x62); 673 outb(0x3D5, 0xA1); 674 outb(0x3D4, 0x69); /* High order bits for cursor address */ 675 outb(0x3D5, 0); 676 677 outb(0x3D4, 0x32); 678 outb(0x3D5, inb(0x3D5)&~0x10); 679} 680 681/* 682 * The following code modifies the PCI Command register 683 * to enable memory and I/O accesses. 684 */ 685static void 686enablePCIvideo(int slot) 687{ 688 689 enablePCI(slot, 1, 1, 0); /* Enable IO and Memory */ 690 691 outb(0x3d4, 0x11); 692 outb(0x3d5, 0x0e); /* unlock CR0-CR7 */ 693} 694#endif /* CONS_VGA */ 695