1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx2_vga.c,v 1.2tsi Exp $ */ 2/* 3 * $Workfile: nsc_gx2_vga.c $ 4 * $Revision: 1.1.1.1 $ 5 * $Author: mrg $ 6 * 7 * This file contains routines to set modes using the VGA registers. 8 * Since this file is for the first generation graphics unit, it interfaces 9 * to SoftVGA registers. It works for both VSA1 and VSA2. 10 * 11 * NSC_LIC_ALTERNATIVE_PREAMBLE 12 * 13 * Revision 1.0 14 * 15 * National Semiconductor Alternative GPL-BSD License 16 * 17 * National Semiconductor Corporation licenses this software 18 * ("Software"): 19 * 20 * nsc XFree86 21 * 22 * under one of the two following licenses, depending on how the 23 * Software is received by the Licensee. 24 * 25 * If this Software is received as part of the Linux Framebuffer or 26 * other GPL licensed software, then the GPL license designated 27 * NSC_LIC_GPL applies to this Software; in all other circumstances 28 * then the BSD-style license designated NSC_LIC_BSD shall apply. 29 * 30 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 31 32/* NSC_LIC_BSD 33 * 34 * National Semiconductor Corporation Open Source License for Durango 35 * 36 * (BSD License with Export Notice) 37 * 38 * Copyright (c) 1999-2001 39 * National Semiconductor Corporation. 40 * All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 46 * * Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 49 * * Redistributions in binary form must reproduce the above 50 * copyright notice, this list of conditions and the following 51 * disclaimer in the documentation and/or other materials provided 52 * with the distribution. 53 * 54 * * Neither the name of the National Semiconductor Corporation nor 55 * the names of its contributors may be used to endorse or promote 56 * products derived from this software without specific prior 57 * written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 60 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 61 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 62 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 63 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 64 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 66 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 67 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 68 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 69 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 71 * OF SUCH DAMAGE. 72 * 73 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 74 * YOUR JURISDICTION. It is licensee's responsibility to comply with 75 * any export regulations applicable in licensee's jurisdiction. Under 76 * CURRENT (2001) U.S. export regulations this software 77 * is eligible for export from the U.S. and can be downloaded by or 78 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 79 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 80 * Syria, Sudan, Afghanistan and any other country to which the U.S. 81 * has embargoed goods and services. 82 * 83 * END_NSC_LIC_BSD */ 84 85/* NSC_LIC_GPL 86 * 87 * National Semiconductor Corporation Gnu General Public License for Durango 88 * 89 * (GPL License with Export Notice) 90 * 91 * Copyright (c) 1999-2001 92 * National Semiconductor Corporation. 93 * All rights reserved. 94 * 95 * Redistribution and use in source and binary forms, with or without 96 * modification, are permitted under the terms of the GNU General 97 * Public License as published by the Free Software Foundation; either 98 * version 2 of the License, or (at your option) any later version 99 * 100 * In addition to the terms of the GNU General Public License, neither 101 * the name of the National Semiconductor Corporation nor the names of 102 * its contributors may be used to endorse or promote products derived 103 * from this software without specific prior written permission. 104 * 105 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 106 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 107 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 108 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 109 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 110 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 111 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 112 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 113 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 114 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 115 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 116 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 117 * OF SUCH DAMAGE. See the GNU General Public License for more details. 118 * 119 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 120 * YOUR JURISDICTION. It is licensee's responsibility to comply with 121 * any export regulations applicable in licensee's jurisdiction. Under 122 * CURRENT (2001) U.S. export regulations this software 123 * is eligible for export from the U.S. and can be downloaded by or 124 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 125 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 126 * Syria, Sudan, Afghanistan and any other country to which the U.S. 127 * has embargoed goods and services. 128 * 129 * You should have received a copy of the GNU General Public License 130 * along with this file; if not, write to the Free Software Foundation, 131 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 132 * 133 * END_NSC_LIC_GPL */ 134 135#ifdef HAVE_CONFIG_H 136#include "config.h" 137#endif 138 139/* VGA STRUCTURE */ 140 141#define GU2_STD_CRTC_REGS 25 142#define GU2_EXT_CRTC_REGS 15 143#define GU2_GDC_REGS 9 144#define GU2_SEQ_REGS 5 145 146#define GU2_VGA_FLAG_MISC_OUTPUT 0x1 147#define GU2_VGA_FLAG_STD_CRTC 0x2 148#define GU2_VGA_FLAG_EXT_CRTC 0x4 149#define GU2_VGA_FLAG_GDC 0x10 150#define GU2_VGA_FLAG_SEQ 0x20 151#define GU2_VGA_FLAG_PALETTE 0x40 152#define GU2_VGA_FLAG_ATTR 0x80 153 154static unsigned int GDCregs[10]; 155static unsigned int SEQregs[10]; 156static unsigned int palette[256]; 157static unsigned int ATTRregs[32]; 158static unsigned char *font_data = NULL; 159 160#define VGA_BLOCK 0x40000 /* 256 k */ 161 162void gu2_vga_extcrtc(char offset, int reset); 163int gu2_get_vga_active(void); 164void gu2_vga_font_data(int flag); 165void gu2_set_vga(int reset); 166int gu2_vga_seq_blanking(void); 167int gu2_vga_attr_ctrl(int reset); 168void gu2_vga_to_gfx(void); 169void gu2_gfx_to_vga(int vga_mode); 170int gu2_vga_seq_reset(int reset); 171int gu2_vga_save(gfx_vga_struct * vga, int flags); 172void gu2_vga_clear_extended(void); 173int gu2_vga_restore(gfx_vga_struct * vga, int flags); 174 175int 176gu2_get_vga_active(void) 177{ 178 int data = gfx_read_reg32(MDC_GENERAL_CFG); 179 180 if (data & MDC_GCFG_VGAE) 181 return 1; 182 return 0; 183} 184 185void 186gu2_vga_font_data(int flag) 187{ 188 if (flag == 0) { 189 if (font_data == NULL) { 190 font_data = malloc(VGA_BLOCK); 191 } 192 DEBUGMSG(1, (0, X_NONE, "Saving VGA Data\n")); 193 memcpy(font_data, gfx_virt_fbptr, VGA_BLOCK); 194 } else { 195 if (font_data) { 196 DEBUGMSG(1, (0, X_NONE, "Restore VGA Data\n")); 197 memcpy(gfx_virt_fbptr, font_data, VGA_BLOCK); 198 free(font_data); 199 font_data = NULL; 200 } 201 } 202} 203 204void 205gu2_set_vga(int reset) 206{ 207 int data = gfx_read_reg32(MDC_GENERAL_CFG); 208 209 if (reset) 210 data |= MDC_GCFG_VGAE; 211 else 212 data &= ~MDC_GCFG_VGAE; 213 gfx_write_reg32(MDC_GENERAL_CFG, data); 214} 215 216int 217gu2_vga_seq_blanking(void) 218{ 219 int tmp; 220 221 gfx_outb(0x3C4, 1); 222 tmp = gfx_inb(0x3C5); 223 tmp |= 0x20; 224 tmp |= tmp << 8; 225 gfx_outw(0x3C4, tmp); 226 227 gfx_delay_milliseconds(1); 228 return (GFX_STATUS_OK); 229} 230 231int 232gu2_vga_attr_ctrl(int reset) 233{ 234 (void) gfx_inb(0x3DA); 235 gfx_outb(0x3C0, (unsigned char)(reset ? 0x00 : 0x20)); 236 if (reset) 237 (void) gfx_inb(0x3DA); 238 return (GFX_STATUS_OK); 239} 240 241void 242gu2_vga_to_gfx(void) 243{ 244 gu2_vga_attr_ctrl(0); 245 246 gu2_vga_seq_blanking(); 247 gfx_delay_milliseconds(2); 248 249 gu2_vga_extcrtc(0x3F, 1); 250} 251 252void 253gu2_gfx_to_vga(int vga_mode) 254{ 255 char sequencer; 256 257 gu2_vga_extcrtc(0x40, vga_mode); 258 259 /* clear the display blanking bit */ 260 gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); 261 sequencer = gfx_inb(MDC_SEQUENCER_DATA); 262 sequencer &= ~MDC_CLK_MODE_SCREEN_OFF; 263 sequencer |= 1; 264 gfx_outb(MDC_SEQUENCER_DATA, sequencer); 265 266 gfx_delay_milliseconds(1); 267 268 /*restart the sequencer */ 269 gfx_outw(0x3C4, 0x300); 270 271 /* turn on the attribute controler */ 272 (void) gfx_inb(0x3DA); 273 gfx_outb(0x3C0, 0x20); 274 (void) gfx_inb(0x3DA); 275 276 gu2_vga_extcrtc(0x3F, 0); 277} 278 279/*----------------------------------------------------------------------------- 280 * gfx_vga_seq_reset 281 * 282 * This routine enables or disables SoftVGA. It is used to make SoftVGA 283 * "be quiet" and not interfere with any of the direct hardware access from 284 * Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may 285 * provide a better way to have SoftVGA sit in the background. 286 *----------------------------------------------------------------------------- 287 */ 288int 289gu2_vga_seq_reset(int reset) 290{ 291 gfx_outb(0x3C4, 0); 292 gfx_outb(0x3C5, (unsigned char)(reset ? 0x00 : 0x03)); 293 return (GFX_STATUS_OK); 294} 295 296/*----------------------------------------------------------------------------- 297 * gfx_vga_save 298 * 299 * This routine saves the state of the VGA registers into the specified 300 * structure. Flags indicate what portions of the register state need to 301 * be saved. 302 *----------------------------------------------------------------------------- 303 */ 304int 305gu2_vga_save(gfx_vga_struct * vga, int flags) 306{ 307 int i; 308 unsigned short crtcindex, crtcdata; 309 310 crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 311 crtcdata = crtcindex + 1; 312 313 /* CHECK MISCELLANEOUS OUTPUT FLAG */ 314 315 if (flags & GU2_VGA_FLAG_MISC_OUTPUT) { 316 /* SAVE MISCCELLANEOUS OUTPUT REGISTER */ 317 318 vga->miscOutput = gfx_inb(0x3CC); 319 } 320 321 /* CHECK SEQ */ 322 323 if (flags & GU2_VGA_FLAG_SEQ) { 324 /* SAVE STANDARD CRTC REGISTERS */ 325 326 for (i = 1; i < GU2_SEQ_REGS; i++) { 327 gfx_outb(0x3C4, (unsigned char)i); 328 SEQregs[i] = gfx_inb(0x3C5); 329 } 330 } 331 332 /* CHECK STANDARD CRTC FLAG */ 333 334 if (flags & GU2_VGA_FLAG_STD_CRTC) { 335 /* SAVE STANDARD CRTC REGISTERS */ 336 337 for (i = 0; i < GU2_STD_CRTC_REGS; i++) { 338 gfx_outb(crtcindex, (unsigned char)i); 339 vga->stdCRTCregs[i] = gfx_inb(crtcdata); 340 } 341 } 342 343 /* CHECK GDC */ 344 345 if (flags & GU2_VGA_FLAG_GDC) { 346 /* SAVE STANDARD CRTC REGISTERS */ 347 348 for (i = 0; i < GU2_GDC_REGS; i++) { 349 gfx_outb(0x3CE, (unsigned char)i); 350 GDCregs[i] = gfx_inb(0x3CF); 351 } 352 } 353 354 /* CHECK EXTENDED CRTC FLAG */ 355 356 if (flags & GU2_VGA_FLAG_EXT_CRTC) { 357 /* SAVE EXTENDED CRTC REGISTERS */ 358 359 for (i = 0; i < GU2_EXT_CRTC_REGS; i++) { 360 gfx_outb(crtcindex, (unsigned char)(0x40 + i)); 361 vga->extCRTCregs[i] = gfx_inb(crtcdata); 362 } 363 } 364 365 if (flags & GU2_VGA_FLAG_PALETTE) { 366 /* SAVE PALETTE DATA */ 367 368 for (i = 0; i < 0x100; i++) { 369 gfx_outb(0x3C7, i); 370 palette[i] = gfx_inb(0x3C9); 371 } 372 } 373 374 if (flags & GU2_VGA_FLAG_ATTR) { 375 /* SAVE Attribute DATA */ 376 377 for (i = 0; i < 21; i++) { 378 gfx_inb(0x3DA); 379 gfx_outb(0x3C0, i); 380 ATTRregs[i] = gfx_inb(0x3C1); 381 } 382 } 383 /* save the VGA data */ 384 gu2_vga_font_data(0); 385 return (0); 386} 387 388/*----------------------------------------------------------------------------- 389 * gfx_vga_clear_extended 390 * 391 * This routine clears the extended SoftVGA register values to have SoftVGA 392 * behave like standard VGA. 393 *----------------------------------------------------------------------------- 394 */ 395void 396gu2_vga_clear_extended(void) 397{ 398 int i; 399 unsigned short crtcindex, crtcdata; 400 401 crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 402 crtcdata = crtcindex + 1; 403 404 gfx_outb(crtcindex, 0x30); 405 gfx_outb(crtcdata, 0x57); 406 gfx_outb(crtcdata, 0x4C); 407 for (i = 0x41; i <= 0x4F; i++) { 408 gfx_outb(crtcindex, (unsigned char)i); 409 gfx_outb(crtcdata, 0); 410 } 411 gfx_outb(crtcindex, 0x30); 412 gfx_outb(crtcdata, 0x00); 413} 414 415void 416gu2_vga_extcrtc(char offset, int reset) 417{ 418 unsigned short crtcindex, crtcdata; 419 420 crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 421 crtcdata = crtcindex + 1; 422 423 /* UNLOCK EXTENDED CRTC REGISTERS */ 424 425 gfx_outb(crtcindex, 0x30); 426 gfx_outb(crtcdata, 0x57); 427 gfx_outb(crtcdata, 0x4C); 428 429 /* RESTORE EXTENDED CRTC REGISTERS */ 430 431 gfx_outb(crtcindex, offset); 432 gfx_outb(crtcdata, reset); 433 434#if 0 435 /* LOCK EXTENDED CRTC REGISTERS */ 436 437 gfx_outb(crtcindex, 0x30); 438 gfx_outb(crtcdata, 0x00); 439#endif 440} 441 442/*----------------------------------------------------------------------------- 443 * gfx_vga_restore 444 * 445 * This routine restores the state of the VGA registers from the specified 446 * structure. Flags indicate what portions of the register state need to 447 * be saved. 448 *----------------------------------------------------------------------------- 449 */ 450int 451gu2_vga_restore(gfx_vga_struct * vga, int flags) 452{ 453 int i; 454 unsigned short crtcindex, crtcdata; 455 456 crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4; 457 crtcdata = crtcindex + 1; 458 459 /* CHECK MISCELLANEOUS OUTPUT FLAG */ 460 461 if (flags & GU2_VGA_FLAG_MISC_OUTPUT) { 462 /* RESTORE MISCELLANEOUS OUTPUT REGISTER VALUE */ 463 464 gfx_outb(0x3C2, vga->miscOutput); 465 } 466 467 /* CHECK SEQ */ 468 469 if (flags & GU2_VGA_FLAG_SEQ) { 470 /* RESTORE STANDARD CRTC REGISTERS */ 471 472 for (i = 1; i < GU2_SEQ_REGS; i++) { 473 gfx_outb(0x3C4, (unsigned char)i); 474 gfx_outb(0x3C5, SEQregs[i]); 475 } 476 } 477 478 /* CHECK STANDARD CRTC FLAG */ 479 480 if (flags & GU2_VGA_FLAG_STD_CRTC) { 481 /* UNLOCK STANDARD CRTC REGISTERS */ 482 483 gfx_outb(crtcindex, 0x11); 484 gfx_outb(crtcdata, 0); 485 486 /* RESTORE STANDARD CRTC REGISTERS */ 487 488 for (i = 0; i < GU2_STD_CRTC_REGS; i++) { 489 gfx_outb(crtcindex, (unsigned char)i); 490 gfx_outb(crtcdata, vga->stdCRTCregs[i]); 491 } 492 } 493 494 /* CHECK GDC */ 495 496 if (flags & GU2_VGA_FLAG_GDC) { 497 /* SAVE STANDARD CRTC REGISTERS */ 498 499 for (i = 0; i < GU2_GDC_REGS; i++) { 500 gfx_outb(0x3CE, (unsigned char)i); 501 gfx_outb(0x3CF, GDCregs[i]); 502 } 503 } 504 505 /* CHECK EXTENDED CRTC FLAG */ 506 507 if (flags & GU2_VGA_FLAG_EXT_CRTC) { 508 /* UNLOCK EXTENDED CRTC REGISTERS */ 509 510 gfx_outb(crtcindex, 0x30); 511 gfx_outb(crtcdata, 0x57); 512 gfx_outb(crtcdata, 0x4C); 513 514 /* RESTORE EXTENDED CRTC REGISTERS */ 515 516 for (i = 1; i < GU2_EXT_CRTC_REGS; i++) { 517 gfx_outb(crtcindex, (unsigned char)(0x40 + i)); 518 gfx_outb(crtcdata, vga->extCRTCregs[i]); 519 } 520 521 /* LOCK EXTENDED CRTC REGISTERS */ 522 523 gfx_outb(crtcindex, 0x30); 524 gfx_outb(crtcdata, 0x00); 525 526 /* CHECK IF DIRECT FRAME BUFFER MODE (VESA MODE) */ 527 528 if (vga->extCRTCregs[0x03] & 1) { 529 /* SET BORDER COLOR TO BLACK */ 530 /* This really should be another thing saved/restored, but */ 531 /* Durango currently doesn't do the attr controller registers. */ 532 533 gfx_inb(0x3BA); /* Reset flip-flop */ 534 gfx_inb(0x3DA); 535 gfx_outb(0x3C0, 0x11); 536 gfx_outb(0x3C0, 0x00); 537 } 538 } 539 540 if (flags & GU2_VGA_FLAG_PALETTE) { 541 /* RESTORE PALETTE DATA */ 542 543 for (i = 0; i < 0x100; i++) { 544 gfx_outb(0x3C8, i); 545 gfx_outb(0x3C9, palette[i]); 546 } 547 } 548 549 if (flags & GU2_VGA_FLAG_ATTR) { 550 /* RESTORE Attribute DATA */ 551 552 for (i = 0; i < 21; i++) { 553 gfx_inb(0x3DA); 554 gfx_outb(0x3C0, i); 555 gfx_outb(0x3C0, ATTRregs[i]); 556 } 557 /* SAVE Attribute DATA */ 558 559 for (i = 0; i < 21; i++) { 560 gfx_inb(0x3DA); 561 gfx_outb(0x3C0, i); 562 } 563 } 564 565 /* restore the VGA data */ 566 gu2_vga_font_data(1); 567 568 return (0); 569} 570 571/* END OF FILE */ 572