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