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