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