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