1f29dbc25Smrg/* Copyright (c) 2005 Advanced Micro Devices, Inc. 2f29dbc25Smrg * 3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to 5f29dbc25Smrg * deal in the Software without restriction, including without limitation the 6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is 8f29dbc25Smrg * furnished to do so, subject to the following conditions: 9f29dbc25Smrg * 10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 11f29dbc25Smrg * all copies or substantial portions of the Software. 12f29dbc25Smrg * 13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19f29dbc25Smrg * IN THE SOFTWARE. 20f29dbc25Smrg * 21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 23f29dbc25Smrg * software without specific prior written permission. 24f29dbc25Smrg * */ 25f29dbc25Smrg 26f29dbc25Smrg/* 27f29dbc25Smrg * This file contains routines to set modes using the VGA registers. 28f29dbc25Smrg * Since this file is for the first generation graphics unit, it interfaces 29f29dbc25Smrg * to SoftVGA registers. It works for both VSA1 and VSA2. 30f29dbc25Smrg * */ 31f29dbc25Smrg 32f29dbc25Smrg/* SoftVGA Extended CRTC register indices and bit definitions */ 33f29dbc25Smrg 34f29dbc25Smrg#define CRTC_EXTENDED_REGISTER_LOCK 0x30 35f29dbc25Smrg#define CRTC_MODE_SWITCH_CONTROL 0x3F 36f29dbc25Smrg 37f29dbc25Smrg/* BIT DEFINITIONS */ 38f29dbc25Smrg 39f29dbc25Smrg#define CRTC_BIT_16BPP 0x01 40f29dbc25Smrg#define CRTC_BIT_555 0x02 41f29dbc25Smrg 42f29dbc25Smrg/* LOCAL ROUTINE DEFINITIONS */ 43f29dbc25Smrg 44f29dbc25Smrgint gu1_detect_vsa2(void); 45f29dbc25Smrg 46f29dbc25Smrg/*---------------------------------*/ 47f29dbc25Smrg/* MODE TABLES FOR VGA REGISTERS */ 48f29dbc25Smrg/*---------------------------------*/ 49f29dbc25Smrg 50f29dbc25Smrg/* FOR SoftVGA, the CRTC_EXTENDED_ADDRESS_CONTROL (0x43) is always equal to 51f29dbc25Smrg * 0x03 for a packed linear frame buffer organization. The 52f29dbc25Smrg * CRTC_EXTENDED_DAC_CONTROL (0x4B) is always equal to 0x03 to work with 53f29dbc25Smrg * older versions of VSA1 (that needed to specify 8 or 16 bit bus to an 54f29dbc25Smrg * external RAMDAC. This is not used in VSA2. The clock frequency is 55f29dbc25Smrg * specified in register 0x4D if clock control (0x4C) is set to 0x80. 56f29dbc25Smrg * Higher resolutions (1280x1024) use the CRTC_EXTENDED_VERTICAL_TIMING 57f29dbc25Smrg * register (index 0x41). 58f29dbc25Smrg */ 59f29dbc25Smrg 60f29dbc25Smrggfx_vga_struct gfx_vga_modes[] = { 61f29dbc25Smrg/*--------------------------------------------------------------------------*/ 62f29dbc25Smrg { 6304007ebaSmrg 640, 480, 60, /* 640x480 */ 6404007ebaSmrg 25, /* 25 MHz clock = 60 Hz refresh rate */ 6504007ebaSmrg 0xE3, /* miscOutput register */ 6604007ebaSmrg { 6704007ebaSmrg 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 6804007ebaSmrg /* standard CRTC */ 6904007ebaSmrg 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7004007ebaSmrg 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF}, 7104007ebaSmrg { 7204007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 7304007ebaSmrg /* extended CRTC */ 7404007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00} 7504007ebaSmrg }, 76f29dbc25Smrg/*--------------------------------------------------------------------------*/ 77f29dbc25Smrg { 7804007ebaSmrg 640, 480, 72, /* 640x480 */ 7904007ebaSmrg 29, /* 29 MHz clock = 72 Hz refresh rate */ 8004007ebaSmrg 0xE3, /* miscOutput register */ 8104007ebaSmrg { 8204007ebaSmrg 0x63, 0x4f, 0x50, 0x86, 0x55, 0x99, 0x06, 0x3e, 8304007ebaSmrg /* standard CRTC */ 8404007ebaSmrg 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8504007ebaSmrg 0xe9, 0x0c, 0xdf, 0x00, 0x00, 0xe7, 0x00, 0xe3, 0xff}, 8604007ebaSmrg { 8704007ebaSmrg 0x6D, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 8804007ebaSmrg /* extended CRTC */ 8904007ebaSmrg 0x00, 0x00, 0x01, 0x08, 0x80, 0x1F, 0x00, 0x4B} 9004007ebaSmrg }, 91f29dbc25Smrg/*--------------------------------------------------------------------------*/ 92f29dbc25Smrg { 9304007ebaSmrg 640, 480, 75, /* 640x480 */ 9404007ebaSmrg 31, 9504007ebaSmrg /* 31.5 MHz clock = 75 Hz refresh rate */ 9604007ebaSmrg 0xE3, /* miscOutput register */ 9704007ebaSmrg { 9804007ebaSmrg 0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, 9904007ebaSmrg /* standard CRTC */ 10004007ebaSmrg 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10104007ebaSmrg 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF}, 10204007ebaSmrg { 10304007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 10404007ebaSmrg /* extended CRTC */ 10504007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x1F, 0x00, 0x00} 10604007ebaSmrg }, 107f29dbc25Smrg/*--------------------------------------------------------------------------*/ 108f29dbc25Smrg { 10904007ebaSmrg 800, 600, 60, /* 800x600 */ 11004007ebaSmrg 40, /* 40 MHz clock = 60 Hz refresh rate */ 11104007ebaSmrg 0x23, /* miscOutput register */ 11204007ebaSmrg { 11304007ebaSmrg 0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, 11404007ebaSmrg /* standard CRTC */ 11504007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11604007ebaSmrg 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF}, 11704007ebaSmrg { 11804007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 11904007ebaSmrg /* extended CRTC */ 12004007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x28, 0x00, 0x00} 12104007ebaSmrg }, 122f29dbc25Smrg/*--------------------------------------------------------------------------*/ 123f29dbc25Smrg { 12404007ebaSmrg 800, 600, 72, /* 800x600 */ 12504007ebaSmrg 47, /* 47 MHz clock = 72 Hz refresh rate */ 12604007ebaSmrg 0x2B, /* miscOutput register */ 12704007ebaSmrg { 12804007ebaSmrg 0x7D, 0x63, 0x63, 0x81, 0x6D, 0x1B, 0x98, 0xF0, 12904007ebaSmrg /* standard CRTC */ 13004007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13104007ebaSmrg 0x7D, 0x03, 0x57, 0x00, 0x00, 0x57, 0x9A, 0xE3, 0xFF}, 13204007ebaSmrg { 13304007ebaSmrg 0x6F, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 13404007ebaSmrg /* extended CRTC */ 13504007ebaSmrg 0x00, 0x00, 0x01, 0x08, 0x80, 0x32, 0x00, 0x4B} 13604007ebaSmrg }, 137f29dbc25Smrg/*--------------------------------------------------------------------------*/ 138f29dbc25Smrg { 13904007ebaSmrg 800, 600, 75, /* 800x600 */ 14004007ebaSmrg 49, 14104007ebaSmrg /* 49.5 MHz clock = 75 Hz refresh rate */ 14204007ebaSmrg 0x23, /* miscOutput register */ 14304007ebaSmrg { 14404007ebaSmrg 0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, 14504007ebaSmrg /* standard CRTC */ 14604007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14704007ebaSmrg 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF}, 14804007ebaSmrg { 14904007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 15004007ebaSmrg /* extended CRTC */ 15104007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x31, 0x00, 0x00} 15204007ebaSmrg }, 153f29dbc25Smrg/*--------------------------------------------------------------------------*/ 154f29dbc25Smrg { 15504007ebaSmrg 1024, 768, 60, /* 1024x768 */ 15604007ebaSmrg 65, /* 65 MHz clock = 60 Hz refresh rate */ 15704007ebaSmrg 0xE3, /* miscOutput register */ 15804007ebaSmrg { 15904007ebaSmrg 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, 16004007ebaSmrg /* standard CRTC */ 16104007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16204007ebaSmrg 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF}, 16304007ebaSmrg { 16404007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 16504007ebaSmrg /* extended CRTC */ 16604007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00} 16704007ebaSmrg }, 168f29dbc25Smrg/*--------------------------------------------------------------------------*/ 169f29dbc25Smrg { 17004007ebaSmrg 1024, 768, 70, /* 1024x768 */ 17104007ebaSmrg 76, /* 76 MHz clock = 70 Hz refresh rate */ 17204007ebaSmrg 0x2B, /* miscOutput register */ 17304007ebaSmrg { 17404007ebaSmrg 0xA1, 0x7F, 0x7F, 0x85, 0x85, 0x95, 0x24, 0xF5, 17504007ebaSmrg /* standard CRTC */ 17604007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17704007ebaSmrg 0x03, 0x09, 0xFF, 0x00, 0x00, 0xFF, 0x26, 0xE3, 0xFF}, 17804007ebaSmrg { 17904007ebaSmrg 0x62, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 18004007ebaSmrg /* extended CRTC */ 18104007ebaSmrg 0x00, 0x00, 0x01, 0x02, 0x80, 0x4B, 0x00, 0x4B} 18204007ebaSmrg }, 183f29dbc25Smrg/*--------------------------------------------------------------------------*/ 184f29dbc25Smrg { 18504007ebaSmrg 1024, 768, 75, /* 1024x768 */ 18604007ebaSmrg 79, /* 79 MHz clock = 75 Hz refresh rate */ 18704007ebaSmrg 0xE3, /* miscOutput register */ 18804007ebaSmrg { 18904007ebaSmrg 0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, 19004007ebaSmrg /* standard CRTC */ 19104007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19204007ebaSmrg 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF}, 19304007ebaSmrg { 19404007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 19504007ebaSmrg /* extended CRTC */ 19604007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x4F, 0x00, 0x00} 19704007ebaSmrg }, 198f29dbc25Smrg/*--------------------------------------------------------------------------*/ 199f29dbc25Smrg { 20004007ebaSmrg 1280, 1024, 60, /* 1280x1024 */ 20104007ebaSmrg 108, 20204007ebaSmrg /* 108 MHz clock = 60 Hz refresh rate */ 20304007ebaSmrg 0x23, /* miscOutput register */ 20404007ebaSmrg { 20504007ebaSmrg 0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, 20604007ebaSmrg /* standard CRTC */ 20704007ebaSmrg 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20804007ebaSmrg 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, 20904007ebaSmrg { 21004007ebaSmrg 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 21104007ebaSmrg /* extended CRTC */ 21204007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x6C, 0x00, 0x00} 21304007ebaSmrg }, 214f29dbc25Smrg/*--------------------------------------------------------------------------*/ 215f29dbc25Smrg { 21604007ebaSmrg 1280, 1024, 75, /* 1280x1024 */ 21704007ebaSmrg 135, 21804007ebaSmrg /* 135 MHz clock = 75 Hz refresh rate */ 21904007ebaSmrg 0x23, /* miscOutput register */ 22004007ebaSmrg { 22104007ebaSmrg 0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, 22204007ebaSmrg /* standard CRTC */ 22304007ebaSmrg 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22404007ebaSmrg 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, 22504007ebaSmrg { 22604007ebaSmrg 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 22704007ebaSmrg /* extended CRTC */ 22804007ebaSmrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x87, 0x00, 0x00} 22904007ebaSmrg }, 230f29dbc25Smrg/*--------------------------------------------------------------------------*/ 231f29dbc25Smrg { 23204007ebaSmrg 1280, 1024, 85, /* 1280x1024 */ 23304007ebaSmrg 159, 23404007ebaSmrg /* 159 MHz clock = 85 Hz refresh rate */ 23504007ebaSmrg 0x2B, /* miscOutput register */ 23604007ebaSmrg { 23704007ebaSmrg 0xD3, 0x9F, 0xA0, 0x98, 0xA8, 0x9C, 0x2E, 0x5A, 23804007ebaSmrg /* standard CRTC */ 23904007ebaSmrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24004007ebaSmrg 0x01, 0x04, 0xFF, 0x00, 0x00, 0xFF, 0x30, 0xE3, 0xFF}, 24104007ebaSmrg { 24204007ebaSmrg 0x6B, 0x41, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 24304007ebaSmrg /* extended CRTC */ 24404007ebaSmrg 0x00, 0x00, 0x01, 0x00, 0x80, 0x9D, 0x00, 0x4B} 24504007ebaSmrg }, 246f29dbc25Smrg/*--------------------------------------------------------------------------*/ 247f29dbc25Smrg}; 248f29dbc25Smrg 249f29dbc25Smrg#define GFX_VGA_MODES sizeof(gfx_vga_modes)/sizeof(gfx_vga_struct) 250f29dbc25Smrg 251f29dbc25Smrg/*---------------------------------------------------------------------------- 252f29dbc25Smrg * gfx_get_softvga_active 253f29dbc25Smrg * 254f29dbc25Smrg * This returns the active status of SoftVGA 255f29dbc25Smrg *---------------------------------------------------------------------------- 256f29dbc25Smrg */ 257f29dbc25Smrgint 258f29dbc25Smrggfx_get_softvga_active(void) 259f29dbc25Smrg{ 260f29dbc25Smrg unsigned short crtcindex, crtcdata; 261f29dbc25Smrg 262f29dbc25Smrg if (gu1_detect_vsa2()) 263f29dbc25Smrg return (gfx_get_vsa2_softvga_enable()); 264f29dbc25Smrg 265f29dbc25Smrg crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 266f29dbc25Smrg crtcdata = crtcindex + 1; 267f29dbc25Smrg 268f29dbc25Smrg OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL); 269f29dbc25Smrg return (INB(crtcdata) & 0x1); 270f29dbc25Smrg} 271f29dbc25Smrg 272f29dbc25Smrg/*---------------------------------------------------------------------------- 273f29dbc25Smrg * gfx_vga_test_pci 274f29dbc25Smrg * 275f29dbc25Smrg * This routine looks for the VGA PCI header. It checks to see that bit 1 276f29dbc25Smrg * of the command register is writable to know that SoftVGA is trapping 277f29dbc25Smrg * the PCI config cuscles. If SoftVGA is not emulating the header, the 278f29dbc25Smrg * hardware will still respond with the proper device ID, etc. 279f29dbc25Smrg * 280f29dbc25Smrg * We need to know that SoftVGA is really there so that we can set the 281f29dbc25Smrg * command register and have the proper effect (enable trapping of VGA). 282f29dbc25Smrg * Otherwise, if we enable VGA via the PCI header, trapping really won't be 283f29dbc25Smrg * enabled and the VGA register writes will go out to the external card. 284f29dbc25Smrg *---------------------------------------------------------------------------- 285f29dbc25Smrg */ 286f29dbc25Smrgint 287f29dbc25Smrggfx_vga_test_pci(void) 288f29dbc25Smrg{ 289f29dbc25Smrg int softvga = 1; 290f29dbc25Smrg unsigned long value; 291f29dbc25Smrg 292f29dbc25Smrg value = gfx_pci_config_read(0x80009400); 293f29dbc25Smrg if ((value & 0x0000FFFF) != 0x1078) 294f29dbc25Smrg softvga = 0; 295f29dbc25Smrg else { 296f29dbc25Smrg value = gfx_pci_config_read(0x80009404); 297f29dbc25Smrg gfx_pci_config_write(0x80009404, value | 0x02); 298f29dbc25Smrg if (!(gfx_pci_config_read(0x80009404) & 0x02)) 299f29dbc25Smrg softvga = 0; 300f29dbc25Smrg gfx_pci_config_write(0x80009404, value); 301f29dbc25Smrg } 302f29dbc25Smrg return (softvga); 303f29dbc25Smrg} 304f29dbc25Smrg 305f29dbc25Smrg/*---------------------------------------------------------------------------- 306f29dbc25Smrg * gfx_vga_get_pci_command 307f29dbc25Smrg * 308f29dbc25Smrg * This routine returns the value of the PCI command register. 309f29dbc25Smrg *---------------------------------------------------------------------------- 310f29dbc25Smrg */ 311f29dbc25Smrgunsigned char 312f29dbc25Smrggfx_vga_get_pci_command(void) 313f29dbc25Smrg{ 314f29dbc25Smrg unsigned long value; 315f29dbc25Smrg 316f29dbc25Smrg value = gfx_pci_config_read(0x80009404); 31704007ebaSmrg return ((unsigned char) value); 318f29dbc25Smrg} 319f29dbc25Smrg 320f29dbc25Smrg/*---------------------------------------------------------------------------- 321f29dbc25Smrg * gfx_vga_set_pci_command 322f29dbc25Smrg * 323f29dbc25Smrg * This routine writes the value of the PCI command register. It is used 324f29dbc25Smrg * to enable or disable SoftVGA. 325f29dbc25Smrg * 326f29dbc25Smrg * Bit 0: Enable VGA IO 327f29dbc25Smrg * Bit 1: Enable VGA memory 328f29dbc25Smrg *---------------------------------------------------------------------------- 329f29dbc25Smrg */ 330f29dbc25Smrgint 331f29dbc25Smrggfx_vga_set_pci_command(unsigned char command) 332f29dbc25Smrg{ 333f29dbc25Smrg unsigned long value; 334f29dbc25Smrg 335f29dbc25Smrg value = gfx_pci_config_read(0x80009404) & 0xFFFFFF00; 33604007ebaSmrg value |= (unsigned long) command; 337f29dbc25Smrg gfx_pci_config_write(0x80009404, value); 338f29dbc25Smrg return (GFX_STATUS_OK); 339f29dbc25Smrg} 340f29dbc25Smrg 341f29dbc25Smrg/*---------------------------------------------------------------------------- 342f29dbc25Smrg * gfx_vga_seq_reset 343f29dbc25Smrg * 344f29dbc25Smrg * This routine enables or disables SoftVGA. It is used to make SoftVGA 345f29dbc25Smrg * "be quiet" and not interfere with any of the direct hardware access from 346f29dbc25Smrg * Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may 347f29dbc25Smrg * provide a better way to have SoftVGA sit in the background. 348f29dbc25Smrg *---------------------------------------------------------------------------- 349f29dbc25Smrg */ 350f29dbc25Smrgint 351f29dbc25Smrggfx_vga_seq_reset(int reset) 352f29dbc25Smrg{ 353f29dbc25Smrg OUTB(0x3C4, 0); 35404007ebaSmrg OUTB(0x3C5, (unsigned char) (reset ? 0x00 : 0x03)); 355f29dbc25Smrg return (GFX_STATUS_OK); 356f29dbc25Smrg} 357f29dbc25Smrg 358f29dbc25Smrg/*---------------------------------------------------------------------------- 359f29dbc25Smrg * gfx_vga_set_graphics_bits 360f29dbc25Smrg * 361f29dbc25Smrg * This routine sets the standard VGA sequencer, graphics controller, and 362f29dbc25Smrg * attribute registers to appropriate values for a graphics mode (packed, 363f29dbc25Smrg * 8 BPP or greater). This is also known as "VESA" modes. The timings for 364f29dbc25Smrg * a particular mode are handled by the CRTC registers, which are set by 365f29dbc25Smrg * the "gfx_vga_restore" routine. Most OSs that use VGA to set modes save 366f29dbc25Smrg * and restore the standard VGA registers themselves, which is why these 367f29dbc25Smrg * registers are not part of the save/restore paradigm. 368f29dbc25Smrg *---------------------------------------------------------------------------- 369f29dbc25Smrg */ 370f29dbc25Smrgint 371f29dbc25Smrggfx_vga_set_graphics_bits(void) 372f29dbc25Smrg{ 373f29dbc25Smrg /* SET GRAPHICS BIT IN GRAPHICS CONTROLLER REG 0x06 */ 374f29dbc25Smrg 375f29dbc25Smrg OUTB(0x3CE, 0x06); 376f29dbc25Smrg OUTB(0x3CF, 0x01); 377f29dbc25Smrg 378f29dbc25Smrg /* SET GRAPHICS BIT IN ATTRIBUTE CONTROLLER REG 0x10 */ 379f29dbc25Smrg 38004007ebaSmrg INB(0x3BA); /* Reset flip-flop */ 381f29dbc25Smrg INB(0x3DA); 382f29dbc25Smrg OUTB(0x3C0, 0x10); 383f29dbc25Smrg OUTB(0x3C0, 0x01); 384f29dbc25Smrg return (GFX_STATUS_OK); 385f29dbc25Smrg} 386f29dbc25Smrg 387f29dbc25Smrg/*---------------------------------------------------------------------------- 388f29dbc25Smrg * gfx_vga_mode 389f29dbc25Smrg * 390f29dbc25Smrg * This routine searches the VGA mode table for a match of the specified 391f29dbc25Smrg * mode and then fills in the VGA structure with the associated VGA register 392f29dbc25Smrg * values. The "gfx_vga_restore" routine can then be called to actually 393f29dbc25Smrg * set the mode. 394f29dbc25Smrg *---------------------------------------------------------------------------- 395f29dbc25Smrg */ 396f29dbc25Smrgint 397f29dbc25Smrggfx_vga_mode(gfx_vga_struct * vga, int xres, int yres, int bpp, int hz) 398f29dbc25Smrg{ 399f29dbc25Smrg unsigned int i; 400f29dbc25Smrg unsigned short pitch; 401f29dbc25Smrg 402f29dbc25Smrg for (i = 0; i < GFX_VGA_MODES; i++) { 403f29dbc25Smrg if ((gfx_vga_modes[i].xsize == xres) && 404f29dbc25Smrg (gfx_vga_modes[i].ysize == yres) && (gfx_vga_modes[i].hz == hz)) { 405f29dbc25Smrg /* COPY ENTIRE STRUCTURE FROM THE TABLE */ 406f29dbc25Smrg 407f29dbc25Smrg *vga = gfx_vga_modes[i]; 408f29dbc25Smrg 409f29dbc25Smrg /* SET PITCH TO 1K OR 2K */ 410f29dbc25Smrg /* CRTC_EXTENDED_OFFSET index is 0x45, so offset = 0x05 */ 411f29dbc25Smrg 41204007ebaSmrg pitch = (unsigned short) xres; 413f29dbc25Smrg if (bpp > 8) 414f29dbc25Smrg pitch <<= 1; 415f29dbc25Smrg if (pitch <= 1024) 416f29dbc25Smrg pitch = 1024 >> 3; 417f29dbc25Smrg else 418f29dbc25Smrg pitch = 2048 >> 3; 41904007ebaSmrg vga->stdCRTCregs[0x13] = (unsigned char) pitch; 42004007ebaSmrg vga->extCRTCregs[0x05] = (unsigned char) ((pitch >> 8) & 0x03); 421f29dbc25Smrg 422f29dbc25Smrg /* SET PROPER COLOR DEPTH VALUE */ 423f29dbc25Smrg /* CRTC_EXTENDED_COLOR_CONTROL index is 0x46, so offset = 0x06 */ 424f29dbc25Smrg 425f29dbc25Smrg switch (bpp) { 426f29dbc25Smrg case 15: 427f29dbc25Smrg vga->extCRTCregs[0x06] = CRTC_BIT_16BPP | CRTC_BIT_555; 428f29dbc25Smrg break; 429f29dbc25Smrg case 16: 430f29dbc25Smrg vga->extCRTCregs[0x06] = CRTC_BIT_16BPP; 431f29dbc25Smrg break; 432f29dbc25Smrg default: 433f29dbc25Smrg vga->extCRTCregs[0x06] = 0; 434f29dbc25Smrg break; 435f29dbc25Smrg } 436f29dbc25Smrg return (GFX_STATUS_OK); 437f29dbc25Smrg } 438f29dbc25Smrg } 439f29dbc25Smrg return (GFX_STATUS_UNSUPPORTED); 440f29dbc25Smrg} 441f29dbc25Smrg 442f29dbc25Smrg/*---------------------------------------------------------------------------- 443f29dbc25Smrg * gfx_vga_pitch 444f29dbc25Smrg * 445f29dbc25Smrg * This routine updates the VGA regisers in the specified VGA structure for 446f29dbc25Smrg * the specified pitch. It does not program the hardware. 447f29dbc25Smrg *---------------------------------------------------------------------------- 448f29dbc25Smrg */ 449f29dbc25Smrgint 450f29dbc25Smrggfx_vga_pitch(gfx_vga_struct * vga, unsigned short pitch) 451f29dbc25Smrg{ 452f29dbc25Smrg pitch >>= 3; 45304007ebaSmrg vga->stdCRTCregs[0x13] = (unsigned char) pitch; 45404007ebaSmrg vga->extCRTCregs[0x05] = (unsigned char) ((pitch >> 8) & 0x03); 455f29dbc25Smrg return (0); 456f29dbc25Smrg} 457f29dbc25Smrg 458f29dbc25Smrg/*---------------------------------------------------------------------------- 459f29dbc25Smrg * gfx_vga_save 460f29dbc25Smrg * 461f29dbc25Smrg * This routine saves the state of the VGA registers into the specified 462f29dbc25Smrg * structure. Flags indicate what portions of the register state need to 463f29dbc25Smrg * be saved. 464f29dbc25Smrg *---------------------------------------------------------------------------- 465f29dbc25Smrg */ 466f29dbc25Smrgint 467f29dbc25Smrggfx_vga_save(gfx_vga_struct * vga, int flags) 468f29dbc25Smrg{ 469f29dbc25Smrg int i; 470f29dbc25Smrg unsigned short crtcindex, crtcdata; 471f29dbc25Smrg 472f29dbc25Smrg crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 473f29dbc25Smrg crtcdata = crtcindex + 1; 474f29dbc25Smrg 475f29dbc25Smrg /* CHECK MISCELLANEOUS OUTPUT FLAG */ 476f29dbc25Smrg 477f29dbc25Smrg if (flags & GFX_VGA_FLAG_MISC_OUTPUT) { 478f29dbc25Smrg /* SAVE MISCCELLANEOUS OUTPUT REGISTER */ 479f29dbc25Smrg 480f29dbc25Smrg vga->miscOutput = INB(0x3CC); 481f29dbc25Smrg } 482f29dbc25Smrg 483f29dbc25Smrg /* CHECK STANDARD CRTC FLAG */ 484f29dbc25Smrg 485f29dbc25Smrg if (flags & GFX_VGA_FLAG_STD_CRTC) { 486f29dbc25Smrg /* SAVE STANDARD CRTC REGISTERS */ 487f29dbc25Smrg 488f29dbc25Smrg for (i = 0; i < GFX_STD_CRTC_REGS; i++) { 48904007ebaSmrg OUTB(crtcindex, (unsigned char) i); 490f29dbc25Smrg vga->stdCRTCregs[i] = INB(crtcdata); 491f29dbc25Smrg } 492f29dbc25Smrg } 493f29dbc25Smrg 494f29dbc25Smrg /* CHECK EXTENDED CRTC FLAG */ 495f29dbc25Smrg 496f29dbc25Smrg if (flags & GFX_VGA_FLAG_EXT_CRTC) { 497f29dbc25Smrg /* SAVE EXTENDED CRTC REGISTERS */ 498f29dbc25Smrg 499f29dbc25Smrg for (i = 0; i < GFX_EXT_CRTC_REGS; i++) { 50004007ebaSmrg OUTB(crtcindex, (unsigned char) (0x40 + i)); 501f29dbc25Smrg vga->extCRTCregs[i] = INB(crtcdata); 502f29dbc25Smrg } 503f29dbc25Smrg } 504f29dbc25Smrg return (0); 505f29dbc25Smrg} 506f29dbc25Smrg 507f29dbc25Smrg/*---------------------------------------------------------------------------- 508f29dbc25Smrg * gfx_vga_clear_extended 509f29dbc25Smrg * 510f29dbc25Smrg * This routine clears the extended SoftVGA register values to have SoftVGA 511f29dbc25Smrg * behave like standard VGA. 512f29dbc25Smrg *---------------------------------------------------------------------------- 513f29dbc25Smrg */ 514f29dbc25Smrgvoid 515f29dbc25Smrggfx_vga_clear_extended(void) 516f29dbc25Smrg{ 517f29dbc25Smrg int i; 518f29dbc25Smrg unsigned short crtcindex, crtcdata; 519f29dbc25Smrg 520f29dbc25Smrg crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 521f29dbc25Smrg crtcdata = crtcindex + 1; 522f29dbc25Smrg 523f29dbc25Smrg OUTB(crtcindex, 0x30); 524f29dbc25Smrg OUTB(crtcdata, 0x57); 525f29dbc25Smrg OUTB(crtcdata, 0x4C); 526f29dbc25Smrg for (i = 0x40; i <= 0x4F; i++) { 52704007ebaSmrg OUTB(crtcindex, (unsigned char) i); 528f29dbc25Smrg OUTB(crtcdata, 0); 529f29dbc25Smrg } 530f29dbc25Smrg OUTB(crtcindex, 0x30); 531f29dbc25Smrg OUTB(crtcdata, 0x00); 532f29dbc25Smrg} 533f29dbc25Smrg 534f29dbc25Smrg/*---------------------------------------------------------------------------- 535f29dbc25Smrg * gfx_vga_restore 536f29dbc25Smrg * 537f29dbc25Smrg * This routine restores the state of the VGA registers from the specified 538f29dbc25Smrg * structure. Flags indicate what portions of the register state need to 539f29dbc25Smrg * be saved. 540f29dbc25Smrg *---------------------------------------------------------------------------- 541f29dbc25Smrg */ 542f29dbc25Smrgint 543f29dbc25Smrggfx_vga_restore(gfx_vga_struct * vga, int flags) 544f29dbc25Smrg{ 545f29dbc25Smrg int i; 546f29dbc25Smrg unsigned short crtcindex, crtcdata; 547f29dbc25Smrg 548f29dbc25Smrg crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 549f29dbc25Smrg crtcdata = crtcindex + 1; 550f29dbc25Smrg 551f29dbc25Smrg /* CHECK MISCELLANEOUS OUTPUT FLAG */ 552f29dbc25Smrg 553f29dbc25Smrg if (flags & GFX_VGA_FLAG_MISC_OUTPUT) { 554f29dbc25Smrg /* RESTORE MISCELLANEOUS OUTPUT REGISTER VALUE */ 555f29dbc25Smrg 556f29dbc25Smrg OUTB(0x3C2, vga->miscOutput); 557f29dbc25Smrg } 558f29dbc25Smrg 559f29dbc25Smrg /* CHECK STANDARD CRTC FLAG */ 560f29dbc25Smrg 561f29dbc25Smrg if (flags & GFX_VGA_FLAG_STD_CRTC) { 562f29dbc25Smrg /* UNLOCK STANDARD CRTC REGISTERS */ 563f29dbc25Smrg 564f29dbc25Smrg OUTB(crtcindex, 0x11); 565f29dbc25Smrg OUTB(crtcdata, 0); 566f29dbc25Smrg 567f29dbc25Smrg /* RESTORE STANDARD CRTC REGISTERS */ 568f29dbc25Smrg 569f29dbc25Smrg for (i = 0; i < GFX_STD_CRTC_REGS; i++) { 57004007ebaSmrg OUTB(crtcindex, (unsigned char) i); 571f29dbc25Smrg OUTB(crtcdata, vga->stdCRTCregs[i]); 572f29dbc25Smrg } 573f29dbc25Smrg } 574f29dbc25Smrg 575f29dbc25Smrg /* CHECK EXTENDED CRTC FLAG */ 576f29dbc25Smrg 577f29dbc25Smrg if (flags & GFX_VGA_FLAG_EXT_CRTC) { 578f29dbc25Smrg /* UNLOCK EXTENDED CRTC REGISTERS */ 579f29dbc25Smrg 580f29dbc25Smrg OUTB(crtcindex, 0x30); 581f29dbc25Smrg OUTB(crtcdata, 0x57); 582f29dbc25Smrg OUTB(crtcdata, 0x4C); 583f29dbc25Smrg 584f29dbc25Smrg /* RESTORE EXTENDED CRTC REGISTERS */ 585f29dbc25Smrg 586f29dbc25Smrg for (i = 0; i < GFX_EXT_CRTC_REGS; i++) { 58704007ebaSmrg OUTB(crtcindex, (unsigned char) (0x40 + i)); 588f29dbc25Smrg OUTB(crtcdata, vga->extCRTCregs[i]); 589f29dbc25Smrg } 590f29dbc25Smrg 591f29dbc25Smrg /* LOCK EXTENDED CRTC REGISTERS */ 592f29dbc25Smrg 593f29dbc25Smrg OUTB(crtcindex, 0x30); 594f29dbc25Smrg OUTB(crtcdata, 0x00); 595f29dbc25Smrg 596f29dbc25Smrg /* CHECK IF DIRECT FRAME BUFFER MODE (VESA MODE) */ 597f29dbc25Smrg 598f29dbc25Smrg if (vga->extCRTCregs[0x03] & 1) { 599f29dbc25Smrg /* SET BORDER COLOR TO BLACK */ 600f29dbc25Smrg /* This really should be another thing saved/restored, but */ 601f29dbc25Smrg /* Durango currently doesn't do the attr controller registers. */ 602f29dbc25Smrg 60304007ebaSmrg INB(0x3BA); /* Reset flip-flop */ 604f29dbc25Smrg INB(0x3DA); 605f29dbc25Smrg OUTB(0x3C0, 0x11); 606f29dbc25Smrg OUTB(0x3C0, 0x00); 607f29dbc25Smrg } 608f29dbc25Smrg } 609f29dbc25Smrg return (0); 610f29dbc25Smrg} 611f29dbc25Smrg 612f29dbc25Smrg/*---------------------------------------------------------------------------- 613f29dbc25Smrg * gfx_vga_mode_switch 614f29dbc25Smrg * 615f29dbc25Smrg * This routine programs the SoftVGA register to indicate that a mode switch 616f29dbc25Smrg * is in progress. This results in a cleaner mode switch since SoftVGA will 617f29dbc25Smrg * not validate the hardware with intermediate values. 618f29dbc25Smrg *---------------------------------------------------------------------------- 619f29dbc25Smrg */ 620f29dbc25Smrgint 621f29dbc25Smrggfx_vga_mode_switch(int active) 622f29dbc25Smrg{ 623f29dbc25Smrg unsigned short crtcindex, crtcdata; 624f29dbc25Smrg 625f29dbc25Smrg crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 626f29dbc25Smrg crtcdata = crtcindex + 1; 627f29dbc25Smrg 628f29dbc25Smrg /* UNLOCK EXTENDED CRTC REGISTERS */ 629f29dbc25Smrg 630f29dbc25Smrg OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK); 631f29dbc25Smrg OUTB(crtcdata, 0x57); 632f29dbc25Smrg OUTB(crtcdata, 0x4C); 633f29dbc25Smrg 634f29dbc25Smrg /* SIGNAL THE BEGINNING OR END OF THE MODE SWITCH */ 635f29dbc25Smrg /* SoftVGA will hold off validating the back end hardware. */ 636f29dbc25Smrg 637f29dbc25Smrg OUTB(crtcindex, CRTC_MODE_SWITCH_CONTROL); 638f29dbc25Smrg active = active ? 1 : 0; 63904007ebaSmrg OUTB(crtcdata, (unsigned char) active); 640f29dbc25Smrg 641f29dbc25Smrg /* WAIT UNTIL SOFTVGA HAS VALIDATED MODE IF ENDING MODE SWITCH */ 642f29dbc25Smrg /* This is for VSA1 only, where SoftVGA waits until the next */ 643f29dbc25Smrg /* vertical blank to validate the hardware state. */ 644f29dbc25Smrg 645f29dbc25Smrg if ((!active) && (!(gu1_detect_vsa2()))) { 646f29dbc25Smrg OUTB(crtcindex, 0x33); 64704007ebaSmrg while (INB(crtcdata) & 0x80); 648f29dbc25Smrg } 649f29dbc25Smrg 650f29dbc25Smrg /* LOCK EXTENDED CRTC REGISTERS */ 651f29dbc25Smrg 652f29dbc25Smrg OUTB(crtcindex, CRTC_EXTENDED_REGISTER_LOCK); 653f29dbc25Smrg OUTB(crtcdata, 0x00); 654f29dbc25Smrg return (0); 655f29dbc25Smrg} 656f29dbc25Smrg 657f29dbc25Smrg/*---------------------------------------------------------------------------- 658f29dbc25Smrg * gu1_detect_vsa2 659f29dbc25Smrg * 660f29dbc25Smrg * This routine detects if VSA2 is present. The interface to SoftVGA 661f29dbc25Smrg * changed slightly. 662f29dbc25Smrg *---------------------------------------------------------------------------- 663f29dbc25Smrg */ 664f29dbc25Smrgint 665f29dbc25Smrggu1_detect_vsa2(void) 666f29dbc25Smrg{ 667f29dbc25Smrg unsigned short crtcindex, crtcdata; 668f29dbc25Smrg 669f29dbc25Smrg crtcindex = (INB(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 670f29dbc25Smrg crtcdata = crtcindex + 1; 671f29dbc25Smrg OUTB(crtcindex, 0x35); 672f29dbc25Smrg if (INB(crtcdata) != 'C') 673f29dbc25Smrg return (0); 674f29dbc25Smrg OUTB(crtcindex, 0x36); 675f29dbc25Smrg if (INB(crtcdata) != 'X') 676f29dbc25Smrg return (0); 677f29dbc25Smrg return (1); 678f29dbc25Smrg} 679f29dbc25Smrg 680f29dbc25Smrg/* END OF FILE */ 681