vga_gu1.c revision f29dbc25
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 { 63f29dbc25Smrg 640, 480, 60, /* 640x480 */ 64f29dbc25Smrg 25, /* 25 MHz clock = 60 Hz refresh rate */ 65f29dbc25Smrg 0xE3, /* miscOutput register */ 66f29dbc25Smrg { 67f29dbc25Smrg 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 68f29dbc25Smrg /* standard CRTC */ 69f29dbc25Smrg 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70f29dbc25Smrg 0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF}, 71f29dbc25Smrg { 72f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 73f29dbc25Smrg /* extended CRTC */ 74f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00} 75f29dbc25Smrg }, 76f29dbc25Smrg/*--------------------------------------------------------------------------*/ 77f29dbc25Smrg { 78f29dbc25Smrg 640, 480, 72, /* 640x480 */ 79f29dbc25Smrg 29, /* 29 MHz clock = 72 Hz refresh rate */ 80f29dbc25Smrg 0xE3, /* miscOutput register */ 81f29dbc25Smrg { 82f29dbc25Smrg 0x63, 0x4f, 0x50, 0x86, 0x55, 0x99, 0x06, 0x3e, 83f29dbc25Smrg /* standard CRTC */ 84f29dbc25Smrg 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85f29dbc25Smrg 0xe9, 0x0c, 0xdf, 0x00, 0x00, 0xe7, 0x00, 0xe3, 0xff}, 86f29dbc25Smrg { 87f29dbc25Smrg 0x6D, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 88f29dbc25Smrg /* extended CRTC */ 89f29dbc25Smrg 0x00, 0x00, 0x01, 0x08, 0x80, 0x1F, 0x00, 0x4B} 90f29dbc25Smrg }, 91f29dbc25Smrg/*--------------------------------------------------------------------------*/ 92f29dbc25Smrg { 93f29dbc25Smrg 640, 480, 75, /* 640x480 */ 94f29dbc25Smrg 31, 95f29dbc25Smrg /* 31.5 MHz clock = 75 Hz refresh rate */ 96f29dbc25Smrg 0xE3, /* miscOutput register */ 97f29dbc25Smrg { 98f29dbc25Smrg 0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, 99f29dbc25Smrg /* standard CRTC */ 100f29dbc25Smrg 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101f29dbc25Smrg 0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF}, 102f29dbc25Smrg { 103f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 104f29dbc25Smrg /* extended CRTC */ 105f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x1F, 0x00, 0x00} 106f29dbc25Smrg }, 107f29dbc25Smrg/*--------------------------------------------------------------------------*/ 108f29dbc25Smrg { 109f29dbc25Smrg 800, 600, 60, /* 800x600 */ 110f29dbc25Smrg 40, /* 40 MHz clock = 60 Hz refresh rate */ 111f29dbc25Smrg 0x23, /* miscOutput register */ 112f29dbc25Smrg { 113f29dbc25Smrg 0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, 114f29dbc25Smrg /* standard CRTC */ 115f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116f29dbc25Smrg 0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF}, 117f29dbc25Smrg { 118f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 119f29dbc25Smrg /* extended CRTC */ 120f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x28, 0x00, 0x00} 121f29dbc25Smrg }, 122f29dbc25Smrg/*--------------------------------------------------------------------------*/ 123f29dbc25Smrg { 124f29dbc25Smrg 800, 600, 72, /* 800x600 */ 125f29dbc25Smrg 47, /* 47 MHz clock = 72 Hz refresh rate */ 126f29dbc25Smrg 0x2B, /* miscOutput register */ 127f29dbc25Smrg { 128f29dbc25Smrg 0x7D, 0x63, 0x63, 0x81, 0x6D, 0x1B, 0x98, 0xF0, 129f29dbc25Smrg /* standard CRTC */ 130f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131f29dbc25Smrg 0x7D, 0x03, 0x57, 0x00, 0x00, 0x57, 0x9A, 0xE3, 0xFF}, 132f29dbc25Smrg { 133f29dbc25Smrg 0x6F, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 134f29dbc25Smrg /* extended CRTC */ 135f29dbc25Smrg 0x00, 0x00, 0x01, 0x08, 0x80, 0x32, 0x00, 0x4B} 136f29dbc25Smrg }, 137f29dbc25Smrg/*--------------------------------------------------------------------------*/ 138f29dbc25Smrg { 139f29dbc25Smrg 800, 600, 75, /* 800x600 */ 140f29dbc25Smrg 49, 141f29dbc25Smrg /* 49.5 MHz clock = 75 Hz refresh rate */ 142f29dbc25Smrg 0x23, /* miscOutput register */ 143f29dbc25Smrg { 144f29dbc25Smrg 0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, 145f29dbc25Smrg /* standard CRTC */ 146f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147f29dbc25Smrg 0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF}, 148f29dbc25Smrg { 149f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 150f29dbc25Smrg /* extended CRTC */ 151f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x31, 0x00, 0x00} 152f29dbc25Smrg }, 153f29dbc25Smrg/*--------------------------------------------------------------------------*/ 154f29dbc25Smrg { 155f29dbc25Smrg 1024, 768, 60, /* 1024x768 */ 156f29dbc25Smrg 65, /* 65 MHz clock = 60 Hz refresh rate */ 157f29dbc25Smrg 0xE3, /* miscOutput register */ 158f29dbc25Smrg { 159f29dbc25Smrg 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, 160f29dbc25Smrg /* standard CRTC */ 161f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 162f29dbc25Smrg 0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF}, 163f29dbc25Smrg { 164f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 165f29dbc25Smrg /* extended CRTC */ 166f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00} 167f29dbc25Smrg }, 168f29dbc25Smrg/*--------------------------------------------------------------------------*/ 169f29dbc25Smrg { 170f29dbc25Smrg 1024, 768, 70, /* 1024x768 */ 171f29dbc25Smrg 76, /* 76 MHz clock = 70 Hz refresh rate */ 172f29dbc25Smrg 0x2B, /* miscOutput register */ 173f29dbc25Smrg { 174f29dbc25Smrg 0xA1, 0x7F, 0x7F, 0x85, 0x85, 0x95, 0x24, 0xF5, 175f29dbc25Smrg /* standard CRTC */ 176f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 177f29dbc25Smrg 0x03, 0x09, 0xFF, 0x00, 0x00, 0xFF, 0x26, 0xE3, 0xFF}, 178f29dbc25Smrg { 179f29dbc25Smrg 0x62, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x00, 180f29dbc25Smrg /* extended CRTC */ 181f29dbc25Smrg 0x00, 0x00, 0x01, 0x02, 0x80, 0x4B, 0x00, 0x4B} 182f29dbc25Smrg }, 183f29dbc25Smrg/*--------------------------------------------------------------------------*/ 184f29dbc25Smrg { 185f29dbc25Smrg 1024, 768, 75, /* 1024x768 */ 186f29dbc25Smrg 79, /* 79 MHz clock = 75 Hz refresh rate */ 187f29dbc25Smrg 0xE3, /* miscOutput register */ 188f29dbc25Smrg { 189f29dbc25Smrg 0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, 190f29dbc25Smrg /* standard CRTC */ 191f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192f29dbc25Smrg 0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF}, 193f29dbc25Smrg { 194f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 195f29dbc25Smrg /* extended CRTC */ 196f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x4F, 0x00, 0x00} 197f29dbc25Smrg }, 198f29dbc25Smrg/*--------------------------------------------------------------------------*/ 199f29dbc25Smrg { 200f29dbc25Smrg 1280, 1024, 60, /* 1280x1024 */ 201f29dbc25Smrg 108, 202f29dbc25Smrg /* 108 MHz clock = 60 Hz refresh rate */ 203f29dbc25Smrg 0x23, /* miscOutput register */ 204f29dbc25Smrg { 205f29dbc25Smrg 0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, 206f29dbc25Smrg /* standard CRTC */ 207f29dbc25Smrg 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 208f29dbc25Smrg 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, 209f29dbc25Smrg { 210f29dbc25Smrg 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 211f29dbc25Smrg /* extended CRTC */ 212f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x6C, 0x00, 0x00} 213f29dbc25Smrg }, 214f29dbc25Smrg/*--------------------------------------------------------------------------*/ 215f29dbc25Smrg { 216f29dbc25Smrg 1280, 1024, 75, /* 1280x1024 */ 217f29dbc25Smrg 135, 218f29dbc25Smrg /* 135 MHz clock = 75 Hz refresh rate */ 219f29dbc25Smrg 0x23, /* miscOutput register */ 220f29dbc25Smrg { 221f29dbc25Smrg 0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, 222f29dbc25Smrg /* standard CRTC */ 223f29dbc25Smrg 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224f29dbc25Smrg 0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF}, 225f29dbc25Smrg { 226f29dbc25Smrg 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 227f29dbc25Smrg /* extended CRTC */ 228f29dbc25Smrg 0x00, 0x00, 0x00, 0x03, 0x80, 0x87, 0x00, 0x00} 229f29dbc25Smrg }, 230f29dbc25Smrg/*--------------------------------------------------------------------------*/ 231f29dbc25Smrg { 232f29dbc25Smrg 1280, 1024, 85, /* 1280x1024 */ 233f29dbc25Smrg 159, 234f29dbc25Smrg /* 159 MHz clock = 85 Hz refresh rate */ 235f29dbc25Smrg 0x2B, /* miscOutput register */ 236f29dbc25Smrg { 237f29dbc25Smrg 0xD3, 0x9F, 0xA0, 0x98, 0xA8, 0x9C, 0x2E, 0x5A, 238f29dbc25Smrg /* standard CRTC */ 239f29dbc25Smrg 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240f29dbc25Smrg 0x01, 0x04, 0xFF, 0x00, 0x00, 0xFF, 0x30, 0xE3, 0xFF}, 241f29dbc25Smrg { 242f29dbc25Smrg 0x6B, 0x41, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 243f29dbc25Smrg /* extended CRTC */ 244f29dbc25Smrg 0x00, 0x00, 0x01, 0x00, 0x80, 0x9D, 0x00, 0x4B} 245f29dbc25Smrg }, 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); 317f29dbc25Smrg 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; 336f29dbc25Smrg 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); 354f29dbc25Smrg 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 380f29dbc25Smrg 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 412f29dbc25Smrg 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; 419f29dbc25Smrg vga->stdCRTCregs[0x13] = (unsigned char)pitch; 420f29dbc25Smrg 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; 453f29dbc25Smrg vga->stdCRTCregs[0x13] = (unsigned char)pitch; 454f29dbc25Smrg 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++) { 489f29dbc25Smrg 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++) { 500f29dbc25Smrg 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++) { 527f29dbc25Smrg 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++) { 570f29dbc25Smrg 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++) { 587f29dbc25Smrg 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 603f29dbc25Smrg 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; 639f29dbc25Smrg 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); 647f29dbc25Smrg 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