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