ct_driver.c revision 8e91ec4d
1/* 2 * Copyright 1993 by Jon Block <block@frc.com> 3 * Modified by Mike Hollick <hollick@graphics.cis.upenn.edu> 4 * Modified 1994 by Régis Cridlig <cridlig@dmi.ens.fr> 5 * 6 * Major Contributors to XFree86 3.2 7 * Modified 1995/6 by Nozomi Ytow 8 * Modified 1996 by Egbert Eich <eich@xfree86.org> 9 * Modified 1996 by David Bateman <dbateman@club-internet.fr> 10 * Modified 1996 by Xavier Ducoin <xavier@rd.lectra.fr> 11 * 12 * Contributors to XFree86 3.2 13 * Modified 1995/6 by Ken Raeburn <raeburn@raeburn.org> 14 * Modified 1996 by Shigehiro Nomura <nomura@sm.sony.co.jp> 15 * Modified 1996 by Marc de Courville <marc@courville.org> 16 * Modified 1996 by Adam Sulmicki <adam@cfar.umd.edu> 17 * Modified 1996 by Jens Maurer <jmaurer@cck.uni-kl.de> 18 * 19 * Large parts rewritten for XFree86 4.0 20 * Modified 1998 by David Bateman <dbateman@club-internet.fr> 21 * Modified 1998 by Egbert Eich <eich@xfree86.org> 22 * Modified 1998 by Nozomi Ytow 23 * 24 * Permission to use, copy, modify, distribute, and sell this software and its 25 * documentation for any purpose is hereby granted without fee, provided that 26 * the above copyright notice appear in all copies and that both that 27 * copyright notice and this permission notice appear in supporting 28 * documentation, and that the name of the authors not be used in 29 * advertising or publicity pertaining to distribution of the software without 30 * specific, written prior permission. The authors makes no representations 31 * about the suitability of this software for any purpose. It is provided 32 * "as is" without express or implied warranty. 33 * 34 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 35 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 36 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 37 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 38 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 39 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 40 * PERFORMANCE OF THIS SOFTWARE. 41 */ 42/* 43 * Copyright 1997 44 * Digital Equipment Corporation. All rights reserved. 45 * This software is furnished under license and may be used and copied only in 46 * accordance with the following terms and conditions. Subject to these 47 * conditions, you may download, copy, install, use, modify and distribute 48 * this software in source and/or binary form. No title or ownership is 49 * transferred hereby. 50 * 1) Any source code used, modified or distributed must reproduce and retain 51 * this copyright notice and list of conditions as they appear in the 52 * source file. 53 * 54 * 2) No right is granted to use any trade name, trademark, or logo of Digital 55 * Equipment Corporation. Neither the "Digital Equipment Corporation" name 56 * nor any trademark or logo of Digital Equipment Corporation may be used 57 * to endorse or promote products derived from this software without the 58 * prior written permission of Digital Equipment Corporation. 59 * 60 * 3) This software is provided "AS-IS" and any express or implied warranties, 61 * including but not limited to, any implied warranties of merchantability, 62 * fitness for a particular purpose, or non-infringement are disclaimed. In 63 * no event shall DIGITAL be liable for any damages whatsoever, and in 64 * particular, DIGITAL shall not be liable for special, indirect, 65 * consequential, or incidental damages or damages for lost profits, loss 66 * of revenue or loss of use, whether such damages arise in contract, 67 * negligence, tort, under statute, in equity, at law or otherwise, even if 68 * advised of the possibility of such damage. 69 */ 70 71#ifdef HAVE_CONFIG_H 72#include "config.h" 73#endif 74 75/* All drivers should typically include these */ 76#include "xf86.h" 77#include "xf86_OSproc.h" 78 79/* Everything using inb/outb, etc needs "compiler.h" */ 80#include "compiler.h" 81 82/* Drivers for PCI hardware need this */ 83#include "xf86PciInfo.h" 84 85/* Drivers that need to access the PCI config space directly need this */ 86#include "xf86Pci.h" 87 88#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 89/* Standard resources are defined here */ 90#include "xf86Resources.h" 91 92/* Needed by Resources Access Control (RAC) */ 93#include "xf86RAC.h" 94#endif 95 96/* All drivers using the vgahw module need this */ 97#include "vgaHW.h" 98 99/* All drivers initialising the SW cursor need this */ 100#include "mipointer.h" 101 102/* All drivers implementing backing store need this */ 103#include "mibstore.h" 104 105/* All drivers using the mi banking wrapper need this */ 106#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 107#define USE_MIBANK 108#endif 109 110#if defined(USE_MIBANK) || defined(HAVE_ISA) 111#include "mibank.h" 112#endif 113 114/* All drivers using the mi colormap manipulation need this */ 115#include "micmap.h" 116 117#include "fb.h" 118#include "fboverlay.h" 119 120/* Needed for the 1 and 4 bpp framebuffers */ 121#ifdef HAVE_XF1BPP 122#include "xf1bpp.h" 123#endif 124#ifdef HAVE_XF4BPP 125#include "xf4bpp.h" 126#endif 127 128#include "hw/xfree86/xf8_16bpp/cfb8_16.h" 129 130/* int10 */ 131#include "xf86int10.h" 132#include "vbe.h" 133 134/* Needed by the Shadow Framebuffer */ 135#include "shadowfb.h" 136 137/* Needed for replacement LoadPalette function for Gamma Correction */ 138#include "xf86cmap.h" 139 140#include "dixstruct.h" 141 142/* Driver specific headers */ 143#include "ct_driver.h" 144 145/* Mandatory functions */ 146static const OptionInfoRec * CHIPSAvailableOptions(int chipid, int busid); 147static void CHIPSIdentify(int flags); 148static Bool CHIPSPciProbe(DriverPtr drv, int entity_num, 149 struct pci_device *dev, intptr_t match_data); 150#ifdef HAVE_ISA 151static Bool CHIPSProbe(DriverPtr drv, int flags); 152#endif 153static Bool CHIPSPreInit(ScrnInfoPtr pScrn, int flags); 154static Bool CHIPSScreenInit(int Index, ScreenPtr pScreen, int argc, 155 char **argv); 156static Bool CHIPSEnterVT(int scrnIndex, int flags); 157static void CHIPSLeaveVT(int scrnIndex, int flags); 158static Bool CHIPSCloseScreen(int scrnIndex, ScreenPtr pScreen); 159static void CHIPSFreeScreen(int scrnIndex, int flags); 160static ModeStatus CHIPSValidMode(int scrnIndex, DisplayModePtr mode, 161 Bool verbose, int flags); 162static Bool CHIPSSaveScreen(ScreenPtr pScreen, int mode); 163 164/* Internally used functions */ 165#ifdef HAVE_ISA 166static int chipsFindIsaDevice(GDevPtr dev); 167#endif 168static Bool chipsClockSelect(ScrnInfoPtr pScrn, int no); 169Bool chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 170static void chipsSave(ScrnInfoPtr pScrn, vgaRegPtr VgaSave, 171 CHIPSRegPtr ChipsSave); 172static void chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, 173 CHIPSRegPtr ChipsReg, Bool restoreFonts); 174static void chipsLock(ScrnInfoPtr pScrn); 175static void chipsUnlock(ScrnInfoPtr pScrn); 176static void chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock); 177static void chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock); 178static Bool chipsClockFind(ScrnInfoPtr pScrn, DisplayModePtr mode, 179 int no, CHIPSClockPtr Clock); 180static void chipsCalcClock(ScrnInfoPtr pScrn, int Clock, 181 unsigned char *vclk); 182static int chipsGetHWClock(ScrnInfoPtr pScrn); 183static Bool chipsPreInit655xx(ScrnInfoPtr pScrn, int flags); 184static Bool chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags); 185static Bool chipsPreInitWingine(ScrnInfoPtr pScrn, int flags); 186static int chipsSetMonitor(ScrnInfoPtr pScrn); 187static Bool chipsMapMem(ScrnInfoPtr pScrn); 188static Bool chipsUnmapMem(ScrnInfoPtr pScrn); 189static void chipsProtect(ScrnInfoPtr pScrn, Bool on); 190static void chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank); 191static void chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs); 192static void chipsRestoreStretching(ScrnInfoPtr pScrn, 193 unsigned char ctHorizontalStretch, 194 unsigned char ctVerticalStretch); 195static Bool chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode); 196static Bool chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode); 197static Bool chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode); 198static int chipsVideoMode(int vgaBitsPerPixel,int displayHSize, 199 int displayVSize); 200static void chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn, 201 int PowerManagementMode, int flags); 202static void chipsHWCursorOn(CHIPSPtr cPtr, ScrnInfoPtr pScrn); 203static void chipsHWCursorOff(CHIPSPtr cPtr, ScrnInfoPtr pScrn); 204static void chipsFixResume(ScrnInfoPtr pScrn); 205static void chipsLoadPalette(ScrnInfoPtr pScrn, int numColors, 206 int *indices, LOCO *colors, VisualPtr pVisual); 207static void chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors, 208 int *indices, LOCO *colors, VisualPtr pVisual); 209static void chipsSetPanelType(CHIPSPtr cPtr); 210static void chipsBlockHandler(int, pointer, pointer, pointer); 211 212/* 213 * This is intentionally screen-independent. It indicates the binding 214 * choice made in the first PreInit. 215 */ 216static int pix24bpp = 0; 217 218/* 219 * Index of Entity 220 */ 221static int CHIPSEntityIndex = -1; 222 223 224/* Set the non-documented SAR04 register for overlay/video */ 225#define SAR04 226 227/* 228 * Initialise some arrays that are used in multiple instances of the 229 * acceleration code. Set them up here as its a convenient place to do it. 230 */ 231/* alu to C&T conversion for use with source data */ 232int ChipsAluConv[] = 233{ 234 0x00, /* dest = 0; GXclear, 0 */ 235 0x88, /* dest &= src; GXand, 0x1 */ 236 0x44, /* dest = src & ~dest; GXandReverse, 0x2 */ 237 0xCC, /* dest = src; GXcopy, 0x3 */ 238 0x22, /* dest &= ~src; GXandInverted, 0x4 */ 239 0xAA, /* dest = dest; GXnoop, 0x5 */ 240 0x66, /* dest = ^src; GXxor, 0x6 */ 241 0xEE, /* dest |= src; GXor, 0x7 */ 242 0x11, /* dest = ~src & ~dest;GXnor, 0x8 */ 243 0x99, /* dest ^= ~src ;GXequiv, 0x9 */ 244 0x55, /* dest = ~dest; GXInvert, 0xA */ 245 0xDD, /* dest = src|~dest ;GXorReverse, 0xB */ 246 0x33, /* dest = ~src; GXcopyInverted, 0xC */ 247 0xBB, /* dest |= ~src; GXorInverted, 0xD */ 248 0x77, /* dest = ~src|~dest ;GXnand, 0xE */ 249 0xFF, /* dest = 0xFF; GXset, 0xF */ 250}; 251 252/* alu to C&T conversion for use with pattern data */ 253int ChipsAluConv2[] = 254{ 255 0x00, /* dest = 0; GXclear, 0 */ 256 0xA0, /* dest &= src; GXand, 0x1 */ 257 0x50, /* dest = src & ~dest; GXandReverse, 0x2 */ 258 0xF0, /* dest = src; GXcopy, 0x3 */ 259 0x0A, /* dest &= ~src; GXandInverted, 0x4 */ 260 0xAA, /* dest = dest; GXnoop, 0x5 */ 261 0x5A, /* dest = ^src; GXxor, 0x6 */ 262 0xFA, /* dest |= src; GXor, 0x7 */ 263 0x05, /* dest = ~src & ~dest;GXnor, 0x8 */ 264 0xA5, /* dest ^= ~src ;GXequiv, 0x9 */ 265 0x55, /* dest = ~dest; GXInvert, 0xA */ 266 0xF5, /* dest = src|~dest ;GXorReverse, 0xB */ 267 0x0F, /* dest = ~src; GXcopyInverted, 0xC */ 268 0xAF, /* dest |= ~src; GXorInverted, 0xD */ 269 0x5F, /* dest = ~src|~dest ;GXnand, 0xE */ 270 0xFF, /* dest = 0xFF; GXset, 0xF */ 271}; 272 273/* alu to C&T conversion for use with pattern data as a planemask */ 274int ChipsAluConv3[] = 275{ 276 0x0A, /* dest = 0; GXclear, 0 */ 277 0x8A, /* dest &= src; GXand, 0x1 */ 278 0x4A, /* dest = src & ~dest; GXandReverse, 0x2 */ 279 0xCA, /* dest = src; GXcopy, 0x3 */ 280 0x2A, /* dest &= ~src; GXandInverted, 0x4 */ 281 0xAA, /* dest = dest; GXnoop, 0x5 */ 282 0x6A, /* dest = ^src; GXxor, 0x6 */ 283 0xEA, /* dest |= src; GXor, 0x7 */ 284 0x1A, /* dest = ~src & ~dest;GXnor, 0x8 */ 285 0x9A, /* dest ^= ~src ;GXequiv, 0x9 */ 286 0x5A, /* dest = ~dest; GXInvert, 0xA */ 287 0xDA, /* dest = src|~dest ;GXorReverse, 0xB */ 288 0x3A, /* dest = ~src; GXcopyInverted, 0xC */ 289 0xBA, /* dest |= ~src; GXorInverted, 0xD */ 290 0x7A, /* dest = ~src|~dest ;GXnand, 0xE */ 291 0xFA, /* dest = 0xFF; GXset, 0xF */ 292}; 293 294/* The addresses of the acceleration registers */ 295unsigned int ChipsReg32HiQV[] = 296{ 297 0x00, /* BR00 Source and Destination offset register */ 298 0x04, /* BR01 Color expansion background color */ 299 0x08, /* BR02 Color expansion foreground color */ 300 0x0C, /* BR03 Monochrome source control register */ 301 0x10, /* BR04 BitBLT control register */ 302 0x14, /* BR05 Pattern address register */ 303 0x18, /* BR06 Source address register */ 304 0x1C, /* BR07 Destination address register */ 305 0x20 /* BR08 Destination width and height register */ 306}; 307 308unsigned int ChipsReg32[] = 309{ 310 /*BitBLT */ 311 0x83D0, /*DR0 src/dest offset */ 312 0x87D0, /*DR1 BitBlt. address of freeVram? */ 313 0x8BD0, /*DR2 BitBlt. paintBrush, or tile pat.*/ 314 0x8FD0, /*DR3 */ 315 0x93D0, /*DR4 BitBlt. */ 316 0x97D0, /*DR5 BitBlt. srcAddr, or 0 in VRAM */ 317 0x9BD0, /*DR6 BitBlt. dest? */ 318 0x9FD0, /*DR7 BitBlt. width << 16 | height */ 319 /*H/W cursor */ 320 0xA3D0, /*DR8 write/erase cursor */ 321 /*bit 0-1 if 0 cursor is not shown 322 * if 1 32x32 cursor 323 * if 2 64x64 cursor 324 * if 3 128x128 cursor 325 */ 326 /* bit 7 if 1 cursor is not shown */ 327 /* bit 9 cursor expansion in X */ 328 /* bit 10 cursor expansion in Y */ 329 0xA7D0, /* DR9 foreGroundCursorColor */ 330 0xABD0, /* DR0xA backGroundCursorColor */ 331 0xAFD0, /* DR0xB cursorPosition */ 332 /* bit 0-7 x coordinate */ 333 /* bit 8-14 0 */ 334 /* bit 15 x signum */ 335 /* bit 16-23 y coordinate */ 336 /* bit 24-30 0 */ 337 /* bit 31 y signum */ 338 0xB3D0, /* DR0xC address of cursor pattern */ 339}; 340 341#if defined(__arm__) && defined(__NetBSD__) 342/* 343 * Built in TV output modes: These modes have been tested on NetBSD with 344 * CT65550 and StrongARM. They give what seems to be the best output for 345 * a roughly 640x480 display. To enable one of the built in modes, add 346 * the identifier "NTSC" or "PAL" to the list of modes in the appropriate 347 * "Display" subsection of the "Screen" section in the XF86Config file. 348 * Note that the call to xf86SetTVOut(), which tells the kernel to enable 349 * TV output results in hardware specific actions. There must be code to 350 * support this in the kernel or TV output won't work. 351 */ 352static DisplayModeRec ChipsPALMode = { 353 NULL, NULL, /* prev, next */ 354 "PAL", /* identifier of this mode */ 355 MODE_OK, /* mode status */ 356 M_T_BUILTIN, /* mode type */ 357 15000, /* Clock frequency */ 358 776, /* HDisplay */ 359 800, /* HSyncStart */ 360 872, /* HSyncEnd */ 361 960, /* HTotal */ 362 0, /* HSkew */ 363 585, /* VDisplay */ 364 590, /* VSyncStart */ 365 595, /* VSyncEnd */ 366 625, /* VTotal */ 367 0, /* VScan */ 368 V_INTERLACE, /* Flags */ 369 -1, /* ClockIndex */ 370 15000, /* SynthClock */ 371 776, /* CRTC HDisplay */ 372 800, /* CRTC HBlankStart */ 373 800, /* CRTC HSyncStart */ 374 872, /* CRTC HSyncEnd */ 375 872, /* CRTC HBlankEnd */ 376 960, /* CRTC HTotal */ 377 0, /* CRTC HSkew */ 378 585, /* CRTC VDisplay */ 379 590, /* CRTC VBlankStart */ 380 590, /* CRTC VSyncStart */ 381 595, /* CRTC VSyncEnd */ 382 595, /* CRTC VBlankEnd */ 383 625, /* CRTC VTotal */ 384 FALSE, /* CrtcHAdjusted */ 385 FALSE, /* CrtcVAdjusted */ 386 0, /* PrivSize */ 387 NULL, /* Private */ 388 0.0, /* HSync */ 389 0.0 /* VRefresh */ 390}; 391 392/* 393** So far, it looks like SECAM uses the same values as PAL 394*/ 395static DisplayModeRec ChipsSECAMMode = { 396 NULL, /* prev */ 397 &ChipsPALMode, /* next */ 398 "SECAM", /* identifier of this mode */ 399 MODE_OK, /* mode status */ 400 M_T_BUILTIN, /* mode type */ 401 15000, /* Clock frequency */ 402 776, /* HDisplay */ 403 800, /* HSyncStart */ 404 872, /* HSyncEnd */ 405 960, /* HTotal */ 406 0, /* HSkew */ 407 585, /* VDisplay */ 408 590, /* VSyncStart */ 409 595, /* VSyncEnd */ 410 625, /* VTotal */ 411 0, /* VScan */ 412 V_INTERLACE, /* Flags */ 413 -1, /* ClockIndex */ 414 15000, /* SynthClock */ 415 776, /* CRTC HDisplay */ 416 800, /* CRTC HBlankStart */ 417 800, /* CRTC HSyncStart */ 418 872, /* CRTC HSyncEnd */ 419 872, /* CRTC HBlankEnd */ 420 960, /* CRTC HTotal */ 421 0, /* CRTC HSkew */ 422 585, /* CRTC VDisplay */ 423 590, /* CRTC VBlankStart */ 424 590, /* CRTC VSyncStart */ 425 595, /* CRTC VSyncEnd */ 426 595, /* CRTC VBlankEnd */ 427 625, /* CRTC VTotal */ 428 FALSE, /* CrtcHAdjusted */ 429 FALSE, /* CrtcVAdjusted */ 430 0, /* PrivSize */ 431 NULL, /* Private */ 432 0.0, /* HSync */ 433 0.0 /* VRefresh */ 434}; 435 436 437static DisplayModeRec ChipsNTSCMode = { 438 NULL, /* prev */ 439 &ChipsSECAMMode,/* next */ 440 "NTSC", /* identifier of this mode */ 441 MODE_OK, /* mode status */ 442 M_T_BUILTIN, /* mode type */ 443 11970, /* Clock frequency */ 444 584, /* HDisplay */ 445 640, /* HSyncStart */ 446 696, /* HSyncEnd */ 447 760, /* HTotal */ 448 0, /* HSkew */ 449 450, /* VDisplay */ 450 479, /* VSyncStart */ 451 485, /* VSyncEnd */ 452 525, /* VTotal */ 453 0, /* VScan */ 454 V_INTERLACE | V_NVSYNC | V_NHSYNC , /* Flags */ 455 -1, /* ClockIndex */ 456 11970, /* SynthClock */ 457 584, /* CRTC HDisplay */ 458 640, /* CRTC HBlankStart */ 459 640, /* CRTC HSyncStart */ 460 696, /* CRTC HSyncEnd */ 461 696, /* CRTC HBlankEnd */ 462 760, /* CRTC HTotal */ 463 0, /* CRTC HSkew */ 464 450, /* CRTC VDisplay */ 465 479, /* CRTC VBlankStart */ 466 479, /* CRTC VSyncStart */ 467 485, /* CRTC VSyncEnd */ 468 485, /* CRTC VBlankEnd */ 469 525, /* CRTC VTotal */ 470 FALSE, /* CrtcHAdjusted */ 471 FALSE, /* CrtcVAdjusted */ 472 0, /* PrivSize */ 473 NULL, /* Private */ 474 0.0, /* HSync */ 475 0.0 /* VRefresh */ 476}; 477#endif 478 479#define CHIPS_VERSION 4000 480#define CHIPS_NAME "CHIPS" 481#define CHIPS_DRIVER_NAME "chips" 482#define CHIPS_MAJOR_VERSION PACKAGE_VERSION_MAJOR 483#define CHIPS_MINOR_VERSION PACKAGE_VERSION_MINOR 484#define CHIPS_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 485 486 487#ifdef XSERVER_LIBPCIACCESS 488 489#define CHIPS_DEVICE_MATCH(d, i) \ 490 { PCI_VENDOR_CHIPSTECH, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } 491 492static const struct pci_id_match chips_device_match[] = { 493 CHIPS_DEVICE_MATCH(PCI_CHIP_65545, CHIPS_CT65545), 494 CHIPS_DEVICE_MATCH(PCI_CHIP_65548, CHIPS_CT65548), 495 CHIPS_DEVICE_MATCH(PCI_CHIP_65550, CHIPS_CT65550), 496 CHIPS_DEVICE_MATCH(PCI_CHIP_65554, CHIPS_CT65554), 497 CHIPS_DEVICE_MATCH(PCI_CHIP_65555, CHIPS_CT65555), 498 CHIPS_DEVICE_MATCH(PCI_CHIP_68554, CHIPS_CT68554), 499 CHIPS_DEVICE_MATCH(PCI_CHIP_69000, CHIPS_CT69000), 500 CHIPS_DEVICE_MATCH(PCI_CHIP_69030, CHIPS_CT69030), 501 { 0, 0, 0 }, 502}; 503#endif 504 505/* 506 * This contains the functions needed by the server after loading the driver 507 * module. It must be supplied, and gets passed back by the SetupProc 508 * function in the dynamic case. In the static case, a reference to this 509 * is compiled in, and this requires that the name of this DriverRec be 510 * an upper-case version of the driver name. 511 */ 512 513_X_EXPORT DriverRec CHIPS = { 514 CHIPS_VERSION, 515 CHIPS_DRIVER_NAME, 516 CHIPSIdentify, 517#ifdef HAVE_ISA 518 CHIPSProbe, 519#else 520 NULL, 521#endif 522 CHIPSAvailableOptions, 523 NULL, 524 0, 525 NULL, 526 527#ifdef XSERVER_LIBPCIACCESS 528 chips_device_match, 529 CHIPSPciProbe, 530#endif 531}; 532 533static SymTabRec CHIPSChipsets[] = { 534 { CHIPS_CT65520, "ct65520" }, 535 { CHIPS_CT65525, "ct65525" }, 536 { CHIPS_CT65530, "ct65530" }, 537 { CHIPS_CT65535, "ct65535" }, 538 { CHIPS_CT65540, "ct65540" }, 539 { CHIPS_CT65545, "ct65545" }, 540 { CHIPS_CT65546, "ct65546" }, 541 { CHIPS_CT65548, "ct65548" }, 542 { CHIPS_CT65550, "ct65550" }, 543 { CHIPS_CT65554, "ct65554" }, 544 { CHIPS_CT65555, "ct65555" }, 545 { CHIPS_CT68554, "ct68554" }, 546 { CHIPS_CT69000, "ct69000" }, 547 { CHIPS_CT69030, "ct69030" }, 548 { CHIPS_CT64200, "ct64200" }, 549 { CHIPS_CT64300, "ct64300" }, 550 { -1, NULL } 551}; 552 553 554/* Conversion PCI ID to chipset name */ 555static PciChipsets CHIPSPCIchipsets[] = { 556 { CHIPS_CT65545, PCI_CHIP_65545, RES_SHARED_VGA }, 557 { CHIPS_CT65548, PCI_CHIP_65548, RES_SHARED_VGA }, 558 { CHIPS_CT65550, PCI_CHIP_65550, RES_SHARED_VGA }, 559 { CHIPS_CT65554, PCI_CHIP_65554, RES_SHARED_VGA }, 560 { CHIPS_CT65555, PCI_CHIP_65555, RES_SHARED_VGA }, 561 { CHIPS_CT68554, PCI_CHIP_68554, RES_SHARED_VGA }, 562 { CHIPS_CT69000, PCI_CHIP_69000, RES_SHARED_VGA }, 563 { CHIPS_CT69030, PCI_CHIP_69030, RES_SHARED_VGA }, 564 { -1, -1, RES_UNDEFINED} 565}; 566 567/* The options supported by the Chips and Technologies Driver */ 568typedef enum { 569 OPTION_LINEAR, 570 OPTION_NOACCEL, 571 OPTION_HW_CLKS, 572 OPTION_SW_CURSOR, 573 OPTION_HW_CURSOR, 574 OPTION_STN, 575 OPTION_USE_MODELINE, 576 OPTION_LCD_STRETCH, 577 OPTION_LCD_CENTER, 578 OPTION_MMIO, 579 OPTION_FULL_MMIO, 580 OPTION_SUSPEND_HACK, 581 OPTION_RGB_BITS, 582 OPTION_SYNC_ON_GREEN, 583 OPTION_PANEL_SIZE, 584 OPTION_18_BIT_BUS, 585 OPTION_SHOWCACHE, 586 OPTION_SHADOW_FB, 587 OPTION_OVERLAY, 588 OPTION_COLOR_KEY, 589 OPTION_VIDEO_KEY, 590 OPTION_FP_CLOCK_8, 591 OPTION_FP_CLOCK_16, 592 OPTION_FP_CLOCK_24, 593 OPTION_FP_CLOCK_32, 594 OPTION_SET_MCLK, 595 OPTION_ROTATE, 596 OPTION_NO_TMED, 597 OPTION_CRT2_MEM, 598 OPTION_DUAL_REFRESH, 599 OPTION_CRT_CLK_INDX, 600 OPTION_FP_CLK_INDX, 601 OPTION_FP_MODE 602} CHIPSOpts; 603 604static const OptionInfoRec Chips655xxOptions[] = { 605 { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE }, 606 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 607 { OPTION_HW_CLKS, "HWclocks", OPTV_BOOLEAN, {0}, FALSE }, 608 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 609 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 610 { OPTION_STN, "STN", OPTV_BOOLEAN, {0}, FALSE }, 611 { OPTION_USE_MODELINE, "UseModeline", OPTV_BOOLEAN, {0}, FALSE }, 612 { OPTION_LCD_STRETCH, "Stretch", OPTV_BOOLEAN, {0}, FALSE }, 613 { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE }, 614 { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE }, 615 { OPTION_SUSPEND_HACK, "SuspendHack", OPTV_BOOLEAN, {0}, FALSE }, 616 { OPTION_PANEL_SIZE, "FixPanelSize", OPTV_BOOLEAN, {0}, FALSE }, 617#if 0 618 { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE }, 619#endif 620 { OPTION_18_BIT_BUS, "18BitBus", OPTV_BOOLEAN, {0}, FALSE }, 621 { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, 622 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 623 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 624 { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE }, 625 { OPTION_FP_CLOCK_8, "FPClock8", OPTV_FREQ, {0}, FALSE }, 626 { OPTION_FP_CLOCK_16, "FPClock16", OPTV_FREQ, {0}, FALSE }, 627 { OPTION_FP_CLOCK_24, "FPClock24", OPTV_FREQ, {0}, FALSE }, 628 { OPTION_FP_MODE, "FPMode", OPTV_BOOLEAN, {0}, FALSE }, 629 { -1, NULL, OPTV_NONE, {0}, FALSE } 630}; 631 632static const OptionInfoRec ChipsWingineOptions[] = { 633 { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE }, 634 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 635 { OPTION_HW_CLKS, "HWclocks", OPTV_BOOLEAN, {0}, FALSE }, 636 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 637 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 638#if 0 639 { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE }, 640#endif 641 { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, 642 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 643 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 644 { -1, NULL, OPTV_NONE, {0}, FALSE } 645}; 646 647static const OptionInfoRec ChipsHiQVOptions[] = { 648 { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE }, 649 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 650 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 651 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 652 { OPTION_STN, "STN", OPTV_BOOLEAN, {0}, FALSE }, 653 { OPTION_USE_MODELINE, "UseModeline", OPTV_BOOLEAN, {0}, FALSE }, 654 { OPTION_LCD_STRETCH, "Stretch", OPTV_BOOLEAN, {0}, FALSE }, 655 { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE }, 656 { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE }, 657 { OPTION_FULL_MMIO, "FullMMIO", OPTV_BOOLEAN, {0}, FALSE }, 658 { OPTION_SUSPEND_HACK, "SuspendHack", OPTV_BOOLEAN, {0}, FALSE }, 659 { OPTION_PANEL_SIZE, "FixPanelSize", OPTV_BOOLEAN, {0}, FALSE }, 660 { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE }, 661 { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE }, 662 { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, 663 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 664 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 665 { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE }, 666 { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE }, 667 { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 668 { OPTION_FP_CLOCK_8, "FPClock8", OPTV_FREQ, {0}, FALSE }, 669 { OPTION_FP_CLOCK_16, "FPClock16", OPTV_FREQ, {0}, FALSE }, 670 { OPTION_FP_CLOCK_24, "FPClock24", OPTV_FREQ, {0}, FALSE }, 671 { OPTION_FP_CLOCK_32, "FPClock32", OPTV_FREQ, {0}, FALSE }, 672 { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE }, 673 { OPTION_NO_TMED, "NoTMED", OPTV_BOOLEAN, {0}, FALSE }, 674 { OPTION_CRT2_MEM, "Crt2Memory", OPTV_INTEGER, {0}, FALSE }, 675 { OPTION_DUAL_REFRESH, "DualRefresh", OPTV_BOOLEAN, {0}, FALSE }, 676 { OPTION_CRT_CLK_INDX, "CrtClkIndx", OPTV_INTEGER, {0}, FALSE }, 677 { OPTION_FP_CLK_INDX, "FPClkIndx", OPTV_INTEGER, {0}, FALSE }, 678 { OPTION_FP_MODE, "FPMode", OPTV_BOOLEAN, {0}, FALSE }, 679 { -1, NULL, OPTV_NONE, {0}, FALSE } 680}; 681 682#ifdef XFree86LOADER 683 684static MODULESETUPPROTO(chipsSetup); 685 686static XF86ModuleVersionInfo chipsVersRec = 687{ 688 "chips", 689 MODULEVENDORSTRING, 690 MODINFOSTRING1, 691 MODINFOSTRING2, 692 XORG_VERSION_CURRENT, 693 CHIPS_MAJOR_VERSION, CHIPS_MINOR_VERSION, CHIPS_PATCHLEVEL, 694 ABI_CLASS_VIDEODRV, 695 ABI_VIDEODRV_VERSION, 696 MOD_CLASS_VIDEODRV, 697 {0,0,0,0} 698}; 699 700/* 701 * This is the module init data. 702 * Its name has to be the driver name followed by ModuleData 703 */ 704_X_EXPORT XF86ModuleData chipsModuleData = { &chipsVersRec, chipsSetup, NULL }; 705 706static pointer 707chipsSetup(pointer module, pointer opts, int *errmaj, int *errmin) 708{ 709 static Bool setupDone = FALSE; 710 711 if (!setupDone) { 712 setupDone = TRUE; 713 xf86AddDriver(&CHIPS, module, HaveDriverFuncs); 714 715 /* 716 * Modules that this driver always requires can be loaded here 717 * by calling LoadSubModule(). 718 */ 719 720 /* 721 * The return value must be non-NULL on success even though there 722 * is no TearDownProc. 723 */ 724 return (pointer)1; 725 } else { 726 if (errmaj) *errmaj = LDR_ONCEONLY; 727 return NULL; 728 } 729} 730 731#endif /* XFree86LOADER */ 732 733static Bool 734CHIPSGetRec(ScrnInfoPtr pScrn) 735{ 736 /* 737 * Allocate a CHIPSRec, and hook it into pScrn->driverPrivate. 738 * pScrn->driverPrivate is initialised to NULL, so we can check if 739 * the allocation has already been done. 740 */ 741 if (pScrn->driverPrivate != NULL) 742 return TRUE; 743 744 pScrn->driverPrivate = xnfcalloc(sizeof(CHIPSRec), 1); 745 746 if (pScrn->driverPrivate == NULL) 747 return FALSE; 748 749 return TRUE; 750} 751 752static void 753CHIPSFreeRec(ScrnInfoPtr pScrn) 754{ 755 if (pScrn->driverPrivate == NULL) 756 return; 757 free(pScrn->driverPrivate); 758 pScrn->driverPrivate = NULL; 759} 760 761/* Mandatory */ 762static void 763CHIPSIdentify(int flags) 764{ 765 xf86PrintChipsets(CHIPS_NAME, "Driver for Chips and Technologies chipsets", 766 CHIPSChipsets); 767} 768 769static const OptionInfoRec * 770CHIPSAvailableOptions(int chipid, int busid) 771{ 772 int chip = chipid & 0x0000ffff; 773 774#ifdef HAVE_ISA 775 if (busid == BUS_ISA) { 776 if ((chip == CHIPS_CT64200) || (chip == CHIPS_CT64300)) 777 return ChipsWingineOptions; 778 } 779#endif 780 if (busid == BUS_PCI) { 781 if ((chip >= CHIPS_CT65550) && (chip <= CHIPS_CT69030)) 782 return ChipsHiQVOptions; 783 } 784 return Chips655xxOptions; 785} 786 787/* Mandatory */ 788Bool 789CHIPSPciProbe(DriverPtr drv, int entity_num, struct pci_device * dev, 790 intptr_t match_data) 791{ 792 ScrnInfoPtr pScrn = NULL; 793 CHIPSPtr cPtr; 794 795 /* Allocate a ScrnInfoRec and claim the slot */ 796 pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, CHIPSPCIchipsets, NULL, 797 NULL, NULL, NULL, NULL); 798 if (pScrn != NULL) { 799 /* Fill in what we can of the ScrnInfoRec */ 800 pScrn->driverVersion = CHIPS_VERSION; 801 pScrn->driverName = CHIPS_DRIVER_NAME; 802 pScrn->name = CHIPS_NAME; 803 pScrn->Probe = NULL; 804 pScrn->PreInit = CHIPSPreInit; 805 pScrn->ScreenInit = CHIPSScreenInit; 806 pScrn->SwitchMode = CHIPSSwitchMode; 807 pScrn->AdjustFrame = CHIPSAdjustFrame; 808 pScrn->EnterVT = CHIPSEnterVT; 809 pScrn->LeaveVT = CHIPSLeaveVT; 810 pScrn->FreeScreen = CHIPSFreeScreen; 811 pScrn->ValidMode = CHIPSValidMode; 812 813 if (!CHIPSGetRec(pScrn)) { 814 return 0; 815 } 816 cPtr = CHIPSPTR(pScrn); 817 cPtr->Chipset = match_data; 818 /* 819 * For cards that can do dual head per entity, mark the entity 820 * as sharable. 821 */ 822 if (match_data == CHIPS_CT69030) { 823 CHIPSEntPtr cPtrEnt = NULL; 824 DevUnion *pPriv; 825 826 xf86SetEntitySharable(entity_num); 827 /* Allocate an entity private if necessary */ 828 if (CHIPSEntityIndex < 0) 829 CHIPSEntityIndex = xf86AllocateEntityPrivateIndex(); 830 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], CHIPSEntityIndex); 831 if (!pPriv->ptr) { 832 pPriv->ptr = xnfcalloc(sizeof(CHIPSEntRec), 1); 833 cPtrEnt = pPriv->ptr; 834 cPtrEnt->lastInstance = -1; 835 } else { 836 cPtrEnt = pPriv->ptr; 837 } 838 /* 839 * Set the entity instance for this instance of the driver. For 840 * dual head per card, instance 0 is the "master" instance, driving 841 * the primary head, and instance 1 is the "slave". 842 */ 843 cPtrEnt->lastInstance++; 844 xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0], 845 cPtrEnt->lastInstance); 846 } 847 } 848 849 return (pScrn != NULL); 850} 851 852#ifdef HAVE_ISA 853static Bool 854CHIPSProbe(DriverPtr drv, int flags) 855{ 856 ScrnInfoPtr pScrn = NULL; 857 CHIPSPtr cPtr; 858 Bool foundScreen = FALSE; 859 int numDevSections, numUsed; 860 GDevPtr *devSections; 861 int *usedChips; 862 int i, chipset, entity; 863 864 /* 865 * Find the config file Device sections that match this 866 * driver, and return if there are none. 867 */ 868 if ((numDevSections = xf86MatchDevice(CHIPS_DRIVER_NAME, 869 &devSections)) <= 0) { 870 return FALSE; 871 } 872 873 /* Isa Bus */ 874 if ((numDevSections = 875 xf86MatchDevice(CHIPS_DRIVER_NAME, &devSections)) > 0) { 876 for (i = 0; i < numDevSections; i++) { 877 if ((chipset = chipsFindIsaDevice(devSections[i])) > -1) { 878 if ( xf86DoConfigure && xf86DoConfigurePass1 ) { 879 xf86AddBusDeviceToConfigure(CHIPS_DRIVER_NAME, BUS_ISA, 880 NULL, chipset); 881 } 882 if (flags & PROBE_DETECT) { 883 return TRUE; 884 } 885 if (!xf86CheckStrOption(devSections[i]->options, "BusID", 886 "ISA")) { 887 continue; 888 } 889 890 pScrn = NULL; 891 entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); 892 pScrn = xf86ConfigFbEntity(NULL, 0, entity, NULL, NULL, 893 NULL, NULL); 894 pScrn->driverVersion = CHIPS_VERSION; 895 pScrn->driverName = CHIPS_DRIVER_NAME; 896 pScrn->name = CHIPS_NAME; 897 pScrn->Probe = CHIPSProbe; 898 pScrn->PreInit = CHIPSPreInit; 899 pScrn->ScreenInit = CHIPSScreenInit; 900 pScrn->SwitchMode = CHIPSSwitchMode; 901 pScrn->AdjustFrame = CHIPSAdjustFrame; 902 pScrn->EnterVT = CHIPSEnterVT; 903 pScrn->LeaveVT = CHIPSLeaveVT; 904 pScrn->FreeScreen = CHIPSFreeScreen; 905 pScrn->ValidMode = CHIPSValidMode; 906 if (!CHIPSGetRec(pScrn)) { 907 return FALSE; 908 } 909 cPtr = CHIPSPTR(pScrn); 910 cPtr->Chipset = chipset; 911 } 912 } 913 } 914 915 xfree(devSections); 916 return foundScreen; 917} 918 919static int 920chipsFindIsaDevice(GDevPtr dev) 921{ 922 int found = -1; 923 unsigned char tmp; 924 925 /* 926 * This function has the only direct register access in the C&T driver. 927 * All other register access through functions to allow for full MMIO. 928 */ 929 outb(0x3D6, 0x00); 930 tmp = inb(0x3D7); 931 932 switch (tmp & 0xF0) { 933 case 0x70: /* CT65520 */ 934 found = CHIPS_CT65520; break; 935 case 0x80: /* CT65525 or CT65530 */ 936 found = CHIPS_CT65530; break; 937 case 0xA0: /* CT64200 */ 938 found = CHIPS_CT64200; break; 939 case 0xB0: /* CT64300 */ 940 found = CHIPS_CT64300; break; 941 case 0xC0: /* CT65535 */ 942 found = CHIPS_CT65535; break; 943 default: 944 switch (tmp & 0xF8) { 945 case 0xD0: /* CT65540 */ 946 found = CHIPS_CT65540; break; 947 case 0xD8: /* CT65545 or CT65546 or CT65548 */ 948 switch (tmp & 7) { 949 case 3: 950 found = CHIPS_CT65546; break; 951 case 4: 952 found = CHIPS_CT65548; break; 953 default: 954 found = CHIPS_CT65545; break; 955 956 } 957 break; 958 default: 959 if (tmp == 0x2C) { 960 outb(0x3D6, 0x01); 961 tmp = inb(0x3D7); 962 if (tmp != 0x10) break; 963 outb(0x3D6, 0x02); 964 tmp = inb(0x3D7); 965 switch (tmp) { 966 case 0xE0: /* CT65550 */ 967 found = CHIPS_CT65550; break; 968 case 0xE4: /* CT65554 */ 969 found = CHIPS_CT65554; break; 970 case 0xE5: /* CT65555 */ 971 found = CHIPS_CT65555; break; 972 case 0xF4: /* CT68554 */ 973 found = CHIPS_CT68554; break; 974 case 0xC0: /* CT69000 */ 975 found = CHIPS_CT69000; break; 976 case 0x30: /* CT69030 */ 977 outb(0x3D6, 0x03); 978 tmp = inb(0x3D7); 979 if (tmp == 0xC) 980 found = CHIPS_CT69030; 981 break; 982 default: 983 break; 984 } 985 } 986 break; 987 } 988 break; 989 } 990 /* We only want ISA/VL Bus - so check for PCI Bus */ 991 if(found > CHIPS_CT65548) { 992 outb(0x3D6, 0x08); 993 tmp = inb(0x3D7); 994 if(tmp & 0x01) found = -1; 995 } else if(found > CHIPS_CT65535) { 996 outb(0x3D6, 0x01); 997 tmp = inb(0x3D7); 998 if ((tmp & 0x07) == 0x06) found = -1; 999 } 1000 return found; 1001} 1002#endif 1003 1004/* Mandatory */ 1005Bool 1006CHIPSPreInit(ScrnInfoPtr pScrn, int flags) 1007{ 1008 pciVideoPtr pciPtr; 1009 ClockRangePtr clockRanges; 1010 int i; 1011 CHIPSPtr cPtr; 1012 Bool res = FALSE; 1013 CHIPSEntPtr cPtrEnt = NULL; 1014 1015 if (flags & PROBE_DETECT) return FALSE; 1016 1017 /* The vgahw module should be loaded here when needed */ 1018 if (!xf86LoadSubModule(pScrn, "vgahw")) 1019 return FALSE; 1020 1021 /* Allocate the ChipsRec driverPrivate */ 1022 if (!CHIPSGetRec(pScrn)) { 1023 return FALSE; 1024 } 1025 cPtr = CHIPSPTR(pScrn); 1026 1027 /* XXX Check the number of entities, and fail if it isn't one. */ 1028 if (pScrn->numEntities != 1) 1029 return FALSE; 1030 1031 /* Since the capabilities are determined by the chipset the very 1032 * first thing to do is, figure out the chipset and its capabilities 1033 */ 1034 1035 /* This is the general case */ 1036 for (i = 0; i<pScrn->numEntities; i++) { 1037 cPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 1038#ifndef XSERVER_LIBPCIACCESS 1039 if (cPtr->pEnt->resources) return FALSE; 1040#endif 1041 /* If we are using libpciaccess this is already set in CHIPSPciProbe. 1042 * If we are using something else we need to set it here. 1043 */ 1044 if (!cPtr->Chipset) 1045 cPtr->Chipset = cPtr->pEnt->chipset; 1046 pScrn->chipset = (char *)xf86TokenToString(CHIPSChipsets, 1047 cPtr->pEnt->chipset); 1048 if ((cPtr->Chipset == CHIPS_CT64200) || 1049 (cPtr->Chipset == CHIPS_CT64300)) cPtr->Flags |= ChipsWingine; 1050 if ((cPtr->Chipset >= CHIPS_CT65550) && 1051 (cPtr->Chipset <= CHIPS_CT69030)) cPtr->Flags |= ChipsHiQV; 1052 1053 /* This driver can handle ISA and PCI buses */ 1054 if (cPtr->pEnt->location.type == BUS_PCI) { 1055 pciPtr = xf86GetPciInfoForEntity(cPtr->pEnt->index); 1056 cPtr->PciInfo = pciPtr; 1057#ifndef XSERVER_LIBPCIACCESS 1058 cPtr->PciTag = pciTag(cPtr->PciInfo->bus, 1059 cPtr->PciInfo->device, 1060 cPtr->PciInfo->func); 1061#endif 1062 } 1063 } 1064 /* INT10 */ 1065#if 0 1066 if (xf86LoadSubModule(pScrn, "int10")) { 1067 xf86Int10InfoPtr pInt; 1068#if 1 1069 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); 1070 pInt = xf86InitInt10(cPtr->pEnt->index); 1071 xf86FreeInt10(pInt); 1072#endif 1073 } 1074#endif 1075 1076 if (xf86LoadSubModule(pScrn, "vbe")) { 1077 cPtr->pVbe = VBEInit(NULL,cPtr->pEnt->index); 1078 } 1079 1080 /* Now that we've identified the chipset, setup the capabilities flags */ 1081 switch (cPtr->Chipset) { 1082 case CHIPS_CT69030: 1083 cPtr->Flags |= ChipsDualChannelSupport; 1084 case CHIPS_CT69000: 1085 cPtr->Flags |= ChipsFullMMIOSupport; 1086 /* Fall through */ 1087 case CHIPS_CT65555: 1088 cPtr->Flags |= ChipsImageReadSupport; /* Does the 69000 support it? */ 1089 /* Fall through */ 1090 case CHIPS_CT68554: 1091 cPtr->Flags |= ChipsTMEDSupport; 1092 /* Fall through */ 1093 case CHIPS_CT65554: 1094 case CHIPS_CT65550: 1095 cPtr->Flags |= ChipsGammaSupport; 1096 cPtr->Flags |= ChipsVideoSupport; 1097 /* Fall through */ 1098 case CHIPS_CT65548: 1099 case CHIPS_CT65546: 1100 case CHIPS_CT65545: 1101 cPtr->Flags |= ChipsMMIOSupport; 1102 /* Fall through */ 1103 case CHIPS_CT64300: 1104 cPtr->Flags |= ChipsAccelSupport; 1105 /* Fall through */ 1106 case CHIPS_CT65540: 1107 cPtr->Flags |= ChipsHDepthSupport; 1108 cPtr->Flags |= ChipsDPMSSupport; 1109 /* Fall through */ 1110 case CHIPS_CT65535: 1111 case CHIPS_CT65530: 1112 case CHIPS_CT65525: 1113 cPtr->Flags |= ChipsLinearSupport; 1114 /* Fall through */ 1115 case CHIPS_CT64200: 1116 case CHIPS_CT65520: 1117 break; 1118 } 1119 1120 /* Check for shared entities */ 1121 if (xf86IsEntityShared(pScrn->entityList[0])) { 1122 if (!(cPtr->Flags & ChipsDualChannelSupport)) 1123 return FALSE; 1124 1125 /* Make sure entity is PCI for now, though this might not be needed. */ 1126 if (cPtr->pEnt->location.type != BUS_PCI) 1127 return FALSE; 1128 1129 /* Allocate an entity private if necessary */ 1130 if (xf86IsEntityShared(pScrn->entityList[0])) { 1131 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 1132 CHIPSEntityIndex)->ptr; 1133 cPtr->entityPrivate = cPtrEnt; 1134 } 1135#if 0 1136 /* Set cPtr->device to the relevant Device section */ 1137 cPtr->device = xf86GetDevFromEntity(pScrn->entityList[0], 1138 pScrn->entityInstanceList[0]); 1139#endif 1140 } 1141 1142 /* Set the driver to use the PIO register functions by default */ 1143 CHIPSSetStdExtFuncs(cPtr); 1144 1145 /* Call the device specific PreInit */ 1146 if (IS_HiQV(cPtr)) 1147 res = chipsPreInitHiQV(pScrn, flags); 1148 else if (IS_Wingine(cPtr)) 1149 res = chipsPreInitWingine(pScrn, flags); 1150 else 1151 res = chipsPreInit655xx(pScrn, flags); 1152 1153 if (cPtr->UseFullMMIO) 1154 chipsUnmapMem(pScrn); 1155 1156 if (!res) { 1157 vbeFree(cPtr->pVbe); 1158 cPtr->pVbe = NULL; 1159 return FALSE; 1160 } 1161 1162/*********/ 1163 /* 1164 * Setup the ClockRanges, which describe what clock ranges are available, 1165 * and what sort of modes they can be used for. 1166 */ 1167 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 1168 clockRanges->next = NULL; 1169 clockRanges->ClockMulFactor = cPtr->ClockMulFactor; 1170 clockRanges->minClock = cPtr->MinClock; 1171 clockRanges->maxClock = cPtr->MaxClock; 1172 clockRanges->clockIndex = -1; /* programmable */ 1173 if (cPtr->PanelType & ChipsLCD) { 1174 clockRanges->interlaceAllowed = FALSE; 1175 clockRanges->doubleScanAllowed = FALSE; 1176 } else { 1177 clockRanges->interlaceAllowed = TRUE; 1178 clockRanges->doubleScanAllowed = TRUE; 1179 } 1180 /* 1181 * Reduce the amount of video ram for the modes, so that they 1182 * don't overlap with the DSTN framebuffer 1183 */ 1184 pScrn->videoRam -= (cPtr->FrameBufferSize + 1023) / 1024; 1185 1186 cPtr->Rounding = 8 * (pScrn->bitsPerPixel <= 8 ? 8 1187 : pScrn->bitsPerPixel); 1188 1189 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 1190 pScrn->display->modes, clockRanges, 1191 NULL, 256, 2048, cPtr->Rounding, 1192 128, 2048, pScrn->display->virtualX, 1193 pScrn->display->virtualY, cPtr->FbMapSize, 1194 LOOKUP_BEST_REFRESH); 1195 1196 if (i == -1) { 1197 vbeFree(cPtr->pVbe); 1198 cPtr->pVbe = NULL; 1199 CHIPSFreeRec(pScrn); 1200 return FALSE; 1201 } 1202 1203 /* 1204 * Put the DSTN framebuffer back into the video ram 1205 */ 1206 pScrn->videoRam += (cPtr->FrameBufferSize + 1023) / 1024; 1207 1208 /* Prune the modes marked as invalid */ 1209 xf86PruneDriverModes(pScrn); 1210 1211 if (i == 0 || pScrn->modes == NULL) { 1212 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 1213 vbeFree(cPtr->pVbe); 1214 cPtr->pVbe = NULL; 1215 CHIPSFreeRec(pScrn); 1216 return FALSE; 1217 } 1218 1219 /* 1220 * Set the CRTC parameters for all of the modes based on the type 1221 * of mode, and the chipset's interlace requirements. 1222 * 1223 * Calling this is required if the mode->Crtc* values are used by the 1224 * driver and if the driver doesn't provide code to set them. They 1225 * are not pre-initialised at all. 1226 */ 1227 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 1228 1229 /* Set the current mode to the first in the list */ 1230 pScrn->currentMode = pScrn->modes; 1231 1232 /* Print the list of modes being used */ 1233 xf86PrintModes(pScrn); 1234 1235 /* If monitor resolution is set on the command line, use it */ 1236 xf86SetDpi(pScrn, 0, 0); 1237 1238 /* Load bpp-specific modules */ 1239 switch (pScrn->bitsPerPixel) { 1240#ifdef HAVE_XF1BPP 1241 case 1: 1242 if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) { 1243 vbeFree(cPtr->pVbe); 1244 cPtr->pVbe = NULL; 1245 CHIPSFreeRec(pScrn); 1246 return FALSE; 1247 } 1248 break; 1249#endif 1250#ifdef HAVE_XF4BPP 1251 case 4: 1252 if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) { 1253 vbeFree(cPtr->pVbe); 1254 cPtr->pVbe = NULL; 1255 CHIPSFreeRec(pScrn); 1256 return FALSE; 1257 } 1258 break; 1259#endif 1260 default: 1261 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 1262 vbeFree(cPtr->pVbe); 1263 cPtr->pVbe = NULL; 1264 CHIPSFreeRec(pScrn); 1265 return FALSE; 1266 } 1267 break; 1268 } 1269 1270 if (cPtr->Flags & ChipsAccelSupport) { 1271 if (!xf86LoadSubModule(pScrn, "xaa")) { 1272 vbeFree(cPtr->pVbe); 1273 cPtr->pVbe = NULL; 1274 CHIPSFreeRec(pScrn); 1275 return FALSE; 1276 } 1277 } 1278 1279 if (cPtr->Flags & ChipsShadowFB) { 1280 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 1281 vbeFree(cPtr->pVbe); 1282 cPtr->pVbe = NULL; 1283 CHIPSFreeRec(pScrn); 1284 return FALSE; 1285 } 1286 } 1287 1288 if (cPtr->Accel.UseHWCursor) { 1289 if (!xf86LoadSubModule(pScrn, "ramdac")) { 1290 vbeFree(cPtr->pVbe); 1291 cPtr->pVbe = NULL; 1292 CHIPSFreeRec(pScrn); 1293 return FALSE; 1294 } 1295 } 1296 1297#ifndef XSERVER_LIBPCIACCESS 1298 if (cPtr->Flags & ChipsLinearSupport) 1299 xf86SetOperatingState(resVgaMem, cPtr->pEnt->index, ResDisableOpr); 1300 1301 if (cPtr->MMIOBaseVGA) 1302 xf86SetOperatingState(resVgaIo, cPtr->pEnt->index, ResDisableOpr); 1303#endif 1304 1305 vbeFree(cPtr->pVbe); 1306 cPtr->pVbe = NULL; 1307 return TRUE; 1308} 1309 1310static Bool 1311chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags) 1312{ 1313 int bytesPerPixel; 1314 unsigned char tmp; 1315 MessageType from; 1316 int i; 1317 unsigned int Probed[3], FPclkI, CRTclkI; 1318 double real; 1319 int val, indx; 1320 const char *s; 1321 pointer pVbeModule = NULL; 1322 1323 vgaHWPtr hwp; 1324 CHIPSPtr cPtr = CHIPSPTR(pScrn); 1325 CHIPSEntPtr cPtrEnt = NULL; 1326 CHIPSPanelSizePtr Size = &cPtr->PanelSize; 1327 CHIPSMemClockPtr MemClk = &cPtr->MemClock; 1328 CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock); 1329#ifndef XSERVER_LIBPCIACCESS 1330 resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END }; 1331#endif 1332 1333 /* Set pScrn->monitor */ 1334 pScrn->monitor = pScrn->confScreen->monitor; 1335 1336 /* All HiQV chips support 16/24/32 bpp */ 1337 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb | 1338 SupportConvert32to24 | PreferConvert32to24)) 1339 return FALSE; 1340 else { 1341 /* Check that the returned depth is one we support */ 1342 switch (pScrn->depth) { 1343 case 1: 1344 case 4: 1345 case 8: 1346 case 15: 1347 case 16: 1348 case 24: 1349 case 32: 1350 /* OK */ 1351 break; 1352 default: 1353 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1354 "Given depth (%d) is not supported by this driver\n", 1355 pScrn->depth); 1356 return FALSE; 1357 } 1358 } 1359 xf86PrintDepthBpp(pScrn); 1360 1361 /* Get the depth24 pixmap format */ 1362 if (pScrn->depth == 24 && pix24bpp == 0) 1363 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 1364 1365 /* 1366 * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp 1367 */ 1368 if (!vgaHWGetHWRec(pScrn)) 1369 return FALSE; 1370 1371 hwp = VGAHWPTR(pScrn); 1372 vgaHWGetIOBase(hwp); 1373 cPtr->PIOBase = hwp->PIOOffset; 1374 /* 1375 * Must allow ensure that storage for the 2nd set of vga registers is 1376 * allocated for dual channel cards 1377 */ 1378 if ((cPtr->Flags & ChipsDualChannelSupport) && 1379 (! xf86IsEntityShared(pScrn->entityList[0]))) 1380 vgaHWAllocDefaultRegs(&(cPtr->VgaSavedReg2)); 1381 1382 /* 1383 * This must happen after pScrn->display has been set because 1384 * xf86SetWeight references it. 1385 */ 1386 if (pScrn->depth > 8) { 1387 /* The defaults are OK for us */ 1388 rgb zeros = {0, 0, 0}; 1389 1390 if (!xf86SetWeight(pScrn, zeros, zeros)) { 1391 return FALSE; 1392 } else { 1393 /* XXX check that weight returned is supported */ 1394 ; 1395 } 1396 } 1397 1398 if (!xf86SetDefaultVisual(pScrn, -1)) 1399 return FALSE; 1400 1401 /* The gamma fields must be initialised when using the new cmap code */ 1402 if (pScrn->depth > 1) { 1403 Gamma zeros = {0.0, 0.0, 0.0}; 1404 1405 if (!xf86SetGamma(pScrn, zeros)) 1406 return FALSE; 1407 } 1408 1409 bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3); 1410 1411 /* Collect all of the relevant option flags (fill in pScrn->options) */ 1412 xf86CollectOptions(pScrn, NULL); 1413 /* Process the options */ 1414 if (!(cPtr->Options = malloc(sizeof(ChipsHiQVOptions)))) 1415 return FALSE; 1416 memcpy(cPtr->Options, ChipsHiQVOptions, sizeof(ChipsHiQVOptions)); 1417 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options); 1418 1419 /* Set the bits per RGB */ 1420 if (pScrn->depth > 1) { 1421 /* Default to 6, is this right for HiQV?? */ 1422 pScrn->rgbBits = 8; 1423 if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS, &val)) { 1424 if (val == 6 || val == 8) { 1425 pScrn->rgbBits = val; 1426 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to " 1427 "%d\n", pScrn->rgbBits); 1428 } else 1429 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid number of " 1430 "rgb bits %d\n", val); 1431 } 1432 } 1433 if ((cPtr->Flags & ChipsAccelSupport) && 1434 (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) { 1435 cPtr->Flags &= ~ChipsAccelSupport; 1436 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 1437 } 1438 1439 from = X_DEFAULT; 1440 if (pScrn->bitsPerPixel < 8) { 1441 /* Default to SW cursor for 1/4 bpp */ 1442 cPtr->Accel.UseHWCursor = FALSE; 1443 } else { 1444 cPtr->Accel.UseHWCursor = TRUE; 1445 } 1446 if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR, 1447 &cPtr->Accel.UseHWCursor)) 1448 from = X_CONFIG; 1449 if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR, 1450 &cPtr->Accel.UseHWCursor)) { 1451 from = X_CONFIG; 1452 cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor; 1453 } 1454 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 1455 (cPtr->Accel.UseHWCursor) ? "HW" : "SW"); 1456 1457 /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */ 1458 if (pScrn->bitsPerPixel < 8) { 1459 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) { 1460 cPtr->Flags &= ~ChipsLinearSupport; 1461 from = X_CONFIG; 1462 } 1463 } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) { 1464 cPtr->Flags &= ~ChipsLinearSupport; 1465 from = X_CONFIG; 1466 } 1467 1468#ifndef HAVE_ISA 1469 if (!(cPtr->Flags & ChipsLinearSupport)) { 1470 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Linear framebuffer required\n"); 1471 return FALSE; 1472 } 1473#endif 1474 1475 /* linear base */ 1476 if (cPtr->Flags & ChipsLinearSupport) { 1477 if (cPtr->pEnt->location.type == BUS_PCI) { 1478 /* Tack on 0x800000 to access the big-endian aperture? */ 1479#if X_BYTE_ORDER == X_BIG_ENDIAN 1480 if (BE_SWAP_APRETURE(pScrn,cPtr)) 1481 cPtr->FbAddress = (PCI_REGION_BASE(cPtr->PciInfo, 0, REGION_MEM) & 0xff800000) + 0x800000L; 1482 else 1483#endif 1484 cPtr->FbAddress = PCI_REGION_BASE(cPtr->PciInfo, 0, REGION_MEM) & 0xff800000; 1485 1486 from = X_PROBED; 1487#ifndef XSERVER_LIBPCIACCESS 1488 if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone)) 1489 cPtr->Flags &= ~ChipsLinearSupport; 1490#endif 1491 } else { 1492 if (cPtr->pEnt->device->MemBase) { 1493 cPtr->FbAddress = cPtr->pEnt->device->MemBase; 1494 from = X_CONFIG; 1495 } else { 1496 cPtr->FbAddress = ((unsigned int) 1497 (cPtr->readXR(cPtr, 0x06))) << 24; 1498 cPtr->FbAddress |= ((unsigned int) 1499 (0x80 & (cPtr->readXR(cPtr, 0x05)))) << 16; 1500 from = X_PROBED; 1501 } 1502#ifndef XSERVER_LIBPCIACCESS 1503 linearRes[0].rBegin = cPtr->FbAddress; 1504 linearRes[0].rEnd = cPtr->FbAddress + 0x800000; 1505 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 1506 cPtr->Flags &= ~ChipsLinearSupport; 1507 from = X_PROBED; 1508 } 1509#endif 1510 } 1511 } 1512 if (cPtr->Flags & ChipsLinearSupport) { 1513 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1514 "Enabling linear addressing\n"); 1515 xf86DrvMsg(pScrn->scrnIndex, from, 1516 "base address is set at 0x%lX.\n", cPtr->FbAddress); 1517#if X_BYTE_ORDER == X_BIG_ENDIAN 1518 if (BE_SWAP_APRETURE(pScrn,cPtr)) 1519 cPtr->IOAddress = cPtr->FbAddress - 0x400000L; 1520 else 1521#endif 1522 cPtr->IOAddress = cPtr->FbAddress + 0x400000L; 1523 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, 1524 "IOAddress is set at 0x%lX.\n",(unsigned long)cPtr->IOAddress); 1525 1526 } else 1527 xf86DrvMsg(pScrn->scrnIndex, from, 1528 "Disabling linear addressing\n"); 1529 1530 if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE)) 1531 || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) { 1532 if (!(cPtr->Flags & ChipsLinearSupport)) { 1533 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1534 "Option \"ShadowFB\" ignored. Not supported without linear addressing\n"); 1535 } else if (pScrn->depth < 8) { 1536 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1537 "Option \"ShadowFB\" ignored. Not supported at this depth.\n"); 1538 } else { 1539 cPtr->Rotate = 0; 1540 if (s) { 1541 if(!xf86NameCmp(s, "CW")) { 1542 /* accel is disabled below for shadowFB */ 1543 cPtr->Flags |= ChipsShadowFB; 1544 cPtr->Rotate = 1; 1545 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1546 "Rotating screen clockwise\n"); 1547 } else if(!xf86NameCmp(s, "CCW")) { 1548 cPtr->Flags |= ChipsShadowFB; 1549 cPtr->Rotate = -1; 1550 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 1551 "counter clockwise\n"); 1552 } else { 1553 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 1554 "value for Option \"Rotate\"\n", s); 1555 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1556 "Valid options are \"CW\" or \"CCW\"\n"); 1557 } 1558 } else { 1559 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1560 "Using \"Shadow Framebuffer\"\n"); 1561 cPtr->Flags |= ChipsShadowFB; 1562 } 1563 } 1564 } 1565 1566 if ((s = xf86GetOptValString(cPtr->Options, OPTION_OVERLAY))) { 1567 if (!*s || !xf86NameCmp(s, "8,16") || !xf86NameCmp(s, "16,8")) { 1568 if (pScrn->bitsPerPixel == 16) { 1569 if (cPtr->Flags & ChipsLinearSupport) { 1570 cPtr->Flags |= ChipsOverlay8plus16; 1571 if(!xf86GetOptValInteger( 1572 cPtr->Options, OPTION_COLOR_KEY, &(pScrn->colorKey))) 1573 pScrn->colorKey = TRANSPARENCY_KEY; 1574 pScrn->overlayFlags = OVERLAY_8_16_DUALFB; 1575 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1576 "PseudoColor overlay enabled.\n"); 1577 if (!xf86IsOptionSet(cPtr->Options, OPTION_LCD_STRETCH)) 1578 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1579 " - Forcing option \"Stretch\" \"ON\".\n"); 1580 if (!xf86IsOptionSet(cPtr->Options, OPTION_LCD_CENTER)) 1581 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1582 " - Forcing option \"LcdCenter\" \"OFF\".\n"); 1583 if (cPtr->Flags & ChipsShadowFB) { 1584 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1585 " - Disabling \"Shadow Framebuffer\".\n"); 1586 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1587 " Not support with option \"8Plus16\".\n"); 1588 cPtr->Flags &= ~ChipsShadowFB; 1589 cPtr->Rotate = 0; 1590 } 1591 } else { 1592 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Option \"Overlay\" ignored. Not supported without linear addressing\n"); 1593 } 1594 } else { 1595 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1596 "Option \"Overlay\" is not supported in this configuration\n"); 1597 } 1598 } else { 1599 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1600 "\"%s\" is not a valid value for Option \"Overlay\"\n", s); 1601 } 1602 } 1603 1604 if (!(cPtr->Flags & ChipsOverlay8plus16)) { 1605 if(xf86GetOptValInteger(cPtr->Options, OPTION_VIDEO_KEY, 1606 &(cPtr->videoKey))) { 1607 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", 1608 cPtr->videoKey); 1609 } else { 1610 cPtr->videoKey = (1 << pScrn->offset.red) | 1611 (1 << pScrn->offset.green) | 1612 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 1613 << pScrn->offset.blue); 1614 } 1615 } 1616 1617 if (cPtr->Flags & ChipsShadowFB) { 1618 if (cPtr->Flags & ChipsAccelSupport) { 1619 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1620 "HW acceleration is not supported with shadow fb\n"); 1621 cPtr->Flags &= ~ChipsAccelSupport; 1622 } 1623 if (cPtr->Rotate && cPtr->Accel.UseHWCursor) { 1624 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1625 "HW cursor is not supported with rotate\n"); 1626 cPtr->Accel.UseHWCursor = FALSE; 1627 } 1628 } 1629 1630 if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, TRUE)) { 1631 cPtr->UseMMIO = TRUE; 1632 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1633 "Using MMIO\n"); 1634 1635 /* Are we using MMIO mapping of VGA registers */ 1636 if (xf86ReturnOptValBool(cPtr->Options, OPTION_FULL_MMIO, FALSE)) { 1637 if ((cPtr->Flags & ChipsLinearSupport) 1638 && (cPtr->Flags & ChipsFullMMIOSupport) 1639 && (cPtr->pEnt->location.type == BUS_PCI)) { 1640 1641 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1642 "Enabling Full MMIO\n"); 1643 cPtr->UseFullMMIO = TRUE; 1644 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1645 "Using Full MMIO\n"); 1646 1647 /* 1648 * We need to map the framebuffer to read/write regs. 1649 * but can't do that without the FbMapSize. So need to 1650 * fake value for PreInit. This isn't a problem as 1651 * framebuffer isn't actually used in PreInit 1652 */ 1653 cPtr->FbMapSize = 1024 * 1024; 1654 1655 /* Map the linear framebuffer */ 1656 if (!chipsMapMem(pScrn)) 1657 return FALSE; 1658 1659 /* Setup the MMIO register functions */ 1660 if (cPtr->MMIOBaseVGA) { 1661 CHIPSSetMmioExtFuncs(cPtr); 1662 CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBaseVGA, 0x0); 1663 } 1664 } else { 1665 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1666 "FULL_MMIO option ignored\n"); 1667 } 1668 } 1669 } else { 1670 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"Disabling MMIO: " 1671 "no acceleration, no hw_cursor\n"); 1672 cPtr->UseMMIO = FALSE; 1673 cPtr->Accel.UseHWCursor = FALSE; 1674 cPtr->Flags &= ~ChipsAccelSupport; 1675 } 1676 1677 1678 if (cPtr->Flags & ChipsDualChannelSupport) { 1679 1680 if (xf86IsEntityShared(pScrn->entityList[0])) { 1681 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 1682 CHIPSEntityIndex)->ptr; 1683#if 1 1684 /* 1685 * XXX This assumes that the lower number screen is always the 1686 * "master" head, and that the "master" is the first CRTC. This 1687 * can result in unexpected behaviour when the config file marks 1688 * the primary CRTC as the second screen. 1689 */ 1690 if (xf86IsPrimInitDone(pScrn->entityList[0])) 1691#else 1692 /* 1693 * This is an alternative version that determines which is the 1694 * secondary CRTC from the screen field in cPtr->pEnt->device. 1695 * It doesn't currently work because there are things that assume 1696 * the primary CRTC is initialised first. 1697 */ 1698 if (cPtr->pEnt->device->screen == 1) 1699 1700#endif 1701 { 1702 /* This is the second crtc */ 1703 cPtr->SecondCrtc = TRUE; 1704 cPtr->UseDualChannel = TRUE; 1705 } else 1706 cPtr->SecondCrtc = FALSE; 1707 1708 } else { 1709 if (xf86ReturnOptValBool(cPtr->Options, 1710 OPTION_DUAL_REFRESH, FALSE)) { 1711 cPtr->Flags |= ChipsDualRefresh; 1712 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1713 "Dual Refresh mode enabled\n"); 1714 cPtr->UseDualChannel = TRUE; 1715 } 1716 } 1717 1718 /* Store IOSS/MSS so that we can restore them */ 1719 cPtr->storeIOSS = cPtr->readIOSS(cPtr); 1720 cPtr->storeMSS = cPtr->readMSS(cPtr); 1721 DUALOPEN; 1722 } 1723 1724 /* memory size */ 1725 if (cPtr->pEnt->device->videoRam != 0) { 1726 pScrn->videoRam = cPtr->pEnt->device->videoRam; 1727 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n", 1728 pScrn->videoRam); 1729 } else { 1730 /* not given, probe it */ 1731 switch (cPtr->Chipset) { 1732 case CHIPS_CT69030: 1733 /* The ct69030 has 4Mb of SGRAM integrated */ 1734 pScrn->videoRam = 4096; 1735 cPtr->Flags |= Chips64BitMemory; 1736 break; 1737 case CHIPS_CT69000: 1738 /* The ct69000 has 2Mb of SGRAM integrated */ 1739 pScrn->videoRam = 2048; 1740 cPtr->Flags |= Chips64BitMemory; 1741 break; 1742 case CHIPS_CT65550: 1743 /* XR43: DRAM interface */ 1744 /* bit 2-1: memory size */ 1745 /* 0: 1024 kB */ 1746 /* 1: 2048 kB */ 1747 /* 2: reserved */ 1748 /* 3: reserved */ 1749 switch (((cPtr->readXR(cPtr, 0x43)) & 0x06) >> 1) { 1750 case 0: 1751 pScrn->videoRam = 1024; 1752 break; 1753 case 1: 1754 case 2: 1755 case 3: 1756 pScrn->videoRam = 2048; 1757 break; 1758 } 1759 break; 1760 default: 1761 /* XRE0: Software reg */ 1762 /* bit 3-0: memory size */ 1763 /* 0: 512k */ 1764 /* 1: 1024k */ 1765 /* 2: 1536k(1.5M)*/ 1766 /* 3: 2048k */ 1767 /* 7: 4096k */ 1768 tmp = (cPtr->readXR(cPtr, 0xE0)) & 0xF; 1769 switch (tmp) { 1770 case 0: 1771 pScrn->videoRam = 512; 1772 break; 1773 case 1: 1774 pScrn->videoRam = 1024; 1775 break; 1776 case 2: 1777 pScrn->videoRam = 1536; 1778 break; 1779 case 3: 1780 pScrn->videoRam = 2048; 1781 break; 1782 case 7: 1783 pScrn->videoRam = 4096; 1784 break; 1785 default: 1786 pScrn->videoRam = 1024; 1787 break; 1788 } 1789 /* XR43: DRAM interface */ 1790 /* bit 4-5 mem interface width */ 1791 /* 00: 32Bit */ 1792 /* 01: 64Bit */ 1793 tmp = cPtr->readXR(cPtr, 0x43); 1794 if ((tmp & 0x10) == 0x10) 1795 cPtr->Flags |= Chips64BitMemory; 1796 break; 1797 } 1798 } 1799 1800#if X_BYTE_ORDER == X_BIG_ENDIAN 1801 if (cPtr->pEnt->chipset == CHIPS_CT69030 && ((cPtr->readXR(cPtr, 0x71) & 0x2)) == 0) /* CFG9: Pipeline variable ByteSwap mapping */ 1802 cPtr->dualEndianAp = TRUE; 1803 else /* CFG9: Pipeline A/B mapping */ 1804 cPtr->dualEndianAp = FALSE; 1805#endif 1806 1807 if ((cPtr->Flags & ChipsDualChannelSupport) && 1808 (xf86IsEntityShared(pScrn->entityList[0]))) { 1809 /* 1810 * This takes gives either half or the amount of memory specified 1811 * with the Crt2Memory option 1812 */ 1813 pScrn->memPhysBase = cPtr->FbAddress; 1814 1815 if(cPtr->SecondCrtc == FALSE) { 1816 int crt2mem = -1, adjust; 1817 1818 xf86GetOptValInteger(cPtr->Options, OPTION_CRT2_MEM, &crt2mem); 1819 if (crt2mem > 0) { 1820 adjust = crt2mem; 1821 from = X_CONFIG; 1822 } else { 1823 adjust = pScrn->videoRam / 2; 1824 from = X_DEFAULT; 1825 } 1826 xf86DrvMsg(pScrn->scrnIndex, from, 1827 "CRT2 will use %dK of VideoRam\n", 1828 adjust); 1829 1830 cPtrEnt->mastervideoRam = pScrn->videoRam - adjust; 1831 pScrn->videoRam = cPtrEnt->mastervideoRam; 1832 cPtrEnt->slavevideoRam = adjust; 1833 cPtrEnt->masterFbAddress = cPtr->FbAddress; 1834 cPtr->FbMapSize = 1835 cPtrEnt->masterFbMapSize = pScrn->videoRam * 1024; 1836 cPtrEnt->slaveFbMapSize = cPtrEnt->slavevideoRam * 1024; 1837 pScrn->fbOffset = 0; 1838 } else { 1839 cPtrEnt->slaveFbAddress = cPtr->FbAddress + 1840 cPtrEnt->masterFbMapSize; 1841 cPtr->FbMapSize = cPtrEnt->slaveFbMapSize; 1842 pScrn->videoRam = cPtrEnt->slavevideoRam; 1843 pScrn->fbOffset = cPtrEnt->masterFbMapSize; 1844 } 1845 1846 cPtrEnt->refCount++; 1847 } else { 1848 /* Normal Handling of video ram etc */ 1849 cPtr->FbMapSize = pScrn->videoRam * 1024; 1850 } 1851 1852 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n", 1853 pScrn->videoRam); 1854 1855 /* Store register values that might be messed up by a suspend resume */ 1856 /* Do this early as some of the other code in PreInit relies on it */ 1857 cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01); 1858 cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ? 1859 0x3D0 : 0x3B0); 1860 1861 /* 1862 * Do DDC here: if VESA BIOS detects an external monitor it 1863 * might switch. SetPanelType() will detect this. 1864 */ 1865 if ((pVbeModule = xf86LoadSubModule(pScrn, "ddc"))) { 1866 Bool ddc_done = FALSE; 1867 xf86MonPtr pMon; 1868 1869 if (cPtr->pVbe) { 1870 if ((pMon 1871 = xf86PrintEDID(vbeDoEDID(cPtr->pVbe, pVbeModule))) != NULL) { 1872 ddc_done = TRUE; 1873 xf86SetDDCproperties(pScrn,pMon); 1874 } 1875 } 1876 1877 if (!ddc_done) 1878 if (xf86LoadSubModule(pScrn, "i2c")) { 1879 if (chips_i2cInit(pScrn)) { 1880 if ((pMon = xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex, 1881 cPtr->I2C))) != NULL) 1882 ddc_done = TRUE; 1883 xf86SetDDCproperties(pScrn,pMon); 1884 } 1885 } 1886 if (!ddc_done) 1887 chips_ddc1(pScrn); 1888 } 1889 1890 /*test STN / TFT */ 1891 tmp = cPtr->readFR(cPtr, 0x10); 1892 1893 /* XR51 or FR10: DISPLAY TYPE REGISTER */ 1894 /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */ 1895 /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */ 1896 switch (tmp & 0x3) { 1897 case 0: 1898 if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) { 1899 cPtr->PanelType |= ChipsSS; 1900 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n"); 1901 } else { 1902 cPtr->PanelType |= ChipsTFT; 1903 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n"); 1904 } 1905 break; 1906 case 2: 1907 cPtr->PanelType |= ChipsDS; 1908 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n"); 1909 case 3: 1910 cPtr->PanelType |= ChipsDD; 1911 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n"); 1912 break; 1913 default: 1914 break; 1915 } 1916 1917 chipsSetPanelType(cPtr); 1918 from = X_PROBED; 1919 { 1920 Bool fp_mode; 1921 if (xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_mode)) { 1922 if (fp_mode) { 1923 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode on\n"); 1924 cPtr->PanelType |= ChipsLCD; 1925 } else { 1926 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode off\n"); 1927 cPtr->PanelType = ~ChipsLCD; 1928 } 1929 from = X_CONFIG; 1930 } 1931 } 1932 if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT)) 1933 xf86DrvMsg(pScrn->scrnIndex, from, "LCD/CRT\n"); 1934 else if (cPtr->PanelType & ChipsLCD) 1935 xf86DrvMsg(pScrn->scrnIndex, from, "LCD\n"); 1936 else if (cPtr->PanelType & ChipsCRT) { 1937 xf86DrvMsg(pScrn->scrnIndex, from, "CRT\n"); 1938 /* monitor info */ 1939#if 1 1940 cPtr->Monitor = chipsSetMonitor(pScrn); 1941#endif 1942 } 1943 /* screen size */ 1944 /* 1945 * In LCD mode / dual mode we want to derive the timing values from 1946 * the ones preset by bios 1947 */ 1948 if (cPtr->PanelType & ChipsLCD) { 1949 1950 /* for 65550 we only need H/VDisplay values for screen size */ 1951 unsigned char fr25, tmp1; 1952#ifdef DEBUG 1953 unsigned char fr26; 1954 char tmp2; 1955#endif 1956 fr25 = cPtr->readFR(cPtr, 0x25); 1957 tmp = cPtr->readFR(cPtr, 0x20); 1958 Size->HDisplay = ((tmp + ((fr25 & 0x0F) << 8)) + 1) << 3; 1959 tmp = cPtr->readFR(cPtr, 0x30); 1960 tmp1 = cPtr->readFR(cPtr, 0x35); 1961 Size->VDisplay = ((tmp1 & 0x0F) << 8) + tmp + 1; 1962#ifdef DEBUG 1963 tmp = cPtr->readFR(cPtr, 0x21); 1964 Size->HRetraceStart = ((tmp + ((fr25 & 0xF0) << 4)) + 1) << 3; 1965 tmp1 = cPtr->readFR(cPtr, 0x22); 1966 tmp2 = (tmp1 & 0x1F) - (tmp & 0x3F); 1967 Size->HRetraceEnd = ((((tmp2 < 0) ? (tmp2 + 0x40) : tmp2) << 3) 1968 + Size->HRetraceStart); 1969 tmp = cPtr->readFR(cPtr, 0x23); 1970 fr26 = cPtr->readFR(cPtr, 0x26); 1971 Size->HTotal = ((tmp + ((fr26 & 0x0F) << 8)) + 5) << 3; 1972 xf86ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n", 1973 Size->HDisplay, Size->VDisplay, 1974 Size->HRetraceStart,Size->HRetraceEnd, 1975 Size->HTotal); 1976#endif 1977 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n", 1978 Size->HDisplay, Size->VDisplay); 1979 /* Warn the user if the panel size has been overridden by 1980 * the modeline values 1981 */ 1982 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 1983 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1984 "Display size overridden by modelines.\n"); 1985 } 1986 } 1987 1988 /* Frame Buffer */ /* for LCDs */ 1989 if (IS_STN(cPtr->PanelType)) { 1990 tmp = cPtr->readFR(cPtr, 0x1A); /*Frame Buffer Ctrl. */ 1991 if (tmp & 1) { 1992 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n"); 1993 if (!(tmp & 0x80)) { 1994 /* Formula for calculating the size of the framebuffer. 3 1995 * bits per pixel 10 pixels per 32 bit dword. If frame 1996 * acceleration is enabled the size can be halved. 1997 */ 1998 cPtr->FrameBufferSize = ( Size->HDisplay * 1999 Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2); 2000 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2001 "Using embedded Frame Buffer, size %d bytes\n", 2002 cPtr->FrameBufferSize); 2003 } else 2004 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2005 "Using external Frame Buffer used\n"); 2006 } 2007 if (tmp & 2) 2008 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2009 "Frame accelerator enabled\n"); 2010 } 2011 2012 /* bus type */ 2013 tmp = (cPtr->readXR(cPtr, 0x08)) & 1; 2014 if (tmp == 1) { /*PCI */ 2015 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n"); 2016 cPtr->Bus = ChipsPCI; 2017 } else { /* XR08: Linear addressing base, not for PCI */ 2018 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 2019 cPtr->Bus = ChipsVLB; 2020 } 2021 2022 /* disable acceleration for 1 and 4 bpp */ 2023 if (pScrn->bitsPerPixel < 8) { 2024 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2025 "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel); 2026 cPtr->Flags &= ~ChipsAccelSupport; 2027 } 2028 2029 /* Set the flags for Colour transparency. This is dependent 2030 * on the revision on the chip. Until exactly which chips 2031 * have this bug are found, only allow 8bpp Colour transparency */ 2032 if ((pScrn->bitsPerPixel == 8) || ((cPtr->Chipset >= CHIPS_CT65555) && 2033 (pScrn->bitsPerPixel >= 8) && (pScrn->bitsPerPixel <= 24))) 2034 cPtr->Flags |= ChipsColorTransparency; 2035 else 2036 cPtr->Flags &= ~ChipsColorTransparency; 2037 2038 /* DAC info */ 2039 if (!((cPtr->readXR(cPtr, 0xD0)) & 0x01)) 2040 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n"); 2041 2042 /* MMIO address offset */ 2043 cPtr->Regs32 = ChipsReg32HiQV; 2044 2045 /* sync reset ignored on this chipset */ 2046 cPtr->SyncResetIgn = TRUE; /* !! */ 2047 2048 /* We use a programmable clock */ 2049 pScrn->numClocks = 26; /* Some number */ 2050 pScrn->progClock = TRUE; 2051 cPtr->ClockType = HiQV_STYLE | TYPE_PROGRAMMABLE; 2052 2053 if (cPtr->pEnt->device->textClockFreq > 0) { 2054 SaveClk->Clock = cPtr->pEnt->device->textClockFreq; 2055 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2056 "Using textclock freq: %7.3f.\n", 2057 SaveClk->Clock/1000.0); 2058 } else 2059 SaveClk->Clock = 0; 2060 2061 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n"); 2062 2063 /* Set the maximum memory clock. */ 2064 switch (cPtr->Chipset) { 2065 case CHIPS_CT65550: 2066 if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6) 2067 MemClk->Max = 38000; /* Revision A chips */ 2068 else 2069 MemClk->Max = 50000; /* Revision B chips */ 2070 break; 2071 case CHIPS_CT65554: 2072 case CHIPS_CT65555: 2073 case CHIPS_CT68554: 2074 MemClk->Max = 55000; 2075 break; 2076 case CHIPS_CT69000: 2077 MemClk->Max = 83000; 2078 break; 2079 case CHIPS_CT69030: 2080 MemClk->Max = 100000; 2081 break; 2082 } 2083 2084 /* Probe the dot clocks */ 2085 for (i = 0; i < 3; i++) { 2086 unsigned int N,M,PSN,P,VCO_D; 2087 int offset = i * 4; 2088 2089 tmp = cPtr->readXR(cPtr,0xC2 + offset); 2090 M = (cPtr->readXR(cPtr, 0xC0 + offset) 2091 | (tmp & 0x03)) + 2; 2092 N = (cPtr->readXR(cPtr, 0xC1 + offset) 2093 | (( tmp >> 4) & 0x03)) + 2; 2094 tmp = cPtr->readXR(cPtr, 0xC3 + offset); 2095 PSN = (cPtr->Chipset == CHIPS_CT69000 || cPtr->Chipset == CHIPS_CT69030) 2096 ? 1 : (((tmp & 0x1) ? 1 : 4) * ((tmp & 0x02) ? 5 : 1)); 2097 VCO_D = ((tmp & 0x04) ? ((cPtr->Chipset == CHIPS_CT69000 || 2098 cPtr->Chipset == CHIPS_CT69030) ? 1 : 16) : 4); 2099 P = ((tmp & 0x70) >> 4); 2100 Probed[i] = VCO_D * Fref / N; 2101 Probed[i] = Probed[i] * M / (PSN * (1 << P)); 2102 Probed[i] = Probed[i] / 1000; 2103 } 2104 CRTclkI = (hwp->readMiscOut(hwp) >> 2) & 0x03; 2105 if (CRTclkI == 3) CRTclkI = 2; 2106 if (cPtr->Chipset == CHIPS_CT69030) 2107 FPclkI = (cPtr->readFR(cPtr, 0x01) >> 2) & 0x3; 2108 else 2109 FPclkI = (cPtr->readFR(cPtr, 0x03) >> 2) & 0x3; 2110 if (FPclkI == 3) FPclkI = 2; 2111 for (i = 0; i < 3; i++) { 2112 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2113 "Dot clock %i: %7.3f MHz",i, 2114 (float)(Probed[i])/1000.); 2115 if (FPclkI == i) xf86ErrorF(" FPclk"); 2116 if (CRTclkI == i) xf86ErrorF(" CRTclk"); 2117 xf86ErrorF("\n"); 2118 } 2119 cPtr->FPclock = Probed[FPclkI]; 2120 cPtr->FPclkInx = FPclkI; 2121 if (CRTclkI == FPclkI) { 2122 if (FPclkI == 2) 2123 CRTclkI = 1; 2124 else 2125 CRTclkI = 2; 2126 } 2127 cPtr->CRTclkInx = CRTclkI; 2128 2129 2130 /* 2131 * Some chips seem to dislike some clocks in one of the PLL's. Give 2132 * the user the oppurtunity to change it 2133 */ 2134 if (xf86GetOptValInteger(cPtr->Options, OPTION_CRT_CLK_INDX, &indx)) { 2135 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Force CRT Clock index to %d\n", 2136 indx); 2137 cPtr->CRTclkInx = indx; 2138 2139 if (xf86GetOptValInteger(cPtr->Options, OPTION_FP_CLK_INDX, &indx)) { 2140 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2141 "Force FP Clock index to %d\n", indx); 2142 cPtr->FPclkInx = indx; 2143 } else { 2144 if (indx == cPtr->FPclkInx) { 2145 if (indx == 2) 2146 cPtr->FPclkInx = 1; 2147 else 2148 cPtr->FPclkInx = indx + 1; 2149 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2150 "FP Clock index forced to %d\n", cPtr->FPclkInx); 2151 } 2152 } 2153 } else if (xf86GetOptValInteger(cPtr->Options, OPTION_FP_CLK_INDX, 2154 &indx)) { 2155 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2156 "Force FP Clock index to %d\n", indx); 2157 cPtr->FPclkInx = indx; 2158 if (indx == cPtr->CRTclkInx) { 2159 if (indx == 2) 2160 cPtr->CRTclkInx = 1; 2161 else 2162 cPtr->CRTclkInx = indx + 1; 2163 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2164 "CRT Clock index forced to %d\n", cPtr->CRTclkInx); 2165 } 2166 } 2167 2168 2169 /* Probe the memory clock currently in use */ 2170 MemClk->xrCC = cPtr->readXR(cPtr, 0xCC); 2171 MemClk->M = (MemClk->xrCC & 0x7F) + 2; 2172 MemClk->xrCD = cPtr->readXR(cPtr, 0xCD); 2173 MemClk->N = (MemClk->xrCD & 0x7F) + 2; 2174 MemClk->xrCE = cPtr->readXR(cPtr, 0xCE); 2175 MemClk->PSN = (MemClk->xrCE & 0x1) ? 1 : 4; 2176 MemClk->P = ((MemClk->xrCE & 0x70) >> 4); 2177 /* Be careful with the calculation of ProbeClk as it can overflow */ 2178 MemClk->ProbedClk = 4 * Fref / MemClk->N; 2179 MemClk->ProbedClk = MemClk->ProbedClk * MemClk->M / (MemClk->PSN * 2180 (1 << MemClk->P)); 2181 MemClk->ProbedClk = MemClk->ProbedClk / 1000; 2182 MemClk->Clk = MemClk->ProbedClk; 2183 2184 if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) { 2185 int mclk = (int)(real * 1000.0); 2186 if (mclk <= MemClk->Max) { 2187 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2188 "Using memory clock of %7.3f MHz\n", 2189 (float)(mclk/1000.)); 2190 2191 /* Only alter the memory clock if the desired memory clock differs 2192 * by 50kHz from the one currently being used. 2193 */ 2194 if (abs(mclk - MemClk->ProbedClk) > 50) { 2195 unsigned char vclk[3]; 2196 2197 MemClk->Clk = mclk; 2198 chipsCalcClock(pScrn, MemClk->Clk, vclk); 2199 MemClk->M = vclk[1] + 2; 2200 MemClk->N = vclk[2] + 2; 2201 MemClk->P = (vclk[0] & 0x70) >> 4; 2202 MemClk->PSN = (vclk[0] & 0x1) ? 1 : 4; 2203 MemClk->xrCC = vclk[1]; 2204 MemClk->xrCD = vclk[2]; 2205 MemClk->xrCE = 0x80 || vclk[0]; 2206 } 2207 } else 2208 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2209 "Memory clock of %7.3f MHz exceeds limit of %7.3f MHz\n", 2210 (float)(mclk/1000.), 2211 (float)(MemClk->Max/1000.)); 2212 } else 2213 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2214 "Probed memory clock of %7.3f MHz\n", 2215 (float)(MemClk->ProbedClk/1000.)); 2216 2217 cPtr->ClockMulFactor = 1; 2218 2219 /* Set the min/max pixel clock */ 2220 switch (cPtr->Chipset) { 2221 case CHIPS_CT69030: 2222 cPtr->MinClock = 3000; 2223 cPtr->MaxClock = 170000; 2224 break; 2225 case CHIPS_CT69000: 2226 cPtr->MinClock = 3000; 2227 cPtr->MaxClock = 135000; 2228 break; 2229 case CHIPS_CT68554: 2230 case CHIPS_CT65555: 2231 cPtr->MinClock = 1000; 2232 cPtr->MaxClock = 110000; 2233 break; 2234 case CHIPS_CT65554: 2235 cPtr->MinClock = 1000; 2236 cPtr->MaxClock = 95000; 2237 break; 2238 case CHIPS_CT65550: 2239 cPtr->MinClock = 1000; 2240 if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6) { 2241 if ((cPtr->readFR(cPtr, 0x0A)) & 2) { 2242 /*5V Vcc */ 2243 cPtr->MaxClock = 100000; 2244 } else { 2245 /*3.3V Vcc */ 2246 cPtr->MaxClock = 80000; 2247 } 2248 } else 2249 cPtr->MaxClock = 95000; /* Revision B */ 2250 break; 2251 } 2252 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n", 2253 (float)(cPtr->MinClock / 1000.)); 2254 2255 /* Check if maxClock is limited by the MemClk. Only 70% to allow for */ 2256 /* RAS/CAS. Extra byte per memory clock needed if framebuffer used */ 2257 /* Extra byte if the overlay plane is activated */ 2258 /* If flag Chips64BitMemory is set assume a 64bitmemory interface, */ 2259 /* and 32bits on the others. Thus multiply by a suitable factor */ 2260 if (cPtr->Flags & Chips64BitMemory) { 2261 if (cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) 2262 if (cPtr->Flags & ChipsOverlay8plus16 ) 2263 cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 8 * 0.7 / 4); 2264 else 2265 cPtr->MaxClock = min(cPtr->MaxClock, 2266 MemClk->Clk * 8 * 0.7 / (bytesPerPixel + 1)); 2267 else 2268 if (cPtr->Flags & ChipsOverlay8plus16) 2269 cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 8 * 0.7 / 3); 2270 else 2271 cPtr->MaxClock = min(cPtr->MaxClock, 2272 MemClk->Clk * 8 * 0.7 / bytesPerPixel); 2273 } else { 2274 if (cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) 2275 if (cPtr->Flags & ChipsOverlay8plus16 ) 2276 cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 4 * 0.7 / 4); 2277 else 2278 cPtr->MaxClock = min(cPtr->MaxClock, 2279 MemClk->Clk * 4 * 0.7 / (bytesPerPixel + 1)); 2280 else 2281 if (cPtr->Flags & ChipsOverlay8plus16) 2282 cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 4 * 0.7 / 3); 2283 else 2284 cPtr->MaxClock = min(cPtr->MaxClock, 2285 MemClk->Clk * 4 * 0.7 / bytesPerPixel); 2286 } 2287 2288 2289 2290 if (cPtr->pEnt->device->dacSpeeds[0]) { 2291 int speed = 0; 2292 switch (pScrn->bitsPerPixel) { 2293 case 1: 2294 case 4: 2295 case 8: 2296 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8]; 2297 break; 2298 case 16: 2299 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16]; 2300 break; 2301 case 24: 2302 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24]; 2303 break; 2304 case 32: 2305 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP32]; 2306 break; 2307 } 2308 2309 if (speed == 0) 2310 speed = cPtr->pEnt->device->dacSpeeds[0]; 2311 from = X_CONFIG; 2312 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2313 "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n", 2314 (float)(speed / 1000.), (float)(cPtr->MaxClock / 1000.)); 2315 cPtr->MaxClock = speed; 2316 } else { 2317 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2318 "Max pixel clock is %7.3f MHz\n", 2319 (float)(cPtr->MaxClock / 1000.)); 2320 } 2321 /* 2322 * Prepare the FPclock: 2323 * if FPclock <= MaxClock : don't modify the FP clock. 2324 * else set FPclock to 90% of MaxClock. 2325 */ 2326 real = 0.; 2327 switch(bytesPerPixel) { 2328 case 1: 2329 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8, OPTUNITS_MHZ, &real)) 2330 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2331 "FP clock %7.3f MHz requested\n",real); 2332 break; 2333 case 2: 2334 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16, OPTUNITS_MHZ, &real)) 2335 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2336 "FP clock %7.3f MHz requested\n",real); 2337 break; 2338 case 3: 2339 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24, OPTUNITS_MHZ, &real)) 2340 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2341 "FP clock %7.3f MHz requested\n",real); 2342 break; 2343 case 4: 2344 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_32, OPTUNITS_MHZ, &real)) 2345 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2346 "FP clock %7.3f MHz requested\n",real); 2347 break; 2348 } 2349 val = (int) (real * 1000.); 2350 if (val && val >= cPtr->MinClock && val <= cPtr->MaxClock) 2351 cPtr->FPclock = val; 2352 else if (cPtr->FPclock > cPtr->MaxClock) 2353 cPtr->FPclock = (int)((float)cPtr->MaxClock * 0.9); 2354 else 2355 cPtr->FPclock = 0; /* special value */ 2356 cPtr->FPClkModified = FALSE; 2357 if (cPtr->FPclock) 2358 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2359 "FP clock set to %7.3f MHz\n", 2360 (float)(cPtr->FPclock / 1000.)); 2361 2362#if defined(__arm__) && defined(__NetBSD__) 2363 ChipsPALMode.next = pScrn->monitor->Modes; 2364 pScrn->monitor->Modes = &ChipsNTSCMode; 2365#endif 2366 2367 2368 if (cPtr->Flags & ChipsDualChannelSupport) { 2369 if (xf86IsEntityShared(pScrn->entityList[0])) { 2370 if (cPtr->SecondCrtc == TRUE) { 2371 cPtrEnt->slaveActive = FALSE; 2372 } else { 2373 cPtrEnt->masterActive = FALSE; 2374 } 2375 } 2376 /* Put IOSS/MSS back to normal */ 2377 cPtr->writeIOSS(cPtr, cPtr->storeIOSS); 2378 cPtr->writeMSS(cPtr, hwp, cPtr->storeMSS); 2379 2380 xf86SetPrimInitDone(pScrn->entityList[0]); 2381 } 2382 2383 return TRUE; 2384} 2385 2386static Bool 2387chipsPreInitWingine(ScrnInfoPtr pScrn, int flags) 2388{ 2389 int i, bytesPerPixel, NoClocks = 0; 2390 unsigned char tmp; 2391 MessageType from; 2392 vgaHWPtr hwp; 2393 CHIPSPtr cPtr = CHIPSPTR(pScrn); 2394 CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock); 2395 Bool useLinear = FALSE; 2396 char *s; 2397#ifndef XSERVER_LIBPCIACCESS 2398 resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END }; 2399#endif 2400 2401 /* Set pScrn->monitor */ 2402 pScrn->monitor = pScrn->confScreen->monitor; 2403 2404 if (cPtr->Flags & ChipsHDepthSupport) 2405 i = xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | 2406 SupportConvert32to24 | PreferConvert32to24); 2407 else 2408 i = xf86SetDepthBpp(pScrn, 8, 0, 0, NoDepth24Support); 2409 2410 if (!i) 2411 return FALSE; 2412 else { 2413 /* Check that the returned depth is one we support */ 2414 switch (pScrn->depth) { 2415 case 1: 2416 case 4: 2417 case 8: 2418 /* OK */ 2419 break; 2420 case 15: 2421 case 16: 2422 case 24: 2423 if (cPtr->Flags & ChipsHDepthSupport) 2424 break; /* OK */ 2425 /* fall through */ 2426 default: 2427 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2428 "Given depth (%d) is not supported by this driver\n", 2429 pScrn->depth); 2430 return FALSE; 2431 } 2432 } 2433 2434 xf86PrintDepthBpp(pScrn); 2435 2436 /* Get the depth24 pixmap format */ 2437 if (pScrn->depth == 24 && pix24bpp == 0) 2438 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 2439 2440 /* 2441 * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp 2442 */ 2443 if (!vgaHWGetHWRec(pScrn)) 2444 return FALSE; 2445 2446 hwp = VGAHWPTR(pScrn); 2447 vgaHWGetIOBase(hwp); 2448 2449 /* 2450 * This must happen after pScrn->display has been set because 2451 * xf86SetWeight references it. 2452 */ 2453 if (pScrn->depth > 8) { 2454 /* The defaults are OK for us */ 2455 rgb zeros = {0, 0, 0}; 2456 2457 if (!xf86SetWeight(pScrn, zeros, zeros)) { 2458 return FALSE; 2459 } else { 2460 /* XXX check that weight returned is supported */ 2461 ; 2462 } 2463 } 2464 2465 if (!xf86SetDefaultVisual(pScrn, -1)) 2466 return FALSE; 2467 2468 /* The gamma fields must be initialised when using the new cmap code */ 2469 if (pScrn->depth > 1) { 2470 Gamma zeros = {0.0, 0.0, 0.0}; 2471 2472 if (!xf86SetGamma(pScrn, zeros)) 2473 return FALSE; 2474 } 2475 2476 /* Store register values that might be messed up by a suspend resume */ 2477 /* Do this early as some of the other code in PreInit relies on it */ 2478 cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18; 2479 cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A; 2480 cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20; 2481 cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15); 2482 2483 cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01); 2484 cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ? 2485 0x3D0 : 0x3B0); 2486 2487 bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3); 2488 2489 /* Collect all of the relevant option flags (fill in pScrn->options) */ 2490 xf86CollectOptions(pScrn, NULL); 2491 2492 /* Process the options */ 2493 if (!(cPtr->Options = malloc(sizeof(ChipsWingineOptions)))) 2494 return FALSE; 2495 memcpy(cPtr->Options, ChipsWingineOptions, sizeof(ChipsWingineOptions)); 2496 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options); 2497 2498 /* Set the bits per RGB */ 2499 if (pScrn->depth > 1) { 2500 /* Default to 6, is this right?? */ 2501 pScrn->rgbBits = 6; 2502#if 0 2503 if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS, 2504 &pScrn->rgbBits)) { 2505 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", 2506 pScrn->rgbBits); 2507 } 2508#endif 2509 } 2510 if ((cPtr->Flags & ChipsAccelSupport) && 2511 (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) { 2512 cPtr->Flags &= ~ChipsAccelSupport; 2513 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 2514 } 2515 2516 from = X_DEFAULT; 2517 if (pScrn->bitsPerPixel < 8) { 2518 /* Default to SW cursor for 1/4 bpp */ 2519 cPtr->Accel.UseHWCursor = FALSE; 2520 } else { 2521 cPtr->Accel.UseHWCursor = TRUE; 2522 } 2523 if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR, 2524 &cPtr->Accel.UseHWCursor)) 2525 from = X_CONFIG; 2526 if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR, 2527 &cPtr->Accel.UseHWCursor)) { 2528 from = X_CONFIG; 2529 cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor; 2530 } 2531 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 2532 (cPtr->Accel.UseHWCursor) ? "HW" : "SW"); 2533 2534 /* memory size */ 2535 if (cPtr->pEnt->device->videoRam != 0) { 2536 pScrn->videoRam = cPtr->pEnt->device->videoRam; 2537 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n", 2538 pScrn->videoRam); 2539 } else { 2540 /* not given, probe it */ 2541 /* XR0F: Software flags 0 */ 2542 /* bit 1-0: memory size */ 2543 /* 0: 256 kB */ 2544 /* 1: 512 kB */ 2545 /* 2: 1024 kB */ 2546 /* 3: 1024 kB */ 2547 2548 switch ((cPtr->readXR(cPtr, 0x0F)) & 3) { 2549 case 0: 2550 pScrn->videoRam = 256; 2551 break; 2552 case 1: 2553 pScrn->videoRam = 512; 2554 break; 2555 case 2: 2556 pScrn->videoRam = 1024; 2557 break; 2558 case 3: 2559 pScrn->videoRam = 2048; 2560 break; 2561 } 2562 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n", 2563 pScrn->videoRam); 2564 } 2565 cPtr->FbMapSize = pScrn->videoRam * 1024; 2566 2567 /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */ 2568 if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE; 2569 if (pScrn->bitsPerPixel < 8) { 2570 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) { 2571 useLinear = FALSE; 2572 from = X_CONFIG; 2573 } 2574 } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) { 2575 useLinear = FALSE; 2576 from = X_CONFIG; 2577 } 2578 2579#ifndef HAVE_ISA 2580 if (!(cPtr->Flags & ChipsLinearSupport)) { 2581 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Linear framebuffer required\n"); 2582 return FALSE; 2583 } 2584#endif 2585 2586 /* linear base */ 2587 if (useLinear) { 2588 unsigned char mask = 0xF8; 2589 if (pScrn->videoRam == 1024) 2590 mask = 0xF0; 2591 else if (pScrn->videoRam == 2048) 2592 mask = 0xE0; 2593 if (cPtr->pEnt->device->MemBase) { 2594 cPtr->FbAddress = cPtr->pEnt->device->MemBase 2595 & ((0xFF << 24) | (mask << 16)); 2596 from = X_CONFIG; 2597 } else { 2598 cPtr->FbAddress = ((0xFF & (cPtr->readXR(cPtr, 0x09))) << 24); 2599 cPtr->FbAddress |= ((mask & (cPtr->readXR(cPtr, 0x08))) << 16); 2600 from = X_PROBED; 2601 } 2602#ifndef XSERVER_LIBPCIACCESS 2603 linearRes[0].rBegin = cPtr->FbAddress; 2604 linearRes[0].rEnd = cPtr->FbAddress + 0x800000; 2605 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 2606 useLinear = FALSE; 2607 from = X_PROBED; 2608 } 2609#endif 2610 } 2611 2612 if (useLinear) { 2613 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2614 "Enabling linear addressing\n"); 2615 xf86DrvMsg(pScrn->scrnIndex, from, 2616 "base address is set at 0x%lX.\n", cPtr->FbAddress); 2617 if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) && 2618 (cPtr->Flags & ChipsMMIOSupport)) { 2619 cPtr->UseMMIO = TRUE; 2620 cPtr->IOAddress = cPtr->FbAddress + 0x200000L; 2621 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n"); 2622 } 2623 } else { 2624 if (cPtr->Flags & ChipsLinearSupport) 2625 xf86DrvMsg(pScrn->scrnIndex, from, 2626 "Disabling linear addressing\n"); 2627 cPtr->Flags &= ~ChipsLinearSupport; 2628 } 2629 2630 if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE)) 2631 || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) { 2632 if (!(cPtr->Flags & ChipsLinearSupport)) { 2633 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2634 "Option \"ShadowFB\" ignored. Not supported without linear addressing\n"); 2635 } else if (pScrn->depth < 8) { 2636 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2637 "Option \"ShadowFB\" ignored. Not supported at this depth.\n"); 2638 } else { 2639 cPtr->Rotate = 0; 2640 if (s) { 2641 if(!xf86NameCmp(s, "CW")) { 2642 /* accel is disabled below for shadowFB */ 2643 cPtr->Flags |= ChipsShadowFB; 2644 cPtr->Rotate = 1; 2645 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2646 "Rotating screen clockwise\n"); 2647 } else if(!xf86NameCmp(s, "CCW")) { 2648 cPtr->Flags |= ChipsShadowFB; 2649 cPtr->Rotate = -1; 2650 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 2651 "counter clockwise\n"); 2652 } else { 2653 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 2654 "value for Option \"Rotate\"\n", s); 2655 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2656 "Valid options are \"CW\" or \"CCW\"\n"); 2657 } 2658 } else { 2659 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2660 "Using \"Shadow Framebuffer\"\n"); 2661 cPtr->Flags |= ChipsShadowFB; 2662 } 2663 } 2664 } 2665 if (cPtr->Flags & ChipsShadowFB) { 2666 if (cPtr->Flags & ChipsAccelSupport) { 2667 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2668 "HW acceleration is not supported with shadow fb\n"); 2669 cPtr->Flags &= ~ChipsAccelSupport; 2670 } 2671 if (cPtr->Rotate && cPtr->Accel.UseHWCursor) { 2672 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2673 "HW cursor is not supported with rotate\n"); 2674 cPtr->Accel.UseHWCursor = FALSE; 2675 } 2676 } 2677 2678 cPtr->PanelType |= ChipsCRT; 2679 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT\n"); 2680 2681 /* monitor info */ 2682 cPtr->Monitor = chipsSetMonitor(pScrn); 2683 2684 /* bus type */ 2685 tmp = cPtr->readXR(cPtr, 0x01) & 3; 2686 switch (tmp) { 2687 case 0: 2688 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n"); 2689 cPtr->Bus = ChipsISA; 2690 break; 2691 case 3: 2692 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 2693 cPtr->Bus = ChipsVLB; 2694 break; 2695 default: 2696 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n"); 2697 cPtr->Bus = ChipsUnknown; 2698 break; 2699 } 2700 2701 /* disable acceleration for 1 and 4 bpp */ 2702 if (pScrn->bitsPerPixel < 8) { 2703 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2704 "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel); 2705 cPtr->Flags &= ~ChipsAccelSupport; 2706 } 2707 2708 /* 32bit register address offsets */ 2709 if ((cPtr->Flags & ChipsAccelSupport) || 2710 (cPtr->Accel.UseHWCursor)) { 2711 cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32)); 2712 tmp = cPtr->readXR(cPtr, 0x07); 2713 for( i = 0; i < (sizeof(ChipsReg32) / sizeof(ChipsReg32[0])); i++) { 2714 cPtr->Regs32[i] = ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80) 2715 << 8)| ((tmp & 0x7F) << 2); 2716#ifdef DEBUG 2717 ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]); 2718#endif 2719 } 2720#ifndef XSERVER_LIBPCIACCESS 2721 linearRes[0].type = ResExcIoSparse | ResBios | ResBus; 2722 linearRes[0].rBase = cPtr->Regs32[0]; 2723 linearRes[0].rMask = 0x83FC; 2724 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 2725 if (cPtr->Flags & ChipsAccelSupport) { 2726 cPtr->Flags &= ~ChipsAccelSupport; 2727 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2728 "Cannot allocate IO registers: " 2729 "Disabling acceleration\n"); 2730 } 2731 if (cPtr->Accel.UseHWCursor) { 2732 cPtr->Accel.UseHWCursor = FALSE; 2733 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2734 "Cannot allocate IO registers: " 2735 "Disabling HWCursor\n"); 2736 } 2737 } 2738#endif 2739 } 2740 2741 cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1); 2742 if (cPtr->ClockMulFactor != 1) 2743 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2744 "Clocks scaled by %d\n", cPtr->ClockMulFactor); 2745 2746 /* Clock type */ 2747 switch (cPtr->Chipset) { 2748 case CHIPS_CT64200: 2749 NoClocks = 4; 2750 cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW; 2751 break; 2752 default: 2753 if (!((cPtr->readXR(cPtr, 0x01)) & 0x10)) { 2754 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2755 "Using external clock generator\n"); 2756 NoClocks = 4; 2757 cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW; 2758 } else { 2759 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2760 "Using internal clock generator\n"); 2761 if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) { 2762 NoClocks = 3; 2763 cPtr->ClockType = WINGINE_2_STYLE | TYPE_HW; 2764 } else { 2765 NoClocks = 26; /* some number */ 2766 cPtr->ClockType = WINGINE_2_STYLE | TYPE_PROGRAMMABLE; 2767 pScrn->progClock = TRUE; 2768 } 2769 } 2770 } 2771 2772 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 2773 pScrn->numClocks = NoClocks; 2774 if(cPtr->pEnt->device->textClockFreq > 0) { 2775 SaveClk->Clock = cPtr->pEnt->device->textClockFreq; 2776 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2777 "Using textclock freq: %7.3f.\n", 2778 SaveClk->Clock/1000.0); 2779 } else 2780 SaveClk->Clock = CRT_TEXT_CLK_FREQ; 2781 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n"); 2782 } else { /* TYPE_PROGRAMMABLE */ 2783 SaveClk->Clock = chipsGetHWClock(pScrn); 2784 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n", 2785 SaveClk->Clock); 2786 if (!cPtr->pEnt->device->numclocks) { 2787 pScrn->numClocks = NoClocks; 2788 xf86GetClocks(pScrn, NoClocks, chipsClockSelect, 2789 chipsProtect, chipsBlankScreen, 2790 cPtr->IOBase + 0x0A, 0x08, 1, 28322); 2791 from = X_PROBED; 2792 } else { 2793 pScrn->numClocks = cPtr->pEnt->device->numclocks; 2794 if (pScrn->numClocks > NoClocks) { 2795 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2796 "Too many Clocks specified in configuration file.\n"); 2797 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2798 "\t\tAt most %d clocks may be specified\n", NoClocks); 2799 pScrn->numClocks= NoClocks; 2800 } 2801 for (i = 0; i < pScrn->numClocks; i++) 2802 pScrn->clock[i] = cPtr->pEnt->device->clock[i]; 2803 from = X_CONFIG; 2804 } 2805 xf86ShowClocks(pScrn, from); 2806 } 2807 2808 /* Set the min pixel clock */ 2809 /* XXX Guess, need to check this */ 2810 cPtr->MinClock = 11000 / cPtr->ClockMulFactor; 2811 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n", 2812 (float)(cPtr->MinClock / 1000.)); 2813 /* maximal clock */ 2814 switch (cPtr->Chipset) { 2815 case CHIPS_CT64200: 2816 cPtr->MaxClock = 80000 / cPtr->ClockMulFactor; 2817 break; 2818 case CHIPS_CT64300: 2819 cPtr->MaxClock = 85000 / cPtr->ClockMulFactor; 2820 break; 2821 } 2822 2823 if (cPtr->pEnt->device->dacSpeeds[0]) { 2824 int speed = 0; 2825 switch (pScrn->bitsPerPixel) { 2826 case 1: 2827 case 4: 2828 case 8: 2829 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8]; 2830 break; 2831 case 16: 2832 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16]; 2833 break; 2834 case 24: 2835 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24]; 2836 break; 2837 } 2838 if (speed == 0) 2839 cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0]; 2840 from = X_CONFIG; 2841 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2842 "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n", 2843 (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.)); 2844 cPtr->MaxClock = speed; 2845 } else { 2846 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2847 "Max pixel clock is %7.3f MHz\n", 2848 (float)(cPtr->MaxClock / 1000.)); 2849 } 2850 2851 if (xf86LoadSubModule(pScrn, "ddc")) { 2852 if (cPtr->pVbe) 2853 xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(cPtr->pVbe, NULL))); 2854 } 2855 return TRUE; 2856} 2857 2858static Bool 2859chipsPreInit655xx(ScrnInfoPtr pScrn, int flags) 2860{ 2861 int i, bytesPerPixel, NoClocks = 0; 2862 unsigned char tmp; 2863 MessageType from; 2864 vgaHWPtr hwp; 2865 CHIPSPtr cPtr = CHIPSPTR(pScrn); 2866 CHIPSPanelSizePtr Size = &cPtr->PanelSize; 2867 CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock); 2868 Bool useLinear = FALSE; 2869 char *s; 2870#ifndef XSERVER_LIBPCIACCESS 2871 resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END }; 2872#endif 2873 2874 /* Set pScrn->monitor */ 2875 pScrn->monitor = pScrn->confScreen->monitor; 2876 2877 if (cPtr->Flags & ChipsHDepthSupport) 2878 i = xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | 2879 SupportConvert32to24 | PreferConvert32to24); 2880 else 2881 i = xf86SetDepthBpp(pScrn, 8, 0, 0, NoDepth24Support); 2882 2883 if (!i) 2884 return FALSE; 2885 else { 2886 /* Check that the returned depth is one we support */ 2887 switch (pScrn->depth) { 2888 case 1: 2889 case 4: 2890 case 8: 2891 /* OK */ 2892 break; 2893 case 15: 2894 case 16: 2895 case 24: 2896 if (cPtr->Flags & ChipsHDepthSupport) 2897 break; /* OK */ 2898 /* fall through */ 2899 default: 2900 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2901 "Given depth (%d) is not supported by this driver\n", 2902 pScrn->depth); 2903 return FALSE; 2904 } 2905 } 2906 xf86PrintDepthBpp(pScrn); 2907 2908 /* Get the depth24 pixmap format */ 2909 if (pScrn->depth == 24 && pix24bpp == 0) 2910 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 2911 2912 /* 2913 * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp 2914 */ 2915 if (!vgaHWGetHWRec(pScrn)) 2916 return FALSE; 2917 2918 hwp = VGAHWPTR(pScrn); 2919 vgaHWGetIOBase(hwp); 2920 2921 /* 2922 * This must happen after pScrn->display has been set because 2923 * xf86SetWeight references it. 2924 */ 2925 if (pScrn->depth > 8) { 2926 /* The defaults are OK for us */ 2927 rgb zeros = {0, 0, 0}; 2928 2929 if (!xf86SetWeight(pScrn, zeros, zeros)) { 2930 return FALSE; 2931 } else { 2932 /* XXX check that weight returned is supported */ 2933 ; 2934 } 2935 } 2936 2937 if (!xf86SetDefaultVisual(pScrn, -1)) 2938 return FALSE; 2939 2940 /* The gamma fields must be initialised when using the new cmap code */ 2941 if (pScrn->depth > 1) { 2942 Gamma zeros = {0.0, 0.0, 0.0}; 2943 2944 if (!xf86SetGamma(pScrn, zeros)) 2945 return FALSE; 2946 } 2947 2948 /* Store register values that might be messed up by a suspend resume */ 2949 /* Do this early as some of the other code in PreInit relies on it */ 2950 cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18; 2951 cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A; 2952 cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20; 2953 cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15); 2954 2955 cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01); 2956 cPtr->IOBase = cPtr->SuspendHack.vgaIOBaseFlag ? 0x3D0 : 0x3B0; 2957 2958 bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3); 2959 2960 /* Collect all of the relevant option flags (fill in pScrn->options) */ 2961 xf86CollectOptions(pScrn, NULL); 2962 2963 /* Process the options */ 2964 if (!(cPtr->Options = malloc(sizeof(Chips655xxOptions)))) 2965 return FALSE; 2966 memcpy(cPtr->Options, Chips655xxOptions, sizeof(Chips655xxOptions)); 2967 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options); 2968 2969 /* Set the bits per RGB */ 2970 if (pScrn->depth > 1) { 2971 /* Default to 6, is this right */ 2972 pScrn->rgbBits = 6; 2973#if 0 2974 if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS, 2975 &pScrn->rgbBits)) { 2976 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", 2977 pScrn->rgbBits); 2978 } 2979#endif 2980 } 2981 if ((cPtr->Flags & ChipsAccelSupport) && 2982 (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) { 2983 cPtr->Flags &= ~ChipsAccelSupport; 2984 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 2985 } 2986 2987 from = X_DEFAULT; 2988 if (pScrn->bitsPerPixel < 8) { 2989 /* Default to SW cursor for 1/4 bpp */ 2990 cPtr->Accel.UseHWCursor = FALSE; 2991 } else { 2992 cPtr->Accel.UseHWCursor = TRUE; 2993 } 2994 if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR, 2995 &cPtr->Accel.UseHWCursor)) 2996 from = X_CONFIG; 2997 if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR, 2998 &cPtr->Accel.UseHWCursor)) { 2999 from = X_CONFIG; 3000 cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor; 3001 } 3002 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 3003 (cPtr->Accel.UseHWCursor) ? "HW" : "SW"); 3004 3005 /* memory size */ 3006 if (cPtr->pEnt->device->videoRam != 0) { 3007 pScrn->videoRam = cPtr->pEnt->device->videoRam; 3008 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n", 3009 pScrn->videoRam); 3010 } else { 3011 /* not given, probe it */ 3012 /* XR0F: Software flags 0 */ 3013 /* bit 1-0: memory size */ 3014 /* 0: 256 kB */ 3015 /* 1: 512 kB */ 3016 /* 2: 1024 kB */ 3017 /* 3: 1024 kB */ 3018 3019 switch ((cPtr->readXR(cPtr, 0x0F)) & 3) { 3020 case 0: 3021 pScrn->videoRam = 256; 3022 break; 3023 case 1: 3024 pScrn->videoRam = 512; 3025 break; 3026 case 2: 3027 case 3: 3028 pScrn->videoRam = 1024; 3029 break; 3030 } 3031 3032 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n", 3033 pScrn->videoRam); 3034 } 3035 cPtr->FbMapSize = pScrn->videoRam * 1024; 3036 3037 /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */ 3038 if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE; 3039 if (pScrn->bitsPerPixel < 8) { 3040 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) { 3041 useLinear = FALSE; 3042 from = X_CONFIG; 3043 } 3044 } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) { 3045 useLinear = FALSE; 3046 from = X_CONFIG; 3047 } 3048 3049#ifndef HAVE_ISA 3050 if (!(cPtr->Flags & ChipsLinearSupport)) { 3051 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Linear framebuffer required\n"); 3052 return FALSE; 3053 } 3054#endif 3055 3056 /* linear base */ 3057 if (useLinear) { 3058 unsigned char mask; 3059 if (cPtr->Chipset == CHIPS_CT65535) { 3060 mask = (pScrn->videoRam > 512) ? 0xF8 :0xFC; 3061 if (cPtr->Bus == ChipsISA) 3062 mask &= 0x7F; 3063 } else if (cPtr->Bus == ChipsISA) { 3064 mask = 0x0F; 3065 } else { 3066 mask = 0xFF; 3067 tmp = cPtr->readXR(cPtr, 0x01); 3068 if(tmp & 0x40) 3069 mask &= 0x3F; 3070 if(!(tmp & 0x80)) 3071 mask &= 0xCF; 3072 } 3073 if (cPtr->pEnt->location.type == BUS_PCI) { 3074 cPtr->FbAddress = PCI_REGION_BASE(cPtr->PciInfo, 0, REGION_MEM) & 0xff800000; 3075#ifndef XSERVER_LIBPCIACCESS 3076 if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone)) { 3077 useLinear = FALSE; 3078 from = X_PROBED; 3079 } 3080#endif 3081 } else { 3082 if (cPtr->pEnt->device->MemBase) { 3083 cPtr->FbAddress = cPtr->pEnt->device->MemBase; 3084 if (cPtr->Chipset == CHIPS_CT65535) 3085 cPtr->FbAddress &= (mask << 17); 3086 else if (cPtr->Chipset > CHIPS_CT65535) 3087 cPtr->FbAddress &= (mask << 20); 3088 from = X_CONFIG; 3089 } else { 3090 if (cPtr->Chipset <= CHIPS_CT65530) { 3091 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3092 "base address assumed at 0xC00000!\n"); 3093 cPtr->FbAddress = 0xC00000; 3094 from = X_CONFIG; 3095 } else if (cPtr->Chipset == CHIPS_CT65535) { 3096 cPtr->FbAddress = 3097 ((mask & (cPtr->readXR(cPtr, 0x08))) << 17); 3098 } else { 3099 cPtr->FbAddress = 3100 ((mask & (cPtr->readXR(cPtr, 0x08))) << 20); 3101 } 3102 from = X_PROBED; 3103 } 3104#ifndef XSERVER_LIBPCIACCESS 3105 linearRes[0].rBegin = cPtr->FbAddress; 3106 linearRes[0].rEnd = cPtr->FbAddress + 0x800000; 3107 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 3108 useLinear = FALSE; 3109 from = X_PROBED; 3110 } 3111#endif 3112 } 3113 } 3114 3115 if (useLinear) { 3116 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3117 "Enabling linear addressing\n"); 3118 xf86DrvMsg(pScrn->scrnIndex, from, 3119 "base address is set at 0x%lX.\n", cPtr->FbAddress); 3120 if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) && 3121 (cPtr->Flags & ChipsMMIOSupport)) { 3122 cPtr->UseMMIO = TRUE; 3123 cPtr->IOAddress = cPtr->FbAddress + 0x200000L; 3124 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n"); 3125 } 3126 } else { 3127 if (cPtr->Flags & ChipsLinearSupport) 3128 xf86DrvMsg(pScrn->scrnIndex, from, 3129 "Disabling linear addressing\n"); 3130 cPtr->Flags &= ~ChipsLinearSupport; 3131 } 3132 3133 if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE)) 3134 || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) { 3135 if (!(cPtr->Flags & ChipsLinearSupport)) { 3136 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3137 "Option \"ShadowFB\" ignored. Not supported without linear addressing\n"); 3138 } else if (pScrn->depth < 8) { 3139 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3140 "Option \"ShadowFB\" ignored. Not supported at this depth.\n"); 3141 } else { 3142 cPtr->Rotate = 0; 3143 if (s) { 3144 if(!xf86NameCmp(s, "CW")) { 3145 /* accel is disabled below for shadowFB */ 3146 cPtr->Flags |= ChipsShadowFB; 3147 cPtr->Rotate = 1; 3148 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3149 "Rotating screen clockwise\n"); 3150 } else if(!xf86NameCmp(s, "CCW")) { 3151 cPtr->Flags |= ChipsShadowFB; 3152 cPtr->Rotate = -1; 3153 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 3154 "counter clockwise\n"); 3155 } else { 3156 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 3157 "value for Option \"Rotate\"\n", s); 3158 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3159 "Valid options are \"CW\" or \"CCW\"\n"); 3160 } 3161 } else { 3162 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3163 "Using \"Shadow Framebuffer\"\n"); 3164 cPtr->Flags |= ChipsShadowFB; 3165 } 3166 } 3167 } 3168 if (cPtr->Flags & ChipsShadowFB) { 3169 if (cPtr->Flags & ChipsAccelSupport) { 3170 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3171 "HW acceleration is not supported with shadow fb\n"); 3172 cPtr->Flags &= ~ChipsAccelSupport; 3173 } 3174 if (cPtr->Rotate && cPtr->Accel.UseHWCursor) { 3175 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3176 "HW cursor is not supported with rotate\n"); 3177 cPtr->Accel.UseHWCursor = FALSE; 3178 } 3179 } 3180 3181 /*test STN / TFT */ 3182 tmp = cPtr->readXR(cPtr, 0x51); 3183 3184 /* XR51 or FR10: DISPLAY TYPE REGISTER */ 3185 /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */ 3186 /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */ 3187 switch (tmp & 0x3) { 3188 case 0: 3189 if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) { 3190 cPtr->PanelType |= ChipsSS; 3191 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n"); 3192 } else { 3193 cPtr->PanelType |= ChipsTFT; 3194 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n"); 3195 } 3196 break; 3197 case 2: 3198 cPtr->PanelType |= ChipsDS; 3199 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n"); 3200 case 3: 3201 cPtr->PanelType |= ChipsDD; 3202 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n"); 3203 break; 3204 default: 3205 break; 3206 } 3207 3208 chipsSetPanelType(cPtr); 3209 from = X_PROBED; 3210 { 3211 Bool fp_mode; 3212 if (xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_mode)) { 3213 if (fp_mode) { 3214 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode on\n"); 3215 cPtr->PanelType |= ChipsLCD; 3216 } else { 3217 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode off\n"); 3218 cPtr->PanelType = ~ChipsLCD; 3219 } 3220 from = X_CONFIG; 3221 } 3222 } 3223 if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT)) 3224 xf86DrvMsg(pScrn->scrnIndex, from, "LCD/CRT\n"); 3225 else if (cPtr->PanelType & ChipsLCD) 3226 xf86DrvMsg(pScrn->scrnIndex, from, "LCD\n"); 3227 else if (cPtr->PanelType & ChipsCRT) { 3228 xf86DrvMsg(pScrn->scrnIndex, from, "CRT\n"); 3229 /* monitor info */ 3230 cPtr->Monitor = chipsSetMonitor(pScrn); 3231 } 3232 3233 /* screen size */ 3234 /* 3235 * In LCD mode / dual mode we want to derive the timing values from 3236 * the ones preset by bios 3237 */ 3238 if (cPtr->PanelType & ChipsLCD) { 3239 unsigned char xr17, tmp1; 3240 char tmp2; 3241 3242 xr17 = cPtr->readXR(cPtr, 0x17); 3243 tmp = cPtr->readXR(cPtr, 0x1B); 3244 Size->HTotal =((tmp + ((xr17 & 0x01) << 8)) + 5) << 3; 3245 tmp = cPtr->readXR(cPtr, 0x1C); 3246 Size->HDisplay = ((tmp + ((xr17 & 0x02) << 7)) + 1) << 3; 3247 tmp = cPtr->readXR(cPtr, 0x19); 3248 Size->HRetraceStart = ((tmp + ((xr17 & 0x04) << 9)) + 1) << 3; 3249 tmp1 = cPtr->readXR(cPtr, 0x1A); 3250 tmp2 = (tmp1 & 0x1F) + ((xr17 & 0x08) << 2) - (tmp & 0x3F); 3251 Size->HRetraceEnd = ((((tmp2 & 0x080u) ? (tmp2 + 0x40) : tmp2) << 3) 3252 + Size->HRetraceStart); 3253 tmp1 = cPtr->readXR(cPtr, 0x65); 3254 tmp = cPtr->readXR(cPtr, 0x68); 3255 Size->VDisplay = ((tmp1 & 0x02) << 7) 3256 + ((tmp1 & 0x40) << 3) + tmp + 1; 3257 tmp = cPtr->readXR(cPtr, 0x66); 3258 Size->VRetraceStart = ((tmp1 & 0x04) << 6) 3259 + ((tmp1 & 0x80) << 2) + tmp + 1; 3260 tmp = cPtr->readXR(cPtr, 0x64); 3261 Size->VTotal = ((tmp1 & 0x01) << 8) 3262 + ((tmp1 & 0x20) << 4) + tmp + 2; 3263#ifdef DEBUG 3264 ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n", 3265 Size->HDisplay, Size->VDisplay, 3266 Size->HRetraceStart, Size->HRetraceEnd, 3267 Size->HTotal); 3268#endif 3269 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n", 3270 Size->HDisplay, Size->VDisplay); 3271 /* Warn the user if the panel size has been overridden by 3272 * the modeline values 3273 */ 3274 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 3275 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3276 "Display size overridden by modelines.\n"); 3277 } 3278 } 3279 3280 /* Frame Buffer */ /* for LCDs */ 3281 if (IS_STN(cPtr->PanelType)) { 3282 tmp = cPtr->readXR(cPtr, 0x6F); /*Frame Buffer Ctrl. */ 3283 if (tmp & 1) { 3284 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n"); 3285 if ((cPtr->Chipset > CHIPS_CT65530) && !(tmp & 0x80)) { 3286 /* Formula for calculating the size of the framebuffer. 3 3287 * bits per pixel 10 pixels per 32 bit dword. If frame 3288 * acceleration is enabled the size can be halved. 3289 */ 3290 cPtr->FrameBufferSize = ( Size->HDisplay * 3291 Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2); 3292 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3293 "Using embedded Frame Buffer, size %d bytes\n", 3294 cPtr->FrameBufferSize); 3295 } else 3296 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3297 "Using external Frame Buffer used\n"); 3298 } 3299 if (tmp & 2) 3300 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3301 "Frame accelerator enabled\n"); 3302 } 3303 3304 /* bus type */ 3305 if (cPtr->Chipset > CHIPS_CT65535) { 3306 tmp = (cPtr->readXR(cPtr, 0x01)) & 7; 3307 if (tmp == 6) { /*PCI */ 3308 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n"); 3309 cPtr->Bus = ChipsPCI; 3310 if ((cPtr->Chipset == CHIPS_CT65545) || 3311 (cPtr->Chipset == CHIPS_CT65546)) { 3312 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3313 "32Bit IO not supported on 65545 PCI\n"); 3314 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "\tenabling MMIO\n"); 3315 cPtr->UseMMIO = TRUE; 3316 cPtr->IOAddress = cPtr->FbAddress + 0x200000L; 3317 } 3318 3319 } else { /* XR08: Linear addressing base, not for PCI */ 3320 switch (tmp) { 3321 case 3: 3322 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CPU Direct\n"); 3323 cPtr->Bus = ChipsCPUDirect; 3324 break; 3325 case 5: 3326 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n"); 3327 cPtr->Bus = ChipsISA; 3328 break; 3329 case 7: 3330 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 3331 cPtr->Bus = ChipsVLB; 3332 break; 3333 default: 3334 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n"); 3335 } 3336 } 3337 } else { 3338 tmp = (cPtr->readXR(cPtr, 0x01)) & 3; 3339 switch (tmp) { 3340 case 0: 3341 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PI Bus\n"); 3342 cPtr->Bus = ChipsPIB; 3343 break; 3344 case 1: 3345 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MC Bus\n"); 3346 cPtr->Bus = ChipsMCB; 3347 break; 3348 case 2: 3349 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 3350 cPtr->Bus = ChipsVLB; 3351 break; 3352 case 3: 3353 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n"); 3354 cPtr->Bus = ChipsISA; 3355 break; 3356 } 3357 } 3358 3359 if (!(cPtr->Bus == ChipsPCI) && (cPtr->UseMMIO)) { 3360 cPtr->UseMMIO = FALSE; 3361 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3362 "MMIO only supported on PCI Bus. Disabling MMIO\n"); 3363 } 3364 3365 /* disable acceleration for 1 and 4 bpp */ 3366 if (pScrn->bitsPerPixel < 8) { 3367 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3368 "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel); 3369 cPtr->Flags &= ~ChipsAccelSupport; 3370 } 3371 3372 if ((cPtr->Chipset == CHIPS_CT65530) && 3373 (cPtr->Flags & ChipsLinearSupport)) { 3374 /* linear mode is no longer default on ct65530 since it */ 3375 /* requires additional hardware which some manufacturers*/ 3376 /* might not provide. */ 3377 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) 3378 cPtr->Flags &= ~ChipsLinearSupport; 3379 3380 /* Test wether linear addressing is possible on 65530 */ 3381 /* on the 65530 only the A19 select scheme can be used*/ 3382 /* for linear addressing since MEMW is used on ISA bus*/ 3383 /* systems. */ 3384 /* A19 however is used if video memory is > 512 Mb */ 3385 if ((cPtr->Bus == ChipsISA) && (pScrn->videoRam > 512)) { 3386 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3387 "User selected linear fb not supported by HW!\n"); 3388 cPtr->Flags &= ~ChipsLinearSupport; 3389 } 3390 } 3391 3392 /* DAC info */ 3393 if ((cPtr->readXR(cPtr, 0x06)) & 0x02) 3394 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n"); 3395 3396 /* MMIO address offset */ 3397 if (cPtr->UseMMIO) 3398 cPtr->Regs32 = ChipsReg32; 3399 else if ((cPtr->Flags & ChipsAccelSupport) || 3400 (cPtr->Accel.UseHWCursor)) { 3401 cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32)); 3402 tmp = cPtr->readXR(cPtr, 0x07); 3403 for (i = 0; i < (sizeof(ChipsReg32)/sizeof(ChipsReg32[0])); i++) { 3404 cPtr->Regs32[i] = 3405 ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80)<< 8) 3406 | ((tmp & 0x7F) << 2); 3407#ifdef DEBUG 3408 ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]); 3409#endif 3410 } 3411#ifndef XSERVER_LIBPCIACCESS 3412 linearRes[0].type = ResExcIoSparse | ResBios | ResBus; 3413 linearRes[0].rBase = cPtr->Regs32[0]; 3414 linearRes[0].rMask = 0x83FC; 3415 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 3416 if (cPtr->Flags & ChipsAccelSupport) { 3417 cPtr->Flags &= ~ChipsAccelSupport; 3418 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3419 "Cannot allocate IO registers: " 3420 "Disabling acceleration\n"); 3421 } 3422 if (cPtr->Accel.UseHWCursor) { 3423 cPtr->Accel.UseHWCursor = FALSE; 3424 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3425 "Cannot allocate IO registers: " 3426 "Disabling HWCursor\n"); 3427 } 3428 } 3429#endif 3430 } 3431 3432 /* sync reset ignored on this chipset */ 3433 if (cPtr->Chipset > CHIPS_CT65530) { 3434 tmp = cPtr->readXR(cPtr, 0x0E); 3435 if (tmp & 0x80) 3436 cPtr->SyncResetIgn = TRUE; 3437 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3438 "Synchronous reset %signored.\n", 3439 (cPtr->SyncResetIgn ? "" : "not ")); 3440 } 3441 3442 cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1); 3443 if (cPtr->ClockMulFactor != 1) 3444 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3445 "Clocks scaled by %d\n", cPtr->ClockMulFactor); 3446 /* We use a programmable clock */ 3447 switch (cPtr->Chipset) { 3448 case CHIPS_CT65520: 3449 case CHIPS_CT65525: 3450 case CHIPS_CT65530: 3451 NoClocks = 4; /* Some number */ 3452 cPtr->ClockType = OLD_STYLE | TYPE_HW; 3453 break; 3454 default: 3455 if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) { 3456 NoClocks = 5; /* Some number */ 3457 cPtr->ClockType = NEW_STYLE | TYPE_HW; 3458 } else { 3459 NoClocks = 26; /* Some number */ 3460 cPtr->ClockType = NEW_STYLE | TYPE_PROGRAMMABLE; 3461 pScrn->progClock = TRUE; 3462 } 3463 } 3464 3465 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 3466 pScrn->numClocks = NoClocks; 3467 if (cPtr->pEnt->device->textClockFreq > 0) { 3468 SaveClk->Clock = cPtr->pEnt->device->textClockFreq; 3469 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3470 "Using textclock freq: %7.3f.\n", 3471 SaveClk->Clock/1000.0); 3472 } else 3473 SaveClk->Clock = ((cPtr->PanelType & ChipsLCDProbed) ? 3474 LCD_TEXT_CLK_FREQ : CRT_TEXT_CLK_FREQ); 3475 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n"); 3476 } else { /* TYPE_PROGRAMMABLE */ 3477 SaveClk->Clock = chipsGetHWClock(pScrn); 3478 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n", 3479 SaveClk->Clock); 3480 if (!cPtr->pEnt->device->numclocks) { 3481 pScrn->numClocks = NoClocks; 3482 xf86GetClocks(pScrn, NoClocks, chipsClockSelect, 3483 chipsProtect, chipsBlankScreen, 3484 cPtr->IOBase + 0x0A, 0x08, 1, 28322); 3485 from = X_PROBED; 3486 } else { 3487 pScrn->numClocks = cPtr->pEnt->device->numclocks; 3488 if (pScrn->numClocks > NoClocks) { 3489 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3490 "Too many Clocks specified in configuration file.\n"); 3491 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3492 "\t\tAt most %d clocks may be specified\n", NoClocks); 3493 pScrn->numClocks = NoClocks; 3494 } 3495 for (i = 0; i < pScrn->numClocks; i++) 3496 pScrn->clock[i] = cPtr->pEnt->device->clock[i]; 3497 from = X_CONFIG; 3498 } 3499 xf86ShowClocks(pScrn, from); 3500 } 3501 /* Set the min pixel clock */ 3502 /* XXX Guess, need to check this */ 3503 cPtr->MinClock = 11000 / cPtr->ClockMulFactor; 3504 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n", 3505 (float)(cPtr->MinClock / 1000.)); 3506 /* Set the max pixel clock */ 3507 switch (cPtr->Chipset) { 3508 case CHIPS_CT65546: 3509 case CHIPS_CT65548: 3510 /* max VCLK is 80 MHz, max MCLK is 75 MHz for CT65548 */ 3511 /* It is not sure for CT65546, but it works with 60 nsec EDODRAM */ 3512 cPtr->MaxClock = 80000 / cPtr->ClockMulFactor; 3513 break; 3514 default: 3515 if ((cPtr->readXR(cPtr, 0x6C)) & 2) { 3516 /*5V Vcc */ 3517 cPtr->MaxClock = 68000 / cPtr->ClockMulFactor; 3518 } else { 3519 /*3.3V Vcc */ 3520 cPtr->MaxClock = 56000 / cPtr->ClockMulFactor; 3521 } 3522 } 3523 3524 if (cPtr->pEnt->device->dacSpeeds[0]) { 3525 int speed = 0; 3526 switch (pScrn->bitsPerPixel) { 3527 case 1: 3528 case 4: 3529 case 8: 3530 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8]; 3531 break; 3532 case 16: 3533 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16]; 3534 break; 3535 case 24: 3536 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24]; 3537 break; 3538 } 3539 if (speed == 0) 3540 cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0]; 3541 from = X_CONFIG; 3542 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3543 "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n", 3544 (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.)); 3545 cPtr->MaxClock = speed; 3546 } else { 3547 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3548 "Max pixel clock is %7.3f MHz\n", 3549 (float)(cPtr->MaxClock / 1000.)); 3550 } 3551 3552 /* FP clock */ 3553 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 3554 double real = 0; 3555 3556 switch(bytesPerPixel) { 3557 case 1: 3558 xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8, 3559 OPTUNITS_MHZ, &real); 3560 break; 3561 case 2: 3562 xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16, 3563 OPTUNITS_MHZ, &real); 3564 break; 3565 case 3: 3566 xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24, 3567 OPTUNITS_MHZ, &real); 3568 break; 3569 } 3570 3571 if (real > 0) { 3572 int val; 3573 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3574 "FP clock %7.3f MHz requested\n",real); 3575 val = (int) (real * 1000.); 3576 if (val && (val >= cPtr->MinClock) 3577 && (val <= cPtr->MaxClock)) 3578 cPtr->FPclock = val * cPtr->ClockMulFactor; 3579 else if (val > cPtr->MaxClock) 3580 cPtr->FPclock = (int)((float)cPtr->MaxClock 3581 * cPtr->ClockMulFactor * 0.9); 3582 else 3583 cPtr->FPclock = 0; /* special value */ 3584 } else 3585 cPtr->FPclock = 0; /* special value */ 3586 3587 if (cPtr->FPclock) 3588 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3589 "FP clock set to %7.3f MHz\n", 3590 (float)(cPtr->FPclock / 1000.)); 3591 } else { 3592 if (xf86IsOptionSet(cPtr->Options, OPTION_SET_MCLK)) 3593 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3594 "FP clock option not supported for this chipset\n"); 3595 } 3596 3597 /* Memory Clock */ 3598 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 3599 double real; 3600 3601 switch (cPtr->Chipset) { 3602 case CHIPS_CT65546: 3603 case CHIPS_CT65548: 3604 /* max MCLK is 75 MHz for CT65548 */ 3605 cPtr->MemClock.Max = 75000; 3606 break; 3607 default: 3608 if ((cPtr->readXR(cPtr, 0x6C)) & 2) { 3609 /*5V Vcc */ 3610 cPtr->MemClock.Max = 68000; 3611 } else { 3612 /*3.3V Vcc */ 3613 cPtr->MemClock.Max = 56000; 3614 } 3615 } 3616 3617 if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK, 3618 OPTUNITS_MHZ, &real)) { 3619 int mclk = (int)(real * 1000.0); 3620 if (mclk <= cPtr->MemClock.Max) { 3621 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3622 "Using memory clock of %7.3f MHz\n", 3623 (float)(mclk/1000.)); 3624 cPtr->MemClock.Clk = mclk; 3625 } else { 3626 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3627 "Memory clock of %7.3f MHz exceeds limit of " 3628 "%7.3f MHz\n",(float)(mclk/1000.), 3629 (float)(cPtr->MemClock.Max/1000.)); 3630 cPtr->MemClock.Clk = cPtr->MemClock.Max * 0.9; 3631 } 3632 } else 3633 cPtr->MemClock.Clk = 0; 3634 } else 3635 if (xf86IsOptionSet(cPtr->Options, OPTION_SET_MCLK)) 3636 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3637 "Memory clock option not supported for this chipset\n"); 3638 3639 if (xf86LoadSubModule(pScrn, "ddc")) { 3640 if (cPtr->pVbe) 3641 xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(cPtr->pVbe, NULL))); 3642 } 3643 return TRUE; 3644} 3645 3646 3647/* Mandatory */ 3648static Bool 3649CHIPSEnterVT(int scrnIndex, int flags) 3650{ 3651 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3652 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3653 CHIPSEntPtr cPtrEnt; 3654 3655 if (cPtr->Flags & ChipsDualChannelSupport) { 3656 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3657 CHIPSEntityIndex)->ptr; 3658 DUALOPEN; 3659 } 3660 /* Should we re-save the text mode on each VT enter? */ 3661 if(!chipsModeInit(pScrn, pScrn->currentMode)) 3662 return FALSE; 3663 if ((!(cPtr->Flags & ChipsOverlay8plus16)) 3664 && (cPtr->Flags & ChipsVideoSupport) 3665 && (cPtr->Flags & ChipsLinearSupport)) 3666 CHIPSResetVideo(pScrn); 3667 3668 /*usleep(50000);*/ 3669 chipsHWCursorOn(cPtr, pScrn); 3670 /* cursor settle delay */ 3671 usleep(50000); 3672 CHIPSAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 3673 usleep(50000); 3674 return TRUE; 3675} 3676 3677/* Mandatory */ 3678static void 3679CHIPSLeaveVT(int scrnIndex, int flags) 3680{ 3681 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3682 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3683 CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn); 3684 CHIPSEntPtr cPtrEnt; 3685 3686 /* Invalidate the cached acceleration registers */ 3687 cAcl->planemask = -1; 3688 cAcl->fgColor = -1; 3689 cAcl->bgColor = -1; 3690 3691 if (cPtr->Flags & ChipsDualChannelSupport) { 3692 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3693 CHIPSEntityIndex)->ptr; 3694 if (cPtr->UseDualChannel) 3695 DUALREOPEN; 3696 DUALCLOSE; 3697 } else { 3698 chipsHWCursorOff(cPtr, pScrn); 3699 chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg, 3700 TRUE); 3701 chipsLock(pScrn); 3702 } 3703} 3704 3705 3706static void 3707chipsLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 3708 VisualPtr pVisual) 3709{ 3710 vgaHWPtr hwp = VGAHWPTR(pScrn); 3711 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3712 int i, index, shift ; 3713 CHIPSEntPtr cPtrEnt; 3714 3715 shift = ((pScrn->depth == 15) && 3716 (!(cPtr->Flags & ChipsOverlay8plus16))) ? 3 : 0; 3717 3718 if (cPtr->UseDualChannel) { 3719 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3720 CHIPSEntityIndex)->ptr; 3721 DUALREOPEN; 3722 } 3723 3724 for (i = 0; i < numColors; i++) { 3725 index = indices[i]; 3726 hwp->writeDacWriteAddr(hwp,index << shift); 3727 DACDelay(hwp); 3728 hwp->writeDacData(hwp, colors[index].red); 3729 DACDelay(hwp); 3730 hwp->writeDacData(hwp, colors[index].green); 3731 DACDelay(hwp); 3732 hwp->writeDacData(hwp, colors[index].blue); 3733 DACDelay(hwp); 3734 } 3735 3736 if (cPtr->UseDualChannel && 3737 (! xf86IsEntityShared(pScrn->entityList[0]))) { 3738 unsigned int IOSS, MSS; 3739 IOSS = cPtr->readIOSS(cPtr); 3740 MSS = cPtr->readMSS(cPtr); 3741 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3742 IOSS_PIPE_B)); 3743 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 3744 3745 for (i = 0; i < numColors; i++) { 3746 index = indices[i]; 3747 hwp->writeDacWriteAddr(hwp,index << shift); 3748 DACDelay(hwp); 3749 hwp->writeDacData(hwp, colors[index].red); 3750 DACDelay(hwp); 3751 hwp->writeDacData(hwp, colors[index].green); 3752 DACDelay(hwp); 3753 hwp->writeDacData(hwp, colors[index].blue); 3754 DACDelay(hwp); 3755 } 3756 cPtr->writeIOSS(cPtr, IOSS); 3757 cPtr->writeMSS(cPtr, hwp, MSS); 3758 } 3759 3760 /* This shouldn't be necessary, but we'll play safe. */ 3761 hwp->disablePalette(hwp); 3762} 3763 3764static void 3765chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, 3766 LOCO *colors, VisualPtr pVisual) 3767{ 3768 vgaHWPtr hwp = VGAHWPTR(pScrn); 3769 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3770 CHIPSEntPtr cPtrEnt; 3771 3772 int i, index; 3773 3774 if (cPtr->UseDualChannel) { 3775 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3776 CHIPSEntityIndex)->ptr; 3777 DUALREOPEN; 3778 } 3779 3780 for (i = 0; i < numColors; i++) { 3781 index = indices[i]; 3782 hwp->writeDacWriteAddr(hwp, index << 2); 3783 DACDelay(hwp); 3784 hwp->writeDacData(hwp, colors[index >> 1].red); 3785 DACDelay(hwp); 3786 hwp->writeDacData(hwp, colors[index].green); 3787 DACDelay(hwp); 3788 hwp->writeDacData(hwp, colors[index >> 1].blue); 3789 DACDelay(hwp); 3790 } 3791 3792 3793 if (cPtr->UseDualChannel && 3794 (! xf86IsEntityShared(pScrn->entityList[0]))) { 3795 unsigned int IOSS, MSS; 3796 IOSS = cPtr->readIOSS(cPtr); 3797 MSS = cPtr->readMSS(cPtr); 3798 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3799 IOSS_PIPE_B)); 3800 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 3801 3802 for (i = 0; i < numColors; i++) { 3803 index = indices[i]; 3804 hwp->writeDacWriteAddr(hwp, index << 2); 3805 DACDelay(hwp); 3806 hwp->writeDacData(hwp, colors[index >> 1].red); 3807 DACDelay(hwp); 3808 hwp->writeDacData(hwp, colors[index].green); 3809 DACDelay(hwp); 3810 hwp->writeDacData(hwp, colors[index >> 1].blue); 3811 DACDelay(hwp); 3812 } 3813 3814 cPtr->writeIOSS(cPtr, IOSS); 3815 cPtr->writeMSS(cPtr, hwp, MSS); 3816 } 3817 3818 /* This shouldn't be necessary, but we'll play safe. */ 3819 hwp->disablePalette(hwp); 3820} 3821 3822static Bool 3823cfb8_16ScreenInit(ScreenPtr pScreen, pointer pbits16, pointer pbits8, 3824 int xsize, int ysize, int dpix, int dpiy, 3825 int width16, int width8) 3826{ 3827 return 3828 (fbOverlaySetupScreen(pScreen, pbits16, pbits8, xsize, ysize, 3829 dpix, dpiy, width16, width8, 16, 8) && 3830 fbOverlayFinishScreenInit(pScreen, pbits16, pbits8, xsize, ysize, 3831 dpix, dpiy, width16, width8, 16, 8, 16, 8)); 3832} 3833 3834/* Mandatory */ 3835static Bool 3836CHIPSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 3837{ 3838 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 3839 vgaHWPtr hwp; 3840 CHIPSPtr cPtr; 3841 CHIPSACLPtr cAcl; 3842 int ret; 3843 int init_picture = 0; 3844 VisualPtr visual; 3845 int allocatebase, freespace, currentaddr; 3846#ifndef XSERVER_LIBPCIACCESS 3847 unsigned int racflag = 0; 3848#endif 3849 unsigned char *FBStart; 3850 int height, width, displayWidth; 3851 CHIPSEntPtr cPtrEnt = NULL; 3852#ifdef DEBUG 3853 ErrorF("CHIPSScreenInit\n"); 3854#endif 3855 3856 /* 3857 * we need to get the ScrnInfoRec for this screen, so let's allocate 3858 * one first thing 3859 */ 3860 cPtr = CHIPSPTR(pScrn); 3861 cAcl = CHIPSACLPTR(pScrn); 3862 3863 hwp = VGAHWPTR(pScrn); 3864 hwp->MapSize = 0x10000; /* Standard 64k VGA window */ 3865 3866 /* Map the VGA memory */ 3867 if (!vgaHWMapMem(pScrn)) 3868 return FALSE; 3869 3870 /* Map the Chips memory and possible MMIO areas */ 3871 if (!chipsMapMem(pScrn)) 3872 return FALSE; 3873 3874 /* Setup a pointer to the overlay if needed */ 3875 if (cPtr->Flags & ChipsOverlay8plus16) { 3876 cPtr->FbOffset16 = pScrn->displayWidth * pScrn->virtualY; 3877 cPtr->FbSize16 = (pScrn->displayWidth << 1) * pScrn->virtualY; 3878 if (cPtr->FbSize16 > (cPtr->FbMapSize - cPtr->FrameBufferSize)) { 3879 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3880 "Too little memory for overlay. Disabling.\n"); 3881 cPtr->Flags &= ~ChipsOverlay8plus16; 3882 } 3883 if ((pScrn->displayWidth > 1024) || (pScrn->virtualY > 1024)) { 3884 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3885 "Max overlay Width/Height 1024 pixels. Disabling.\n"); 3886 cPtr->Flags &= ~ChipsOverlay8plus16; 3887 } 3888 } 3889 3890 /* Setup the MMIO register access functions if need */ 3891 if (cPtr->UseFullMMIO && cPtr->MMIOBaseVGA) { 3892 CHIPSSetMmioExtFuncs(cPtr); 3893 CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBaseVGA, 0x0); 3894 } 3895 3896 if (cPtr->Flags & ChipsDualChannelSupport) { 3897 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3898 CHIPSEntityIndex)->ptr; 3899 DUALOPEN; 3900 } 3901 3902#if defined(__arm__) && defined(___NetBSD__) 3903 if (strcmp(pScrn->currentMode->name,"PAL") == 0) { 3904 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using built-in PAL TV mode\n"); 3905 cPtr->TVMode = XMODE_PAL; 3906 } else if (strcmp(pScrn->currentMode->name,"SECAM") == 0){ 3907 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3908 "Using built-in SECAM TV mode\n"); 3909 cPtr->TVMode = XMODE_SECAM; 3910 } else if (strcmp(pScrn->currentMode->name,"NTSC") == 0) { 3911 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3912 "Using built-in NTSC TV mode\n"); 3913 cPtr->TVMode = XMODE_NTSC; 3914 } else 3915 cPtr->TVMode = XMODE_RGB; 3916#endif 3917 3918 /* 3919 * next we save the current state and setup the first mode 3920 */ 3921 if ((cPtr->Flags & ChipsDualChannelSupport) && 3922 (! xf86IsEntityShared(pScrn->entityList[0]))) { 3923 unsigned int IOSS, MSS; 3924 IOSS = cPtr->readIOSS(cPtr); 3925 MSS = cPtr->readMSS(cPtr); 3926 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3927 IOSS_PIPE_A)); 3928 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_A)); 3929 chipsSave(pScrn, &hwp->SavedReg, &cPtr->SavedReg); 3930 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3931 IOSS_PIPE_B)); 3932 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 3933 chipsSave(pScrn, &cPtr->VgaSavedReg2, &cPtr->SavedReg2); 3934 cPtr->writeIOSS(cPtr, IOSS); 3935 cPtr->writeMSS(cPtr, hwp, MSS); 3936 } else 3937 chipsSave(pScrn, &hwp->SavedReg, &cPtr->SavedReg); 3938 3939 if (!chipsModeInit(pScrn,pScrn->currentMode)) 3940 return FALSE; 3941 CHIPSSaveScreen(pScreen,SCREEN_SAVER_ON); 3942 CHIPSAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 3943 3944 /* 3945 * The next step is to setup the screen's visuals, and initialise the 3946 * framebuffer code. In cases where the framebuffer's default 3947 * choices for things like visual layouts and bits per RGB are OK, 3948 * this may be as simple as calling the framebuffer's ScreenInit() 3949 * function. If not, the visuals will need to be setup before calling 3950 * a fb ScreenInit() function and fixed up after. 3951 * 3952 * For most PC hardware at depths >= 8, the defaults that cfb uses 3953 * are not appropriate. In this driver, we fixup the visuals after. 3954 */ 3955 3956 /* 3957 * Reset visual list. 3958 */ 3959 miClearVisualTypes(); 3960 3961 /* Setup the visuals we support. */ 3962 if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)){ 3963 if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask, 3964 pScrn->rgbBits, PseudoColor)) 3965 return FALSE; 3966 if (!miSetVisualTypes(16, TrueColorMask, pScrn->rgbBits, TrueColor)) 3967 return FALSE; 3968 } else { 3969 if (!miSetVisualTypes(pScrn->depth, 3970 miGetDefaultVisualMask(pScrn->depth), 3971 pScrn->rgbBits, pScrn->defaultVisual)) 3972 return FALSE; 3973 } 3974 miSetPixmapDepths (); 3975 3976 /* 3977 * Call the framebuffer layer's ScreenInit function, and fill in other 3978 * pScreen fields. 3979 */ 3980 if ((cPtr->Flags & ChipsShadowFB) && cPtr->Rotate) { 3981 height = pScrn->virtualX; 3982 width = pScrn->virtualY; 3983 } else { 3984 width = pScrn->virtualX; 3985 height = pScrn->virtualY; 3986 } 3987 3988 if(cPtr->Flags & ChipsShadowFB) { 3989 cPtr->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 3990 cPtr->ShadowPtr = malloc(cPtr->ShadowPitch * height); 3991 displayWidth = cPtr->ShadowPitch / (pScrn->bitsPerPixel >> 3); 3992 FBStart = cPtr->ShadowPtr; 3993 } else { 3994 cPtr->ShadowPtr = NULL; 3995 displayWidth = pScrn->displayWidth; 3996 FBStart = cPtr->FbBase; 3997 } 3998 3999 switch (pScrn->bitsPerPixel) { 4000#ifdef HAVE_XF1BPP 4001 case 1: 4002 ret = xf1bppScreenInit(pScreen, FBStart, 4003 width,height, 4004 pScrn->xDpi, pScrn->yDpi, 4005 displayWidth); 4006 break; 4007#endif 4008#ifdef HAVE_XF4BPP 4009 case 4: 4010 ret = xf4bppScreenInit(pScreen, FBStart, 4011 width,height, 4012 pScrn->xDpi, pScrn->yDpi, 4013 displayWidth); 4014 break; 4015#endif 4016 case 16: 4017 if (cPtr->Flags & ChipsOverlay8plus16) { 4018 ret = cfb8_16ScreenInit(pScreen, (unsigned char *)FBStart + 4019 cPtr->FbOffset16, FBStart, width, 4020 height, pScrn->xDpi, pScrn->yDpi, 4021 displayWidth, displayWidth); 4022 break; 4023 } 4024 default: 4025 ret = fbScreenInit(pScreen, FBStart, 4026 width,height, 4027 pScrn->xDpi, pScrn->yDpi, 4028 displayWidth,pScrn->bitsPerPixel); 4029 init_picture = 1; 4030 break; 4031 } 4032 4033 if (!ret) 4034 return FALSE; 4035 4036#if X_BYTE_ORDER == X_BIG_ENDIAN 4037 /* TODO : find a better way to do this */ 4038 if (pScrn->depth == 24) { 4039 int dummy ; 4040 /* Fixup RGB ordering in 24 BPP */ 4041 dummy = pScrn->offset.red ; 4042 pScrn->offset.red = pScrn->offset.blue; 4043 pScrn->offset.blue = dummy ; 4044 4045 dummy = pScrn->mask.red ; 4046 pScrn->mask.red = pScrn->mask.blue; 4047 pScrn->mask.blue = dummy ; 4048 } 4049#endif 4050 4051 if (pScrn->depth > 8) { 4052 /* Fixup RGB ordering */ 4053 visual = pScreen->visuals + pScreen->numVisuals; 4054 while (--visual >= pScreen->visuals) { 4055 if ((visual->class | DynamicClass) == DirectColor) { 4056 visual->offsetRed = pScrn->offset.red; 4057 visual->offsetGreen = pScrn->offset.green; 4058 visual->offsetBlue = pScrn->offset.blue; 4059 visual->redMask = pScrn->mask.red; 4060 visual->greenMask = pScrn->mask.green; 4061 visual->blueMask = pScrn->mask.blue; 4062 } 4063 } 4064 } 4065 4066 /* must be after RGB ordering fixed */ 4067 if (init_picture) 4068 fbPictureInit (pScreen, 0, 0); 4069 4070 xf86SetBlackWhitePixels(pScreen); 4071 4072 cPtr->BlockHandler = pScreen->BlockHandler; 4073 pScreen->BlockHandler = chipsBlockHandler; 4074 4075 if ( (pScrn->depth >= 8)) 4076 CHIPSDGAInit(pScreen); 4077 4078 cPtr->HWCursorShown = FALSE; 4079 4080#if defined(USE_MIBANK) || defined(HAVE_ISA) 4081 if (!(cPtr->Flags & ChipsLinearSupport)) { 4082 miBankInfoPtr pBankInfo; 4083 4084 /* Setup the vga banking variables */ 4085 pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1); 4086 if (pBankInfo == NULL) 4087 return FALSE; 4088 4089#if defined(__arm__) 4090 cPtr->Bank = -1; 4091#endif 4092 pBankInfo->pBankA = hwp->Base; 4093 pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x08000; 4094 pBankInfo->BankSize = 0x08000; 4095 pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth; 4096 4097 if (IS_HiQV(cPtr)) { 4098 pBankInfo->pBankB = hwp->Base; 4099 pBankInfo->BankSize = 0x10000; 4100 if (pScrn->bitsPerPixel < 8) { 4101 pBankInfo->SetSourceBank = 4102 (miBankProcPtr)CHIPSHiQVSetReadWritePlanar; 4103 pBankInfo->SetDestinationBank = 4104 (miBankProcPtr)CHIPSHiQVSetReadWritePlanar; 4105 pBankInfo->SetSourceAndDestinationBanks = 4106 (miBankProcPtr)CHIPSHiQVSetReadWritePlanar; 4107 } else { 4108 pBankInfo->SetSourceBank = 4109 (miBankProcPtr)CHIPSHiQVSetReadWrite; 4110 pBankInfo->SetDestinationBank = 4111 (miBankProcPtr)CHIPSHiQVSetReadWrite; 4112 pBankInfo->SetSourceAndDestinationBanks = 4113 (miBankProcPtr)CHIPSHiQVSetReadWrite; 4114 } 4115 } else { 4116 if (IS_Wingine(cPtr)) { 4117 if (pScrn->bitsPerPixel < 8) { 4118 pBankInfo->SetSourceBank = 4119 (miBankProcPtr)CHIPSWINSetReadPlanar; 4120 pBankInfo->SetDestinationBank = 4121 (miBankProcPtr)CHIPSWINSetWritePlanar; 4122 pBankInfo->SetSourceAndDestinationBanks = 4123 (miBankProcPtr)CHIPSWINSetReadWritePlanar; 4124 } else { 4125 pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSWINSetRead; 4126 pBankInfo->SetDestinationBank = 4127 (miBankProcPtr)CHIPSWINSetWrite; 4128 pBankInfo->SetSourceAndDestinationBanks = 4129 (miBankProcPtr)CHIPSWINSetReadWrite; 4130 } 4131 } else { 4132 if (pScrn->bitsPerPixel < 8) { 4133 pBankInfo->SetSourceBank = 4134 (miBankProcPtr)CHIPSSetReadPlanar; 4135 pBankInfo->SetDestinationBank = 4136 (miBankProcPtr)CHIPSSetWritePlanar; 4137 pBankInfo->SetSourceAndDestinationBanks = 4138 (miBankProcPtr)CHIPSSetReadWritePlanar; 4139 } else { 4140 pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSSetRead; 4141 pBankInfo->SetDestinationBank = 4142 (miBankProcPtr)CHIPSSetWrite; 4143 pBankInfo->SetSourceAndDestinationBanks = 4144 (miBankProcPtr)CHIPSSetReadWrite; 4145 } 4146 } 4147 } 4148 if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, 4149 pScrn->displayWidth, pBankInfo)) { 4150 xfree(pBankInfo); 4151 pBankInfo = NULL; 4152 return FALSE; 4153 } 4154 miInitializeBackingStore(pScreen); 4155 xf86SetBackingStore(pScreen); 4156 4157 /* Initialise cursor functions */ 4158 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 4159 4160 } else 4161#endif /* HAVE_ISA */ 4162 { 4163 /* !!! Only support linear addressing for now. This might change */ 4164 /* Setup pointers to free space in video ram */ 4165#define CHIPSALIGN(size, align) (currentaddr - ((currentaddr - size) & ~align)) 4166 allocatebase = (pScrn->videoRam<<10) - cPtr->FrameBufferSize; 4167 4168 if (pScrn->bitsPerPixel < 8) 4169 freespace = allocatebase - pScrn->displayWidth * 4170 pScrn->virtualY / 2; 4171 else if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)) 4172 freespace = allocatebase - pScrn->displayWidth * 4173 pScrn->virtualY - cPtr->FbSize16; 4174 else 4175 freespace = allocatebase - pScrn->displayWidth * 4176 pScrn->virtualY * (pScrn->bitsPerPixel >> 3); 4177 4178 if ((cPtr->Flags & ChipsDualChannelSupport) && 4179 (cPtr->SecondCrtc == TRUE)) { 4180 currentaddr = allocatebase + cPtrEnt->masterFbMapSize; 4181 } else 4182 currentaddr = allocatebase; 4183 if (serverGeneration == 1) 4184 xf86DrvMsg(scrnIndex, X_PROBED, 4185 "%d bytes off-screen memory available\n", freespace); 4186 4187 /* 4188 * Allocate video memory to store the hardware cursor. Allocate 1kB 4189 * vram to the cursor, with 1kB alignment for 6554x's and 4kb alignment 4190 * for 65550's. Wingine cursor is stored in registers and so no memory 4191 * is needed. 4192 */ 4193 if (cAcl->UseHWCursor) { 4194 cAcl->CursorAddress = -1; 4195 if (IS_HiQV(cPtr)) { 4196 if (CHIPSALIGN(1024, 0xFFF) <= freespace) { 4197 currentaddr -= CHIPSALIGN(1024, 0xFFF); 4198 freespace -= CHIPSALIGN(1024, 0xFFF); 4199 cAcl->CursorAddress = currentaddr; 4200 } 4201 } else if (IS_Wingine(cPtr)) { 4202 cAcl->CursorAddress = 0; 4203 } else if (CHIPSALIGN(1024, 0x3FF) <= freespace) { 4204 currentaddr -= CHIPSALIGN(1024, 0x3FF); 4205 freespace -= CHIPSALIGN(1024, 0x3FF); 4206 cAcl->CursorAddress = currentaddr; 4207 } 4208 if (cAcl->CursorAddress == -1) 4209 xf86DrvMsg(scrnIndex, X_ERROR, 4210 "Too little space for H/W cursor.\n"); 4211 } 4212 4213 cAcl->CacheEnd = currentaddr; 4214 4215 /* Setup the acceleration primitives */ 4216 /* Calculate space needed of offscreen pixmaps etc. */ 4217 if (cPtr->Flags & ChipsAccelSupport) { 4218 /* 4219 * A scratch area is now allocated in the video ram. This is used 4220 * at 8 and 16 bpp to simulate a planemask with a complex ROP, and 4221 * at 24 and 32 bpp to aid in accelerating solid fills 4222 */ 4223 cAcl->ScratchAddress = -1; 4224 switch (pScrn->bitsPerPixel) { 4225 case 8: 4226 if (CHIPSALIGN(64, 0x3F) <= freespace) { 4227 currentaddr -= CHIPSALIGN(64, 0x3F); 4228 freespace -= CHIPSALIGN(64, 0x3F); 4229 cAcl->ScratchAddress = currentaddr; 4230 } 4231 break; 4232 case 16: 4233 if (CHIPSALIGN(128, 0x7F) <= freespace) { 4234 currentaddr -= CHIPSALIGN(128, 0x7F); 4235 freespace -= CHIPSALIGN(128, 0x7F); 4236 cAcl->ScratchAddress = currentaddr; 4237 } 4238 break; 4239 case 24: 4240 /* One scanline of data used for solid fill */ 4241 if (!IS_HiQV(cPtr)) { 4242 if (CHIPSALIGN(3 * (pScrn->displayWidth + 4), 0x3) 4243 <= freespace) { 4244 currentaddr -= CHIPSALIGN(3 * (pScrn->displayWidth 4245 + 4), 0x3); 4246 freespace -= CHIPSALIGN(3 * (pScrn->displayWidth + 4), 4247 0x3); 4248 cAcl->ScratchAddress = currentaddr; 4249 } 4250 } 4251 break; 4252 case 32: 4253 /* 16bpp 8x8 mono pattern fill for solid fill. QWORD aligned */ 4254 if (IS_HiQV(cPtr)) { 4255 if (CHIPSALIGN(8, 0x7) <= freespace) { 4256 currentaddr -= CHIPSALIGN(8, 0x7); 4257 freespace -= CHIPSALIGN(8, 0x7); 4258 cAcl->ScratchAddress = currentaddr; 4259 } 4260 } 4261 break; 4262 } 4263 4264 /* Setup the boundaries of the pixmap cache */ 4265 cAcl->CacheStart = currentaddr - freespace; 4266 cAcl->CacheEnd = currentaddr; 4267 4268 if (cAcl->CacheStart >= cAcl->CacheEnd) { 4269 xf86DrvMsg(scrnIndex, X_ERROR, 4270 "Too little space for pixmap cache.\n"); 4271 cAcl->CacheStart = 0; 4272 cAcl->CacheEnd = 0; 4273 } 4274 4275 if (IS_HiQV(cPtr)) 4276 cAcl->BltDataWindow = (unsigned char *)cPtr->MMIOBase 4277 + 0x10000L; 4278 else 4279 cAcl->BltDataWindow = cPtr->FbBase; 4280 4281 } 4282 /* 4283 * Initialize FBManager: 4284 * we do even with no acceleration enabled 4285 * so that video support can allocate space. 4286 */ 4287 4288 { 4289 BoxRec AvailFBArea; 4290 AvailFBArea.x1 = 0; 4291 AvailFBArea.y1 = 0; 4292 AvailFBArea.x2 = pScrn->displayWidth; 4293 AvailFBArea.y2 = cAcl->CacheEnd / 4294 (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 4295 4296 if (!(cPtr->Flags & ChipsOverlay8plus16)) { 4297 xf86InitFBManager(pScreen, &AvailFBArea); 4298 } 4299 } 4300 if (cPtr->Flags & ChipsAccelSupport) { 4301 if (IS_HiQV(cPtr)) { 4302 CHIPSHiQVAccelInit(pScreen); 4303 } else if (cPtr->UseMMIO) { 4304 CHIPSMMIOAccelInit(pScreen); 4305 } else { 4306 CHIPSAccelInit(pScreen); 4307 } 4308 } 4309 4310 miInitializeBackingStore(pScreen); 4311 xf86SetBackingStore(pScreen); 4312#ifdef ENABLE_SILKEN_MOUSE 4313 xf86SetSilkenMouse(pScreen); 4314#endif 4315 4316 /* Initialise cursor functions */ 4317 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 4318 4319 if ((cAcl->UseHWCursor) && (cAcl->CursorAddress != -1)) { 4320 /* HW cursor functions */ 4321 if (!CHIPSCursorInit(pScreen)) { 4322 xf86DrvMsg(scrnIndex, X_ERROR, 4323 "Hardware cursor initialization failed\n"); 4324 return FALSE; 4325 } 4326 } 4327 } 4328 4329 if (cPtr->Flags & ChipsShadowFB) { 4330 RefreshAreaFuncPtr refreshArea = chipsRefreshArea; 4331 4332 if(cPtr->Rotate) { 4333 if (!cPtr->PointerMoved) { 4334 cPtr->PointerMoved = pScrn->PointerMoved; 4335 pScrn->PointerMoved = chipsPointerMoved; 4336 } 4337 4338 switch(pScrn->bitsPerPixel) { 4339 case 8: refreshArea = chipsRefreshArea8; break; 4340 case 16: refreshArea = chipsRefreshArea16; break; 4341 case 24: refreshArea = chipsRefreshArea24; break; 4342 case 32: refreshArea = chipsRefreshArea32; break; 4343 } 4344 } 4345 ShadowFBInit(pScreen, refreshArea); 4346 } 4347 4348 /* Initialise default colourmap */ 4349 if (!miCreateDefColormap(pScreen)) 4350 return FALSE; 4351 4352 if ((cPtr->Flags & ChipsOverlay8plus16) && (pScrn->bitsPerPixel == 16)) { 4353 if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, chipsLoadPalette, 4354 NULL, CMAP_RELOAD_ON_MODE_SWITCH)) 4355 return FALSE; 4356 } else { 4357 if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, 4358 (pScrn->depth == 16 ? chipsLoadPalette16 : chipsLoadPalette), 4359 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 4360 return FALSE; 4361 } 4362 4363#ifndef XSERVER_LIBPCIACCESS 4364 racflag = RAC_COLORMAP; 4365 if (cAcl->UseHWCursor) 4366 racflag |= RAC_CURSOR; 4367 racflag |= (RAC_FB | RAC_VIEWPORT); 4368 /* XXX Check if I/O and Mem flags need to be the same. */ 4369 pScrn->racIoFlags = pScrn->racMemFlags = racflag; 4370#endif 4371#ifdef ENABLE_SILKEN_MOUSE 4372 xf86SetSilkenMouse(pScreen); 4373#endif 4374 4375 if ((!(cPtr->Flags & ChipsOverlay8plus16)) 4376 && (cPtr->Flags & ChipsVideoSupport) 4377 && (cPtr->Flags & ChipsLinearSupport)) { 4378 CHIPSInitVideo(pScreen); 4379 } 4380 4381 pScreen->SaveScreen = CHIPSSaveScreen; 4382 4383 /* Setup DPMS mode */ 4384 if (cPtr->Flags & ChipsDPMSSupport) 4385 xf86DPMSInit(pScreen, (DPMSSetProcPtr)chipsDisplayPowerManagementSet, 4386 0); 4387 4388 /* Wrap the current CloseScreen function */ 4389 cPtr->CloseScreen = pScreen->CloseScreen; 4390 pScreen->CloseScreen = CHIPSCloseScreen; 4391 4392 /* Report any unused options (only for the first generation) */ 4393 if (serverGeneration == 1) { 4394 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 4395 } 4396 4397 return TRUE; 4398} 4399 4400/* Mandatory */ 4401Bool 4402CHIPSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 4403{ 4404 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4405 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4406 CHIPSEntPtr cPtrEnt; 4407 4408#ifdef DEBUG 4409 ErrorF("CHIPSSwitchMode\n"); 4410#endif 4411 if (cPtr->UseDualChannel) { 4412 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4413 CHIPSEntityIndex)->ptr; 4414 DUALREOPEN; 4415 } 4416 4417 return chipsModeInit(xf86Screens[scrnIndex], mode); 4418} 4419 4420/* Mandatory */ 4421void 4422CHIPSAdjustFrame(int scrnIndex, int x, int y, int flags) 4423{ 4424 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4425 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4426 CHIPSEntPtr cPtrEnt; 4427 4428 int Base; 4429 vgaHWPtr hwp = VGAHWPTR(pScrn); 4430 unsigned char tmp; 4431 4432 if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHOWCACHE, FALSE) && y) { 4433 int lastline = cPtr->FbMapSize / 4434 ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8); 4435 lastline -= pScrn->currentMode->VDisplay; 4436 y += pScrn->virtualY - 1; 4437 if (y > lastline) y = lastline; 4438 } 4439 4440 Base = y * pScrn->displayWidth + x; 4441 4442 /* calculate base bpp dep. */ 4443 switch (pScrn->bitsPerPixel) { 4444 case 1: 4445 case 4: 4446 Base >>= 3; 4447 break; 4448 case 16: 4449 if (!(cPtr->Flags & ChipsOverlay8plus16)) 4450 Base >>= 1; 4451 else 4452 Base >>= 2; 4453 break; 4454 case 24: 4455 if (!IS_HiQV(cPtr)) 4456 Base = (Base >> 2) * 3; 4457 else 4458 Base = (Base >> 3) * 6; /* 65550 seems to need 64bit alignment */ 4459 break; 4460 case 32: 4461 break; 4462 default: /* 8bpp */ 4463 Base >>= 2; 4464 break; 4465 } 4466 4467 if (cPtr->UseDualChannel) { 4468 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4469 CHIPSEntityIndex)->ptr; 4470 DUALREOPEN; 4471 } 4472 4473 /* write base to chip */ 4474 /* 4475 * These are the generic starting address registers. 4476 */ 4477 chipsFixResume(pScrn); 4478 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 4479 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 4480 if (IS_HiQV(cPtr)) { 4481 if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1) 4482 hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80); 4483 } else { 4484 tmp = cPtr->readXR(cPtr, 0x0C); 4485 cPtr->writeXR(cPtr, 0x0C, ((Base & (IS_Wingine(cPtr) ? 0x0F0000 : 4486 0x030000)) >> 16) | (tmp & 0xF8)); 4487 } 4488 4489 if (cPtr->UseDualChannel && 4490 (! xf86IsEntityShared(pScrn->entityList[0]))) { 4491 unsigned int IOSS, MSS; 4492 IOSS = cPtr->readIOSS(cPtr); 4493 MSS = cPtr->readMSS(cPtr); 4494 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 4495 IOSS_PIPE_B)); 4496 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 4497 4498 chipsFixResume(pScrn); 4499 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 4500 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 4501 if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1) 4502 hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80); 4503 4504 cPtr->writeIOSS(cPtr, IOSS); 4505 cPtr->writeMSS(cPtr, hwp, MSS); 4506 } 4507 4508 if (cPtr->Flags & ChipsOverlay8plus16) { 4509 Base = (Base << 3) & ~(unsigned long)0xF; 4510 4511 cPtr->writeMR(cPtr, 0x22, (cPtr->FbOffset16 + Base) & 0xF8); 4512 cPtr->writeMR(cPtr, 0x23, ((cPtr->FbOffset16 + Base) >> 8) & 0xFF); 4513 cPtr->writeMR(cPtr, 0x24, ((cPtr->FbOffset16 + Base) >> 16) & 0xFF); 4514 } 4515 4516} 4517 4518/* Mandatory */ 4519static Bool 4520CHIPSCloseScreen(int scrnIndex, ScreenPtr pScreen) 4521{ 4522 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4523 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4524 CHIPSEntPtr cPtrEnt; 4525 4526 if(pScrn->vtSema){ /*§§§*/ 4527 if (cPtr->Flags & ChipsDualChannelSupport) { 4528 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4529 CHIPSEntityIndex)->ptr; 4530 if (cPtr->UseDualChannel) 4531 DUALREOPEN; 4532 DUALCLOSE; 4533 } else { 4534 chipsHWCursorOff(cPtr, pScrn); 4535 chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg, 4536 TRUE); 4537 chipsLock(pScrn); 4538 } 4539 chipsUnmapMem(pScrn); 4540 } 4541 4542 if (xf86IsEntityShared(pScrn->entityList[0])) { 4543 DevUnion *pPriv; 4544 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], CHIPSEntityIndex); 4545 cPtrEnt = pPriv->ptr; 4546 cPtrEnt->refCount--; 4547 } 4548 if (cPtr->AccelInfoRec) 4549 XAADestroyInfoRec(cPtr->AccelInfoRec); 4550 if (cPtr->CursorInfoRec) 4551 xf86DestroyCursorInfoRec(cPtr->CursorInfoRec); 4552 free(cPtr->ShadowPtr); 4553 free(cPtr->DGAModes); 4554 pScrn->vtSema = FALSE; 4555 if(cPtr->BlockHandler) 4556 pScreen->BlockHandler = cPtr->BlockHandler; 4557 4558 pScreen->CloseScreen = cPtr->CloseScreen; /*§§§*/ 4559 xf86ClearPrimInitDone(pScrn->entityList[0]); 4560 return (*pScreen->CloseScreen)(scrnIndex, pScreen);/*§§§*/ 4561} 4562 4563/* Optional */ 4564static void 4565CHIPSFreeScreen(int scrnIndex, int flags) 4566{ 4567 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 4568 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 4569 CHIPSFreeRec(xf86Screens[scrnIndex]); 4570} 4571 4572/* Optional */ 4573static ModeStatus 4574CHIPSValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 4575{ 4576 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4577 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4578 4579 if (flags & MODECHECK_FINAL) { 4580 /* Don't subtract FrambufferSize here as it should be subtracted already */ 4581 if ((cPtr->Flags & ChipsOverlay8plus16) 4582 && ((pScrn->videoRam<<10) - pScrn->displayWidth * 3 * pScrn->virtualY 4583 < 0)) 4584 return MODE_MEM; 4585 } 4586 /* The tests here need to be expanded */ 4587 if ((mode->Flags & V_INTERLACE) && (cPtr->PanelType & ChipsLCD)) 4588 return MODE_NO_INTERLACE; 4589 if ((cPtr->PanelType & ChipsLCD) 4590 && !xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE) 4591 && ((cPtr->PanelSize.HDisplay < mode->HDisplay) 4592 || (cPtr->PanelSize.VDisplay < mode->VDisplay))) 4593 return MODE_PANEL; 4594 4595 return MODE_OK; 4596} 4597 4598/* 4599 * DPMS Control registers 4600 * 4601 * XR73 6554x and 64300 (what about 65535?) 4602 * XR61 6555x 4603 * 0 HSync Powerdown data 4604 * 1 HSync Select 1=Powerdown 4605 * 2 VSync Powerdown data 4606 * 3 VSync Select 1=Powerdown 4607 */ 4608 4609static void 4610chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 4611 int flags) 4612{ 4613 vgaHWPtr hwp = VGAHWPTR(pScrn); 4614 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4615 CHIPSEntPtr cPtrEnt; 4616 4617 unsigned char dpmsreg, seqreg, lcdoff, tmp; 4618 4619 if (!pScrn->vtSema) 4620 return; 4621 4622#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 8 4623 xf86EnableAccess(pScrn); 4624#endif 4625 switch (PowerManagementMode) { 4626 case DPMSModeOn: 4627 /* Screen: On; HSync: On, VSync: On */ 4628 dpmsreg = 0x00; 4629 seqreg = 0x00; 4630 lcdoff = 0x0; 4631 break; 4632 case DPMSModeStandby: 4633 /* Screen: Off; HSync: Off, VSync: On */ 4634 dpmsreg = 0x02; 4635 seqreg = 0x20; 4636 lcdoff = 0x0; 4637 break; 4638 case DPMSModeSuspend: 4639 /* Screen: Off; HSync: On, VSync: Off */ 4640 dpmsreg = 0x08; 4641 seqreg = 0x20; 4642 lcdoff = 0x1; 4643 break; 4644 case DPMSModeOff: 4645 /* Screen: Off; HSync: Off, VSync: Off */ 4646 dpmsreg = 0x0A; 4647 seqreg = 0x20; 4648 lcdoff = 0x1; 4649 break; 4650 default: 4651 return; 4652 } 4653 4654 if (cPtr->UseDualChannel) { 4655 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4656 CHIPSEntityIndex)->ptr; 4657 DUALREOPEN; 4658 } 4659 4660 seqreg |= hwp->readSeq(hwp, 0x01) & ~0x20; 4661 hwp->writeSeq(hwp, 0x01, seqreg); 4662 if (IS_HiQV(cPtr)) { 4663 tmp = cPtr->readXR(cPtr, 0x61); 4664 cPtr->writeXR(cPtr, 0x61, (tmp & 0xF0) | dpmsreg); 4665 } else { 4666 tmp = cPtr->readXR(cPtr, 0x73); 4667 cPtr->writeXR(cPtr, 0x73, (tmp & 0xF0) | dpmsreg); 4668 } 4669 4670 /* Turn off the flat panel */ 4671 if (cPtr->PanelType & ChipsLCDProbed) { 4672 if (IS_HiQV(cPtr)) { 4673 if (cPtr->Chipset == CHIPS_CT69030) { 4674#if 0 4675 /* Where is this for the 69030?? */ 4676 tmp = cPtr->readFR(cPtr, 0x05); 4677 if (lcdoff) 4678 cPtr->writeFR(cPtr, 0x05, tmp | 0x08); 4679 else 4680 cPtr->writeFR(cPtr, 0x05, tmp & 0xF7); 4681#endif 4682 } else { 4683 tmp = cPtr->readFR(cPtr, 0x05); 4684 if (lcdoff) 4685 cPtr->writeFR(cPtr, 0x05, tmp | 0x08); 4686 else 4687 cPtr->writeFR(cPtr, 0x05, tmp & 0xF7); 4688 } 4689 } else { 4690 tmp = cPtr->readXR(cPtr, 0x52); 4691 if (lcdoff) 4692 cPtr->writeXR(cPtr, 0x52, tmp | 0x08); 4693 else 4694 cPtr->writeXR(cPtr, 0x52, tmp & 0xF7); 4695 } 4696 } 4697} 4698 4699static Bool 4700CHIPSSaveScreen(ScreenPtr pScreen, int mode) 4701{ 4702 ScrnInfoPtr pScrn = NULL; /* §§§ */ 4703 Bool unblank; 4704 4705 unblank = xf86IsUnblank(mode); 4706 4707 if (pScreen != NULL) 4708 pScrn = xf86Screens[pScreen->myNum]; 4709 4710 if (unblank) 4711 SetTimeSinceLastInputEvent(); 4712 4713 if ((pScrn != NULL) && pScrn->vtSema) { /* §§§ */ 4714 chipsBlankScreen(pScrn, unblank); 4715 } 4716 return (TRUE); 4717} 4718 4719static Bool 4720chipsClockSelect(ScrnInfoPtr pScrn, int no) 4721{ 4722 CHIPSClockReg TmpClock; 4723 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4724 4725 switch (no) { 4726 case CLK_REG_SAVE: 4727 chipsClockSave(pScrn, &cPtr->SaveClock); 4728 break; 4729 4730 case CLK_REG_RESTORE: 4731 chipsClockLoad(pScrn, &cPtr->SaveClock); 4732 break; 4733 4734 default: 4735 if (!chipsClockFind(pScrn, NULL, no, &TmpClock)) 4736 return (FALSE); 4737 chipsClockLoad(pScrn, &TmpClock); 4738 } 4739 return (TRUE); 4740} 4741 4742/* 4743 * 4744 * Fout = (Fref * 4 * M) / (PSN * N * (1 << P) ) 4745 * Fvco = (Fref * 4 * M) / (PSN * N) 4746 * where 4747 * M = XR31+2 4748 * N = XR32+2 4749 * P = XR30[3:1] 4750 * PSN = XR30[0]? 1:4 4751 * 4752 * constraints: 4753 * 4 MHz <= Fref <= 20 MHz (typ. 14.31818 MHz) 4754 * 150 kHz <= Fref/(PSN * N) <= 2 MHz 4755 * 48 MHz <= Fvco <= 220 MHz 4756 * 2 < M < 128 4757 * 2 < N < 128 4758 */ 4759 4760static void 4761chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock) 4762{ 4763 unsigned char tmp; 4764 vgaHWPtr hwp = VGAHWPTR(pScrn); 4765 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4766 unsigned char Type = cPtr->ClockType; 4767 CHIPSEntPtr cPtrEnt; 4768 4769 Clock->msr = hwp->readMiscOut(hwp)&0xFE; /* save standard VGA clock reg */ 4770 switch (Type & GET_STYLE) { 4771 case HiQV_STYLE: 4772 /* save alternate clock select reg.*/ 4773 /* The 69030 FP clock select is at FR01 instead */ 4774 if (cPtr->UseDualChannel) { 4775 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4776 CHIPSEntityIndex)->ptr; 4777 DUALREOPEN; 4778 } 4779 4780 if (cPtr->Flags & ChipsDualChannelSupport) 4781 Clock->fr03 = cPtr->readFR(cPtr, 0x01); 4782 else 4783 Clock->fr03 = cPtr->readFR(cPtr, 0x03); 4784 if (!Clock->Clock) { /* save HiQV console clock */ 4785 tmp = cPtr->CRTclkInx << 2; 4786 cPtr->CRTClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp); 4787 cPtr->CRTClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp); 4788 cPtr->CRTClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp); 4789 cPtr->CRTClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp); 4790 tmp = cPtr->FPclkInx << 2; 4791 cPtr->FPClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp); 4792 cPtr->FPClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp); 4793 cPtr->FPClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp); 4794 cPtr->FPClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp); 4795 } 4796 break; 4797 case OLD_STYLE: 4798 Clock->fcr = hwp->readFCR(hwp); 4799 Clock->xr02 = cPtr->readXR(cPtr, 0x02); 4800 Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/ 4801 break; 4802 case WINGINE_1_STYLE: 4803 case WINGINE_2_STYLE: 4804 break; 4805 case NEW_STYLE: 4806 Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/ 4807 Clock->xr33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK sel reg.*/ 4808 break; 4809 } 4810#ifdef DEBUG 4811 ErrorF("saved \n"); 4812#endif 4813} 4814 4815static Bool 4816chipsClockFind(ScrnInfoPtr pScrn, DisplayModePtr mode, 4817 int no, CHIPSClockPtr Clock ) 4818{ 4819 vgaHWPtr hwp = VGAHWPTR(pScrn); 4820 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4821 unsigned char Type = cPtr->ClockType; 4822 CHIPSEntPtr cPtrEnt; 4823 4824 if (no > (pScrn->numClocks - 1)) 4825 return (FALSE); 4826 4827 if (cPtr->UseDualChannel) { 4828 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4829 CHIPSEntityIndex)->ptr; 4830 DUALREOPEN; 4831 } 4832 4833 switch (Type & GET_STYLE) { 4834 case HiQV_STYLE: 4835 Clock->msr = cPtr->CRTclkInx << 2; 4836 Clock->fr03 = cPtr->FPclkInx << 2; 4837 Clock->Clock = mode ? mode->Clock : 0; 4838 if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 4839 Clock->FPClock = mode ? mode->Clock : 0; 4840 } else 4841 Clock->FPClock = cPtr->FPclock; 4842 break; 4843 case NEW_STYLE: 4844 if (Type & TYPE_HW) { 4845 Clock->msr = (no == 4 ? 3 << 2: (no & 0x01) << 2); 4846 Clock->xr54 = Clock->msr; 4847 Clock->xr33 = no > 1 ? 0x80 : 0; 4848 } else { 4849 Clock->msr = 3 << 2; 4850 Clock->xr33 = 0; 4851 Clock->xr54 = Clock->msr; 4852 /* update panel type in case somebody switched. 4853 * This should be handled more generally: 4854 * On mode switch DDC should be reread, all 4855 * display dependent data should be reevaluated. 4856 * This will be built in when we start Display 4857 * HotPlug support. 4858 * Until then we have to do it here as somebody 4859 * might have switched displays on us and we only 4860 * have one programmable clock which needs to 4861 * be shared for CRT and LCD. 4862 */ 4863 chipsSetPanelType(cPtr); 4864 { 4865 Bool fp_m; 4866 if (cPtr->Options 4867 && xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_m)) { 4868 if (fp_m) 4869 cPtr->PanelType |= ChipsLCD; 4870 else 4871 cPtr->PanelType = ~ChipsLCD; 4872 } 4873 } 4874 4875 if ((cPtr->PanelType & ChipsLCD) && cPtr->FPclock) 4876 Clock->Clock = cPtr->FPclock; 4877 else 4878 Clock->Clock = mode ? mode->SynthClock : 0; 4879 } 4880 break; 4881 case OLD_STYLE: 4882 if (no > 3) { 4883 Clock->msr = 3 << 2; 4884 Clock->fcr = no & 0x03; 4885 Clock->xr02 = 0; 4886 Clock->xr54 = Clock->msr & (Clock->fcr << 4); 4887 } else { 4888 Clock->msr = (no << 2) & 0x4; 4889 Clock->fcr = 0; 4890 Clock->xr02 = no & 0x02; 4891 Clock->xr54 = Clock->msr; 4892 } 4893 break; 4894 case WINGINE_1_STYLE: 4895 Clock->msr = no << 2; 4896 case WINGINE_2_STYLE: 4897 if (Type & TYPE_HW) { 4898 Clock->msr = (no == 2 ? 3 << 2: (no & 0x01) << 2); 4899 Clock->xr33 = 0; 4900 } else { 4901 Clock->msr = 3 << 2; 4902 Clock->xr33 = 0; 4903 Clock->Clock = mode ? mode->SynthClock : 0; 4904 } 4905 break; 4906 } 4907 Clock->msr |= (hwp->readMiscOut(hwp) & 0xF2); 4908 4909#ifdef DEBUG 4910 ErrorF("found\n"); 4911#endif 4912 return (TRUE); 4913} 4914 4915 4916static int 4917chipsGetHWClock(ScrnInfoPtr pScrn) 4918{ 4919 vgaHWPtr hwp = VGAHWPTR(pScrn); 4920 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4921 unsigned char Type = cPtr->ClockType; 4922 unsigned char tmp, tmp1; 4923 4924 if (!(Type & TYPE_HW)) 4925 return 0; /* shouldn't happen */ 4926 4927 switch (Type & GET_STYLE) { 4928 case WINGINE_1_STYLE: 4929 return ((hwp->readMiscOut(hwp) & 0x0C) >> 2); 4930 case WINGINE_2_STYLE: 4931 tmp = ((hwp->readMiscOut(hwp) & 0x04) >> 2); 4932 return (tmp > 2) ? 2 : tmp; 4933 case OLD_STYLE: 4934 if (!(cPtr->PanelType & ChipsLCDProbed)) 4935 tmp = hwp->readMiscOut(hwp); 4936 else 4937 tmp = cPtr->readXR(cPtr, 0x54); 4938 if (tmp & 0x08) { 4939 if (!(cPtr->PanelType & ChipsLCDProbed)) 4940 tmp = hwp->readFCR(hwp) & 0x03; 4941 else 4942 tmp = (tmp >> 4) & 0x03; 4943 return (tmp + 4); 4944 } else { 4945 tmp = (tmp >> 2) & 0x01; 4946 tmp1 = cPtr->readXR(cPtr, 0x02); 4947 return (tmp + (tmp1 & 0x02)); 4948 } 4949 case NEW_STYLE: 4950 if (cPtr->PanelType & ChipsLCDProbed) { 4951 tmp = cPtr->readXR(cPtr, 0x54); 4952 } else 4953 tmp = hwp->readMiscOut(hwp); 4954 tmp = (tmp & 0x0C) >> 2; 4955 if (tmp > 1) return 4; 4956 tmp1 = cPtr->readXR(cPtr, 0x33); 4957 tmp1 = (tmp1 & 0x80) >> 6; /* iso mode 25.175/28.322 or 32/36 MHz */ 4958 return (tmp + tmp1); /* ^=0 ^=1 ^=4 ^=5 */ 4959 default: /* we should never get here */ 4960 return (0); 4961 } 4962} 4963 4964static void 4965chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock) 4966{ 4967 vgaHWPtr hwp = VGAHWPTR(pScrn); 4968 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4969 unsigned char Type = cPtr->ClockType; 4970 volatile unsigned char tmp, tmpmsr, tmpfcr, tmp02; 4971 volatile unsigned char tmp33, tmp54, tmpf03; 4972 unsigned char vclk[3]; 4973 4974 tmpmsr = hwp->readMiscOut(hwp); /* read msr, needed for all styles */ 4975 4976 switch (Type & GET_STYLE) { 4977 case HiQV_STYLE: 4978 /* save alternate clock select reg. */ 4979 /* The 69030 FP clock select is at FR01 instead */ 4980 if (cPtr->Flags & ChipsDualChannelSupport) { 4981 tmpf03 = cPtr->readFR(cPtr, 0x01); 4982 } else 4983 tmpf03 = cPtr->readFR(cPtr, 0x03); 4984 /* select fixed clock 0 before tampering with VCLK select */ 4985 hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) | 4986 cPtr->SuspendHack.vgaIOBaseFlag); 4987 /* The 69030 FP clock select is at FR01 instead */ 4988 if (cPtr->Flags & ChipsDualChannelSupport) { 4989 cPtr->writeFR(cPtr, 0x01, (tmpf03 & ~0x0C) | 0x04); 4990 } else 4991 cPtr->writeFR(cPtr, 0x03, (tmpf03 & ~0x0C) | 0x04); 4992 if (!Clock->Clock) { /* Hack to load saved console clock */ 4993 tmp = cPtr->CRTclkInx << 2; 4994 cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->CRTClk[0] & 0xFF)); 4995 cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->CRTClk[1] & 0xFF)); 4996 cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->CRTClk[2] & 0xFF)); 4997 cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->CRTClk[3] & 0xFF)); 4998 4999 if (cPtr->FPClkModified) { 5000 usleep(10000); /* let VCO stabilize */ 5001 tmp = cPtr->FPclkInx << 2; 5002 cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->FPClk[0] & 0xFF)); 5003 cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->FPClk[1] & 0xFF)); 5004 cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->FPClk[2] & 0xFF)); 5005 cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->FPClk[3] & 0xFF)); 5006 } 5007 } else { 5008 /* 5009 * Don't use the extra 2 bits in the M, N registers available 5010 * on the HiQV, so write zero to 0xCA 5011 */ 5012 chipsCalcClock(pScrn, Clock->Clock, vclk); 5013 tmp = cPtr->CRTclkInx << 2; 5014 cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF)); 5015 cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF)); 5016 cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0); 5017 cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF)); 5018 if (Clock->FPClock) { 5019 usleep(10000); /* let VCO stabilize */ 5020 chipsCalcClock(pScrn, Clock->FPClock, vclk); 5021 tmp = cPtr->FPclkInx << 2; 5022 cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF)); 5023 cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF)); 5024 cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0); 5025 cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF)); 5026 cPtr->FPClkModified = TRUE; 5027 } 5028 } 5029 usleep(10000); /* Let VCO stabilise */ 5030 /* The 69030 FP clock select is at FR01 instead */ 5031 if (cPtr->Flags & ChipsDualChannelSupport) { 5032 cPtr->writeFR(cPtr, 0x01, ((tmpf03 & ~0x0C) | 5033 (Clock->fr03 & 0x0C))); 5034 } else 5035 cPtr->writeFR(cPtr, 0x03, ((tmpf03 & ~0x0C) | 5036 (Clock->fr03 & 0x0C))); 5037 break; 5038 case WINGINE_1_STYLE: 5039 break; 5040 case WINGINE_2_STYLE: 5041 /* Only write to soft clock registers if we really need to */ 5042 if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) { 5043 /* select fixed clock 0 before tampering with VCLK select */ 5044 hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) | 5045 cPtr->SuspendHack.vgaIOBaseFlag); 5046 chipsCalcClock(pScrn, Clock->Clock, vclk); 5047 tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */ 5048 cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20); 5049 cPtr->writeXR(cPtr, 0x30, vclk[0]); 5050 cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */ 5051 cPtr->writeXR(cPtr, 0x32, vclk[2]); 5052 /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/ 5053 usleep(10000); /* Let VCO stabilise */ 5054 } 5055 break; 5056 case OLD_STYLE: 5057 tmp02 = cPtr->readXR(cPtr, 0x02); 5058 tmp54 = cPtr->readXR(cPtr, 0x54); 5059 tmpfcr = hwp->readFCR(hwp); 5060 cPtr->writeXR(cPtr, 0x02, ((tmp02 & ~0x02) | (Clock->xr02 & 0x02))); 5061 cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF0) | (Clock->xr54 & ~0xF0))); 5062 hwp->writeFCR(hwp, (tmpfcr & ~0x03) & Clock->fcr); 5063 break; 5064 case NEW_STYLE: 5065 tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */ 5066 tmp54 = cPtr->readXR(cPtr, 0x54); 5067 /* Only write to soft clock registers if we really need to */ 5068 if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) { 5069 /* select fixed clock 0 before tampering with VCLK select */ 5070 hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) | 5071 cPtr->SuspendHack.vgaIOBaseFlag); 5072 cPtr->writeXR(cPtr, 0x54, (tmp54 & 0xF3)); 5073 /* if user wants to set the memory clock, do it first */ 5074 if (cPtr->MemClock.Clk) { 5075 chipsCalcClock(pScrn, cPtr->MemClock.Clk, vclk); 5076 /* close eyes, hold breath ....*/ 5077 cPtr->writeXR(cPtr, 0x33, tmp33 | 0x20); 5078 cPtr->writeXR(cPtr, 0x30, vclk[0]); 5079 cPtr->writeXR(cPtr, 0x31, vclk[1]); 5080 cPtr->writeXR(cPtr, 0x32, vclk[2]); 5081 usleep(10000); 5082 } 5083 chipsCalcClock(pScrn, Clock->Clock, vclk); 5084 cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20); 5085 cPtr->writeXR(cPtr, 0x30, vclk[0]); 5086 cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */ 5087 cPtr->writeXR(cPtr, 0x32, vclk[2]); 5088 /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/ 5089 usleep(10000); /* Let VCO stabilise */ 5090 } 5091 cPtr->writeXR(cPtr, 0x33, ((tmp33 & ~0x80) | (Clock->xr33 & 0x80))); 5092 cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF3) | (Clock->xr54 & ~0xF3))); 5093 break; 5094 } 5095 hwp->writeMiscOut(hwp, (Clock->msr & 0xFE) | 5096 cPtr->SuspendHack.vgaIOBaseFlag); 5097#ifdef DEBUG 5098 ErrorF("restored\n"); 5099#endif 5100} 5101 5102/* 5103 * This is Ken Raeburn's <raeburn@raeburn.org> clock 5104 * calculation code just modified a little bit to fit in here. 5105 */ 5106 5107static void 5108chipsCalcClock(ScrnInfoPtr pScrn, int Clock, unsigned char *vclk) 5109{ 5110 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5111 int M, N, P = 0, PSN = 0, PSNx = 0; 5112 5113 int bestM = 0, bestN = 0, bestP = 0, bestPSN = 0; 5114 double abest = 42; 5115#ifdef DEBUG 5116 double bestFout = 0; 5117#endif 5118 double target; 5119 5120 double Fvco, Fout; 5121 double error, aerror; 5122 5123 int M_min = 3; 5124 5125 /* Hack to deal with problem of Toshiba 720CDT clock */ 5126 int M_max = (IS_HiQV(cPtr) && cPtr->Chipset != CHIPS_CT69000 && 5127 cPtr->Chipset != CHIPS_CT69030) ? 63 : 127; 5128 5129 /* @@@ < CHIPS_CT690x0 ?? */ 5130 5131 /* Other parameters available on the 65548 but not the 65545, and 5132 * not documented in the Clock Synthesizer doc in rev 1.0 of the 5133 * 65548 datasheet: 5134 * 5135 * + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545) 5136 * 1, VCO divider loop uses divide by 16 5137 * 5138 * + XR30[5] = 1, reference clock is divided by 5 5139 * 5140 * Other parameters available on the 65550 and not on the 65545 5141 * 5142 * + XRCB[2] = 0, VCO divider loop uses divide by 4 (same as 65545) 5143 * 1, VCO divider loop uses divide by 16 5144 * 5145 * + XRCB[1] = 1, reference clock is divided by 5 5146 * 5147 * + XRCB[7] = Vclk = Mclk 5148 * 5149 * + XRCA[0:1] = 2 MSB of a 10 bit M-Divisor 5150 * 5151 * + XRCA[4:5] = 2 MSB of a 10 bit N-Divisor 5152 * 5153 * I haven't put in any support for those here. For simplicity, 5154 * they should be set to 0 on the 65548, and left untouched on 5155 * earlier chips. 5156 * 5157 * Other parameters available on the 690x0 5158 * 5159 * + The 690x0 has no reference clock divider, so PSN must 5160 * always be 1. 5161 * XRCB[0:1] are reserved according to the data book 5162 */ 5163 5164 5165 target = Clock * 1000; 5166 5167 /* @@@ >= CHIPS_CT690x0 ?? */ 5168 for (PSNx = ((cPtr->Chipset == CHIPS_CT69000) || 5169 (cPtr->Chipset == CHIPS_CT69030)) ? 1 : 0; PSNx <= 1; PSNx++) { 5170 int low_N, high_N; 5171 double Fref4PSN; 5172 5173 PSN = PSNx ? 1 : 4; 5174 5175 low_N = 3; 5176 high_N = 127; 5177 5178 while (Fref / (PSN * low_N) > (((cPtr->Chipset == CHIPS_CT69000) || 5179 (cPtr->Chipset == CHIPS_CT69030)) ? 5.0e6 : 2.0e6)) 5180 low_N++; 5181 while (Fref / (PSN * high_N) < 150.0e3) 5182 high_N--; 5183 5184 Fref4PSN = Fref * 4 / PSN; 5185 for (N = low_N; N <= high_N; N++) { 5186 double tmp = Fref4PSN / N; 5187 5188 /* @@@ < CHIPS_CT690x0 ?? */ 5189 for (P = (IS_HiQV(cPtr) && (cPtr->Chipset != CHIPS_CT69000) && 5190 (cPtr->Chipset != CHIPS_CT69030)) ? 1 : 0; 5191 P <= 5; P++) { 5192 /* to force post divisor on Toshiba 720CDT */ 5193 double Fvco_desired = target * (1 << P); 5194 double M_desired = Fvco_desired / tmp; 5195 5196 /* Which way will M_desired be rounded? Do all three just to 5197 * be safe. */ 5198 int M_low = M_desired - 1; 5199 int M_hi = M_desired + 1; 5200 5201 if (M_hi < M_min || M_low > M_max) 5202 continue; 5203 5204 if (M_low < M_min) 5205 M_low = M_min; 5206 if (M_hi > M_max) 5207 M_hi = M_max; 5208 5209 for (M = M_low; M <= M_hi; M++) { 5210 Fvco = tmp * M; 5211 /* @@@ >= CHIPS_CT690x0 ?? */ 5212 if (Fvco <= ((cPtr->Chipset == CHIPS_CT69000 || 5213 cPtr->Chipset == CHIPS_CT69030) ? 100.0e6 : 48.0e6)) 5214 continue; 5215 if (Fvco > 220.0e6) 5216 break; 5217 5218 Fout = Fvco / (1 << P); 5219 5220 error = (target - Fout) / target; 5221 5222 aerror = (error < 0) ? -error : error; 5223 if (aerror < abest) { 5224 abest = aerror; 5225 bestM = M; 5226 bestN = N; 5227 bestP = P; 5228 bestPSN = PSN; 5229#ifdef DEBUG 5230 bestFout = Fout; 5231#endif 5232 } 5233 } 5234 } 5235 } 5236 } 5237 /* @@@ >= CHIPS_CT690x0 ?? */ 5238 vclk[0] = (bestP << (IS_HiQV(cPtr) ? 4 : 1)) + 5239 (((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030)) 5240 ? 0 : (bestPSN == 1)); 5241 vclk[1] = bestM - 2; 5242 vclk[2] = bestN - 2; 5243#ifdef DEBUG 5244 ErrorF("Freq. selected: %.2f MHz, vclk[0]=%X, vclk[1]=%X, vclk[2]=%X\n", 5245 (float)(Clock / 1000.), vclk[0], vclk[1], vclk[2]); 5246 ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6); 5247#endif 5248} 5249 5250static void 5251chipsSave(ScrnInfoPtr pScrn, vgaRegPtr VgaSave, CHIPSRegPtr ChipsSave) 5252{ 5253 vgaHWPtr hwp = VGAHWPTR(pScrn); 5254 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5255 int i; 5256 unsigned char tmp; 5257#ifdef DEBUG 5258 ErrorF("chipsSave\n"); 5259#endif 5260 5261 /* set registers that we can program the controller */ 5262 /* bank 0 */ 5263 if (IS_HiQV(cPtr)) { 5264 cPtr->writeXR(cPtr, 0x0E, 0x00); 5265 } else { 5266 cPtr->writeXR(cPtr, 0x10, 0x00); 5267 cPtr->writeXR(cPtr, 0x11, 0x00); 5268 tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */ 5269 cPtr->writeXR(cPtr, 0x0C, tmp); 5270 } 5271 chipsFixResume(pScrn); 5272 tmp = cPtr->readXR(cPtr, 0x02); 5273 cPtr->writeXR(cPtr, 0x02, tmp & ~0x18); 5274 /* get generic registers */ 5275 vgaHWSave(pScrn, VgaSave, VGA_SR_ALL); 5276 5277 /* save clock */ 5278 chipsClockSave(pScrn, &ChipsSave->Clock); 5279 5280 /* save extended registers */ 5281 if (IS_HiQV(cPtr)) { 5282 for (i = 0; i < 0xFF; i++) { 5283#ifdef SAR04 5284 /* Save SAR04 multimedia register correctly */ 5285 if (i == 0x4F) 5286 cPtr->writeXR(cPtr, 0x4E, 0x04); 5287#endif 5288 ChipsSave->XR[i] = cPtr->readXR(cPtr,i); 5289#ifdef DEBUG 5290 ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]); 5291#endif 5292 } 5293 for (i = 0; i < 0x80; i++) { 5294 ChipsSave->FR[i] = cPtr->readFR(cPtr, i); 5295#ifdef DEBUG 5296 ErrorF("FS%X - %X\n", i, ChipsSave->FR[i]); 5297#endif 5298 } 5299 for (i = 0; i < 0x80; i++) { 5300 ChipsSave->MR[i] = cPtr->readMR(cPtr, i); 5301#ifdef DEBUG 5302 ErrorF("MS%X - %X\n", i, ChipsSave->FR[i]); 5303#endif 5304 } 5305 /* Save CR0-CR40 even though we don't use them, so they can be 5306 * printed */ 5307 for (i = 0x0; i < 0x80; i++) { 5308 ChipsSave->CR[i] = hwp->readCrtc(hwp, i); 5309#ifdef DEBUG 5310 ErrorF("CS%X - %X\n", i, ChipsSave->CR[i]); 5311#endif 5312 } 5313 } else { 5314 for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */ 5315 ChipsSave->XR[i] = cPtr->readXR(cPtr, i); 5316#ifdef DEBUG 5317 ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]); 5318#endif 5319 } 5320 } 5321} 5322 5323Bool 5324chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 5325{ 5326 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5327#ifdef DEBUG 5328 ErrorF("chipsModeInit\n"); 5329#endif 5330#if 0 5331 *(int*)0xFFFFFF0 = 0; 5332 ErrorF("done\n"); 5333#endif 5334 5335 chipsUnlock(pScrn); 5336 chipsFixResume(pScrn); 5337 5338 if (cPtr->Accel.UseHWCursor) 5339 cPtr->Flags |= ChipsHWCursor; 5340 else 5341 cPtr->Flags &= ~ChipsHWCursor; 5342 /* 5343 * We need to delay cursor loading after resetting the video mode 5344 * to give the engine a chance to recover. 5345 */ 5346 cPtr->cursorDelay = TRUE; 5347 5348 if (IS_HiQV(cPtr)) 5349 return chipsModeInitHiQV(pScrn, mode); 5350 else if (IS_Wingine(cPtr)) 5351 return chipsModeInitWingine(pScrn, mode); 5352 else 5353 return chipsModeInit655xx(pScrn, mode); 5354} 5355 5356/* 5357 * The timing register of the C&T FP chipsets are organized 5358 * as follows: 5359 * The chipsets have two sets of timing registers: 5360 * the standard horizontal and vertical timing registers for 5361 * display size, blank start, sync start, sync end, blank end 5362 * and total size at their default VGA locations and extensions 5363 * and the alternate horizontal and vertical timing registers for 5364 * display size, sync start, sync end and total size. 5365 * In LCD and mixed (LCD+CRT) mode the alternate timing registers 5366 * control the timing. The alternate horizontal and vertical display 5367 * size registers are set to the physical pixel size of the display. 5368 * Normally the alternalte registers are set by the BIOS to optimized 5369 * values. 5370 * While the horizontal an vertical refresh rates are fixed independent 5371 * of the visible display size to ensure optimal performace of both 5372 * displays they can be adapted to the screen resolution and CRT 5373 * requirements in CRT mode by programming the standard timing registers 5374 * in the VGA fashion. 5375 * In LCD and mixed mode the _standard_ horizontal and vertical display 5376 * size registers control the size of the _visible_ part of the display 5377 * in contast to the _physical_ size of the display which is specified 5378 * by the _alternate_ horizontal and vertical display size registers. 5379 * The size of the visible should always be equal or less than the 5380 * physical size. 5381 * For the 69030 chipsets, the CRT and LCD display channels are seperate 5382 * and so can be driven independently. 5383 */ 5384static Bool 5385chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode) 5386{ 5387 int i; 5388 int lcdHTotal, lcdHDisplay; 5389 int lcdVTotal, lcdVDisplay; 5390 int lcdHRetraceStart, lcdHRetraceEnd; 5391 int lcdVRetraceStart, lcdVRetraceEnd; 5392 int lcdHSyncStart; 5393 vgaHWPtr hwp = VGAHWPTR(pScrn); 5394 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5395 CHIPSRegPtr ChipsNew; 5396 vgaRegPtr ChipsStd; 5397 unsigned int tmp; 5398 5399 ChipsNew = &cPtr->ModeReg; 5400 ChipsStd = &hwp->ModeReg; 5401 5402 5403 /* 5404 * Possibly fix up the panel size, if the manufacture is stupid 5405 * enough to set it incorrectly in text modes 5406 */ 5407 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 5408 cPtr->PanelSize.HDisplay = mode->CrtcHDisplay; 5409 cPtr->PanelSize.VDisplay = mode->CrtcVDisplay; 5410 } 5411 5412 /* generic init */ 5413 if (!vgaHWInit(pScrn, mode)) { 5414 ErrorF("bomb 1\n"); 5415 return (FALSE); 5416 } 5417 pScrn->vtSema = TRUE; 5418 5419 /* init clock */ 5420 if (!chipsClockFind(pScrn, mode, mode->ClockIndex, &ChipsNew->Clock)) { 5421 ErrorF("bomb 2\n"); 5422 return (FALSE); 5423 } 5424 5425 /* Give Warning if the dual display mode will cause problems */ 5426 /* Note 64bit wide memory bus assumed (as in 69000 and 69030 */ 5427 if (cPtr->UseDualChannel && ((cPtr->SecondCrtc == TRUE) || 5428 (cPtr->Flags & ChipsDualRefresh))) { 5429 if (((ChipsNew->Clock.FPClock + ChipsNew->Clock.Clock) * 5430 (max(1, pScrn->bitsPerPixel >> 3) + 5431 ((cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) ? 5432 1 : 0)) / (8 * 0.7)) > cPtr->MemClock.Max) { 5433 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5434 "Memory bandwidth requirements exceeded by dual-channel\n"); 5435 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5436 " mode. Display might be corrupted!!!\n"); 5437 } 5438 } 5439 5440 /* get C&T Specific Registers */ 5441 for (i = 0; i < 0xFF; i++) { 5442#ifdef SAR04 5443 /* Save SAR04 multimedia register correctly */ 5444 if (i == 0x4F) 5445 cPtr->writeXR(cPtr, 0x4E, 0x04); 5446#endif 5447 ChipsNew->XR[i] = cPtr->readXR(cPtr, i); 5448 } 5449 for (i = 0; i < 0x80; i++) { 5450 ChipsNew->FR[i] = cPtr->readFR(cPtr, i); 5451 } 5452 for (i = 0; i < 0x80; i++) { 5453 ChipsNew->MR[i] = cPtr->readMR(cPtr, i); 5454 } 5455 for (i = 0x30; i < 0x80; i++) { /* These are the CT extended CRT regs */ 5456 ChipsNew->CR[i] = hwp->readCrtc(hwp, i); 5457 } 5458 5459 /* 5460 * Here all of the other fields of 'ChipsNew' get filled in, to 5461 * handle the SVGA extended registers. It is also allowable 5462 * to override generic registers whenever necessary. 5463 */ 5464 5465 /* some generic settings */ 5466 if (pScrn->depth == 1) { 5467 ChipsStd->Attribute[0x10] = 0x03; /* mode */ 5468 } else { 5469 ChipsStd->Attribute[0x10] = 0x01; /* mode */ 5470 } 5471 if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)) { 5472 /* Make sure that the overlay isn't visible in the overscan region */ 5473 if (ChipsStd->Attribute[0x11] == pScrn->colorKey) 5474 ChipsStd->Attribute[0x11] = pScrn->colorKey - 1; 5475 } else 5476 ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */ 5477 ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */ 5478 ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ 5479 5480 ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */ 5481 5482 /* set virtual screen width */ 5483 tmp = pScrn->displayWidth >> 3; 5484 if (pScrn->bitsPerPixel == 16) { 5485 if (!(cPtr->Flags & ChipsOverlay8plus16)) 5486 tmp <<= 1; /* double the width of the buffer */ 5487 } else if (pScrn->bitsPerPixel == 24) { 5488 tmp += tmp << 1; 5489 } else if (pScrn->bitsPerPixel == 32) { 5490 tmp <<= 2; 5491 } else if (pScrn->bitsPerPixel < 8) { 5492 tmp >>= 1; 5493 } 5494 ChipsStd->CRTC[0x13] = tmp & 0xFF; 5495 ChipsNew->CR[0x41] = (tmp >> 8) & 0x0F; 5496 5497 /* Set paging mode on the HiQV32 architecture, if required */ 5498 if (!(cPtr->Flags & ChipsLinearSupport) || (pScrn->bitsPerPixel < 8)) 5499 ChipsNew->XR[0x0A] |= 0x1; 5500 5501#if X_BYTE_ORDER == X_BIG_ENDIAN 5502 ChipsNew->XR[0x0A] &= 0xCF; 5503 if (pScrn->bitsPerPixel == 16) { 5504 if (!cPtr->dualEndianAp) 5505 ChipsNew->XR[0x0A] |= 0x10; 5506 } 5507#endif 5508 ChipsNew->XR[0x09] |= 0x1; /* Enable extended CRT registers */ 5509 ChipsNew->XR[0x0E] = 0; /* Single map */ 5510 ChipsNew->XR[0x40] |= 0x2; /* Don't wrap at 256kb */ 5511 ChipsNew->XR[0x81] &= 0xF8; 5512 if (pScrn->bitsPerPixel >= 8) { 5513 ChipsNew->XR[0x40] |= 0x1; /* High Resolution. XR40[1] reserved? */ 5514 ChipsNew->XR[0x81] |= 0x2; /* 256 Color Video */ 5515 } 5516 ChipsNew->XR[0x80] |= 0x10; /* Enable cursor output on P0 and P1 */ 5517 if (pScrn->depth > 1) { 5518 if (pScrn->rgbBits == 8) 5519 ChipsNew->XR[0x80] |= 0x80; 5520 else 5521 ChipsNew->XR[0x80] &= ~0x80; 5522 } 5523 5524 if (abs(cPtr->MemClock.Clk - cPtr->MemClock.ProbedClk) > 50) { 5525 /* set mem clk */ 5526 ChipsNew->XR[0xCC] = cPtr->MemClock.xrCC; 5527 ChipsNew->XR[0xCD] = cPtr->MemClock.xrCD; 5528 ChipsNew->XR[0xCE] = cPtr->MemClock.xrCE; 5529 } 5530 5531 /* Set the 69030 dual channel settings */ 5532 if (cPtr->Flags & ChipsDualChannelSupport) { 5533 ChipsNew->FR[0x01] &= 0xFC; 5534 if ((cPtr->SecondCrtc == FALSE) && (cPtr->PanelType & ChipsLCD)) 5535 ChipsNew->FR[0x01] |= 0x02; 5536 else 5537 ChipsNew->FR[0x01] |= 0x01; 5538 ChipsNew->FR[0x02] &= 0xCC; 5539 if ((cPtr->SecondCrtc == TRUE) || (cPtr->Flags & ChipsDualRefresh)) 5540 ChipsNew->FR[0x02] |= 0x01; /* Set DAC to pipe B */ 5541 else 5542 ChipsNew->FR[0x02] &= 0xFE; /* Set DAC to pipe A */ 5543 5544 if (cPtr->PanelType & ChipsLCD) 5545 ChipsNew->FR[0x02] |= 0x20; /* Enable the LCD output */ 5546 if (cPtr->PanelType & ChipsCRT) 5547 ChipsNew->FR[0x02] |= 0x10; /* Enable the CRT output */ 5548 } 5549 5550 /* linear specific */ 5551 if (cPtr->Flags & ChipsLinearSupport) { 5552 ChipsNew->XR[0x0A] |= 0x02; /* Linear Addressing Mode */ 5553 ChipsNew->XR[0x20] = 0x0; /*BitBLT Draw Mode for 8 */ 5554 ChipsNew->XR[0x05] = 5555 (unsigned char)((cPtr->FbAddress >> 16) & 0xFF); 5556 ChipsNew->XR[0x06] = 5557 (unsigned char)((cPtr->FbAddress >> 24) & 0xFF); 5558 } 5559 5560 /* panel timing */ 5561 /* By default don't set panel timings, but allow it as an option */ 5562 if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 5563 lcdHTotal = (mode->CrtcHTotal >> 3) - 5; 5564 lcdHDisplay = (cPtr->PanelSize.HDisplay >> 3) - 1; 5565 lcdHRetraceStart = (mode->CrtcHSyncStart >> 3); 5566 lcdHRetraceEnd = (mode->CrtcHSyncEnd >> 3); 5567 lcdHSyncStart = lcdHRetraceStart - 2; 5568 5569 lcdVTotal = mode->CrtcVTotal - 2; 5570 lcdVDisplay = cPtr->PanelSize.VDisplay - 1; 5571 lcdVRetraceStart = mode->CrtcVSyncStart; 5572 lcdVRetraceEnd = mode->CrtcVSyncEnd; 5573 5574 ChipsNew->FR[0x20] = lcdHDisplay & 0xFF; 5575 ChipsNew->FR[0x21] = lcdHRetraceStart & 0xFF; 5576 ChipsNew->FR[0x25] = ((lcdHRetraceStart & 0xF00) >> 4) | 5577 ((lcdHDisplay & 0xF00) >> 8); 5578 ChipsNew->FR[0x22] = lcdHRetraceEnd & 0x1F; 5579 ChipsNew->FR[0x23] = lcdHTotal & 0xFF; 5580 ChipsNew->FR[0x24] = (lcdHSyncStart >> 3) & 0xFF; 5581 ChipsNew->FR[0x26] = (ChipsNew->FR[0x26] & ~0x1F) 5582 | ((lcdHTotal & 0xF00) >> 8) 5583 | (((lcdHSyncStart >> 3) & 0x100) >> 4); 5584 ChipsNew->FR[0x27] &= 0x7F; 5585 5586 ChipsNew->FR[0x30] = lcdVDisplay & 0xFF; 5587 ChipsNew->FR[0x31] = lcdVRetraceStart & 0xFF; 5588 ChipsNew->FR[0x35] = ((lcdVRetraceStart & 0xF00) >> 4) 5589 | ((lcdVDisplay & 0xF00) >> 8); 5590 ChipsNew->FR[0x32] = lcdVRetraceEnd & 0x0F; 5591 ChipsNew->FR[0x33] = lcdVTotal & 0xFF; 5592 ChipsNew->FR[0x34] = (lcdVTotal - lcdVRetraceStart) & 0xFF; 5593 ChipsNew->FR[0x36] = ((lcdVTotal & 0xF00) >> 8) | 5594 (((lcdVTotal - lcdVRetraceStart) & 0x700) >> 4); 5595 ChipsNew->FR[0x37] |= 0x80; 5596 } 5597 5598 /* Set up the extended CRT registers of the HiQV32 chips */ 5599 ChipsNew->CR[0x30] = ((mode->CrtcVTotal - 2) & 0xF00) >> 8; 5600 ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8; 5601 ChipsNew->CR[0x32] = (mode->CrtcVSyncStart & 0xF00) >> 8; 5602 ChipsNew->CR[0x33] = (mode->CrtcVBlankStart & 0xF00) >> 8; 5603 if ((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030)) { 5604 /* The 690xx has overflow bits for the horizontal values as well */ 5605 ChipsNew->CR[0x38] = (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8; 5606 ChipsNew->CR[0x3C] = vgaHWHBlankKGA(mode, ChipsStd, 8, 0) << 6; 5607 } else 5608 vgaHWHBlankKGA(mode, ChipsStd, 6, 0); 5609 vgaHWVBlankKGA(mode, ChipsStd, 8, 0); 5610 5611 ChipsNew->CR[0x40] |= 0x80; 5612 5613 /* centering/stretching */ 5614 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) { 5615 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, FALSE) || 5616 (cPtr->Flags & ChipsOverlay8plus16)) { 5617 ChipsNew->FR[0x40] &= 0xDF; /* Disable Horizontal stretching */ 5618 ChipsNew->FR[0x48] &= 0xFB; /* Disable vertical stretching */ 5619 ChipsNew->XR[0xA0] = 0x10; /* Disable cursor stretching */ 5620 } else { 5621 ChipsNew->FR[0x40] |= 0x21; /* Enable Horizontal stretching */ 5622 ChipsNew->FR[0x48] |= 0x05; /* Enable vertical stretching */ 5623 ChipsNew->XR[0xA0] = 0x70; /* Enable cursor stretching */ 5624 if (cPtr->Accel.UseHWCursor 5625 && cPtr->PanelSize.HDisplay && cPtr->PanelSize.VDisplay 5626 && (cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) 5627 && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) { 5628 if(cPtr->Accel.UseHWCursor) 5629 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5630 "Disabling HW Cursor on stretched LCD\n"); 5631 cPtr->Flags &= ~ChipsHWCursor; 5632 } 5633 } 5634 } 5635 5636 if ((xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_CENTER, TRUE)) 5637 || (cPtr->Flags & ChipsOverlay8plus16)) { 5638 ChipsNew->FR[0x40] |= 0x3; /* Enable Horizontal centering */ 5639 ChipsNew->FR[0x48] |= 0x3; /* Enable Vertical centering */ 5640 } else { 5641 ChipsNew->FR[0x40] &= 0xFD; /* Disable Horizontal centering */ 5642 ChipsNew->FR[0x48] &= 0xFD; /* Disable Vertical centering */ 5643 } 5644 5645 /* sync on green */ 5646 if (xf86ReturnOptValBool(cPtr->Options, OPTION_SYNC_ON_GREEN, FALSE)) 5647 ChipsNew->XR[0x82] |=0x02; 5648 5649 /* software mode flag */ 5650 ChipsNew->XR[0xE2] = chipsVideoMode(((cPtr->Flags & ChipsOverlay8plus16) ? 5651 8 : pScrn->depth), (cPtr->PanelType & ChipsLCD) ? 5652 min(mode->CrtcHDisplay, cPtr->PanelSize.HDisplay) : 5653 mode->CrtcHDisplay, mode->CrtcVDisplay); 5654#ifdef DEBUG 5655 ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0xE2]); 5656#endif 5657 5658 /* sync. polarities */ 5659 if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 5660 && (mode->Flags & (V_PVSYNC | V_NVSYNC))) { 5661 if (mode->Flags & (V_PHSYNC | V_NHSYNC)) { 5662 if (mode->Flags & V_PHSYNC) 5663 ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */ 5664 else 5665 ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */ 5666 } 5667 if (mode->Flags & (V_PVSYNC | V_NVSYNC)) { 5668 if (mode->Flags & V_PVSYNC) 5669 ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */ 5670 else 5671 ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */ 5672 } 5673 } 5674 if (mode->Flags & (V_PCSYNC | V_NCSYNC)) { 5675 ChipsNew->FR[0x0B] |= 0x20; 5676 if (mode->Flags & V_PCSYNC) { 5677 ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */ 5678 ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */ 5679 ChipsStd->MiscOutReg &= 0x7F; 5680 ChipsStd->MiscOutReg &= 0xBF; 5681 } else { 5682 ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */ 5683 ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */ 5684 ChipsStd->MiscOutReg |= 0x40; 5685 ChipsStd->MiscOutReg |= 0x80; 5686 } 5687 } 5688 /* bpp depend */ 5689 if ((pScrn->bitsPerPixel == 16) && (!(cPtr->Flags & ChipsOverlay8plus16))) { 5690 ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x4; 5691 if (cPtr->Flags & ChipsGammaSupport) 5692 ChipsNew->XR[0x82] |= 0x0C; 5693 /* 16bpp = 5-5-5 */ 5694 ChipsNew->FR[0x10] |= 0x0C; /*Colour Panel */ 5695 ChipsNew->XR[0x20] = 0x10; /*BitBLT Draw Mode for 16 bpp */ 5696 if (pScrn->weight.green != 5) 5697 ChipsNew->XR[0x81] |= 0x01; /*16bpp */ 5698 } else if (pScrn->bitsPerPixel == 24) { 5699 ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x6; 5700 if (cPtr->Flags & ChipsGammaSupport) 5701 ChipsNew->XR[0x82] |= 0x0C; 5702 /* 24bpp colour */ 5703 ChipsNew->XR[0x20] = 0x20; /*BitBLT Draw Mode for 24 bpp */ 5704 } else if (pScrn->bitsPerPixel == 32) { 5705 ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x7; 5706 if (cPtr->Flags & ChipsGammaSupport) 5707 ChipsNew->XR[0x82] |= 0x0C; 5708 /* 32bpp colour */ 5709 ChipsNew->XR[0x20] = 0x10; /*BitBLT Mode for 16bpp used at 32bpp */ 5710 } 5711 5712 /*CRT only */ 5713 if (!(cPtr->PanelType & ChipsLCD)) { 5714 if (mode->Flags & V_INTERLACE) { 5715 ChipsNew->CR[0x70] = 0x80 /* set interlace */ 5716 | (((((mode->CrtcHDisplay >> 3) - 1) >> 1) - 6) & 0x7F); 5717 /* 5718 ** Double VDisplay to get back the full screen value, otherwise 5719 ** you only see half the picture. 5720 */ 5721 mode->CrtcVDisplay = mode->VDisplay; 5722 tmp = ChipsStd->CRTC[7] & ~0x42; 5723 ChipsStd->CRTC[7] = (tmp | 5724 ((((mode->CrtcVDisplay -1) & 0x100) >> 7 ) | 5725 (((mode->CrtcVDisplay -1) & 0x200) >> 3 ))); 5726 ChipsStd->CRTC[0x12] = (mode->CrtcVDisplay -1) & 0xFF; 5727 ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8; 5728 } else { 5729 ChipsNew->CR[0x70] &= ~0x80; /* unset interlace */ 5730 } 5731 } 5732 5733#if defined(__arm__) && defined(___NetBSD__) 5734 if (cPtr->TVMode != XMODE_RGB) { 5735 /* 5736 * Put the console into TV Out mode. 5737 */ 5738 xf86SetTVOut(cPtr->TVMode); 5739 5740 ChipsNew->CR[0x72] = (mode->CrtcHTotal >> 1) >> 3;/* First horizontal 5741 * serration pulse */ 5742 ChipsNew->CR[0x73] = mode->CrtcHTotal >> 3; /* Second pulse */ 5743 ChipsNew->CR[0x74] = (((mode->HSyncEnd - mode->HSyncStart) >> 3) - 1) 5744 & 0x1F; /* equalization pulse */ 5745 5746 if (cPtr->TVMode == XMODE_PAL || cPtr->TVMode == XMODE_SECAM) { 5747 ChipsNew->CR[0x71] = 0xA0; /* PAL support with blanking delay */ 5748 } else { 5749 ChipsNew->CR[0x71] = 0x20; /* NTSC support with blanking delay */ 5750 } 5751 } else { /* XMODE_RGB */ 5752 /* 5753 * Put the console into RGB Out mode. 5754 */ 5755 xf86SetRGBOut(); 5756 } 5757#endif 5758 5759 /* STN specific */ 5760 if (IS_STN(cPtr->PanelType)) { 5761 ChipsNew->FR[0x11] &= ~0x03; /* FRC clear */ 5762 ChipsNew->FR[0x11] &= ~0x8C; /* Dither clear */ 5763 ChipsNew->FR[0x11] |= 0x01; /* 16 frame FRC */ 5764 ChipsNew->FR[0x11] |= 0x84; /* Dither */ 5765 if ((cPtr->Flags & ChipsTMEDSupport) && 5766 !xf86ReturnOptValBool(cPtr->Options, OPTION_NO_TMED, FALSE)) { 5767 ChipsNew->FR[0x73] &= 0x4F; /* Clear TMED */ 5768 ChipsNew->FR[0x73] |= 0x80; /* Enable TMED */ 5769 ChipsNew->FR[0x73] |= 0x30; /* TMED 256 Shades of RGB */ 5770 } 5771 if (cPtr->PanelType & ChipsDD) /* Shift Clock Mask. Use to get */ 5772 ChipsNew->FR[0x12] |= 0x4; /* rid of line in DSTN screens */ 5773 } 5774 5775 /* 5776 * The zero position of the overlay does not align with the zero 5777 * position of the display. The skew is dependent on the depth, 5778 * display type and refresh rate. Calculate the skew before setting 5779 * the X and Y dimensions of the overlay. These values are needed 5780 * both by the overlay and XvImages. So calculate and store them 5781 */ 5782 if (cPtr->PanelType & ChipsLCD) { 5783 cPtr->OverlaySkewX = (((ChipsNew->FR[0x23] & 0xFF) 5784 - (ChipsNew->FR[0x20] & 0xFF) + 3) << 3) 5785 - 1; 5786 cPtr->OverlaySkewY = (ChipsNew->FR[0x33] 5787 + ((ChipsNew->FR[0x36] & 0xF) << 8) 5788 - (ChipsNew->FR[0x31] & 0xF0) 5789 - (ChipsNew->FR[0x32] & 0x0F) 5790 - ((ChipsNew->FR[0x35] & 0xF0) << 4)); 5791 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, FALSE) 5792 && xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_CENTER, TRUE)) 5793 { 5794 if (cPtr->PanelSize.HDisplay > mode->CrtcHDisplay) 5795 cPtr->OverlaySkewX += (cPtr->PanelSize.HDisplay - 5796 mode->CrtcHDisplay) / 2; 5797 if (cPtr->PanelSize.VDisplay > mode->CrtcVDisplay) 5798 cPtr->OverlaySkewY += (cPtr->PanelSize.VDisplay - 5799 mode->CrtcVDisplay) / 2; 5800 } 5801 } else { 5802 cPtr->OverlaySkewX = mode->CrtcHTotal - mode->CrtcHBlankStart - 9; 5803 cPtr->OverlaySkewY = mode->CrtcVTotal - mode->CrtcVSyncEnd - 1; 5804 5805 if (mode->Flags & V_INTERLACE) { 5806 /* 5807 * This handles 1024 and 1280 interlaced modes only. Its 5808 * pretty arbitrary, but its what C&T recommends 5809 */ 5810#if 0 5811 if (mode->CrtcHDisplay == 1024) 5812 cPtr->OverlaySkewY += 5; 5813 else if (mode->CrtcHDisplay == 1280) 5814#endif 5815 cPtr->OverlaySkewY *= 2; 5816 5817 } 5818 } 5819 5820 /* mask for viewport granularity */ 5821 5822 switch (pScrn->bitsPerPixel) { 5823 case 8: 5824 cPtr->viewportMask = ~7U; 5825 break; 5826 case 16: 5827 cPtr->viewportMask = ~3U; 5828 break; 5829 case 24: 5830 cPtr->viewportMask = ~7U; 5831 break; 5832 case 32: 5833 cPtr->viewportMask = ~0U; 5834 break; 5835 default: 5836 cPtr->viewportMask = ~7U; 5837 } 5838 5839 /* Turn off multimedia by default as it degrades performance */ 5840 ChipsNew->XR[0xD0] &= 0x0f; 5841 5842 /* Setup the video/overlay */ 5843 if (cPtr->Flags & ChipsOverlay8plus16) { 5844 ChipsNew->XR[0xD0] |= 0x10; /* Force the Multimedia engine on */ 5845#ifdef SAR04 5846 ChipsNew->XR[0x4F] = 0x2A; /* SAR04 >352 pixel overlay width */ 5847#endif 5848 ChipsNew->MR[0x1E] &= 0xE0; /* Set Zoom and Direction */ 5849 if ((!(cPtr->PanelType & ChipsLCD)) && (mode->Flags & V_INTERLACE)) 5850 ChipsNew->MR[0x1E] |= 0x10; /* Interlace */ 5851 ChipsNew->MR[0x1F] &= 0x14; /* Mask reserved bits */ 5852 ChipsNew->MR[0x1F] |= 0x08; /* RGB 16bpp */ 5853 if (pScrn->weight.green == 5) 5854 ChipsNew->MR[0x1F] |= 0x01; /* RGB 15bpp */ 5855 5856 ChipsNew->MR[0x20] &= 0x03; /* Mask reserved bits */ 5857 ChipsNew->MR[0x20] |= 0x80; /* Auto Centre, Use mem ptr1 */ 5858 ChipsNew->MR[0x22] = cPtr->FbOffset16 & 0xF8; /* Setup Pointer 1 */ 5859 ChipsNew->MR[0x23] = (cPtr->FbOffset16 >> 8) & 0xFF; 5860 ChipsNew->MR[0x24] = (cPtr->FbOffset16 >> 16) & 0xFF; 5861 ChipsNew->MR[0x25] = cPtr->FbOffset16 & 0xF8; /* Setup Pointer 2 */ 5862 ChipsNew->MR[0x26] = (cPtr->FbOffset16 >> 8) & 0xFF; 5863 ChipsNew->MR[0x27] = (cPtr->FbOffset16 >> 16) & 0xFF; 5864 ChipsNew->MR[0x28] = (pScrn->displayWidth >> 2) - 1; /* Width */ 5865 ChipsNew->MR[0x34] = (pScrn->displayWidth >> 2) - 1; 5866 5867 /* Left Edge of Overlay */ 5868 ChipsNew->MR[0x2A] = cPtr->OverlaySkewX; 5869 ChipsNew->MR[0x2B] &= 0xF8; /* Mask reserved bits */ 5870 ChipsNew->MR[0x2B] |= ((cPtr->OverlaySkewX >> 8) & 0x7); 5871 /* Right Edge of Overlay */ 5872 ChipsNew->MR[0x2C] = (cPtr->OverlaySkewX + pScrn->displayWidth - 5873 1) & 0xFF; 5874 ChipsNew->MR[0x2D] &= 0xF8; /* Mask reserved bits */ 5875 ChipsNew->MR[0x2D] |= ((cPtr->OverlaySkewX + pScrn->displayWidth - 5876 1) >> 8) & 0x07; 5877 /* Top Edge of Overlay */ 5878 ChipsNew->MR[0x2E] = cPtr->OverlaySkewY; 5879 ChipsNew->MR[0x2F] &= 0xF8; 5880 ChipsNew->MR[0x2F] |= ((cPtr->OverlaySkewY >> 8) & 0x7); 5881 /* Bottom Edge of Overlay*/ 5882 ChipsNew->MR[0x30] = (cPtr->OverlaySkewY + pScrn->virtualY - 1 )& 0xFF; 5883 ChipsNew->MR[0x31] &= 0xF8; /* Mask reserved bits */ 5884 ChipsNew->MR[0x31] |= ((cPtr->OverlaySkewY + pScrn->virtualY - 5885 1 ) >> 8) & 0x07; 5886 5887 ChipsNew->MR[0x3C] &= 0x18; /* Mask reserved bits */ 5888 ChipsNew->MR[0x3C] |= 0x07; /* Enable keyed overlay window */ 5889 ChipsNew->MR[0x3D] = 0x00; 5890 ChipsNew->MR[0x3E] = 0x00; 5891 ChipsNew->MR[0x3F] = pScrn->colorKey; /* 8bpp transparency key */ 5892 ChipsNew->MR[0x40] = 0xFF; 5893 ChipsNew->MR[0x41] = 0xFF; 5894 ChipsNew->MR[0x42] = 0x00; 5895 } else if (cPtr->Flags & ChipsVideoSupport) { 5896#if 0 /* if we do this even though video isn't playing we kill performance */ 5897 ChipsNew->XR[0xD0] |= 0x10; /* Force the Multimedia engine on */ 5898#endif 5899#ifdef SAR04 5900 ChipsNew->XR[0x4F] = 0x2A; /* SAR04 >352 pixel overlay width */ 5901#endif 5902 ChipsNew->MR[0x3C] &= 0x18; /* Ensure that the overlay is off */ 5903 cPtr->VideoZoomMax = 0x100; 5904 5905 if (cPtr->Chipset == CHIPS_CT65550) { 5906 tmp = cPtr->readXR(cPtr, 0x04); 5907 if (tmp < 0x02) /* 65550 ES0 has */ 5908 cPtr->VideoZoomMax = 0x40; /* 0x40 max zoom */ 5909 } 5910 } 5911 5912 /* Program the registers */ 5913 /*vgaHWProtect(pScrn, TRUE);*/ 5914 5915 if (cPtr->Chipset <= CHIPS_CT69000) { 5916 ChipsNew->FR[0x01] &= ~0x03; 5917 if (cPtr->PanelType & ChipsLCD) 5918 ChipsNew->FR[0x01] |= 0x02; 5919 else 5920 ChipsNew->FR[0x01] |= 0x01; 5921 } 5922 if ((cPtr->Flags & ChipsDualChannelSupport) && 5923 (!xf86IsEntityShared(pScrn->entityList[0]))) { 5924 unsigned char IOSS, MSS, tmpfr01; 5925 5926 5927 IOSS = cPtr->readIOSS(cPtr); 5928 MSS = cPtr->readMSS(cPtr); 5929 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 5930 IOSS_PIPE_A)); 5931 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | 5932 MSS_PIPE_A)); 5933 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 5934 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 5935 IOSS_PIPE_B)); 5936 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | 5937 MSS_PIPE_B)); 5938 /* 5939 * Hack:: Force Pipe-B on for dual refresh, and off elsewise 5940 */ 5941 tmpfr01 = ChipsNew->FR[0x01]; 5942 ChipsNew->FR[0x01] &= 0xFC; 5943 if (cPtr->UseDualChannel) 5944 ChipsNew->FR[0x01] |= 0x01; 5945 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 5946 ChipsNew->FR[0x01] = tmpfr01; 5947 cPtr->writeIOSS(cPtr, IOSS); 5948 cPtr->writeMSS(cPtr, hwp, MSS); 5949 } else { 5950 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 5951 } 5952 5953 /*vgaHWProtect(pScrn, FALSE);*/ 5954 usleep(100000); /* prevents cursor corruption seen on a TECRA 510 */ 5955 5956 return(TRUE); 5957} 5958 5959static Bool 5960chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode) 5961{ 5962 int i, bytesPerPixel; 5963 vgaHWPtr hwp = VGAHWPTR(pScrn); 5964 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5965 CHIPSRegPtr ChipsNew; 5966 vgaRegPtr ChipsStd; 5967 unsigned int tmp; 5968 5969 ChipsNew = &cPtr->ModeReg; 5970 ChipsStd = &hwp->ModeReg; 5971 5972 bytesPerPixel = pScrn->bitsPerPixel >> 3; 5973 5974 /* 5975 * This chipset seems to have problems if 5976 * HBlankEnd is choosen equals HTotal 5977 */ 5978 if (!mode->CrtcHAdjusted) 5979 mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2); 5980 5981 /* correct the timings for 16/24 bpp */ 5982 if (pScrn->bitsPerPixel == 16) { 5983 if (!mode->CrtcHAdjusted) { 5984 mode->CrtcHDisplay++; 5985 mode->CrtcHDisplay <<= 1; 5986 mode->CrtcHDisplay--; 5987 mode->CrtcHSyncStart <<= 1; 5988 mode->CrtcHSyncEnd <<= 1; 5989 mode->CrtcHBlankStart <<= 1; 5990 mode->CrtcHBlankEnd <<= 1; 5991 mode->CrtcHTotal <<= 1; 5992 mode->CrtcHAdjusted = TRUE; 5993 } 5994 } else if (pScrn->bitsPerPixel == 24) { 5995 if (!mode->CrtcHAdjusted) { 5996 mode->CrtcHDisplay++; 5997 mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1); 5998 mode->CrtcHDisplay--; 5999 mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1); 6000 mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1); 6001 mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1); 6002 mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1); 6003 mode->CrtcHTotal += ((mode->CrtcHTotal) << 1); 6004 mode->CrtcHAdjusted = TRUE; 6005 } 6006 } 6007 6008 /* generic init */ 6009 if (!vgaHWInit(pScrn, mode)) { 6010 ErrorF("bomb 3\n"); 6011 return (FALSE); 6012 } 6013 pScrn->vtSema = TRUE; 6014 6015 /* init clock */ 6016 if (!chipsClockFind(pScrn, mode, mode->ClockIndex, &ChipsNew->Clock)) { 6017 ErrorF("bomb 4\n"); 6018 return (FALSE); 6019 } 6020 6021 /* get C&T Specific Registers */ 6022 for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */ 6023 ChipsNew->XR[i] = cPtr->readXR(cPtr, i); 6024 } 6025 6026 /* some generic settings */ 6027 if (pScrn->bitsPerPixel == 1) { 6028 ChipsStd->Attribute[0x10] = 0x03; /* mode */ 6029 } else { 6030 ChipsStd->Attribute[0x10] = 0x01; /* mode */ 6031 } 6032 ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */ 6033 ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */ 6034 ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ 6035 6036 ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */ 6037 6038 6039 /* set virtual screen width */ 6040 if (pScrn->bitsPerPixel >= 8) 6041 ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3; 6042 else 6043 ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4; 6044 6045 6046 /* set C&T Specific Registers */ 6047 /* set virtual screen width */ 6048 if (pScrn->bitsPerPixel >= 8) 6049 tmp = (pScrn->displayWidth >> 4) * bytesPerPixel; 6050 else 6051 tmp = (pScrn->displayWidth >> 5); 6052 ChipsNew->XR[0x0D] = (tmp & 0x80) >> 5; 6053 6054 ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */ 6055 /* XR04: Memory control 1 */ 6056 /* bit 2: Memory Wraparound */ 6057 /* Enable CRTC addr counter bits 16-17 if set */ 6058 6059 ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */ 6060 ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */ 6061 /* XR0B: CPU paging */ 6062 /* bit 0: Memory mapping mode */ 6063 /* VGA compatible if 0 (default) */ 6064 /* Extended mode (mapping for > 256 kB mem) if 1 */ 6065 /* bit 1: CPU single/dual mapping */ 6066 /* 0, CPU uses only a single map to access (default) */ 6067 /* 1, CPU uses two maps to access */ 6068 /* bit 2: CPU address divide by 4 */ 6069 6070 ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */ 6071 ChipsNew->XR[0x11] = 0; /* XR11: High map */ 6072 ChipsNew->XR[0x0C] &= ~0x50; /* MSB for XR10 & XR11 */ 6073 if (pScrn->bitsPerPixel >= 8) { 6074 ChipsNew->XR[0x28] |= 0x10; /* 256-color video */ 6075 } else { 6076 ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */ 6077 } 6078 /* set up extended display timings */ 6079 /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */ 6080 ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) 6081 | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) 6082 | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) 6083 | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2) 6084 | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4) 6085 | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1); 6086 6087 6088 ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 ) 6089 | (((mode->CrtcVDisplay -1) & 0x400) >> 9 ) 6090 | ((mode->CrtcVSyncStart & 0x400) >> 8 ) 6091 | (((mode->CrtcVBlankStart) & 0x400) >> 6 ); 6092 6093 /* set video mode */ 6094 ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->depth, mode->CrtcHDisplay, mode->CrtcVDisplay); 6095#ifdef DEBUG 6096 ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]); 6097#endif 6098 6099 /* set some linear specific registers */ 6100 if (cPtr->Flags & ChipsLinearSupport) { 6101 /* enable linear addressing */ 6102 ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */ 6103 ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */ 6104 6105 ChipsNew->XR[0x08] = 6106 (unsigned char)((cPtr->FbAddress >> 16) & 0xFF); 6107 ChipsNew->XR[0x09] = 6108 (unsigned char)((cPtr->FbAddress >> 24) & 0xFF); 6109 6110 /* general setup */ 6111 ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */ 6112 } 6113 6114 /* common general setup */ 6115 ChipsNew->XR[0x52] |= 0x01; /* Refresh count */ 6116 ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */ 6117 ChipsNew->XR[0x02] &= 0xE7; /* Attr. Cont. default access */ 6118 /* use ext. regs. for hor. in dual */ 6119 ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */ 6120 6121 /* bpp depend */ 6122 /*XR06: Palette control */ 6123 /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */ 6124 /* bit 1: Internal DAC disable */ 6125 /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */ 6126 /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */ 6127 /* bit 4: Enable PC Video Overlay on colour key */ 6128 /* bit 5: Bypass Internal VGA palette */ 6129 /* bit 7-6: Colour reduction select, 0 for NTSC (default), */ 6130 /* 1 for Equivalent weighting, 2 for green only, */ 6131 /* 3 for Colour w/o reduction */ 6132 /* XR50 Panel Format Register 1 */ 6133 /* bit 1-0: Frame Rate Control; 00, No FRC; */ 6134 /* 01, 16-frame FRC for colour STN and monochrome */ 6135 /* 10, 2-frame FRC for colour TFT or monochrome; */ 6136 /* 11, reserved */ 6137 /* bit 3-2: Dither Enable */ 6138 /* 00, disable dithering; 01, enable dithering */ 6139 /* for 256 mode */ 6140 /* 10, enable dithering for all modes; 11, reserved */ 6141 /* bit6-4: Clock Divide (CD) */ 6142 /* 000, Shift Clock Freq = Dot Clock Freq; */ 6143 /* 001, SClk = DClk/2; 010 SClk = DClk/4; */ 6144 /* 011, SClk = DClk/8; 100 SClk = DClk/16; */ 6145 /* bit 7: TFT data width */ 6146 /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */ 6147 if (pScrn->bitsPerPixel == 16) { 6148 ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */ 6149 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6150 ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */ 6151 if (pScrn->weight.green != 5) 6152 ChipsNew->XR[0x06] |= 0x08; /*16bpp */ 6153 } else if (pScrn->bitsPerPixel == 24) { 6154 ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */ 6155 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6156 } 6157 6158 /*CRT only: interlaced mode */ 6159 if (mode->Flags & V_INTERLACE) { 6160 ChipsNew->XR[0x28] |= 0x20; /* set interlace */ 6161 /* empirical value */ 6162 tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1) 6163 - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 )); 6164 ChipsNew->XR[0x19] = tmp & 0xFF; 6165 ChipsNew->XR[0x17] |= ((tmp & 0x100) >> 1); /* overflow */ 6166 ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */ 6167 } else { 6168 ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */ 6169 ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */ 6170 } 6171 6172 /* Program the registers */ 6173 /*vgaHWProtect(pScrn, TRUE);*/ 6174 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 6175 /*vgaHWProtect(pScrn, FALSE);*/ 6176 6177 return (TRUE); 6178} 6179 6180static Bool 6181chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode) 6182{ 6183 int i, bytesPerPixel; 6184 int lcdHTotal, lcdHDisplay; 6185 int lcdVTotal, lcdVDisplay; 6186 int lcdHRetraceStart, lcdHRetraceEnd; 6187 int lcdVRetraceStart, lcdVRetraceEnd; 6188 int HSyncStart, HDisplay; 6189 int CrtcHDisplay; 6190 vgaHWPtr hwp = VGAHWPTR(pScrn); 6191 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6192 CHIPSRegPtr ChipsNew; 6193 vgaRegPtr ChipsStd; 6194 unsigned int tmp; 6195 6196 ChipsNew = &cPtr->ModeReg; 6197 ChipsStd = &hwp->ModeReg; 6198 6199 bytesPerPixel = pScrn->bitsPerPixel >> 3; 6200 6201 /* 6202 * Possibly fix up the panel size, if the manufacture is stupid 6203 * enough to set it incorrectly in text modes 6204 */ 6205 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 6206 cPtr->PanelSize.HDisplay = mode->CrtcHDisplay; 6207 cPtr->PanelSize.VDisplay = mode->CrtcVDisplay; 6208 } 6209 6210 /* 6211 * This chipset seems to have problems if 6212 * HBlankEnd is choosen equals HTotal 6213 */ 6214 if (!mode->CrtcHAdjusted) 6215 mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2); 6216 6217 /* correct the timings for 16/24 bpp */ 6218 if (pScrn->bitsPerPixel == 16) { 6219 if (!mode->CrtcHAdjusted) { 6220 mode->CrtcHDisplay++; 6221 mode->CrtcHDisplay <<= 1; 6222 mode->CrtcHDisplay--; 6223 mode->CrtcHSyncStart <<= 1; 6224 mode->CrtcHSyncEnd <<= 1; 6225 mode->CrtcHBlankStart <<= 1; 6226 mode->CrtcHBlankEnd <<= 1; 6227 mode->CrtcHTotal <<= 1; 6228 mode->CrtcHAdjusted = TRUE; 6229 } 6230 } else if (pScrn->bitsPerPixel == 24) { 6231 if (!mode->CrtcHAdjusted) { 6232 mode->CrtcHDisplay++; 6233 mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1); 6234 mode->CrtcHDisplay--; 6235 mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1); 6236 mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1); 6237 mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1); 6238 mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1); 6239 mode->CrtcHTotal += ((mode->CrtcHTotal) << 1); 6240 mode->CrtcHAdjusted = TRUE; 6241 } 6242 } 6243 6244 /* store orig. HSyncStart needed for flat panel mode */ 6245 HSyncStart = mode->CrtcHSyncStart / (pScrn->bitsPerPixel >= 8 ? 6246 bytesPerPixel : 1 ) - 16; 6247 HDisplay = (mode->CrtcHDisplay + 1) / (pScrn->bitsPerPixel >= 8 ? 6248 bytesPerPixel : 1 ); 6249 6250 /* generic init */ 6251 if (!vgaHWInit(pScrn, mode)) { 6252 ErrorF("bomb 5\n"); 6253 return (FALSE); 6254 } 6255 pScrn->vtSema = TRUE; 6256 6257 /* init clock */ 6258 if (!chipsClockFind(pScrn, mode, mode->ClockIndex, &ChipsNew->Clock)) { 6259 ErrorF("bomb 6\n"); 6260 return (FALSE); 6261 } 6262 6263 /* get C&T Specific Registers */ 6264 for (i = 0; i < 0x80; i++) { 6265 ChipsNew->XR[i] = cPtr->readXR(cPtr, i); 6266 } 6267 6268 /* some generic settings */ 6269 if (pScrn->bitsPerPixel == 1) { 6270 ChipsStd->Attribute[0x10] = 0x03; /* mode */ 6271 } else { 6272 ChipsStd->Attribute[0x10] = 0x01; /* mode */ 6273 } 6274 ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */ 6275 ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */ 6276 ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ 6277 6278 ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */ 6279 6280 /* set virtual screen width */ 6281 if (pScrn->bitsPerPixel >= 8) 6282 ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3; 6283 else 6284 ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4; 6285 6286 6287 /* set C&T Specific Registers */ 6288 /* set virtual screen width */ 6289 ChipsNew->XR[0x1E] = ChipsStd->CRTC[0x13]; /* alternate offset */ 6290 /*databook is not clear about 0x1E might be needed for 65520/30 */ 6291 if (pScrn->bitsPerPixel >= 8) 6292 tmp = (pScrn->displayWidth * bytesPerPixel) >> 2; 6293 else 6294 tmp = pScrn->displayWidth >> 3; 6295 ChipsNew->XR[0x0D] = (tmp & 0x01) | ((tmp << 1) & 0x02) ; 6296 6297 ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */ 6298 /* XR04: Memory control 1 */ 6299 /* bit 2: Memory Wraparound */ 6300 /* Enable CRTC addr counter bits 16-17 if set */ 6301 6302 ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */ 6303 ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */ 6304 /* XR0B: CPU paging */ 6305 /* bit 0: Memory mapping mode */ 6306 /* VGA compatible if 0 (default) */ 6307 /* Extended mode (mapping for > 256 kB mem) if 1 */ 6308 /* bit 1: CPU single/dual mapping */ 6309 /* 0, CPU uses only a single map to access (default) */ 6310 /* 1, CPU uses two maps to access */ 6311 /* bit 2: CPU address divide by 4 */ 6312 6313 ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */ 6314 ChipsNew->XR[0x11] = 0; /* XR11: High map */ 6315 if (pScrn->bitsPerPixel >= 8) { 6316 ChipsNew->XR[0x28] |= 0x10; /* 256-color video */ 6317 } else { 6318 ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */ 6319 } 6320 /* set up extended display timings */ 6321 if (!(cPtr->PanelType & ChipsLCD)) { 6322 /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */ 6323 ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) 6324 | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) 6325 | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) 6326 | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2) 6327 | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4) 6328 | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1); 6329 6330 ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 ) 6331 | (((mode->CrtcVDisplay -1) & 0x400) >> 9 ) 6332 | ((mode->CrtcVSyncStart & 0x400) >> 8 ) 6333 | (((mode->CrtcVBlankStart) & 0x400) >> 6 ); 6334 } else { 6335 /* horizontal timing registers */ 6336 /* in LCD/dual mode use saved bios values to derive timing values if 6337 * not told otherwise */ 6338 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 6339 lcdHTotal = cPtr->PanelSize.HTotal; 6340 lcdHRetraceStart = cPtr->PanelSize.HRetraceStart; 6341 lcdHRetraceEnd = cPtr->PanelSize.HRetraceEnd; 6342 if (pScrn->bitsPerPixel == 16) { 6343 lcdHRetraceStart <<= 1; 6344 lcdHRetraceEnd <<= 1; 6345 lcdHTotal <<= 1; 6346 } else if (pScrn->bitsPerPixel == 24) { 6347 lcdHRetraceStart += (lcdHRetraceStart << 1); 6348 lcdHRetraceEnd += (lcdHRetraceEnd << 1); 6349 lcdHTotal += (lcdHTotal << 1); 6350 } 6351 lcdHRetraceStart -=8; /* HBlank = HRetrace - 1: for */ 6352 lcdHRetraceEnd -=8; /* compatibility with vgaHW.c */ 6353 } else { 6354 /* use modeline values if bios values don't work */ 6355 lcdHTotal = mode->CrtcHTotal; 6356 lcdHRetraceStart = mode->CrtcHSyncStart; 6357 lcdHRetraceEnd = mode->CrtcHSyncEnd; 6358 } 6359 /* The chip takes the size of the visible display area from the 6360 * CRTC values. We use bios screensize for LCD in LCD/dual mode 6361 * wether or not we use modeline for LCD. This way we can specify 6362 * always specify a smaller than default display size on LCD 6363 * by writing it to the CRTC registers. */ 6364 lcdHDisplay = cPtr->PanelSize.HDisplay; 6365 if (pScrn->bitsPerPixel == 16) { 6366 lcdHDisplay++; 6367 lcdHDisplay <<= 1; 6368 lcdHDisplay--; 6369 } else if (pScrn->bitsPerPixel == 24) { 6370 lcdHDisplay++; 6371 lcdHDisplay += (lcdHDisplay << 1); 6372 lcdHDisplay--; 6373 } 6374 lcdHTotal = (lcdHTotal >> 3) - 5; 6375 lcdHDisplay = (lcdHDisplay >> 3) - 1; 6376 lcdHRetraceStart = (lcdHRetraceStart >> 3); 6377 lcdHRetraceEnd = (lcdHRetraceEnd >> 3); 6378 /* This ugly hack is needed because CR01 and XR1C share the 8th bit!*/ 6379 CrtcHDisplay = ((mode->CrtcHDisplay >> 3) - 1); 6380 if ((lcdHDisplay & 0x100) != (CrtcHDisplay & 0x100)) { 6381 xf86ErrorF("This display configuration might cause problems !\n"); 6382 lcdHDisplay = 255; 6383 } 6384 6385 /* now init register values */ 6386 ChipsNew->XR[0x17] = (((lcdHTotal) & 0x100) >> 8) 6387 | ((lcdHDisplay & 0x100) >> 7) 6388 | ((lcdHRetraceStart & 0x100) >> 6) 6389 | (((lcdHRetraceEnd) & 0x20) >> 2); 6390 6391 ChipsNew->XR[0x19] = lcdHRetraceStart & 0xFF; 6392 ChipsNew->XR[0x1A] = lcdHRetraceEnd & 0x1F; 6393 6394 /* XR1B: Alternate horizontal total */ 6395 /* used in all flat panel mode with horiz. compression disabled, */ 6396 /* CRT CGA text and graphic modes and Hercules graphics mode */ 6397 /* similar to CR00, actual value - 5 */ 6398 ChipsNew->XR[0x1B] = lcdHTotal & 0xFF; 6399 6400 /*XR1C: Alternate horizontal blank start (CRT mode) */ 6401 /* /horizontal panel size (FP mode) */ 6402 /* FP horizontal panel size (FP mode), */ 6403 /* actual value - 1 (in characters unit) */ 6404 /* CRT horizontal blank start (CRT mode) */ 6405 /* similar to CR02, actual value - 1 */ 6406 ChipsNew->XR[0x1C] = lcdHDisplay & 0xFF; 6407 6408 if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 6409 /* for ext. packed pixel mode on 64520/64530 */ 6410 /* no need to rescale: used only in 65530 */ 6411 ChipsNew->XR[0x21] = lcdHRetraceStart & 0xFF; 6412 ChipsNew->XR[0x22] = lcdHRetraceEnd & 0x1F; 6413 ChipsNew->XR[0x23] = lcdHTotal & 0xFF; 6414 6415 /* vertical timing registers */ 6416 lcdVTotal = mode->CrtcVTotal - 2; 6417 lcdVDisplay = cPtr->PanelSize.VDisplay - 1; 6418 lcdVRetraceStart = mode->CrtcVSyncStart; 6419 lcdVRetraceEnd = mode->CrtcVSyncEnd; 6420 6421 ChipsNew->XR[0x64] = lcdVTotal & 0xFF; 6422 ChipsNew->XR[0x66] = lcdVRetraceStart & 0xFF; 6423 ChipsNew->XR[0x67] = lcdVRetraceEnd & 0x0F; 6424 ChipsNew->XR[0x68] = lcdVDisplay & 0xFF; 6425 ChipsNew->XR[0x65] = ((lcdVTotal & 0x100) >> 8) 6426 | ((lcdVDisplay & 0x100) >> 7) 6427 | ((lcdVRetraceStart & 0x100) >> 6) 6428 | ((lcdVRetraceStart & 0x400) >> 7) 6429 | ((lcdVTotal & 0x400) >> 6) 6430 | ((lcdVTotal & 0x200) >> 4) 6431 | ((lcdVDisplay & 0x200) >> 3) 6432 | ((lcdVRetraceStart & 0x200) >> 2); 6433 6434 /* 6435 * These are important: 0x2C specifies the numbers of lines 6436 * (hsync pulses) between vertical blank start and vertical 6437 * line total, 0x2D specifies the number of clock ticks? to 6438 * horiz. blank start ( caution ! 16bpp/24bpp modes: that's 6439 * why we need HSyncStart - can't use mode->CrtcHSyncStart) 6440 */ 6441 tmp = ((cPtr->PanelType & ChipsDD) && !(ChipsNew->XR[0x6F] & 0x02)) 6442 ? 1 : 0; /* double LP delay, FLM: 2 lines iff DD+no acc*/ 6443 /* Currently we support 2 FLM schemes: #1: FLM coincides with 6444 * VTotal ie. the delay is programmed to the difference bet- 6445 * ween lctVTotal and lcdVRetraceStart. #2: FLM coincides 6446 * lcdVRetraceStart - in this case FLM delay will be turned 6447 * off. To decide which scheme to use we compare the value of 6448 * XR2C set by the bios to the two schemes. The one that fits 6449 * better will be used. 6450 */ 6451 6452 if (ChipsNew->XR[0x2C] < abs((cPtr->PanelSize.VTotal - 6453 cPtr->PanelSize.VRetraceStart - tmp - 1) - 6454 ChipsNew->XR[0x2C])) 6455 ChipsNew->XR[0x2F] |= 0x80; /* turn FLM delay off */ 6456 ChipsNew->XR[0x2C] = lcdVTotal - lcdVRetraceStart - tmp; 6457 /*ChipsNew->XR[0x2D] = (HSyncStart >> (3 - tmp)) & 0xFF;*/ 6458 ChipsNew->XR[0x2D] = (HDisplay >> (3 - tmp)) & 0xFF; 6459 ChipsNew->XR[0x2F] = (ChipsNew->XR[0x2F] & 0xDF) 6460 | (((HSyncStart >> (3 - tmp)) & 0x100) >> 3); 6461 } 6462 6463 /* set stretching/centering */ 6464 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) { 6465 ChipsNew->XR[0x51] |= 0x40; /* enable FP compensation */ 6466 ChipsNew->XR[0x55] |= 0x01; /* enable horiz. compensation */ 6467 ChipsNew->XR[0x57] |= 0x01; /* enable horiz. compensation */ 6468 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, 6469 FALSE)) { 6470 if (mode->CrtcHDisplay < 1489) /* HWBug */ 6471 ChipsNew->XR[0x55] |= 0x02; /* enable auto h-centering */ 6472 else { 6473 ChipsNew->XR[0x55] &= 0xFD; /* disable auto h-centering */ 6474 if (pScrn->bitsPerPixel == 24) /* ? */ 6475 ChipsNew->XR[0x56] = (lcdHDisplay - CrtcHDisplay) >> 1; 6476 } 6477 } else { 6478 ChipsNew->XR[0x55] &= 0xFD; /* disable h-centering */ 6479 ChipsNew->XR[0x56] = 0; 6480 } 6481 ChipsNew->XR[0x57] = 0x03; /* enable v-comp disable v-stretch */ 6482 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, 6483 FALSE)) { 6484 ChipsNew->XR[0x55] |= 0x20; /* enable h-comp disable h-double*/ 6485 ChipsNew->XR[0x57] |= 0x60; /* Enable vertical stretching */ 6486 tmp = (mode->CrtcVDisplay / (cPtr->PanelSize.VDisplay - 6487 mode->CrtcVDisplay + 1)); 6488 if (tmp) { 6489 if (cPtr->PanelSize.HDisplay 6490 && cPtr->PanelSize.VDisplay 6491 && (cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) 6492 && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) { 6493 /* Possible H/W bug? */ 6494 if(cPtr->Accel.UseHWCursor) 6495 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 6496 "Disabling HW Cursor on stretched LCD\n"); 6497 cPtr->Flags &= ~ChipsHWCursor; 6498 } 6499 } 6500 if (cPtr->Flags & ChipsHWCursor) 6501 tmp = (tmp == 0 ? 1 : tmp); /* Bug when doubling */ 6502 ChipsNew->XR[0x5A] = tmp > 0x0F ? 0 : (unsigned char)tmp; 6503 } else { 6504 ChipsNew->XR[0x55] &= 0xDF; /* disable h-comp, h-double */ 6505 ChipsNew->XR[0x57] &= 0x9F; /* disable vertical stretching */ 6506 } 6507 } 6508 } 6509 6510 /* set video mode */ 6511 ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->depth, (cPtr->PanelType & ChipsLCD) ? 6512 min(HDisplay, cPtr->PanelSize.HDisplay) : HDisplay,cPtr->PanelSize.VDisplay); 6513#ifdef DEBUG 6514 ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]); 6515#endif 6516 6517 /* set some linear specific registers */ 6518 if (cPtr->Flags & ChipsLinearSupport) { 6519 /* enable linear addressing */ 6520 ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */ 6521 ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */ 6522 if (cPtr->Chipset == CHIPS_CT65535) 6523 ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 17); 6524 else if (cPtr->Chipset > CHIPS_CT65535) 6525 ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 20); 6526 else { 6527 /* Its probably set correctly by BIOS anyway. Leave it alone */ 6528 /* 65525 - 65530 require XR04[6] set for greater than 512k of */ 6529 /* ram. We only correct obvious bugs; VL probably uses MEMR/MEMW*/ 6530 if (cPtr->Bus == ChipsISA) 6531 ChipsNew->XR[0x04] &= ~0x40; /* A19 sceme */ 6532 if (pScrn->videoRam > 512) 6533 ChipsNew->XR[0x04] |= 0x40; /* MEMR/MEMW sceme */ 6534 } 6535 6536 /* general setup */ 6537 ChipsNew->XR[0x03] |= 0x08; /* High bandwidth on 65548 */ 6538 ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */ 6539 } 6540 6541 /* common general setup */ 6542 ChipsNew->XR[0x52] |= 0x01; /* Refresh count */ 6543 ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */ 6544 ChipsNew->XR[0x02] |= 0x01; /* 16bit CPU Memory Access */ 6545 ChipsNew->XR[0x02] &= 0xE3; /* Attr. Cont. default access */ 6546 /* use ext. regs. for hor. in dual */ 6547 ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */ 6548 6549 /* PCI */ 6550 if (cPtr->Bus == ChipsPCI) 6551 ChipsNew->XR[0x03] |= 0x40; /*PCI burst */ 6552 6553 /* sync. polarities */ 6554 if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 6555 && (mode->Flags & (V_PVSYNC | V_NVSYNC))) { 6556 if (mode->Flags & (V_PHSYNC | V_NHSYNC)) { 6557 if (mode->Flags & V_PHSYNC) { 6558 ChipsNew->XR[0x55] &= 0xBF; /* CRT Hsync positive */ 6559 } else { 6560 ChipsNew->XR[0x55] |= 0x40; /* CRT Hsync negative */ 6561 } 6562 } 6563 if (mode->Flags & (V_PVSYNC | V_NVSYNC)) { 6564 if (mode->Flags & V_PVSYNC) { 6565 ChipsNew->XR[0x55] &= 0x7F; /* CRT Vsync positive */ 6566 } else { 6567 ChipsNew->XR[0x55] |= 0x80; /* CRT Vsync negative */ 6568 } 6569 } 6570 } 6571 6572 /* bpp depend */ 6573 /*XR06: Palette control */ 6574 /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */ 6575 /* bit 1: Internal DAC disable */ 6576 /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */ 6577 /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */ 6578 /* bit 4: Enable PC Video Overlay on colour key */ 6579 /* bit 5: Bypass Internal VGA palette */ 6580 /* bit 7-6: Colour reduction select, 0 for NTSC (default), */ 6581 /* 1 for Equivalent weighting, 2 for green only, */ 6582 /* 3 for Colour w/o reduction */ 6583 /* XR50 Panel Format Register 1 */ 6584 /* bit 1-0: Frame Rate Control; 00, No FRC; */ 6585 /* 01, 16-frame FRC for colour STN and monochrome */ 6586 /* 10, 2-frame FRC for colour TFT or monochrome; */ 6587 /* 11, reserved */ 6588 /* bit 3-2: Dither Enable */ 6589 /* 00, disable dithering; 01, enable dithering */ 6590 /* for 256 mode */ 6591 /* 10, enable dithering for all modes; 11, reserved */ 6592 /* bit6-4: Clock Divide (CD) */ 6593 /* 000, Shift Clock Freq = Dot Clock Freq; */ 6594 /* 001, SClk = DClk/2; 010 SClk = DClk/4; */ 6595 /* 011, SClk = DClk/8; 100 SClk = DClk/16; */ 6596 /* bit 7: TFT data width */ 6597 /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */ 6598 if (pScrn->bitsPerPixel == 16) { 6599 ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */ 6600 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6601 ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */ 6602 if (pScrn->weight.green != 5) 6603 ChipsNew->XR[0x06] |= 0x08; /*16bpp */ 6604 } else if (pScrn->bitsPerPixel == 24) { 6605 ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */ 6606 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6607 if (xf86ReturnOptValBool(cPtr->Options, OPTION_18_BIT_BUS, FALSE)) { 6608 ChipsNew->XR[0x50] &= 0x7F; /*18 bit TFT data width */ 6609 } else { 6610 ChipsNew->XR[0x50] |= 0x80; /*24 bit TFT data width */ 6611 } 6612 } 6613 6614 /*CRT only: interlaced mode */ 6615 if (!(cPtr->PanelType & ChipsLCD)) { 6616 if (mode->Flags & V_INTERLACE){ 6617 ChipsNew->XR[0x28] |= 0x20; /* set interlace */ 6618 /* empirical value */ 6619 tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1) 6620 - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 )); 6621 if(cPtr->Chipset < CHIPS_CT65535) 6622 ChipsNew->XR[0x19] = tmp & 0xFF; 6623 else 6624 ChipsNew->XR[0x29] = tmp & 0xFF; 6625 ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */ 6626 } else { 6627 ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */ 6628 ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */ 6629 } 6630 } 6631 6632 /* STN specific */ 6633 if (IS_STN(cPtr->PanelType)) { 6634 ChipsNew->XR[0x50] &= ~0x03; /* FRC clear */ 6635 ChipsNew->XR[0x50] |= 0x01; /* 16 frame FRC */ 6636 ChipsNew->XR[0x50] &= ~0x0C; /* Dither clear */ 6637 ChipsNew->XR[0x50] |= 0x08; /* Dither all modes */ 6638 if (cPtr->Chipset == CHIPS_CT65548) { 6639 ChipsNew->XR[0x03] |= 0x20; /* CRT I/F priority */ 6640 ChipsNew->XR[0x04] |= 0x10; /* RAS precharge 65548 */ 6641 } 6642 } 6643 6644 /* This stuff was emprically derived several years ago. Not sure its 6645 * still needed, and I'd love to get rid of it as its ugly 6646 */ 6647 switch (cPtr->Chipset) { 6648 case CHIPS_CT65545: /*jet mini *//*DEC HighNote Ultra DSTN */ 6649 ChipsNew->XR[0x03] |= 0x10; /* do not hold off CPU for palette acc*/ 6650 break; 6651 case CHIPS_CT65546: /*CT 65546, only for Toshiba */ 6652 ChipsNew->XR[0x05] |= 0x80; /* EDO RAM enable */ 6653 break; 6654 } 6655 6656 if (cPtr->PanelType & ChipsLCD) 6657 ChipsNew->XR[0x51] |= 0x04; 6658 else 6659 ChipsNew->XR[0x51] &= ~0x04; 6660 6661 /* Program the registers */ 6662 /*vgaHWProtect(pScrn, TRUE);*/ 6663 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 6664 /*vgaHWProtect(pScrn, FALSE);*/ 6665 6666 return (TRUE); 6667} 6668 6669static void 6670chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, CHIPSRegPtr ChipsReg, 6671 Bool restoreFonts) 6672{ 6673 vgaHWPtr hwp = VGAHWPTR(pScrn); 6674 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6675 unsigned char tmp = 0; 6676 6677 /*vgaHWProtect(pScrn, TRUE);*/ 6678 6679 /* set registers so that we can program the controller */ 6680 if (IS_HiQV(cPtr)) { 6681 cPtr->writeXR(cPtr, 0x0E, 0x00); 6682 if (cPtr->Flags & ChipsDualChannelSupport) { 6683 tmp = cPtr->readFR(cPtr, 0x01); /* Disable pipeline */ 6684 cPtr->writeFR(cPtr, 0x01, (tmp & 0xFC)); 6685 cPtr->writeFR(cPtr, 0x02, 0x00); /* CRT/FP off */ 6686 } 6687 } else { 6688 cPtr->writeXR(cPtr, 0x10, 0x00); 6689 cPtr->writeXR(cPtr, 0x11, 0x00); 6690 tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */ 6691 cPtr->writeXR(cPtr, 0x0C, tmp); 6692 cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect all registers */ 6693 tmp = cPtr->readXR(cPtr, 0x14); 6694 cPtr->writeXR(cPtr, 0x14, tmp & ~0x20); /* enable vsync on ST01 */ 6695 } 6696 6697 chipsFixResume(pScrn); 6698 6699 /* 6700 * Wait for vsync if sequencer is running - stop sequencer. 6701 * Only do if sync reset is ignored. Dual pipeline capable 6702 * chips have pipeline forced off here, so we don't care. 6703 */ 6704 if ((cPtr->SyncResetIgn) && (!(cPtr->Flags & ChipsDualChannelSupport))) { 6705 while (((hwp->readST01(hwp)) & 0x08) == 0x08); /* VSync off */ 6706 while (((hwp->readST01(hwp)) & 0x08) == 0x00); /* VSync on */ 6707 hwp->writeSeq(hwp, 0x07, 0x00); /* reset hsync - just in case... */ 6708 } 6709 6710 /* set the clock */ 6711 chipsClockLoad(pScrn, &ChipsReg->Clock); 6712 /* chipsClockLoad() sets this so we don't want vgaHWRestore() change it */ 6713 VgaReg->MiscOutReg = inb(cPtr->PIOBase + 0x3CC); 6714 6715 /* set extended regs */ 6716 chipsRestoreExtendedRegs(pScrn, ChipsReg); 6717#if 0 6718 /* if people complain about lock ups or blank screens -- reenable */ 6719 /* set CRTC registers - do it before sequencer restarts */ 6720 for (i=0; i<25; i++) 6721 hwp->writeCrtc(hwp, i, VgaReg->CRTC[i]); 6722#endif 6723 /* set generic registers */ 6724 /* 6725 * Enabling writing to the colourmap causes 69030's to lock. 6726 * Anyone care to explain to me why ???? 6727 */ 6728 if (cPtr->Flags & ChipsDualChannelSupport) { 6729 /* Enable pipeline if needed */ 6730 cPtr->writeFR(cPtr, 0x01, ChipsReg->FR[0x01]); 6731 cPtr->writeFR(cPtr, 0x02, ChipsReg->FR[0x02]); 6732 vgaHWRestore(pScrn, VgaReg, VGA_SR_MODE | 6733 (restoreFonts ? VGA_SR_FONTS : 0)); 6734 } else { 6735 vgaHWRestore(pScrn, VgaReg, VGA_SR_MODE | VGA_SR_CMAP | 6736 (restoreFonts ? VGA_SR_FONTS : 0)); 6737 } 6738 6739 /* set stretching registers */ 6740 if (IS_HiQV(cPtr)) { 6741 chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40], 6742 (unsigned char)ChipsReg->FR[0x48]); 6743#if 0 6744 /* if people report about stretching not working -- reenable */ 6745 /* why twice ? : 6746 * sometimes the console is not well restored even if these registers 6747 * are good, re-write the registers works around it 6748 */ 6749 chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40], 6750 (unsigned char)ChipsReg->FR[0x48]); 6751#endif 6752 } else if (!IS_Wingine(cPtr)) 6753 chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->XR[0x55], 6754 (unsigned char)ChipsReg->XR[0x57]); 6755 6756 /* perform a synchronous reset */ 6757 if (!cPtr->SyncResetIgn) { 6758 if (!IS_HiQV(cPtr)) { 6759 /* enable syncronous reset on 655xx */ 6760 tmp = cPtr->readXR(cPtr, 0x0E); 6761 cPtr->writeXR(cPtr, 0x0E, tmp & 0x7F); 6762 } 6763 hwp->writeSeq(hwp, 0x00, 0x01); 6764 usleep(10000); 6765 hwp->writeSeq(hwp, 0x00, 0x03); 6766 if (!IS_HiQV(cPtr)) 6767 cPtr->writeXR(cPtr, 0x0E, tmp); 6768 } 6769 /* Flag valid start address, if using CRT extensions */ 6770 if (IS_HiQV(cPtr) && (ChipsReg->XR[0x09] & 0x1) == 0x1) { 6771 tmp = hwp->readCrtc(hwp, 0x40); 6772 hwp->writeCrtc(hwp, 0x40, tmp | 0x80); 6773 } 6774 6775 /* Fix resume again here, as Nozomi seems to need it */ 6776 chipsFixResume(pScrn); 6777 /*vgaHWProtect(pScrn, FALSE);*/ 6778 6779#if 0 6780 /* Enable pipeline if needed */ 6781 if (cPtr->Flags & ChipsDualChannelSupport) { 6782 cPtr->writeFR(cPtr, 0x01, ChipsReg->FR[0x01]); 6783 cPtr->writeFR(cPtr, 0x02, ChipsReg->FR[0x02]); 6784 } 6785#endif 6786} 6787 6788static void 6789chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs) 6790{ 6791 vgaHWPtr hwp = VGAHWPTR(pScrn); 6792 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6793 int i; 6794 unsigned char tmp; 6795 6796 if (IS_HiQV(cPtr)) { 6797 /* set extended regs */ 6798 for (i = 0; i < 0x43; i++) { 6799 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6800 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6801 } 6802 6803 /* Set SAR04 multimedia register correctly */ 6804 if ((cPtr->Flags & ChipsOverlay8plus16) 6805 || (cPtr->Flags & ChipsVideoSupport)) { 6806#ifdef SAR04 6807 cPtr->writeXR(cPtr, 0x4E, 0x04); 6808 if (cPtr->readXR(cPtr, 0x4F) != Regs->XR[0x4F]) 6809 cPtr->writeXR(cPtr, 0x4F, Regs->XR[0x4F]); 6810#endif 6811 } 6812 6813 /* Don't touch reserved memory control registers */ 6814 for (i = 0x50; i < 0xBF; i++) { 6815 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6816 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6817 } 6818 /* Don't touch VCLK regs, but fix up MClk */ 6819 6820 /* set mem clock */ 6821 tmp = cPtr->readXR(cPtr, 0xCE); /* Select Fixed MClk before */ 6822 cPtr->writeXR(cPtr, 0xCE, tmp & 0x7F); 6823 if ((cPtr->readXR(cPtr, 0xCC)) != Regs->XR[0xCC]) 6824 cPtr->writeXR(cPtr, 0xCC, Regs->XR[0xCC]); 6825 if ((cPtr->readXR(cPtr, 0xCD)) != Regs->XR[0xCD]) 6826 cPtr->writeXR(cPtr, 0xCD, Regs->XR[0xCD]); 6827 if ((cPtr->readXR(cPtr, 0xCE)) != Regs->XR[0xCE]) 6828 cPtr->writeXR(cPtr, 0xCE, Regs->XR[0xCE]); 6829 6830 /* set flat panel regs. */ 6831 for (i = 0xD0; i < 0xFF; i++) { 6832 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6833 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6834 } 6835 6836 for (i = 0; i < 0x80; i++) { 6837 /* Don't touch alternate clock select reg. */ 6838 if ((i == 0x01) && (cPtr->Chipset == CHIPS_CT69030)) { 6839 /* restore the non clock bits */ 6840 tmp = cPtr->readFR(cPtr, 0x01); 6841 cPtr->writeFR(cPtr, 0x01, ((Regs->FR[0x01] & 0xF0) | 6842 (tmp & ~0xF0))); 6843 continue; 6844 } 6845 6846 if ((i == 0x02) && (cPtr->Chipset == CHIPS_CT69030)) 6847 /* keep pipeline disabled till we are ready */ 6848 continue; 6849 6850 if ((i == 0x03) && (cPtr->Chipset != CHIPS_CT69030)) { 6851 /* restore the non clock bits */ 6852 tmp = cPtr->readFR(cPtr, 0x03); 6853 cPtr->writeFR(cPtr, 0x03, ((Regs->FR[0x03] & 0xC3) | 6854 (tmp & ~0xC3))); 6855 continue; 6856 } 6857 6858 if ((i > 0x03) && (cPtr->Chipset != CHIPS_CT69030) && 6859 (cPtr->SecondCrtc == TRUE)) 6860 continue; 6861 6862 if ( (i == 0x40) || (i==0x48)) { 6863 /* !! set stretching but disable compensation */ 6864 cPtr->writeFR(cPtr, i, Regs->FR[i] & 0xFE); 6865 continue ; /* some registers must be set before FR40/FR48 */ 6866 } 6867 if ((cPtr->readFR(cPtr, i)) != Regs->FR[i]) { 6868 cPtr->writeFR(cPtr, i, Regs->FR[i]); 6869 } 6870 } 6871 6872 /* set the multimedia regs */ 6873 for (i = 0x02; i < 0x80; i++) { 6874 if ( (i == 0x43) || (i == 0x44)) 6875 continue; 6876 if ((cPtr->readMR(cPtr, i)) != Regs->MR[i]) 6877 cPtr->writeMR(cPtr, i, Regs->MR[i]); 6878 } 6879 6880 /* set extended crtc regs. */ 6881 for (i = 0x30; i < 0x80; i++) { 6882 if ((hwp->readCrtc(hwp, i)) != Regs->CR[i]) 6883 hwp->writeCrtc(hwp, i, Regs->CR[i]); 6884 } 6885 } else { 6886 /* set extended regs. */ 6887 for (i = 0; i < 0x30; i++) { 6888 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6889 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6890 } 6891 cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect just in case ... */ 6892 /* Don't touch MCLK/VCLK regs. */ 6893 for (i = 0x34; i < 0x54; i++) { 6894 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6895 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6896 } 6897 tmp = cPtr->readXR(cPtr, 0x54); /* restore the non clock bits */ 6898 cPtr->writeXR(cPtr, 0x54, ((Regs->XR[0x54] & 0xF3) | (tmp & ~0xF3))); 6899 cPtr->writeXR(cPtr, 0x55, Regs->XR[0x55] & 0xFE); /* h-comp off */ 6900 cPtr->writeXR(cPtr, 0x56, Regs->XR[0x56]); 6901 cPtr->writeXR(cPtr, 0x57, Regs->XR[0x57] & 0xFE); /* v-comp off */ 6902 for (i=0x58; i < 0x7D; i++) {/* don't touch XR7D and XR7F on WINGINE */ 6903 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6904 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6905 } 6906 } 6907#ifdef DEBUG 6908 /* debug - dump out all the extended registers... */ 6909 if (IS_HiQV(cPtr)) { 6910 for (i = 0; i < 0xFF; i++) { 6911 ErrorF("XR%X - %X : %X\n", i, Regs->XR[i], 6912 cPtr->readXR(cPtr, i)); 6913 } 6914 for (i = 0; i < 0x80; i++) { 6915 ErrorF("FR%X - %X : %X\n", i, Regs->FR[i], 6916 cPtr->readFR(cPtr, i)); 6917 } 6918 } else { 6919 for (i = 0; i < 0x80; i++) { 6920 ErrorF("XR%X - %X : %X\n", i, Regs->XR[i], 6921 cPtr->readXR(cPtr, i)); 6922 } 6923 } 6924#endif 6925} 6926 6927static void 6928chipsRestoreStretching(ScrnInfoPtr pScrn, unsigned char ctHorizontalStretch, 6929 unsigned char ctVerticalStretch) 6930{ 6931 unsigned char tmp; 6932 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6933 6934 /* write to regs. */ 6935 if (IS_HiQV(cPtr)) { 6936 tmp = cPtr->readFR(cPtr, 0x48); 6937 cPtr->writeFR(cPtr, 0x48, (tmp & 0xFE) | (ctVerticalStretch & 0x01)); 6938 tmp = cPtr->readFR(cPtr, 0x40); 6939 cPtr->writeFR(cPtr, 0x40, (tmp & 0xFE) | (ctHorizontalStretch & 0x01)); 6940 } else { 6941 tmp = cPtr->readXR(cPtr, 0x55); 6942 cPtr->writeXR(cPtr, 0x55, (tmp & 0xFE) | (ctHorizontalStretch & 0x01)); 6943 tmp = cPtr->readXR(cPtr, 0x57); 6944 cPtr->writeXR(cPtr, 0x57, (tmp & 0xFE) | (ctVerticalStretch & 0x01)); 6945 } 6946 6947 usleep(20000); /* to be active */ 6948} 6949 6950static int 6951chipsVideoMode(int depth, int displayHSize, 6952 int displayVSize) 6953{ 6954 /* 4 bpp 8 bpp 16 bpp 18 bpp 24 bpp 32 bpp */ 6955 /* 640 0x20 0x30 0x40 - 0x50 - */ 6956 /* 800 0x22 0x32 0x42 - 0x52 - */ 6957 /*1024 0x24 0x34 0x44 - 0x54 - for 1024x768 */ 6958 /*1024 - 0x36 0x47 - 0x56 - for 1024x600 */ 6959 /*1152 0x27 0x37 0x47 - 0x57 - */ 6960 /*1280 0x28 0x38 0x49 - - - */ 6961 /*1600 0x2C 0x3C 0x4C 0x5D - - */ 6962 /*This value is only for BIOS.... */ 6963 6964 int videoMode = 0; 6965 6966 switch (depth) { 6967 case 1: 6968 case 4: 6969 videoMode = 0x20; 6970 break; 6971 case 8: 6972 videoMode = 0x30; 6973 break; 6974 case 15: 6975 videoMode = 0x40; 6976 break; 6977 case 16: 6978 videoMode = 0x41; 6979 break; 6980 default: 6981 videoMode = 0x50; 6982 break; 6983 } 6984 6985 switch (displayHSize) { 6986 case 800: 6987 videoMode |= 0x02; 6988 break; 6989 case 1024: 6990 videoMode |= 0x04; 6991 if(displayVSize < 768) 6992 videoMode |= 0x02; 6993 break; 6994 case 1152: 6995 videoMode |= 0x07; 6996 break; 6997 case 1280: 6998 videoMode |= 0x08; 6999 break; 7000 case 1600: 7001 videoMode |= 0x0C; /*0x0A??*/ 7002 break; 7003 } 7004 7005 return videoMode; 7006} 7007 7008 7009/* 7010 * Map the framebuffer and MMIO memory. 7011 */ 7012 7013static Bool 7014chipsMapMem(ScrnInfoPtr pScrn) 7015{ 7016 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7017 vgaHWPtr hwp = VGAHWPTR(pScrn); 7018 CHIPSEntPtr cPtrEnt; 7019 7020 if (cPtr->Flags & ChipsLinearSupport) { 7021 if (cPtr->UseMMIO) { 7022 if (IS_HiQV(cPtr)) { 7023#ifndef XSERVER_LIBPCIACCESS 7024 if (cPtr->pEnt->location.type == BUS_PCI) 7025 cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, 7026 VIDMEM_MMIO_32BIT,cPtr->PciTag, cPtr->IOAddress, 7027 0x20000L); 7028 else 7029 cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, 7030 VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x20000L); 7031#else 7032 { 7033 if (cPtr->pEnt->location.type == BUS_PCI) { 7034 void** result = (void**)&cPtr->MMIOBase; 7035 int err = pci_device_map_range(cPtr->PciInfo, 7036 cPtr->IOAddress, 7037 0x20000L, 7038 PCI_DEV_MAP_FLAG_WRITABLE, 7039 result); 7040 if (err) { 7041 xf86Msg(X_ERROR, "PCI mmap failed\n"); 7042 return FALSE; 7043 } 7044 } else 7045 cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, 7046 VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x20000L); 7047 7048 } 7049#endif 7050 } else { 7051#ifndef XSERVER_LIBPCIACCESS 7052 if (cPtr->pEnt->location.type == BUS_PCI) 7053 cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, 7054 VIDMEM_MMIO_32BIT, cPtr->PciTag, cPtr->IOAddress, 7055 0x10000L); 7056 else 7057 cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, 7058 VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x10000L); 7059#else 7060 { 7061 if (cPtr->pEnt->location.type == BUS_PCI) { 7062 void** result = (void**)&cPtr->MMIOBase; 7063 int err = pci_device_map_range(cPtr->PciInfo, 7064 cPtr->IOAddress, 7065 0x10000L, 7066 PCI_DEV_MAP_FLAG_WRITABLE, 7067 result); 7068 if (err) { 7069 xf86Msg(X_ERROR, "PCI mmap failed\n"); 7070 return FALSE; 7071 } 7072 } else 7073 cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, 7074 VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x10000L); 7075 } 7076#endif 7077 } 7078 7079 if (cPtr->MMIOBase == NULL) 7080 return FALSE; 7081 } 7082 if (cPtr->FbMapSize) { 7083 unsigned long Addr = (unsigned long)cPtr->FbAddress; 7084 unsigned int Map = cPtr->FbMapSize; 7085 7086 if ((cPtr->Flags & ChipsDualChannelSupport) && 7087 (xf86IsEntityShared(pScrn->entityList[0]))) { 7088 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 7089 CHIPSEntityIndex)->ptr; 7090 if(cPtr->SecondCrtc == FALSE) { 7091 Addr = cPtrEnt->masterFbAddress; 7092 Map = cPtrEnt->masterFbMapSize; 7093 } else { 7094 Addr = cPtrEnt->slaveFbAddress; 7095 Map = cPtrEnt->slaveFbMapSize; 7096 } 7097 } 7098 7099#ifndef XSERVER_LIBPCIACCESS 7100 if (cPtr->pEnt->location.type == BUS_PCI) 7101 cPtr->FbBase = xf86MapPciMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER, 7102 cPtr->PciTag, Addr, Map); 7103 7104 else 7105 cPtr->FbBase = xf86MapVidMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER, 7106 Addr, Map); 7107#else 7108 if (cPtr->pEnt->location.type == BUS_PCI) { 7109 void** result = (void**)&cPtr->FbBase; 7110 int err = pci_device_map_range(cPtr->PciInfo, 7111 Addr, 7112 Map, 7113 PCI_DEV_MAP_FLAG_WRITABLE | 7114 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 7115 result); 7116 if (err) { 7117 xf86Msg(X_ERROR, "PCI mmap fb failed\n"); 7118 return FALSE; 7119 } 7120 } else 7121 cPtr->FbBase = xf86MapVidMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER, 7122 Addr, Map); 7123 7124#endif 7125 7126 if (cPtr->FbBase == NULL) 7127 return FALSE; 7128 } 7129 if (cPtr->Flags & ChipsFullMMIOSupport) { 7130#ifndef XSERVER_LIBPCIACCESS 7131 cPtr->MMIOBaseVGA = xf86MapPciMem(pScrn->scrnIndex, 7132 VIDMEM_MMIO,cPtr->PciTag, 7133 cPtr->IOAddress, 0x2000L); 7134#else 7135 cPtr->MMIOBaseVGA = cPtr->MMIOBase; 7136#endif 7137 /* 69030 MMIO Fix. 7138 * 7139 * The hardware lets us map the PipeB data registers 7140 * into the MMIO address space normally occupied by PipeA, 7141 * but it doesn't allow remapping of the index registers. 7142 * So we're forced to map a separate MMIO space for each 7143 * pipe and to toggle between them as necessary. -GHB 7144 */ 7145 if (cPtr->Flags & ChipsDualChannelSupport) 7146#ifndef XSERVER_LIBPCIACCESS 7147 cPtr->MMIOBasePipeB = xf86MapPciMem(pScrn->scrnIndex, 7148 VIDMEM_MMIO,cPtr->PciTag, 7149 cPtr->IOAddress + 0x800000, 0x2000L); 7150#else 7151 { 7152 void** result = (void**)&cPtr->MMIOBasePipeB; 7153 int err = pci_device_map_range(cPtr->PciInfo, 7154 cPtr->IOAddress + 0x800000, 7155 0x2000L, 7156 PCI_DEV_MAP_FLAG_WRITABLE, 7157 result); 7158 if (err) 7159 return FALSE; 7160 } 7161#endif 7162 7163 cPtr->MMIOBasePipeA = cPtr->MMIOBaseVGA; 7164 } 7165 } else { 7166 /* In paged mode Base is the VGA window at 0xA0000 */ 7167 cPtr->FbBase = hwp->Base; 7168 } 7169 7170 return TRUE; 7171} 7172 7173 7174/* 7175 * Unmap the framebuffer and MMIO memory. 7176 */ 7177 7178static Bool 7179chipsUnmapMem(ScrnInfoPtr pScrn) 7180{ 7181 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7182 7183 if (cPtr->Flags & ChipsLinearSupport) { 7184 if (IS_HiQV(cPtr)) { 7185#ifndef XSERVER_LIBPCIACCESS 7186 if (cPtr->MMIOBase) 7187 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase, 7188 0x20000); 7189 if (cPtr->MMIOBasePipeB) 7190 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBasePipeB, 7191 0x20000); 7192#else 7193 if (cPtr->MMIOBase) 7194 pci_device_unmap_range(cPtr->PciInfo, cPtr->MMIOBase, 0x20000); 7195 7196 if (cPtr->MMIOBasePipeB) 7197 pci_device_unmap_range(cPtr->PciInfo, cPtr->MMIOBasePipeB, 0x2000); 7198 7199#endif 7200 cPtr->MMIOBasePipeB = NULL; 7201 } else { 7202#ifndef XSERVER_LIBPCIACCESS 7203 if (cPtr->MMIOBase) 7204 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase, 7205 0x10000); 7206#else 7207 if (cPtr->MMIOBase) 7208 pci_device_unmap_range(cPtr->PciInfo, cPtr->MMIOBase, 0x10000); 7209#endif 7210 } 7211 cPtr->MMIOBase = NULL; 7212#ifndef XSERVER_LIBPCIACCESS 7213 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->FbBase, 7214 cPtr->FbMapSize); 7215#else 7216 pci_device_unmap_range(cPtr->PciInfo, cPtr->FbBase, cPtr->FbMapSize); 7217#endif 7218 } 7219 cPtr->FbBase = NULL; 7220 7221 return TRUE; 7222} 7223 7224static void 7225chipsProtect(ScrnInfoPtr pScrn, Bool on) 7226{ 7227 vgaHWProtect(pScrn, on); 7228} 7229 7230static void 7231chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank) 7232{ 7233 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7234 vgaHWPtr hwp = VGAHWPTR(pScrn); 7235 unsigned char scrn; 7236 CHIPSEntPtr cPtrEnt; 7237 7238 if (cPtr->UseDualChannel) { 7239 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 7240 CHIPSEntityIndex)->ptr; 7241 DUALREOPEN; 7242 } 7243 7244 /* fix things that could be messed up by suspend/resume */ 7245 if (!IS_HiQV(cPtr)) 7246 cPtr->writeXR(cPtr, 0x15, 0x00); 7247 7248 scrn = hwp->readSeq(hwp, 0x01); 7249 7250 if (unblank) { 7251 scrn &= 0xDF; /* enable screen */ 7252 } else { 7253 scrn |= 0x20; /* blank screen */ 7254 } 7255 7256 /* synchronous reset - stop counters */ 7257 if (!cPtr->SyncResetIgn) { 7258 hwp->writeSeq(hwp, 0x00, 0x01); 7259 } 7260 7261 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 7262 7263 /* end reset - start counters */ 7264 if (!cPtr->SyncResetIgn) { 7265 hwp->writeSeq(hwp, 0x00, 0x03); 7266 } 7267 7268 if ((cPtr->UseDualChannel) && 7269 (! xf86IsEntityShared(pScrn->entityList[0]))) { 7270 unsigned int IOSS, MSS; 7271 IOSS = cPtr->readIOSS(cPtr); 7272 MSS = cPtr->readMSS(cPtr); 7273 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 7274 IOSS_PIPE_B)); 7275 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 7276 7277 /* fix things that could be messed up by suspend/resume */ 7278 if (!IS_HiQV(cPtr)) 7279 cPtr->writeXR(cPtr, 0x15, 0x00); 7280 7281 scrn = hwp->readSeq(hwp, 0x01); 7282 7283 if (unblank) { 7284 scrn &= 0xDF; /* enable screen */ 7285 } else { 7286 scrn |= 0x20; /* blank screen */ 7287 } 7288 7289 /* synchronous reset - stop counters */ 7290 if (!cPtr->SyncResetIgn) { 7291 hwp->writeSeq(hwp, 0x00, 0x01); 7292 } 7293 7294 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 7295 7296 /* end reset - start counters */ 7297 if (!cPtr->SyncResetIgn) { 7298 hwp->writeSeq(hwp, 0x00, 0x03); 7299 } 7300 7301 cPtr->writeIOSS(cPtr, IOSS); 7302 cPtr->writeMSS(cPtr, hwp, MSS); 7303 } 7304 7305} 7306 7307static void 7308chipsLock(ScrnInfoPtr pScrn) 7309{ 7310 vgaHWPtr hwp = VGAHWPTR(pScrn); 7311 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7312 unsigned char tmp; 7313 7314 vgaHWLock(hwp); 7315 7316 if (!IS_HiQV(cPtr)) { 7317 /* group protection attribute controller access */ 7318 cPtr->writeXR(cPtr, 0x15, cPtr->SuspendHack.xr15); 7319 tmp = cPtr->readXR(cPtr, 0x02); 7320 cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18) | cPtr->SuspendHack.xr02); 7321 tmp = cPtr->readXR(cPtr, 0x14); 7322 cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20) | cPtr->SuspendHack.xr14); 7323 7324 /* reset 32 bit register access */ 7325 if (cPtr->Chipset > CHIPS_CT65540) { 7326 tmp = cPtr->readXR(cPtr, 0x03); 7327 cPtr->writeXR(cPtr, 0x03, (tmp & ~0x0A) | cPtr->SuspendHack.xr03); 7328 } 7329 } 7330} 7331 7332static void 7333chipsUnlock(ScrnInfoPtr pScrn) 7334{ 7335 vgaHWPtr hwp = VGAHWPTR(pScrn); 7336 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7337 unsigned char tmp; 7338 7339 if (!IS_HiQV(cPtr)) { 7340 /* group protection attribute controller access */ 7341 cPtr->writeXR(cPtr, 0x15, 0x00); 7342 tmp = cPtr->readXR(cPtr, 0x02); 7343 cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18)); 7344 tmp = cPtr->readXR(cPtr, 0x14); 7345 cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20)); 7346 /* enable 32 bit register access */ 7347 if (cPtr->Chipset > CHIPS_CT65540) { 7348 cPtr->writeXR(cPtr, 0x03, cPtr->SuspendHack.xr03 | 0x0A); 7349 } 7350 } 7351 vgaHWUnlock(hwp); 7352} 7353 7354static void 7355chipsHWCursorOn(CHIPSPtr cPtr, ScrnInfoPtr pScrn) 7356{ 7357 /* enable HW cursor */ 7358 if (cPtr->HWCursorShown) { 7359 if (IS_HiQV(cPtr)) { 7360 cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF); 7361 if (cPtr->UseDualChannel && 7362 (! xf86IsEntityShared(pScrn->entityList[0]))) { 7363 unsigned int IOSS, MSS; 7364 IOSS = cPtr->readIOSS(cPtr); 7365 MSS = cPtr->readMSS(cPtr); 7366 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 7367 IOSS_PIPE_B)); 7368 cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & 7369 MSS_MASK) | MSS_PIPE_B)); 7370 cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF); 7371 cPtr->writeIOSS(cPtr, IOSS); 7372 cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS); 7373 } 7374 } else { 7375 HW_DEBUG(0x8); 7376 if (cPtr->UseMMIO) { 7377 MMIOmeml(DR(0x8)) = cPtr->HWCursorContents; 7378 } else { 7379 outl(cPtr->PIOBase + DR(0x8), cPtr->HWCursorContents); 7380 } 7381 } 7382 } 7383} 7384 7385static void 7386chipsHWCursorOff(CHIPSPtr cPtr, ScrnInfoPtr pScrn) 7387{ 7388 /* disable HW cursor */ 7389 if (cPtr->HWCursorShown) { 7390 if (IS_HiQV(cPtr)) { 7391 cPtr->HWCursorContents = cPtr->readXR(cPtr, 0xA0); 7392 cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xF8); 7393 } else { 7394 HW_DEBUG(0x8); 7395 if (cPtr->UseMMIO) { 7396 cPtr->HWCursorContents = MMIOmeml(DR(0x8)); 7397 /* Below used to be MMIOmemw() change back if problem!!! */ 7398 /* Also see ct_cursor.c */ 7399 MMIOmeml(DR(0x8)) = cPtr->HWCursorContents & 0xFFFE; 7400 } else { 7401 cPtr->HWCursorContents = inl(cPtr->PIOBase + DR(0x8)); 7402 outw(cPtr->PIOBase + DR(0x8), cPtr->HWCursorContents & 0xFFFE); 7403 } 7404 } 7405 } 7406} 7407 7408void 7409chipsFixResume(ScrnInfoPtr pScrn) 7410{ 7411 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7412 vgaHWPtr hwp = VGAHWPTR(pScrn); 7413 unsigned char tmp; 7414 7415 /* fix things that could be messed up by suspend/resume */ 7416 if (!IS_HiQV(cPtr)) 7417 cPtr->writeXR(cPtr, 0x15, 0x00); 7418 tmp = hwp->readMiscOut(hwp); 7419 hwp->writeMiscOut(hwp, (tmp & 0xFE) | cPtr->SuspendHack.vgaIOBaseFlag); 7420 tmp = hwp->readCrtc(hwp, 0x11); 7421 hwp->writeCrtc(hwp, 0x11, (tmp & 0x7F)); 7422} 7423 7424static char 7425chipsTestDACComp(ScrnInfoPtr pScrn, unsigned char a, unsigned char b, 7426 unsigned char c) 7427{ 7428 vgaHWPtr hwp = VGAHWPTR(pScrn); 7429 unsigned char type; 7430 7431 hwp->writeDacWriteAddr(hwp, 0x00); 7432 while ((hwp->readST01(hwp)) & 0x08){}; /* wait for vsync to end */ 7433 while (!((hwp->readST01(hwp)) & 0x08)){}; /* wait for new vsync */ 7434 hwp->writeDacData(hwp, a); /* set pattern */ 7435 hwp->writeDacData(hwp, b); 7436 hwp->writeDacData(hwp, c); 7437 while (!(hwp->readST01(hwp)) & 0x01){}; /* wait for hsync to end */ 7438 while ((hwp->readST01(hwp)) & 0x01){}; /* wait for hsync to end */ 7439 type = hwp->readST00(hwp); /* read comparator */ 7440 return (type & 0x10); 7441} 7442 7443static int 7444chipsProbeMonitor(ScrnInfoPtr pScrn) 7445{ 7446 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7447 vgaHWPtr hwp = VGAHWPTR(pScrn); 7448 unsigned char dacmask; 7449 unsigned char dacdata[3]; 7450 unsigned char xr1, xr2; 7451 int type = 2; /* no monitor */ 7452 unsigned char IOSS=0, MSS=0, tmpfr02=0, tmpfr01a=0, tmpfr01b=0; 7453 7454 /* Dual channel display, enable both pipelines */ 7455 if (cPtr->Flags & ChipsDualChannelSupport) { 7456 IOSS = cPtr->readIOSS(cPtr); 7457 MSS = cPtr->readMSS(cPtr); 7458 tmpfr02 = cPtr->readFR(cPtr,0x02); 7459 cPtr->writeFR(cPtr, 0x02, (tmpfr02 & 0xCF)); /* CRT/FP off */ 7460 usleep(1000); 7461 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_A)); 7462 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_A)); 7463 tmpfr01a = cPtr->readFR(cPtr,0x01); 7464 if ((tmpfr01a & 0x3) != 0x01) 7465 cPtr->writeFR(cPtr, 0x01, ((tmpfr01a & 0xFC) | 0x1)); 7466 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_B)); 7467 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_B)); 7468 tmpfr01b = cPtr->readFR(cPtr,0x01); 7469 if ((tmpfr01b & 0x3) != 0x01) 7470 cPtr->writeFR(cPtr, 0x01, ((tmpfr01b & 0xFC) | 0x1)); 7471 cPtr->writeIOSS(cPtr, IOSS); 7472 cPtr->writeMSS(cPtr, hwp, MSS); 7473 cPtr->writeFR(cPtr, 0x02, (tmpfr02 & 0xCF) | 0x10); /* CRT on/FP off*/ 7474 } 7475 7476 dacmask = hwp->readDacMask(hwp); /* save registers */ 7477 hwp->writeDacMask(hwp, 0x00); 7478 hwp->writeDacReadAddr(hwp, 0x00); 7479 7480 dacdata[0]=hwp->readDacData(hwp); 7481 dacdata[1]=hwp->readDacData(hwp); 7482 dacdata[2]=hwp->readDacData(hwp); 7483 7484 if (!IS_HiQV(cPtr)) { 7485 xr1 = cPtr->readXR(cPtr, 0x06); 7486 xr2 = cPtr->readXR(cPtr, 0x1F); 7487 cPtr->writeXR(cPtr, 0x06, xr1 & 0xF1); /* turn on dac */ 7488 cPtr->writeXR(cPtr, 0x1F, xr2 & 0x7F); /* enable comp */ 7489 } else { 7490 xr1 = cPtr->readXR(cPtr, 0x81); 7491 xr2 = cPtr->readXR(cPtr, 0xD0); 7492 cPtr->writeXR(cPtr, 0x81,(xr1 & 0xF0)); 7493 cPtr->writeXR(cPtr, 0xD0,(xr2 | 0x03)); 7494 } 7495 if (chipsTestDACComp(pScrn, 0x12,0x12,0x12)) { /* test patterns */ 7496 if (chipsTestDACComp(pScrn,0x14,0x14,0x14)) /* taken from */ 7497 if (!chipsTestDACComp(pScrn,0x2D,0x14,0x14)) /* BIOS */ 7498 if (!chipsTestDACComp(pScrn,0x14,0x2D,0x14)) 7499 if (!chipsTestDACComp(pScrn,0x14,0x14,0x2D)) 7500 if (!chipsTestDACComp(pScrn,0x2D,0x2D,0x2D)) 7501 type = 0; /* color monitor */ 7502 } else { 7503 if (chipsTestDACComp(pScrn,0x04,0x12,0x04)) 7504 if (!chipsTestDACComp(pScrn,0x1E,0x12,0x04)) 7505 if (!chipsTestDACComp(pScrn,0x04,0x2D,0x04)) 7506 if (!chipsTestDACComp(pScrn,0x1E,0x16,0x15)) 7507 if (chipsTestDACComp(pScrn,0x00,0x00,0x00)) 7508 type = 1; /* monochrome */ 7509 } 7510 7511 hwp->writeDacWriteAddr(hwp, 0x00); /* restore registers */ 7512 hwp->writeDacData(hwp, dacdata[0]); 7513 hwp->writeDacData(hwp, dacdata[1]); 7514 hwp->writeDacData(hwp, dacdata[2]); 7515 hwp->writeDacMask(hwp, dacmask); 7516 if (!IS_HiQV(cPtr)) { 7517 cPtr->writeXR(cPtr,0x06,xr1); 7518 cPtr->writeXR(cPtr,0x1F,xr2); 7519 } else { 7520 cPtr->writeXR(cPtr,0x81,xr1); 7521 cPtr->writeXR(cPtr,0xD0,xr2); 7522 } 7523 7524 if (cPtr->Flags & ChipsDualChannelSupport) { 7525 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_A)); 7526 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_A)); 7527 cPtr->writeFR(cPtr, 0x01, tmpfr01a); 7528 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_B)); 7529 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_B)); 7530 cPtr->writeFR(cPtr, 0x01, tmpfr01b); 7531 usleep(1000); 7532 cPtr->writeIOSS(cPtr, IOSS); 7533 cPtr->writeMSS(cPtr, hwp, MSS); 7534 cPtr->writeFR(cPtr, 0x02, tmpfr02); 7535 } 7536 7537 return type; 7538} 7539 7540static int 7541chipsSetMonitor(ScrnInfoPtr pScrn) 7542{ 7543 int tmp= chipsProbeMonitor(pScrn); 7544 7545 switch (tmp) { 7546 case 0: 7547 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Color monitor detected\n"); 7548 break; 7549 case 1: 7550 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Monochrome monitor detected\n"); 7551 break; 7552 default: 7553 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No monitor detected\n"); 7554 } 7555 return (tmp); 7556} 7557 7558static void 7559chipsSetPanelType(CHIPSPtr cPtr) 7560{ 7561 CARD8 tmp; 7562 7563 if (IS_HiQV(cPtr)) { 7564 if (cPtr->Chipset == CHIPS_CT69030) { 7565 tmp = cPtr->readFR(cPtr, 0x00); 7566 if (tmp & 0x20) { 7567 /* FR02: DISPLAY TYPE REGISTER */ 7568 /* FR02[4] = CRT, FR02[5] = FlatPanel */ 7569 tmp = cPtr->readFR(cPtr, 0x02); 7570 if (tmp & 0x10) 7571 cPtr->PanelType |= ChipsCRT; 7572 if (tmp & 0x20) 7573 cPtr->PanelType |= ChipsLCD | ChipsLCDProbed; 7574 } else { 7575 cPtr->PanelType |= ChipsCRT; 7576 } 7577 } else { 7578 /* test LCD */ 7579 /* FR01: DISPLAY TYPE REGISTER */ 7580 /* FR01[1:0]: Display Type, 01 = CRT, 10 = FlatPanel */ 7581 /* LCD */ 7582 tmp = cPtr->readFR(cPtr, 0x01); 7583 if ((tmp & 0x03) == 0x02) { 7584 cPtr->PanelType |= ChipsLCD | ChipsLCDProbed; 7585 } 7586 tmp = cPtr->readXR(cPtr,0xD0); 7587 if (tmp & 0x01) { 7588 cPtr->PanelType |= ChipsCRT; 7589 } 7590 } 7591 } else { 7592 tmp = cPtr->readXR(cPtr, 0x51); 7593 /* test LCD */ 7594 /* XR51: DISPLAY TYPE REGISTER */ 7595 /* XR51[2]: Display Type, 0 = CRT, 1 = FlatPanel */ 7596 if (tmp & 0x04) { 7597 cPtr->PanelType |= ChipsLCD | ChipsLCDProbed; 7598 } 7599 if ((cPtr->readXR(cPtr, 0x06)) & 0x02) { 7600 cPtr->PanelType |= ChipsCRT; 7601 } 7602 } 7603} 7604 7605static void 7606chipsBlockHandler ( 7607 int i, 7608 pointer blockData, 7609 pointer pTimeout, 7610 pointer pReadmask 7611){ 7612 ScreenPtr pScreen = screenInfo.screens[i]; 7613 ScrnInfoPtr pScrn = xf86Screens[i]; 7614 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7615 7616 pScreen->BlockHandler = cPtr->BlockHandler; 7617 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 7618 pScreen->BlockHandler = chipsBlockHandler; 7619 7620 if(cPtr->VideoTimerCallback) { 7621 UpdateCurrentTime(); 7622 (*cPtr->VideoTimerCallback)(pScrn, currentTime.milliseconds); 7623 } 7624} 7625