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