1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vga_gu1.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ 2/* 3 * $Workfile: vga_gu1.c $ 4 * 5 * This file contains routines to set modes using the VGA registers. 6 * Since this file is for the first generation graphics unit, it interfaces 7 * to SoftVGA registers. It works for both VSA1 and VSA2. 8 * 9 * NSC_LIC_ALTERNATIVE_PREAMBLE 10 * 11 * Revision 1.0 12 * 13 * National Semiconductor Alternative GPL-BSD License 14 * 15 * National Semiconductor Corporation licenses this software 16 * ("Software"): 17 * 18 * Durango 19 * 20 * under one of the two following licenses, depending on how the 21 * Software is received by the Licensee. 22 * 23 * If this Software is received as part of the Linux Framebuffer or 24 * other GPL licensed software, then the GPL license designated 25 * NSC_LIC_GPL applies to this Software; in all other circumstances 26 * then the BSD-style license designated NSC_LIC_BSD shall apply. 27 * 28 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 29 30/* NSC_LIC_BSD 31 * 32 * National Semiconductor Corporation Open Source License for Durango 33 * 34 * (BSD License with Export Notice) 35 * 36 * Copyright (c) 1999-2001 37 * National Semiconductor Corporation. 38 * All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 44 * * Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 47 * * Redistributions in binary form must reproduce the above 48 * copyright notice, this list of conditions and the following 49 * disclaimer in the documentation and/or other materials provided 50 * with the distribution. 51 * 52 * * Neither the name of the National Semiconductor Corporation nor 53 * the names of its contributors may be used to endorse or promote 54 * products derived from this software without specific prior 55 * written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 58 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 59 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 60 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 61 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 62 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 64 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 65 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 66 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 67 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 69 * OF SUCH DAMAGE. 70 * 71 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 72 * YOUR JURISDICTION. It is licensee's responsibility to comply with 73 * any export regulations applicable in licensee's jurisdiction. Under 74 * CURRENT (2001) U.S. export regulations this software 75 * is eligible for export from the U.S. and can be downloaded by or 76 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 77 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 78 * Syria, Sudan, Afghanistan and any other country to which the U.S. 79 * has embargoed goods and services. 80 * 81 * END_NSC_LIC_BSD */ 82 83/* NSC_LIC_GPL 84 * 85 * National Semiconductor Corporation Gnu General Public License for Durango 86 * 87 * (GPL License with Export Notice) 88 * 89 * Copyright (c) 1999-2001 90 * National Semiconductor Corporation. 91 * All rights reserved. 92 * 93 * Redistribution and use in source and binary forms, with or without 94 * modification, are permitted under the terms of the GNU General 95 * Public License as published by the Free Software Foundation; either 96 * version 2 of the License, or (at your option) any later version 97 * 98 * In addition to the terms of the GNU General Public License, neither 99 * the name of the National Semiconductor Corporation nor the names of 100 * its contributors may be used to endorse or promote products derived 101 * from this software without specific prior written permission. 102 * 103 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 104 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 105 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 106 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 107 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 108 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 109 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 110 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 111 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 112 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 113 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 114 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 115 * OF SUCH DAMAGE. See the GNU General Public License for more details. 116 * 117 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 118 * YOUR JURISDICTION. It is licensee's responsibility to comply with 119 * any export regulations applicable in licensee's jurisdiction. Under 120 * CURRENT (2001) U.S. export regulations this software 121 * is eligible for export from the U.S. and can be downloaded by or 122 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 123 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 124 * Syria, Sudan, Afghanistan and any other country to which the U.S. 125 * has embargoed goods and services. 126 * 127 * You should have received a copy of the GNU General Public License 128 * along with this file; if not, write to the Free Software Foundation, 129 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 130 * 131 * END_NSC_LIC_GPL */ 132 133/* SoftVGA Extended CRTC register indices and bit definitions */ 134 135#define CRTC_EXTENDED_REGISTER_LOCK 0x30 136#define CRTC_MODE_SWITCH_CONTROL 0x3F 137 138/* BIT DEFINITIONS */ 139 140#define CRTC_BIT_16BPP 0x01 141#define CRTC_BIT_555 0x02 142 143/* LOCAL ROUTINE DEFINITIONS */ 144 145int gu1_detect_vsa2(void); 146 147/*---------------------------------*/ 148/* MODE TABLES FOR VGA REGISTERS */ 149/*---------------------------------*/ 150 151/* FOR SoftVGA, the CRTC_EXTENDED_ADDRESS_CONTROL (0x43) is always equal to 152 * 0x03 for a packed linear frame buffer organization. The 153 * CRTC_EXTENDED_DAC_CONTROL (0x4B) is always equal to 0x03 to work with 154 * older versions of VSA1 (that needed to specify 8 or 16 bit bus to an 155 * external RAMDAC. This is not used in VSA2. The clock frequency is 156 * specified in register 0x4D if clock control (0x4C) is set to 0x80. 157 * Higher resolutions (1280x1024) use the CRTC_EXTENDED_VERTICAL_TIMING 158 * register (index 0x41). 159 */ 160 161gfx_vga_struct gfx_vga_modes[] = { 162/*------------------------------------------------------------------------------*/ 163 {640, 480, 60, /* 640x480 */ 164 25, /* 25 MHz clock = 60 Hz refresh rate */ 165 0xE3, /* miscOutput register */ 166 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, /* standard CRTC */ 167 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF}, 169 {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 170 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}}, 171/*------------------------------------------------------------------------------*/ 172 {640, 480, 72, /* 640x480 */ 173 29, /* 29 MHz clock = 72 Hz refresh rate */ 174 0xE3, /* miscOutput register */ 175 {0x63, 0x4f, 0x50, 0x86, 0x55, 0x99, 0x06, 0x3e, /* standard CRTC */ 176 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 177 0xe9, 0x0c, 0xdf, 0x00, 0x00, 0xe7, 0x00, 0xe3, 0xff}, 178 {0x6D, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, /* extended CRTC */ 179 0x00, 0x00, 0x01, 0x08, 0x80, 0x1F, 0x00, 0x4B}}, 180/*------------------------------------------------------------------------------*/ 181 {640, 480, 75, /* 640x480 */ 182 31, /* 31.5 MHz clock = 75 Hz refresh rate */ 183 0xE3, /* miscOutput register */ 184 {0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, /* standard CRTC */ 185 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 186 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF}, 187 {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 188 0x00, 0x00, 0x00, 0x03, 0x80, 0x1F, 0x00, 0x00}}, 189/*------------------------------------------------------------------------------*/ 190 {800, 600, 60, /* 800x600 */ 191 40, /* 40 MHz clock = 60 Hz refresh rate */ 192 0x23, /* miscOutput register */ 193 {0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, /* standard CRTC */ 194 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 195 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF}, 196 {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 197 0x00, 0x00, 0x00, 0x03, 0x80, 0x28, 0x00, 0x00}}, 198/*------------------------------------------------------------------------------*/ 199 {800, 600, 72, /* 800x600 */ 200 47, /* 47 MHz clock = 72 Hz refresh rate */ 201 0x2B, /* miscOutput register */ 202 {0x7D, 0x63, 0x63, 0x81, 0x6D, 0x1B, 0x98, 0xF0, /* standard CRTC */ 203 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 204 0x7D, 0x03, 0x57, 0x00, 0x00, 0x57, 0x9A, 0xE3, 0xFF}, 205 {0x6F, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, /* extended CRTC */ 206 0x00, 0x00, 0x01, 0x08, 0x80, 0x32, 0x00, 0x4B}}, 207/*------------------------------------------------------------------------------*/ 208 {800, 600, 75, /* 800x600 */ 209 49, /* 49.5 MHz clock = 75 Hz refresh rate */ 210 0x23, /* miscOutput register */ 211 {0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, /* standard CRTC */ 212 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 213 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF}, 214 {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 215 0x00, 0x00, 0x00, 0x03, 0x80, 0x31, 0x00, 0x00}}, 216/*------------------------------------------------------------------------------*/ 217 {1024, 768, 60, /* 1024x768 */ 218 65, /* 65 MHz clock = 60 Hz refresh rate */ 219 0xE3, /* miscOutput register */ 220 {0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, /* standard CRTC */ 221 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF}, 223 {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 224 0x00, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00}}, 225/*------------------------------------------------------------------------------*/ 226 {1024, 768, 70, /* 1024x768 */ 227 76, /* 76 MHz clock = 70 Hz refresh rate */ 228 0x2B, /* miscOutput register */ 229 {0xA1, 0x7F, 0x7F, 0x85, 0x85, 0x95, 0x24, 0xF5, /* standard CRTC */ 230 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 0x03, 0x09, 0xFF, 0x00, 0x00, 0xFF, 0x26, 0xE3, 0xFF}, 232 {0x62, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, /* extended CRTC */ 233 0x00, 0x00, 0x01, 0x02, 0x80, 0x4B, 0x00, 0x4B}}, 234/*------------------------------------------------------------------------------*/ 235 {1024, 768, 75, /* 1024x768 */ 236 79, /* 79 MHz clock = 75 Hz refresh rate */ 237 0xE3, /* miscOutput register */ 238 {0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, /* standard CRTC */ 239 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF}, 241 {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 242 0x00, 0x00, 0x00, 0x03, 0x80, 0x4F, 0x00, 0x00}}, 243/*------------------------------------------------------------------------------*/ 244 {1280, 1024, 60, /* 1280x1024 */ 245 108, /* 108 MHz clock = 60 Hz refresh rate */ 246 0x23, /* miscOutput register */ 247 {0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, /* standard CRTC */ 248 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, 250 {0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 251 0x00, 0x00, 0x00, 0x03, 0x80, 0x6C, 0x00, 0x00}}, 252/*------------------------------------------------------------------------------*/ 253 {1280, 1024, 75, /* 1280x1024 */ 254 135, /* 135 MHz clock = 75 Hz refresh rate */ 255 0x23, /* miscOutput register */ 256 {0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, /* standard CRTC */ 257 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, 259 {0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */ 260 0x00, 0x00, 0x00, 0x03, 0x80, 0x87, 0x00, 0x00}}, 261/*------------------------------------------------------------------------------*/ 262 {1280, 1024, 85, /* 1280x1024 */ 263 159, /* 159 MHz clock = 85 Hz refresh rate */ 264 0x2B, /* miscOutput register */ 265 {0xD3, 0x9F, 0xA0, 0x98, 0xA8, 0x9C, 0x2E, 0x5A, /* standard CRTC */ 266 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 267 0x01, 0x04, 0xFF, 0x00, 0x00, 0xFF, 0x30, 0xE3, 0xFF}, 268 {0x6B, 0x41, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, /* extended CRTC */ 269 0x00, 0x00, 0x01, 0x00, 0x80, 0x9D, 0x00, 0x4B}}, 270 271/*------------------------------------------------------------------------------*/ 272}; 273 274#define GFX_VGA_MODES sizeof(gfx_vga_modes)/sizeof(gfx_vga_struct) 275 276/*----------------------------------------------------------------------------- 277 * gfx_get_softvga_active 278 * 279 * This returns the active status of SoftVGA 280 *----------------------------------------------------------------------------- 281 */ 282int 283gfx_get_softvga_active(void) 284{ 285 unsigned short crtcindex, crtcdata; 286 287 if (gu1_detect_vsa2()) 288 return (gfx_get_vsa2_softvga_enable()); 289 290 crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 291 crtcdata = crtcindex + 1; 292 293 OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL); 294 return (INB(crtcdata) & 0x1); 295} 296 297/*----------------------------------------------------------------------------- 298 * gfx_vga_test_pci 299 * 300 * This routine looks for the VGA PCI header. It checks to see that bit 1 301 * of the command register is writable to know that SoftVGA is trapping 302 * the PCI config cuscles. If SoftVGA is not emulating the header, the 303 * hardware will still respond with the proper device ID, etc. 304 * 305 * We need to know that SoftVGA is really there so that we can set the 306 * command register and have the proper effect (enable trapping of VGA). 307 * Otherwise, if we enable VGA via the PCI header, trapping really won't be 308 * enabled and the VGA register writes will go out to the external card. 309 *----------------------------------------------------------------------------- 310 */ 311int 312gfx_vga_test_pci(void) 313{ 314 int softvga = 1; 315 unsigned long value; 316 317 value = gfx_pci_config_read(0x80009400); 318 if ((value & 0x0000FFFF) != 0x1078) 319 softvga = 0; 320 else { 321 value = gfx_pci_config_read(0x80009404); 322 gfx_pci_config_write(0x80009404, value | 0x02); 323 if (!(gfx_pci_config_read(0x80009404) & 0x02)) 324 softvga = 0; 325 gfx_pci_config_write(0x80009404, value); 326 } 327 return (softvga); 328} 329 330/*----------------------------------------------------------------------------- 331 * gfx_vga_get_pci_command 332 * 333 * This routine returns the value of the PCI command register. 334 *----------------------------------------------------------------------------- 335 */ 336unsigned char 337gfx_vga_get_pci_command(void) 338{ 339 unsigned long value; 340 341 value = gfx_pci_config_read(0x80009404); 342 return ((unsigned char)value); 343} 344 345/*----------------------------------------------------------------------------- 346 * gfx_vga_set_pci_command 347 * 348 * This routine writes the value of the PCI command register. It is used 349 * to enable or disable SoftVGA. 350 * 351 * Bit 0: Enable VGA IO 352 * Bit 1: Enable VGA memory 353 *----------------------------------------------------------------------------- 354 */ 355int 356gfx_vga_set_pci_command(unsigned char command) 357{ 358 unsigned long value; 359 360 value = gfx_pci_config_read(0x80009404) & 0xFFFFFF00; 361 value |= (unsigned long)command; 362 gfx_pci_config_write(0x80009404, value); 363 return (GFX_STATUS_OK); 364} 365 366/*----------------------------------------------------------------------------- 367 * gfx_vga_seq_reset 368 * 369 * This routine enables or disables SoftVGA. It is used to make SoftVGA 370 * "be quiet" and not interfere with any of the direct hardware access from 371 * Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may 372 * provide a better way to have SoftVGA sit in the background. 373 *----------------------------------------------------------------------------- 374 */ 375int 376gfx_vga_seq_reset(int reset) 377{ 378 OUTB(0x3C4, 0); 379 OUTB(0x3C5, (unsigned char)(reset ? 0x00 : 0x03)); 380 return (GFX_STATUS_OK); 381} 382 383/*----------------------------------------------------------------------------- 384 * gfx_vga_set_graphics_bits 385 * 386 * This routine sets the standard VGA sequencer, graphics controller, and 387 * attribute registers to appropriate values for a graphics mode (packed, 388 * 8 BPP or greater). This is also known as "VESA" modes. The timings for 389 * a particular mode are handled by the CRTC registers, which are set by 390 * the "gfx_vga_restore" routine. Most OSs that use VGA to set modes save 391 * and restore the standard VGA registers themselves, which is why these 392 * registers are not part of the save/restore paradigm. 393 *----------------------------------------------------------------------------- 394 */ 395int 396gfx_vga_set_graphics_bits(void) 397{ 398 /* SET GRAPHICS BIT IN GRAPHICS CONTROLLER REG 0x06 */ 399 400 OUTB(0x3CE, 0x06); 401 OUTB(0x3CF, 0x01); 402 403 /* SET GRAPHICS BIT IN ATTRIBUTE CONTROLLER REG 0x10 */ 404 405 INB(0x3BA); /* Reset flip-flop */ 406 INB(0x3DA); 407 OUTB(0x3C0, 0x10); 408 OUTB(0x3C0, 0x01); 409 return (GFX_STATUS_OK); 410} 411 412/*----------------------------------------------------------------------------- 413 * gfx_vga_mode 414 * 415 * This routine searches the VGA mode table for a match of the specified 416 * mode and then fills in the VGA structure with the associated VGA register 417 * values. The "gfx_vga_restore" routine can then be called to actually 418 * set the mode. 419 *----------------------------------------------------------------------------- 420 */ 421int 422gfx_vga_mode(gfx_vga_struct * vga, int xres, int yres, int bpp, int hz) 423{ 424 unsigned int i; 425 unsigned short pitch; 426 427 for (i = 0; i < GFX_VGA_MODES; i++) { 428 if ((gfx_vga_modes[i].xsize == xres) && 429 (gfx_vga_modes[i].ysize == yres) && (gfx_vga_modes[i].hz == hz)) { 430 /* COPY ENTIRE STRUCTURE FROM THE TABLE */ 431 432 *vga = gfx_vga_modes[i]; 433 434 /* SET PITCH TO 1K OR 2K */ 435 /* CRTC_EXTENDED_OFFSET index is 0x45, so offset = 0x05 */ 436 437 pitch = (unsigned short)xres; 438 if (bpp > 8) 439 pitch <<= 1; 440 if (pitch <= 1024) 441 pitch = 1024 >> 3; 442 else 443 pitch = 2048 >> 3; 444 vga->stdCRTCregs[0x13] = (unsigned char)pitch; 445 vga->extCRTCregs[0x05] = (unsigned char)((pitch >> 8) & 0x03); 446 447 /* SET PROPER COLOR DEPTH VALUE */ 448 /* CRTC_EXTENDED_COLOR_CONTROL index is 0x46, so offset = 0x06 */ 449 450 switch (bpp) { 451 case 15: 452 vga->extCRTCregs[0x06] = CRTC_BIT_16BPP | CRTC_BIT_555; 453 break; 454 case 16: 455 vga->extCRTCregs[0x06] = CRTC_BIT_16BPP; 456 break; 457 default: 458 vga->extCRTCregs[0x06] = 0; 459 break; 460 } 461 return (GFX_STATUS_OK); 462 } 463 } 464 return (GFX_STATUS_UNSUPPORTED); 465} 466 467/*----------------------------------------------------------------------------- 468 * gfx_vga_pitch 469 * 470 * This routine updates the VGA regisers in the specified VGA structure for 471 * the specified pitch. It does not program the hardware. 472 *----------------------------------------------------------------------------- 473 */ 474int 475gfx_vga_pitch(gfx_vga_struct * vga, unsigned short pitch) 476{ 477 pitch >>= 3; 478 vga->stdCRTCregs[0x13] = (unsigned char)pitch; 479 vga->extCRTCregs[0x05] = (unsigned char)((pitch >> 8) & 0x03); 480 return (0); 481} 482 483/*----------------------------------------------------------------------------- 484 * gfx_vga_save 485 * 486 * This routine saves the state of the VGA registers into the specified 487 * structure. Flags indicate what portions of the register state need to 488 * be saved. 489 *----------------------------------------------------------------------------- 490 */ 491int 492gfx_vga_save(gfx_vga_struct * vga, int flags) 493{ 494 int i; 495 unsigned short crtcindex, crtcdata; 496 497 crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 498 crtcdata = crtcindex + 1; 499 500 /* CHECK MISCELLANEOUS OUTPUT FLAG */ 501 502 if (flags & GFX_VGA_FLAG_MISC_OUTPUT) { 503 /* SAVE MISCCELLANEOUS OUTPUT REGISTER */ 504 505 vga->miscOutput = INB(0x3CC); 506 } 507 508 /* CHECK STANDARD CRTC FLAG */ 509 510 if (flags & GFX_VGA_FLAG_STD_CRTC) { 511 /* SAVE STANDARD CRTC REGISTERS */ 512 513 for (i = 0; i < GFX_STD_CRTC_REGS; i++) { 514 OUTB(crtcindex, (unsigned char)i); 515 vga->stdCRTCregs[i] = INB(crtcdata); 516 } 517 } 518 519 /* CHECK EXTENDED CRTC FLAG */ 520 521 if (flags & GFX_VGA_FLAG_EXT_CRTC) { 522 /* SAVE EXTENDED CRTC REGISTERS */ 523 524 for (i = 0; i < GFX_EXT_CRTC_REGS; i++) { 525 OUTB(crtcindex, (unsigned char)(0x40 + i)); 526 vga->extCRTCregs[i] = INB(crtcdata); 527 } 528 } 529 return (0); 530} 531 532/*----------------------------------------------------------------------------- 533 * gfx_vga_clear_extended 534 * 535 * This routine clears the extended SoftVGA register values to have SoftVGA 536 * behave like standard VGA. 537 *----------------------------------------------------------------------------- 538 */ 539void 540gfx_vga_clear_extended(void) 541{ 542 int i; 543 unsigned short crtcindex, crtcdata; 544 545 crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 546 crtcdata = crtcindex + 1; 547 548 OUTB(crtcindex, 0x30); 549 OUTB(crtcdata, 0x57); 550 OUTB(crtcdata, 0x4C); 551 for (i = 0x40; i <= 0x4F; i++) { 552 OUTB(crtcindex, (unsigned char)i); 553 OUTB(crtcdata, 0); 554 } 555 OUTB(crtcindex, 0x30); 556 OUTB(crtcdata, 0x00); 557} 558 559/*----------------------------------------------------------------------------- 560 * gfx_vga_restore 561 * 562 * This routine restores the state of the VGA registers from the specified 563 * structure. Flags indicate what portions of the register state need to 564 * be saved. 565 *----------------------------------------------------------------------------- 566 */ 567int 568gfx_vga_restore(gfx_vga_struct * vga, int flags) 569{ 570 int i; 571 unsigned short crtcindex, crtcdata; 572 573 crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 574 crtcdata = crtcindex + 1; 575 576 /* CHECK MISCELLANEOUS OUTPUT FLAG */ 577 578 if (flags & GFX_VGA_FLAG_MISC_OUTPUT) { 579 /* RESTORE MISCELLANEOUS OUTPUT REGISTER VALUE */ 580 581 OUTB(0x3C2, vga->miscOutput); 582 } 583 584 /* CHECK STANDARD CRTC FLAG */ 585 586 if (flags & GFX_VGA_FLAG_STD_CRTC) { 587 /* UNLOCK STANDARD CRTC REGISTERS */ 588 589 OUTB(crtcindex, 0x11); 590 OUTB(crtcdata, 0); 591 592 /* RESTORE STANDARD CRTC REGISTERS */ 593 594 for (i = 0; i < GFX_STD_CRTC_REGS; i++) { 595 OUTB(crtcindex, (unsigned char)i); 596 OUTB(crtcdata, vga->stdCRTCregs[i]); 597 } 598 } 599 600 /* CHECK EXTENDED CRTC FLAG */ 601 602 if (flags & GFX_VGA_FLAG_EXT_CRTC) { 603 /* UNLOCK EXTENDED CRTC REGISTERS */ 604 605 OUTB(crtcindex, 0x30); 606 OUTB(crtcdata, 0x57); 607 OUTB(crtcdata, 0x4C); 608 609 /* RESTORE EXTENDED CRTC REGISTERS */ 610 611 for (i = 0; i < GFX_EXT_CRTC_REGS; i++) { 612 OUTB(crtcindex, (unsigned char)(0x40 + i)); 613 OUTB(crtcdata, vga->extCRTCregs[i]); 614 } 615 616 /* LOCK EXTENDED CRTC REGISTERS */ 617 618 OUTB(crtcindex, 0x30); 619 OUTB(crtcdata, 0x00); 620 621 /* CHECK IF DIRECT FRAME BUFFER MODE (VESA MODE) */ 622 623 if (vga->extCRTCregs[0x03] & 1) { 624 /* SET BORDER COLOR TO BLACK */ 625 /* This really should be another thing saved/restored, but */ 626 /* Durango currently doesn't do the attr controller registers. */ 627 628 INB(0x3BA); /* Reset flip-flop */ 629 INB(0x3DA); 630 OUTB(0x3C0, 0x11); 631 OUTB(0x3C0, 0x00); 632 } 633 } 634 return (0); 635} 636 637/*----------------------------------------------------------------------------- 638 * gfx_vga_mode_switch 639 * 640 * This routine programs the SoftVGA register to indicate that a mode switch 641 * is in progress. This results in a cleaner mode switch since SoftVGA will 642 * not validate the hardware with intermediate values. 643 *----------------------------------------------------------------------------- 644 */ 645int 646gfx_vga_mode_switch(int active) 647{ 648 unsigned short crtcindex, crtcdata; 649 650 crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 651 crtcdata = crtcindex + 1; 652 653 /* UNLOCK EXTENDED CRTC REGISTERS */ 654 655 OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK); 656 OUTB(crtcdata, 0x57); 657 OUTB(crtcdata, 0x4C); 658 659 /* SIGNAL THE BEGINNING OR END OF THE MODE SWITCH */ 660 /* SoftVGA will hold off validating the back end hardware. */ 661 662 OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL); 663 active = active ? 1 : 0; 664 OUTB(crtcdata, (unsigned char)active); 665 666 /* WAIT UNTIL SOFTVGA HAS VALIDATED MODE IF ENDING MODE SWITCH */ 667 /* This is for VSA1 only, where SoftVGA waits until the next */ 668 /* vertical blank to validate the hardware state. */ 669 670 if ((!active) && (!(gu1_detect_vsa2()))) { 671 OUTB(crtcindex, 0x33); 672 while (INB(crtcdata) & 0x80) ; 673 } 674 675 /* LOCK EXTENDED CRTC REGISTERS */ 676 677 OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK); 678 OUTB(crtcdata, 0x00); 679 return (0); 680} 681 682/*----------------------------------------------------------------------------- 683 * gu1_detect_vsa2 684 * 685 * This routine detects if VSA2 is present. The interface to SoftVGA 686 * changed slightly. 687 *----------------------------------------------------------------------------- 688 */ 689int 690gu1_detect_vsa2(void) 691{ 692 unsigned short crtcindex, crtcdata; 693 694 crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 695 crtcdata = crtcindex + 1; 696 OUTB(crtcindex, 0x35); 697 if (INB(crtcdata) != 'C') 698 return (0); 699 OUTB(crtcindex, 0x36); 700 if (INB(crtcdata) != 'X') 701 return (0); 702 return (1); 703} 704 705/* END OF FILE */ 706