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