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 shareable. 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/* 1869 * XXX 1870 * this takes forever 1871 * do halfway modern monitors even support ddc1? 1872 */ 1873#if 0 1874 if (!ddc_done) 1875 chips_ddc1(pScrn); 1876#endif 1877 } 1878 1879 /*test STN / TFT */ 1880 tmp = cPtr->readFR(cPtr, 0x10); 1881 1882 /* XR51 or FR10: DISPLAY TYPE REGISTER */ 1883 /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */ 1884 /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */ 1885 switch (tmp & 0x3) { 1886 case 0: 1887 if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) { 1888 cPtr->PanelType |= ChipsSS; 1889 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n"); 1890 } else { 1891 cPtr->PanelType |= ChipsTFT; 1892 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n"); 1893 } 1894 break; 1895 case 2: 1896 cPtr->PanelType |= ChipsDS; 1897 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n"); 1898 case 3: 1899 cPtr->PanelType |= ChipsDD; 1900 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n"); 1901 break; 1902 default: 1903 break; 1904 } 1905 1906 chipsSetPanelType(cPtr); 1907 from = X_PROBED; 1908 { 1909 Bool fp_mode; 1910 if (xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_mode)) { 1911 if (fp_mode) { 1912 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode on\n"); 1913 cPtr->PanelType |= ChipsLCD; 1914 } else { 1915 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode off\n"); 1916 cPtr->PanelType = ~ChipsLCD; 1917 } 1918 from = X_CONFIG; 1919 } 1920 } 1921 if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT)) 1922 xf86DrvMsg(pScrn->scrnIndex, from, "LCD/CRT\n"); 1923 else if (cPtr->PanelType & ChipsLCD) 1924 xf86DrvMsg(pScrn->scrnIndex, from, "LCD\n"); 1925 else if (cPtr->PanelType & ChipsCRT) { 1926 xf86DrvMsg(pScrn->scrnIndex, from, "CRT\n"); 1927 /* monitor info */ 1928#if 1 1929 cPtr->Monitor = chipsSetMonitor(pScrn); 1930#endif 1931 } 1932 /* screen size */ 1933 /* 1934 * In LCD mode / dual mode we want to derive the timing values from 1935 * the ones preset by bios 1936 */ 1937 if (cPtr->PanelType & ChipsLCD) { 1938 1939 /* for 65550 we only need H/VDisplay values for screen size */ 1940 unsigned char fr25, tmp1; 1941#ifdef DEBUG 1942 unsigned char fr26; 1943 char tmp2; 1944#endif 1945 fr25 = cPtr->readFR(cPtr, 0x25); 1946 tmp = cPtr->readFR(cPtr, 0x20); 1947 Size->HDisplay = ((tmp + ((fr25 & 0x0F) << 8)) + 1) << 3; 1948 tmp = cPtr->readFR(cPtr, 0x30); 1949 tmp1 = cPtr->readFR(cPtr, 0x35); 1950 Size->VDisplay = ((tmp1 & 0x0F) << 8) + tmp + 1; 1951#ifdef DEBUG 1952 tmp = cPtr->readFR(cPtr, 0x21); 1953 Size->HRetraceStart = ((tmp + ((fr25 & 0xF0) << 4)) + 1) << 3; 1954 tmp1 = cPtr->readFR(cPtr, 0x22); 1955 tmp2 = (tmp1 & 0x1F) - (tmp & 0x3F); 1956 Size->HRetraceEnd = ((((tmp2 < 0) ? (tmp2 + 0x40) : tmp2) << 3) 1957 + Size->HRetraceStart); 1958 tmp = cPtr->readFR(cPtr, 0x23); 1959 fr26 = cPtr->readFR(cPtr, 0x26); 1960 Size->HTotal = ((tmp + ((fr26 & 0x0F) << 8)) + 5) << 3; 1961 xf86ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n", 1962 Size->HDisplay, Size->VDisplay, 1963 Size->HRetraceStart,Size->HRetraceEnd, 1964 Size->HTotal); 1965#endif 1966 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n", 1967 Size->HDisplay, Size->VDisplay); 1968 /* Warn the user if the panel size has been overridden by 1969 * the modeline values 1970 */ 1971 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 1972 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1973 "Display size overridden by modelines.\n"); 1974 } 1975 } 1976 1977 /* Frame Buffer */ /* for LCDs */ 1978 if (IS_STN(cPtr->PanelType)) { 1979 tmp = cPtr->readFR(cPtr, 0x1A); /*Frame Buffer Ctrl. */ 1980 if (tmp & 1) { 1981 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n"); 1982 if (!(tmp & 0x80)) { 1983 /* Formula for calculating the size of the framebuffer. 3 1984 * bits per pixel 10 pixels per 32 bit dword. If frame 1985 * acceleration is enabled the size can be halved. 1986 */ 1987 cPtr->FrameBufferSize = ( Size->HDisplay * 1988 Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2); 1989 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1990 "Using embedded Frame Buffer, size %d bytes\n", 1991 cPtr->FrameBufferSize); 1992 } else 1993 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1994 "Using external Frame Buffer used\n"); 1995 } 1996 if (tmp & 2) 1997 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1998 "Frame accelerator enabled\n"); 1999 } 2000 2001 /* bus type */ 2002 tmp = (cPtr->readXR(cPtr, 0x08)) & 1; 2003 if (tmp == 1) { /*PCI */ 2004 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n"); 2005 cPtr->Bus = ChipsPCI; 2006 } else { /* XR08: Linear addressing base, not for PCI */ 2007 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 2008 cPtr->Bus = ChipsVLB; 2009 } 2010 2011 /* disable acceleration for 1 and 4 bpp */ 2012 if (pScrn->bitsPerPixel < 8) { 2013 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2014 "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel); 2015 cPtr->Flags &= ~ChipsAccelSupport; 2016 } 2017 2018 /* Set the flags for Colour transparency. This is dependent 2019 * on the revision on the chip. Until exactly which chips 2020 * have this bug are found, only allow 8bpp Colour transparency */ 2021 if ((pScrn->bitsPerPixel == 8) || ((cPtr->Chipset >= CHIPS_CT65555) && 2022 (pScrn->bitsPerPixel >= 8) && (pScrn->bitsPerPixel <= 24))) 2023 cPtr->Flags |= ChipsColorTransparency; 2024 else 2025 cPtr->Flags &= ~ChipsColorTransparency; 2026 2027 /* DAC info */ 2028 if (!((cPtr->readXR(cPtr, 0xD0)) & 0x01)) 2029 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n"); 2030 2031 /* MMIO address offset */ 2032 cPtr->Regs32 = ChipsReg32HiQV; 2033 2034 /* sync reset ignored on this chipset */ 2035 cPtr->SyncResetIgn = TRUE; /* !! */ 2036 2037 /* We use a programmable clock */ 2038 pScrn->numClocks = 26; /* Some number */ 2039 pScrn->progClock = TRUE; 2040 cPtr->ClockType = HiQV_STYLE | TYPE_PROGRAMMABLE; 2041 2042 SaveClk->Clock = 0; 2043 2044 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n"); 2045 2046 /* Set the maximum memory clock. */ 2047 switch (cPtr->Chipset) { 2048 case CHIPS_CT65550: 2049 if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6) 2050 MemClk->Max = 38000; /* Revision A chips */ 2051 else 2052 MemClk->Max = 50000; /* Revision B chips */ 2053 break; 2054 case CHIPS_CT65554: 2055 case CHIPS_CT65555: 2056 case CHIPS_CT68554: 2057 MemClk->Max = 55000; 2058 break; 2059 case CHIPS_CT69000: 2060 MemClk->Max = 83000; 2061 break; 2062 case CHIPS_CT69030: 2063 MemClk->Max = 100000; 2064 break; 2065 } 2066 2067 /* Probe the dot clocks */ 2068 for (i = 0; i < 3; i++) { 2069 unsigned int N,M,PSN,P,VCO_D; 2070 int offset = i * 4; 2071 2072 tmp = cPtr->readXR(cPtr,0xC2 + offset); 2073 M = (cPtr->readXR(cPtr, 0xC0 + offset) 2074 | (tmp & 0x03)) + 2; 2075 N = (cPtr->readXR(cPtr, 0xC1 + offset) 2076 | (( tmp >> 4) & 0x03)) + 2; 2077 tmp = cPtr->readXR(cPtr, 0xC3 + offset); 2078 PSN = (cPtr->Chipset == CHIPS_CT69000 || cPtr->Chipset == CHIPS_CT69030) 2079 ? 1 : (((tmp & 0x1) ? 1 : 4) * ((tmp & 0x02) ? 5 : 1)); 2080 VCO_D = ((tmp & 0x04) ? ((cPtr->Chipset == CHIPS_CT69000 || 2081 cPtr->Chipset == CHIPS_CT69030) ? 1 : 16) : 4); 2082 P = ((tmp & 0x70) >> 4); 2083 Probed[i] = VCO_D * Fref / N; 2084 Probed[i] = Probed[i] * M / (PSN * (1 << P)); 2085 Probed[i] = Probed[i] / 1000; 2086 } 2087 CRTclkI = (hwp->readMiscOut(hwp) >> 2) & 0x03; 2088 if (CRTclkI == 3) CRTclkI = 2; 2089 if (cPtr->Chipset == CHIPS_CT69030) 2090 FPclkI = (cPtr->readFR(cPtr, 0x01) >> 2) & 0x3; 2091 else 2092 FPclkI = (cPtr->readFR(cPtr, 0x03) >> 2) & 0x3; 2093 if (FPclkI == 3) FPclkI = 2; 2094 for (i = 0; i < 3; i++) { 2095 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2096 "Dot clock %i: %7.3f MHz",i, 2097 (float)(Probed[i])/1000.); 2098 if (FPclkI == i) xf86ErrorF(" FPclk"); 2099 if (CRTclkI == i) xf86ErrorF(" CRTclk"); 2100 xf86ErrorF("\n"); 2101 } 2102 cPtr->FPclock = Probed[FPclkI]; 2103 cPtr->FPclkInx = FPclkI; 2104 if (CRTclkI == FPclkI) { 2105 if (FPclkI == 2) 2106 CRTclkI = 1; 2107 else 2108 CRTclkI = 2; 2109 } 2110 cPtr->CRTclkInx = CRTclkI; 2111 2112 2113 /* 2114 * Some chips seem to dislike some clocks in one of the PLL's. Give 2115 * the user the opportunity to change it 2116 */ 2117 if (xf86GetOptValInteger(cPtr->Options, OPTION_CRT_CLK_INDX, &indx)) { 2118 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Force CRT Clock index to %d\n", 2119 indx); 2120 cPtr->CRTclkInx = indx; 2121 2122 if (xf86GetOptValInteger(cPtr->Options, OPTION_FP_CLK_INDX, &indx)) { 2123 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2124 "Force FP Clock index to %d\n", indx); 2125 cPtr->FPclkInx = indx; 2126 } else { 2127 if (indx == cPtr->FPclkInx) { 2128 if (indx == 2) 2129 cPtr->FPclkInx = 1; 2130 else 2131 cPtr->FPclkInx = indx + 1; 2132 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2133 "FP Clock index forced to %d\n", cPtr->FPclkInx); 2134 } 2135 } 2136 } else if (xf86GetOptValInteger(cPtr->Options, OPTION_FP_CLK_INDX, 2137 &indx)) { 2138 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2139 "Force FP Clock index to %d\n", indx); 2140 cPtr->FPclkInx = indx; 2141 if (indx == cPtr->CRTclkInx) { 2142 if (indx == 2) 2143 cPtr->CRTclkInx = 1; 2144 else 2145 cPtr->CRTclkInx = indx + 1; 2146 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2147 "CRT Clock index forced to %d\n", cPtr->CRTclkInx); 2148 } 2149 } 2150 2151 2152 /* Probe the memory clock currently in use */ 2153 MemClk->xrCC = cPtr->readXR(cPtr, 0xCC); 2154 MemClk->M = (MemClk->xrCC & 0x7F) + 2; 2155 MemClk->xrCD = cPtr->readXR(cPtr, 0xCD); 2156 MemClk->N = (MemClk->xrCD & 0x7F) + 2; 2157 MemClk->xrCE = cPtr->readXR(cPtr, 0xCE); 2158 MemClk->PSN = (MemClk->xrCE & 0x1) ? 1 : 4; 2159 MemClk->P = ((MemClk->xrCE & 0x70) >> 4); 2160 /* Be careful with the calculation of ProbeClk as it can overflow */ 2161 MemClk->ProbedClk = 4 * Fref / MemClk->N; 2162 MemClk->ProbedClk = MemClk->ProbedClk * MemClk->M / (MemClk->PSN * 2163 (1 << MemClk->P)); 2164 MemClk->ProbedClk = MemClk->ProbedClk / 1000; 2165 MemClk->Clk = MemClk->ProbedClk; 2166 2167 if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) { 2168 int mclk = (int)(real * 1000.0); 2169 if (mclk <= MemClk->Max) { 2170 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2171 "Using memory clock of %7.3f MHz\n", 2172 (float)(mclk/1000.)); 2173 2174 /* Only alter the memory clock if the desired memory clock differs 2175 * by 50kHz from the one currently being used. 2176 */ 2177 if ((mclk - MemClk->ProbedClk) > 50U) { 2178 unsigned char vclk[3]; 2179 2180 MemClk->Clk = mclk; 2181 chipsCalcClock(pScrn, MemClk->Clk, vclk); 2182 MemClk->M = vclk[1] + 2; 2183 MemClk->N = vclk[2] + 2; 2184 MemClk->P = (vclk[0] & 0x70) >> 4; 2185 MemClk->PSN = (vclk[0] & 0x1) ? 1 : 4; 2186 MemClk->xrCC = vclk[1]; 2187 MemClk->xrCD = vclk[2]; 2188 MemClk->xrCE = 0x80 || vclk[0]; 2189 } 2190 } else 2191 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2192 "Memory clock of %7.3f MHz exceeds limit of %7.3f MHz\n", 2193 (float)(mclk/1000.), 2194 (float)(MemClk->Max/1000.)); 2195 } else 2196 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2197 "Probed memory clock of %7.3f MHz\n", 2198 (float)(MemClk->ProbedClk/1000.)); 2199 2200 cPtr->ClockMulFactor = 1; 2201 2202 /* Set the min/max pixel clock */ 2203 switch (cPtr->Chipset) { 2204 case CHIPS_CT69030: 2205 cPtr->MinClock = 3000; 2206 cPtr->MaxClock = 170000; 2207 break; 2208 case CHIPS_CT69000: 2209 cPtr->MinClock = 3000; 2210 cPtr->MaxClock = 135000; 2211 break; 2212 case CHIPS_CT68554: 2213 case CHIPS_CT65555: 2214 cPtr->MinClock = 1000; 2215 cPtr->MaxClock = 110000; 2216 break; 2217 case CHIPS_CT65554: 2218 cPtr->MinClock = 1000; 2219 cPtr->MaxClock = 95000; 2220 break; 2221 case CHIPS_CT65550: 2222 cPtr->MinClock = 1000; 2223 if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6) { 2224 if ((cPtr->readFR(cPtr, 0x0A)) & 2) { 2225 /*5V Vcc */ 2226 cPtr->MaxClock = 100000; 2227 } else { 2228 /*3.3V Vcc */ 2229 cPtr->MaxClock = 80000; 2230 } 2231 } else 2232 cPtr->MaxClock = 95000; /* Revision B */ 2233 break; 2234 } 2235 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n", 2236 (float)(cPtr->MinClock / 1000.)); 2237 2238 /* Check if maxClock is limited by the MemClk. Only 70% to allow for */ 2239 /* RAS/CAS. Extra byte per memory clock needed if framebuffer used */ 2240 /* Extra byte if the overlay plane is activated */ 2241 /* If flag Chips64BitMemory is set assume a 64bitmemory interface, */ 2242 /* and 32bits on the others. Thus multiply by a suitable factor */ 2243 if (cPtr->Flags & Chips64BitMemory) { 2244 if (cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) 2245 cPtr->MaxClock = min(cPtr->MaxClock, 2246 MemClk->Clk * 8 * 0.7 / (bytesPerPixel + 1)); 2247 else 2248 cPtr->MaxClock = min(cPtr->MaxClock, 2249 MemClk->Clk * 8 * 0.7 / bytesPerPixel); 2250 } else { 2251 if (cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) 2252 cPtr->MaxClock = min(cPtr->MaxClock, 2253 MemClk->Clk * 4 * 0.7 / (bytesPerPixel + 1)); 2254 else 2255 cPtr->MaxClock = min(cPtr->MaxClock, 2256 MemClk->Clk * 4 * 0.7 / bytesPerPixel); 2257 } 2258 2259 2260 2261 if (cPtr->pEnt->device->dacSpeeds[0]) { 2262 int speed = 0; 2263 switch (pScrn->bitsPerPixel) { 2264 case 1: 2265 case 4: 2266 case 8: 2267 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8]; 2268 break; 2269 case 16: 2270 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16]; 2271 break; 2272 case 24: 2273 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24]; 2274 break; 2275 case 32: 2276 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP32]; 2277 break; 2278 } 2279 2280 if (speed == 0) 2281 speed = cPtr->pEnt->device->dacSpeeds[0]; 2282 from = X_CONFIG; 2283 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2284 "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n", 2285 (float)(speed / 1000.), (float)(cPtr->MaxClock / 1000.)); 2286 cPtr->MaxClock = speed; 2287 } else { 2288 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2289 "Max pixel clock is %7.3f MHz\n", 2290 (float)(cPtr->MaxClock / 1000.)); 2291 } 2292 /* 2293 * Prepare the FPclock: 2294 * if FPclock <= MaxClock : don't modify the FP clock. 2295 * else set FPclock to 90% of MaxClock. 2296 */ 2297 real = 0.; 2298 switch(bytesPerPixel) { 2299 case 1: 2300 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8, OPTUNITS_MHZ, &real)) 2301 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2302 "FP clock %7.3f MHz requested\n",real); 2303 break; 2304 case 2: 2305 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16, OPTUNITS_MHZ, &real)) 2306 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2307 "FP clock %7.3f MHz requested\n",real); 2308 break; 2309 case 3: 2310 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24, OPTUNITS_MHZ, &real)) 2311 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2312 "FP clock %7.3f MHz requested\n",real); 2313 break; 2314 case 4: 2315 if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_32, OPTUNITS_MHZ, &real)) 2316 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2317 "FP clock %7.3f MHz requested\n",real); 2318 break; 2319 } 2320 val = (int) (real * 1000.); 2321 if (val && val >= cPtr->MinClock && val <= cPtr->MaxClock) 2322 cPtr->FPclock = val; 2323 else if (cPtr->FPclock > cPtr->MaxClock) 2324 cPtr->FPclock = (int)((float)cPtr->MaxClock * 0.9); 2325 else 2326 cPtr->FPclock = 0; /* special value */ 2327 cPtr->FPClkModified = FALSE; 2328 if (cPtr->FPclock) 2329 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2330 "FP clock set to %7.3f MHz\n", 2331 (float)(cPtr->FPclock / 1000.)); 2332 2333#if defined(__arm__) && defined(__NetBSD__) 2334 ChipsPALMode.next = pScrn->monitor->Modes; 2335 pScrn->monitor->Modes = &ChipsNTSCMode; 2336#endif 2337 2338 2339 if (cPtr->Flags & ChipsDualChannelSupport) { 2340 if (xf86IsEntityShared(pScrn->entityList[0])) { 2341 if (cPtr->SecondCrtc == TRUE) { 2342 cPtrEnt->slaveActive = FALSE; 2343 } else { 2344 cPtrEnt->masterActive = FALSE; 2345 } 2346 } 2347 /* Put IOSS/MSS back to normal */ 2348 cPtr->writeIOSS(cPtr, cPtr->storeIOSS); 2349 cPtr->writeMSS(cPtr, hwp, cPtr->storeMSS); 2350 2351 xf86SetPrimInitDone(pScrn->entityList[0]); 2352 } 2353 2354 return TRUE; 2355} 2356 2357static Bool 2358chipsPreInitWingine(ScrnInfoPtr pScrn, int flags) 2359{ 2360 int i, bytesPerPixel, NoClocks = 0; 2361 unsigned char tmp; 2362 MessageType from; 2363 vgaHWPtr hwp; 2364 CHIPSPtr cPtr = CHIPSPTR(pScrn); 2365 CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock); 2366 Bool useLinear = FALSE; 2367 const char *s; 2368#ifndef XSERVER_LIBPCIACCESS 2369 resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END }; 2370#endif 2371 2372 /* Set pScrn->monitor */ 2373 pScrn->monitor = pScrn->confScreen->monitor; 2374 2375 if (cPtr->Flags & ChipsHDepthSupport) 2376 i = xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | 2377 SupportConvert32to24 | PreferConvert32to24); 2378 else 2379 i = xf86SetDepthBpp(pScrn, 8, 0, 0, NoDepth24Support); 2380 2381 if (!i) 2382 return FALSE; 2383 else { 2384 /* Check that the returned depth is one we support */ 2385 switch (pScrn->depth) { 2386 case 1: 2387 case 4: 2388 case 8: 2389 /* OK */ 2390 break; 2391 case 15: 2392 case 16: 2393 case 24: 2394 if (cPtr->Flags & ChipsHDepthSupport) 2395 break; /* OK */ 2396 /* fall through */ 2397 default: 2398 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2399 "Given depth (%d) is not supported by this driver\n", 2400 pScrn->depth); 2401 return FALSE; 2402 } 2403 } 2404 2405 xf86PrintDepthBpp(pScrn); 2406 2407 /* Get the depth24 pixmap format */ 2408 if (pScrn->depth == 24 && pix24bpp == 0) 2409 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 2410 2411 /* 2412 * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp 2413 */ 2414 if (!vgaHWGetHWRec(pScrn)) 2415 return FALSE; 2416 2417 hwp = VGAHWPTR(pScrn); 2418 vgaHWSetStdFuncs(hwp); 2419 vgaHWGetIOBase(hwp); 2420 2421 /* 2422 * This must happen after pScrn->display has been set because 2423 * xf86SetWeight references it. 2424 */ 2425 if (pScrn->depth > 8) { 2426 /* The defaults are OK for us */ 2427 rgb zeros = {0, 0, 0}; 2428 2429 if (!xf86SetWeight(pScrn, zeros, zeros)) { 2430 return FALSE; 2431 } else { 2432 /* XXX check that weight returned is supported */ 2433 ; 2434 } 2435 } 2436 2437 if (!xf86SetDefaultVisual(pScrn, -1)) 2438 return FALSE; 2439 2440 /* The gamma fields must be initialised when using the new cmap code */ 2441 if (pScrn->depth > 1) { 2442 Gamma zeros = {0.0, 0.0, 0.0}; 2443 2444 if (!xf86SetGamma(pScrn, zeros)) 2445 return FALSE; 2446 } 2447 2448 /* Store register values that might be messed up by a suspend resume */ 2449 /* Do this early as some of the other code in PreInit relies on it */ 2450 cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18; 2451 cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A; 2452 cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20; 2453 cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15); 2454 2455 cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01); 2456 cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ? 2457 0x3D0 : 0x3B0); 2458 2459 bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3); 2460 2461 /* Collect all of the relevant option flags (fill in pScrn->options) */ 2462 xf86CollectOptions(pScrn, NULL); 2463 2464 /* Process the options */ 2465 if (!(cPtr->Options = malloc(sizeof(ChipsWingineOptions)))) 2466 return FALSE; 2467 memcpy(cPtr->Options, ChipsWingineOptions, sizeof(ChipsWingineOptions)); 2468 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options); 2469 2470 /* Set the bits per RGB */ 2471 if (pScrn->depth > 1) { 2472 /* Default to 6, is this right?? */ 2473 pScrn->rgbBits = 6; 2474#if 0 2475 if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS, 2476 &pScrn->rgbBits)) { 2477 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", 2478 pScrn->rgbBits); 2479 } 2480#endif 2481 } 2482 if ((cPtr->Flags & ChipsAccelSupport) && 2483 (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) { 2484 cPtr->Flags &= ~ChipsAccelSupport; 2485 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 2486 } 2487 2488 from = X_DEFAULT; 2489 if (pScrn->bitsPerPixel < 8) { 2490 /* Default to SW cursor for 1/4 bpp */ 2491 cPtr->Accel.UseHWCursor = FALSE; 2492 } else { 2493 cPtr->Accel.UseHWCursor = TRUE; 2494 } 2495 if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR, 2496 &cPtr->Accel.UseHWCursor)) 2497 from = X_CONFIG; 2498 if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR, 2499 &cPtr->Accel.UseHWCursor)) { 2500 from = X_CONFIG; 2501 cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor; 2502 } 2503 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 2504 (cPtr->Accel.UseHWCursor) ? "HW" : "SW"); 2505 2506 /* memory size */ 2507 if (cPtr->pEnt->device->videoRam != 0) { 2508 pScrn->videoRam = cPtr->pEnt->device->videoRam; 2509 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n", 2510 pScrn->videoRam); 2511 } else { 2512 /* not given, probe it */ 2513 /* XR0F: Software flags 0 */ 2514 /* bit 1-0: memory size */ 2515 /* 0: 256 kB */ 2516 /* 1: 512 kB */ 2517 /* 2: 1024 kB */ 2518 /* 3: 1024 kB */ 2519 2520 switch ((cPtr->readXR(cPtr, 0x0F)) & 3) { 2521 case 0: 2522 pScrn->videoRam = 256; 2523 break; 2524 case 1: 2525 pScrn->videoRam = 512; 2526 break; 2527 case 2: 2528 pScrn->videoRam = 1024; 2529 break; 2530 case 3: 2531 pScrn->videoRam = 2048; 2532 break; 2533 } 2534 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n", 2535 pScrn->videoRam); 2536 } 2537 cPtr->FbMapSize = pScrn->videoRam * 1024; 2538 2539 /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */ 2540 if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE; 2541 if (pScrn->bitsPerPixel < 8) { 2542 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) { 2543 useLinear = FALSE; 2544 from = X_CONFIG; 2545 } 2546 } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) { 2547 useLinear = FALSE; 2548 from = X_CONFIG; 2549 } 2550 2551#ifndef HAVE_ISA 2552 if (!(cPtr->Flags & ChipsLinearSupport)) { 2553 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Linear framebuffer required\n"); 2554 return FALSE; 2555 } 2556#endif 2557 2558 /* linear base */ 2559 if (useLinear) { 2560 unsigned char mask = 0xF8; 2561 if (pScrn->videoRam == 1024) 2562 mask = 0xF0; 2563 else if (pScrn->videoRam == 2048) 2564 mask = 0xE0; 2565 if (cPtr->pEnt->device->MemBase) { 2566 cPtr->FbAddress = cPtr->pEnt->device->MemBase 2567 & ((0xFF << 24) | (mask << 16)); 2568 from = X_CONFIG; 2569 } else { 2570 cPtr->FbAddress = ((0xFF & (cPtr->readXR(cPtr, 0x09))) << 24); 2571 cPtr->FbAddress |= ((mask & (cPtr->readXR(cPtr, 0x08))) << 16); 2572 from = X_PROBED; 2573 } 2574#ifndef XSERVER_LIBPCIACCESS 2575 linearRes[0].rBegin = cPtr->FbAddress; 2576 linearRes[0].rEnd = cPtr->FbAddress + 0x800000; 2577 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 2578 useLinear = FALSE; 2579 from = X_PROBED; 2580 } 2581#endif 2582 } 2583 2584 if (useLinear) { 2585 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2586 "Enabling linear addressing\n"); 2587 xf86DrvMsg(pScrn->scrnIndex, from, 2588 "base address is set at 0x%lX.\n", cPtr->FbAddress); 2589 if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) && 2590 (cPtr->Flags & ChipsMMIOSupport)) { 2591 cPtr->UseMMIO = TRUE; 2592 cPtr->IOAddress = cPtr->FbAddress + 0x200000L; 2593 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n"); 2594 } 2595 } else { 2596 if (cPtr->Flags & ChipsLinearSupport) 2597 xf86DrvMsg(pScrn->scrnIndex, from, 2598 "Disabling linear addressing\n"); 2599 cPtr->Flags &= ~ChipsLinearSupport; 2600 } 2601 2602 if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE)) 2603 || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) { 2604 if (!(cPtr->Flags & ChipsLinearSupport)) { 2605 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2606 "Option \"ShadowFB\" ignored. Not supported without linear addressing\n"); 2607 } else if (pScrn->depth < 8) { 2608 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2609 "Option \"ShadowFB\" ignored. Not supported at this depth.\n"); 2610 } else { 2611 cPtr->Rotate = 0; 2612 if (s) { 2613 if(!xf86NameCmp(s, "CW")) { 2614 /* accel is disabled below for shadowFB */ 2615 cPtr->Flags |= ChipsShadowFB; 2616 cPtr->Rotate = 1; 2617 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2618 "Rotating screen clockwise\n"); 2619 } else if(!xf86NameCmp(s, "CCW")) { 2620 cPtr->Flags |= ChipsShadowFB; 2621 cPtr->Rotate = -1; 2622 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 2623 "counter clockwise\n"); 2624 } else { 2625 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 2626 "value for Option \"Rotate\"\n", s); 2627 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2628 "Valid options are \"CW\" or \"CCW\"\n"); 2629 } 2630 } else { 2631 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2632 "Using \"Shadow Framebuffer\"\n"); 2633 cPtr->Flags |= ChipsShadowFB; 2634 } 2635 } 2636 } 2637 if (cPtr->Flags & ChipsShadowFB) { 2638 if (cPtr->Flags & ChipsAccelSupport) { 2639 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2640 "HW acceleration is not supported with shadow fb\n"); 2641 cPtr->Flags &= ~ChipsAccelSupport; 2642 } 2643 if (cPtr->Rotate && cPtr->Accel.UseHWCursor) { 2644 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2645 "HW cursor is not supported with rotate\n"); 2646 cPtr->Accel.UseHWCursor = FALSE; 2647 } 2648 } 2649 2650 cPtr->PanelType |= ChipsCRT; 2651 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT\n"); 2652 2653 /* monitor info */ 2654 cPtr->Monitor = chipsSetMonitor(pScrn); 2655 2656 /* bus type */ 2657 tmp = cPtr->readXR(cPtr, 0x01) & 3; 2658 switch (tmp) { 2659 case 0: 2660 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n"); 2661 cPtr->Bus = ChipsISA; 2662 break; 2663 case 3: 2664 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 2665 cPtr->Bus = ChipsVLB; 2666 break; 2667 default: 2668 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n"); 2669 cPtr->Bus = ChipsUnknown; 2670 break; 2671 } 2672 2673 /* disable acceleration for 1 and 4 bpp */ 2674 if (pScrn->bitsPerPixel < 8) { 2675 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2676 "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel); 2677 cPtr->Flags &= ~ChipsAccelSupport; 2678 } 2679 2680 /* 32bit register address offsets */ 2681 if ((cPtr->Flags & ChipsAccelSupport) || 2682 (cPtr->Accel.UseHWCursor)) { 2683 cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32)); 2684 tmp = cPtr->readXR(cPtr, 0x07); 2685 for( i = 0; i < (sizeof(ChipsReg32) / sizeof(ChipsReg32[0])); i++) { 2686 cPtr->Regs32[i] = ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80) 2687 << 8)| ((tmp & 0x7F) << 2); 2688#ifdef DEBUG 2689 ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]); 2690#endif 2691 } 2692#ifndef XSERVER_LIBPCIACCESS 2693 linearRes[0].type = ResExcIoSparse | ResBios | ResBus; 2694 linearRes[0].rBase = cPtr->Regs32[0]; 2695 linearRes[0].rMask = 0x83FC; 2696 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 2697 if (cPtr->Flags & ChipsAccelSupport) { 2698 cPtr->Flags &= ~ChipsAccelSupport; 2699 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2700 "Cannot allocate IO registers: " 2701 "Disabling acceleration\n"); 2702 } 2703 if (cPtr->Accel.UseHWCursor) { 2704 cPtr->Accel.UseHWCursor = FALSE; 2705 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2706 "Cannot allocate IO registers: " 2707 "Disabling HWCursor\n"); 2708 } 2709 } 2710#endif 2711 } 2712 2713 cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1); 2714 if (cPtr->ClockMulFactor != 1) 2715 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2716 "Clocks scaled by %d\n", cPtr->ClockMulFactor); 2717 2718 /* Clock type */ 2719 switch (cPtr->Chipset) { 2720 case CHIPS_CT64200: 2721 NoClocks = 4; 2722 cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW; 2723 break; 2724 default: 2725 if (!((cPtr->readXR(cPtr, 0x01)) & 0x10)) { 2726 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2727 "Using external clock generator\n"); 2728 NoClocks = 4; 2729 cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW; 2730 } else { 2731 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2732 "Using internal clock generator\n"); 2733 if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) { 2734 NoClocks = 3; 2735 cPtr->ClockType = WINGINE_2_STYLE | TYPE_HW; 2736 } else { 2737 NoClocks = 26; /* some number */ 2738 cPtr->ClockType = WINGINE_2_STYLE | TYPE_PROGRAMMABLE; 2739 pScrn->progClock = TRUE; 2740 } 2741 } 2742 } 2743 2744 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 2745 pScrn->numClocks = NoClocks; 2746 SaveClk->Clock = CRT_TEXT_CLK_FREQ; 2747 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n"); 2748 } else { /* TYPE_PROGRAMMABLE */ 2749 SaveClk->Clock = chipsGetHWClock(pScrn); 2750 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n", 2751 SaveClk->Clock); 2752 if (!cPtr->pEnt->device->numclocks) { 2753 pScrn->numClocks = NoClocks; 2754 xf86GetClocks(pScrn, NoClocks, chipsClockSelect, 2755 chipsProtect, chipsBlankScreen, 2756 cPtr->IOBase + 0x0A, 0x08, 1, 28322); 2757 from = X_PROBED; 2758 } else { 2759 pScrn->numClocks = cPtr->pEnt->device->numclocks; 2760 if (pScrn->numClocks > NoClocks) { 2761 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2762 "Too many Clocks specified in configuration file.\n"); 2763 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2764 "\t\tAt most %d clocks may be specified\n", NoClocks); 2765 pScrn->numClocks= NoClocks; 2766 } 2767 for (i = 0; i < pScrn->numClocks; i++) 2768 pScrn->clock[i] = cPtr->pEnt->device->clock[i]; 2769 from = X_CONFIG; 2770 } 2771 xf86ShowClocks(pScrn, from); 2772 } 2773 2774 /* Set the min pixel clock */ 2775 /* XXX Guess, need to check this */ 2776 cPtr->MinClock = 11000 / cPtr->ClockMulFactor; 2777 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n", 2778 (float)(cPtr->MinClock / 1000.)); 2779 /* maximal clock */ 2780 switch (cPtr->Chipset) { 2781 case CHIPS_CT64200: 2782 cPtr->MaxClock = 80000 / cPtr->ClockMulFactor; 2783 break; 2784 case CHIPS_CT64300: 2785 cPtr->MaxClock = 85000 / cPtr->ClockMulFactor; 2786 break; 2787 } 2788 2789 if (cPtr->pEnt->device->dacSpeeds[0]) { 2790 int speed = 0; 2791 switch (pScrn->bitsPerPixel) { 2792 case 1: 2793 case 4: 2794 case 8: 2795 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8]; 2796 break; 2797 case 16: 2798 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16]; 2799 break; 2800 case 24: 2801 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24]; 2802 break; 2803 } 2804 if (speed == 0) 2805 cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0]; 2806 from = X_CONFIG; 2807 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2808 "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n", 2809 (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.)); 2810 cPtr->MaxClock = speed; 2811 } else { 2812 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2813 "Max pixel clock is %7.3f MHz\n", 2814 (float)(cPtr->MaxClock / 1000.)); 2815 } 2816 2817 if (xf86LoadSubModule(pScrn, "ddc")) { 2818 if (cPtr->pVbe) 2819 xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(cPtr->pVbe, NULL))); 2820 } 2821 return TRUE; 2822} 2823 2824static Bool 2825chipsPreInit655xx(ScrnInfoPtr pScrn, int flags) 2826{ 2827 int i, bytesPerPixel, NoClocks = 0; 2828 unsigned char tmp; 2829 MessageType from; 2830 vgaHWPtr hwp; 2831 CHIPSPtr cPtr = CHIPSPTR(pScrn); 2832 CHIPSPanelSizePtr Size = &cPtr->PanelSize; 2833 CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock); 2834 Bool useLinear = FALSE; 2835 const char *s; 2836#ifndef XSERVER_LIBPCIACCESS 2837 resRange linearRes[] = { {ResExcMemBlock|ResBios|ResBus,0,0},_END }; 2838#endif 2839 2840 /* Set pScrn->monitor */ 2841 pScrn->monitor = pScrn->confScreen->monitor; 2842 2843 if (cPtr->Flags & ChipsHDepthSupport) 2844 i = xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | 2845 SupportConvert32to24 | PreferConvert32to24); 2846 else 2847 i = xf86SetDepthBpp(pScrn, 8, 0, 0, NoDepth24Support); 2848 2849 if (!i) 2850 return FALSE; 2851 else { 2852 /* Check that the returned depth is one we support */ 2853 switch (pScrn->depth) { 2854 case 1: 2855 case 4: 2856 case 8: 2857 /* OK */ 2858 break; 2859 case 15: 2860 case 16: 2861 case 24: 2862 if (cPtr->Flags & ChipsHDepthSupport) 2863 break; /* OK */ 2864 /* fall through */ 2865 default: 2866 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2867 "Given depth (%d) is not supported by this driver\n", 2868 pScrn->depth); 2869 return FALSE; 2870 } 2871 } 2872 xf86PrintDepthBpp(pScrn); 2873 2874 /* Get the depth24 pixmap format */ 2875 if (pScrn->depth == 24 && pix24bpp == 0) 2876 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 2877 2878 /* 2879 * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp 2880 */ 2881 if (!vgaHWGetHWRec(pScrn)) 2882 return FALSE; 2883 2884 hwp = VGAHWPTR(pScrn); 2885 vgaHWSetStdFuncs(hwp); 2886 vgaHWGetIOBase(hwp); 2887 2888 /* 2889 * This must happen after pScrn->display has been set because 2890 * xf86SetWeight references it. 2891 */ 2892 if (pScrn->depth > 8) { 2893 /* The defaults are OK for us */ 2894 rgb zeros = {0, 0, 0}; 2895 2896 if (!xf86SetWeight(pScrn, zeros, zeros)) { 2897 return FALSE; 2898 } else { 2899 /* XXX check that weight returned is supported */ 2900 ; 2901 } 2902 } 2903 2904 if (!xf86SetDefaultVisual(pScrn, -1)) 2905 return FALSE; 2906 2907 /* The gamma fields must be initialised when using the new cmap code */ 2908 if (pScrn->depth > 1) { 2909 Gamma zeros = {0.0, 0.0, 0.0}; 2910 2911 if (!xf86SetGamma(pScrn, zeros)) 2912 return FALSE; 2913 } 2914 2915 /* Store register values that might be messed up by a suspend resume */ 2916 /* Do this early as some of the other code in PreInit relies on it */ 2917 cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18; 2918 cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A; 2919 cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20; 2920 cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15); 2921 2922 cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01); 2923 cPtr->IOBase = cPtr->SuspendHack.vgaIOBaseFlag ? 0x3D0 : 0x3B0; 2924 2925 bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3); 2926 2927 /* Collect all of the relevant option flags (fill in pScrn->options) */ 2928 xf86CollectOptions(pScrn, NULL); 2929 2930 /* Process the options */ 2931 if (!(cPtr->Options = malloc(sizeof(Chips655xxOptions)))) 2932 return FALSE; 2933 memcpy(cPtr->Options, Chips655xxOptions, sizeof(Chips655xxOptions)); 2934 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options); 2935 2936 /* Set the bits per RGB */ 2937 if (pScrn->depth > 1) { 2938 /* Default to 6, is this right */ 2939 pScrn->rgbBits = 6; 2940#if 0 2941 if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS, 2942 &pScrn->rgbBits)) { 2943 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", 2944 pScrn->rgbBits); 2945 } 2946#endif 2947 } 2948 if ((cPtr->Flags & ChipsAccelSupport) && 2949 (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) { 2950 cPtr->Flags &= ~ChipsAccelSupport; 2951 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 2952 } 2953 2954 from = X_DEFAULT; 2955 if (pScrn->bitsPerPixel < 8) { 2956 /* Default to SW cursor for 1/4 bpp */ 2957 cPtr->Accel.UseHWCursor = FALSE; 2958 } else { 2959 cPtr->Accel.UseHWCursor = TRUE; 2960 } 2961 if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR, 2962 &cPtr->Accel.UseHWCursor)) 2963 from = X_CONFIG; 2964 if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR, 2965 &cPtr->Accel.UseHWCursor)) { 2966 from = X_CONFIG; 2967 cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor; 2968 } 2969 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 2970 (cPtr->Accel.UseHWCursor) ? "HW" : "SW"); 2971 2972 /* memory size */ 2973 if (cPtr->pEnt->device->videoRam != 0) { 2974 pScrn->videoRam = cPtr->pEnt->device->videoRam; 2975 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n", 2976 pScrn->videoRam); 2977 } else { 2978 /* not given, probe it */ 2979 /* XR0F: Software flags 0 */ 2980 /* bit 1-0: memory size */ 2981 /* 0: 256 kB */ 2982 /* 1: 512 kB */ 2983 /* 2: 1024 kB */ 2984 /* 3: 1024 kB */ 2985 2986 switch ((cPtr->readXR(cPtr, 0x0F)) & 3) { 2987 case 0: 2988 pScrn->videoRam = 256; 2989 break; 2990 case 1: 2991 pScrn->videoRam = 512; 2992 break; 2993 case 2: 2994 case 3: 2995 pScrn->videoRam = 1024; 2996 break; 2997 } 2998 2999 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n", 3000 pScrn->videoRam); 3001 } 3002 cPtr->FbMapSize = pScrn->videoRam * 1024; 3003 3004 /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */ 3005 if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE; 3006 if (pScrn->bitsPerPixel < 8) { 3007 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) { 3008 useLinear = FALSE; 3009 from = X_CONFIG; 3010 } 3011 } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) { 3012 useLinear = FALSE; 3013 from = X_CONFIG; 3014 } 3015 3016#ifndef HAVE_ISA 3017 if (!(cPtr->Flags & ChipsLinearSupport)) { 3018 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Linear framebuffer required\n"); 3019 return FALSE; 3020 } 3021#endif 3022 3023 /* linear base */ 3024 if (useLinear) { 3025 unsigned char mask; 3026 if (cPtr->Chipset == CHIPS_CT65535) { 3027 mask = (pScrn->videoRam > 512) ? 0xF8 :0xFC; 3028 if (cPtr->Bus == ChipsISA) 3029 mask &= 0x7F; 3030 } else if (cPtr->Bus == ChipsISA) { 3031 mask = 0x0F; 3032 } else { 3033 mask = 0xFF; 3034 tmp = cPtr->readXR(cPtr, 0x01); 3035 if(tmp & 0x40) 3036 mask &= 0x3F; 3037 if(!(tmp & 0x80)) 3038 mask &= 0xCF; 3039 } 3040 if (cPtr->pEnt->location.type == BUS_PCI) { 3041 cPtr->FbAddress = PCI_REGION_BASE(cPtr->PciInfo, 0, REGION_MEM) & 0xff800000; 3042#ifndef XSERVER_LIBPCIACCESS 3043 if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone)) { 3044 useLinear = FALSE; 3045 from = X_PROBED; 3046 } 3047#endif 3048 } else { 3049 if (cPtr->pEnt->device->MemBase) { 3050 cPtr->FbAddress = cPtr->pEnt->device->MemBase; 3051 if (cPtr->Chipset == CHIPS_CT65535) 3052 cPtr->FbAddress &= (mask << 17); 3053 else if (cPtr->Chipset > CHIPS_CT65535) 3054 cPtr->FbAddress &= (mask << 20); 3055 from = X_CONFIG; 3056 } else { 3057 if (cPtr->Chipset <= CHIPS_CT65530) { 3058 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3059 "base address assumed at 0xC00000!\n"); 3060 cPtr->FbAddress = 0xC00000; 3061 from = X_CONFIG; 3062 } else if (cPtr->Chipset == CHIPS_CT65535) { 3063 cPtr->FbAddress = 3064 ((mask & (cPtr->readXR(cPtr, 0x08))) << 17); 3065 } else { 3066 cPtr->FbAddress = 3067 ((mask & (cPtr->readXR(cPtr, 0x08))) << 20); 3068 } 3069 from = X_PROBED; 3070 } 3071#ifndef XSERVER_LIBPCIACCESS 3072 linearRes[0].rBegin = cPtr->FbAddress; 3073 linearRes[0].rEnd = cPtr->FbAddress + 0x800000; 3074 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 3075 useLinear = FALSE; 3076 from = X_PROBED; 3077 } 3078#endif 3079 } 3080 } 3081 3082 if (useLinear) { 3083 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3084 "Enabling linear addressing\n"); 3085 xf86DrvMsg(pScrn->scrnIndex, from, 3086 "base address is set at 0x%lX.\n", cPtr->FbAddress); 3087 if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) && 3088 (cPtr->Flags & ChipsMMIOSupport)) { 3089 cPtr->UseMMIO = TRUE; 3090 cPtr->IOAddress = cPtr->FbAddress + 0x200000L; 3091 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n"); 3092 } 3093 } else { 3094 if (cPtr->Flags & ChipsLinearSupport) 3095 xf86DrvMsg(pScrn->scrnIndex, from, 3096 "Disabling linear addressing\n"); 3097 cPtr->Flags &= ~ChipsLinearSupport; 3098 } 3099 3100 if ((s = xf86GetOptValString(cPtr->Options, OPTION_ROTATE)) 3101 || xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) { 3102 if (!(cPtr->Flags & ChipsLinearSupport)) { 3103 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3104 "Option \"ShadowFB\" ignored. Not supported without linear addressing\n"); 3105 } else if (pScrn->depth < 8) { 3106 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3107 "Option \"ShadowFB\" ignored. Not supported at this depth.\n"); 3108 } else { 3109 cPtr->Rotate = 0; 3110 if (s) { 3111 if(!xf86NameCmp(s, "CW")) { 3112 /* accel is disabled below for shadowFB */ 3113 cPtr->Flags |= ChipsShadowFB; 3114 cPtr->Rotate = 1; 3115 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3116 "Rotating screen clockwise\n"); 3117 } else if(!xf86NameCmp(s, "CCW")) { 3118 cPtr->Flags |= ChipsShadowFB; 3119 cPtr->Rotate = -1; 3120 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 3121 "counter clockwise\n"); 3122 } else { 3123 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 3124 "value for Option \"Rotate\"\n", s); 3125 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3126 "Valid options are \"CW\" or \"CCW\"\n"); 3127 } 3128 } else { 3129 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3130 "Using \"Shadow Framebuffer\"\n"); 3131 cPtr->Flags |= ChipsShadowFB; 3132 } 3133 } 3134 } 3135 if (cPtr->Flags & ChipsShadowFB) { 3136 if (cPtr->Flags & ChipsAccelSupport) { 3137 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3138 "HW acceleration is not supported with shadow fb\n"); 3139 cPtr->Flags &= ~ChipsAccelSupport; 3140 } 3141 if (cPtr->Rotate && cPtr->Accel.UseHWCursor) { 3142 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3143 "HW cursor is not supported with rotate\n"); 3144 cPtr->Accel.UseHWCursor = FALSE; 3145 } 3146 } 3147 3148 /*test STN / TFT */ 3149 tmp = cPtr->readXR(cPtr, 0x51); 3150 3151 /* XR51 or FR10: DISPLAY TYPE REGISTER */ 3152 /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */ 3153 /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */ 3154 switch (tmp & 0x3) { 3155 case 0: 3156 if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) { 3157 cPtr->PanelType |= ChipsSS; 3158 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n"); 3159 } else { 3160 cPtr->PanelType |= ChipsTFT; 3161 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n"); 3162 } 3163 break; 3164 case 2: 3165 cPtr->PanelType |= ChipsDS; 3166 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n"); 3167 case 3: 3168 cPtr->PanelType |= ChipsDD; 3169 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n"); 3170 break; 3171 default: 3172 break; 3173 } 3174 3175 chipsSetPanelType(cPtr); 3176 from = X_PROBED; 3177 { 3178 Bool fp_mode; 3179 if (xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_mode)) { 3180 if (fp_mode) { 3181 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode on\n"); 3182 cPtr->PanelType |= ChipsLCD; 3183 } else { 3184 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing FP Mode off\n"); 3185 cPtr->PanelType = ~ChipsLCD; 3186 } 3187 from = X_CONFIG; 3188 } 3189 } 3190 if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT)) 3191 xf86DrvMsg(pScrn->scrnIndex, from, "LCD/CRT\n"); 3192 else if (cPtr->PanelType & ChipsLCD) 3193 xf86DrvMsg(pScrn->scrnIndex, from, "LCD\n"); 3194 else if (cPtr->PanelType & ChipsCRT) { 3195 xf86DrvMsg(pScrn->scrnIndex, from, "CRT\n"); 3196 /* monitor info */ 3197 cPtr->Monitor = chipsSetMonitor(pScrn); 3198 } 3199 3200 /* screen size */ 3201 /* 3202 * In LCD mode / dual mode we want to derive the timing values from 3203 * the ones preset by bios 3204 */ 3205 if (cPtr->PanelType & ChipsLCD) { 3206 unsigned char xr17, tmp1; 3207 char tmp2; 3208 3209 xr17 = cPtr->readXR(cPtr, 0x17); 3210 tmp = cPtr->readXR(cPtr, 0x1B); 3211 Size->HTotal =((tmp + ((xr17 & 0x01) << 8)) + 5) << 3; 3212 tmp = cPtr->readXR(cPtr, 0x1C); 3213 Size->HDisplay = ((tmp + ((xr17 & 0x02) << 7)) + 1) << 3; 3214 tmp = cPtr->readXR(cPtr, 0x19); 3215 Size->HRetraceStart = ((tmp + ((xr17 & 0x04) << 9)) + 1) << 3; 3216 tmp1 = cPtr->readXR(cPtr, 0x1A); 3217 tmp2 = (tmp1 & 0x1F) + ((xr17 & 0x08) << 2) - (tmp & 0x3F); 3218 Size->HRetraceEnd = ((((tmp2 & 0x080u) ? (tmp2 + 0x40) : tmp2) << 3) 3219 + Size->HRetraceStart); 3220 tmp1 = cPtr->readXR(cPtr, 0x65); 3221 tmp = cPtr->readXR(cPtr, 0x68); 3222 Size->VDisplay = ((tmp1 & 0x02) << 7) 3223 + ((tmp1 & 0x40) << 3) + tmp + 1; 3224 tmp = cPtr->readXR(cPtr, 0x66); 3225 Size->VRetraceStart = ((tmp1 & 0x04) << 6) 3226 + ((tmp1 & 0x80) << 2) + tmp + 1; 3227 tmp = cPtr->readXR(cPtr, 0x64); 3228 Size->VTotal = ((tmp1 & 0x01) << 8) 3229 + ((tmp1 & 0x20) << 4) + tmp + 2; 3230#ifdef DEBUG 3231 ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n", 3232 Size->HDisplay, Size->VDisplay, 3233 Size->HRetraceStart, Size->HRetraceEnd, 3234 Size->HTotal); 3235#endif 3236 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n", 3237 Size->HDisplay, Size->VDisplay); 3238 /* Warn the user if the panel size has been overridden by 3239 * the modeline values 3240 */ 3241 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 3242 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3243 "Display size overridden by modelines.\n"); 3244 } 3245 } 3246 3247 /* Frame Buffer */ /* for LCDs */ 3248 if (IS_STN(cPtr->PanelType)) { 3249 tmp = cPtr->readXR(cPtr, 0x6F); /*Frame Buffer Ctrl. */ 3250 if (tmp & 1) { 3251 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n"); 3252 if ((cPtr->Chipset > CHIPS_CT65530) && !(tmp & 0x80)) { 3253 /* Formula for calculating the size of the framebuffer. 3 3254 * bits per pixel 10 pixels per 32 bit dword. If frame 3255 * acceleration is enabled the size can be halved. 3256 */ 3257 cPtr->FrameBufferSize = ( Size->HDisplay * 3258 Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2); 3259 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3260 "Using embedded Frame Buffer, size %d bytes\n", 3261 cPtr->FrameBufferSize); 3262 } else 3263 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3264 "Using external Frame Buffer used\n"); 3265 } 3266 if (tmp & 2) 3267 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3268 "Frame accelerator enabled\n"); 3269 } 3270 3271 /* bus type */ 3272 if (cPtr->Chipset > CHIPS_CT65535) { 3273 tmp = (cPtr->readXR(cPtr, 0x01)) & 7; 3274 if (tmp == 6) { /*PCI */ 3275 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n"); 3276 cPtr->Bus = ChipsPCI; 3277 if ((cPtr->Chipset == CHIPS_CT65545) || 3278 (cPtr->Chipset == CHIPS_CT65546)) { 3279 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3280 "32Bit IO not supported on 65545 PCI\n"); 3281 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "\tenabling MMIO\n"); 3282 cPtr->UseMMIO = TRUE; 3283 cPtr->IOAddress = cPtr->FbAddress + 0x200000L; 3284 } 3285 3286 } else { /* XR08: Linear addressing base, not for PCI */ 3287 switch (tmp) { 3288 case 3: 3289 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CPU Direct\n"); 3290 cPtr->Bus = ChipsCPUDirect; 3291 break; 3292 case 5: 3293 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n"); 3294 cPtr->Bus = ChipsISA; 3295 break; 3296 case 7: 3297 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 3298 cPtr->Bus = ChipsVLB; 3299 break; 3300 default: 3301 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n"); 3302 } 3303 } 3304 } else { 3305 tmp = (cPtr->readXR(cPtr, 0x01)) & 3; 3306 switch (tmp) { 3307 case 0: 3308 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PI Bus\n"); 3309 cPtr->Bus = ChipsPIB; 3310 break; 3311 case 1: 3312 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MC Bus\n"); 3313 cPtr->Bus = ChipsMCB; 3314 break; 3315 case 2: 3316 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n"); 3317 cPtr->Bus = ChipsVLB; 3318 break; 3319 case 3: 3320 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n"); 3321 cPtr->Bus = ChipsISA; 3322 break; 3323 } 3324 } 3325 3326 if (!(cPtr->Bus == ChipsPCI) && (cPtr->UseMMIO)) { 3327 cPtr->UseMMIO = FALSE; 3328 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3329 "MMIO only supported on PCI Bus. Disabling MMIO\n"); 3330 } 3331 3332 /* disable acceleration for 1 and 4 bpp */ 3333 if (pScrn->bitsPerPixel < 8) { 3334 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3335 "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel); 3336 cPtr->Flags &= ~ChipsAccelSupport; 3337 } 3338 3339 if ((cPtr->Chipset == CHIPS_CT65530) && 3340 (cPtr->Flags & ChipsLinearSupport)) { 3341 /* linear mode is no longer default on ct65530 since it */ 3342 /* requires additional hardware which some manufacturers*/ 3343 /* might not provide. */ 3344 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) 3345 cPtr->Flags &= ~ChipsLinearSupport; 3346 3347 /* Test wether linear addressing is possible on 65530 */ 3348 /* on the 65530 only the A19 select scheme can be used*/ 3349 /* for linear addressing since MEMW is used on ISA bus*/ 3350 /* systems. */ 3351 /* A19 however is used if video memory is > 512 Mb */ 3352 if ((cPtr->Bus == ChipsISA) && (pScrn->videoRam > 512)) { 3353 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3354 "User selected linear fb not supported by HW!\n"); 3355 cPtr->Flags &= ~ChipsLinearSupport; 3356 } 3357 } 3358 3359 /* DAC info */ 3360 if ((cPtr->readXR(cPtr, 0x06)) & 0x02) 3361 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n"); 3362 3363 /* MMIO address offset */ 3364 if (cPtr->UseMMIO) 3365 cPtr->Regs32 = ChipsReg32; 3366 else if ((cPtr->Flags & ChipsAccelSupport) || 3367 (cPtr->Accel.UseHWCursor)) { 3368 cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32)); 3369 tmp = cPtr->readXR(cPtr, 0x07); 3370 for (i = 0; i < (sizeof(ChipsReg32)/sizeof(ChipsReg32[0])); i++) { 3371 cPtr->Regs32[i] = 3372 ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80)<< 8) 3373 | ((tmp & 0x7F) << 2); 3374#ifdef DEBUG 3375 ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]); 3376#endif 3377 } 3378#ifndef XSERVER_LIBPCIACCESS 3379 linearRes[0].type = ResExcIoSparse | ResBios | ResBus; 3380 linearRes[0].rBase = cPtr->Regs32[0]; 3381 linearRes[0].rMask = 0x83FC; 3382 if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) { 3383 if (cPtr->Flags & ChipsAccelSupport) { 3384 cPtr->Flags &= ~ChipsAccelSupport; 3385 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3386 "Cannot allocate IO registers: " 3387 "Disabling acceleration\n"); 3388 } 3389 if (cPtr->Accel.UseHWCursor) { 3390 cPtr->Accel.UseHWCursor = FALSE; 3391 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3392 "Cannot allocate IO registers: " 3393 "Disabling HWCursor\n"); 3394 } 3395 } 3396#endif 3397 } 3398 3399 /* sync reset ignored on this chipset */ 3400 if (cPtr->Chipset > CHIPS_CT65530) { 3401 tmp = cPtr->readXR(cPtr, 0x0E); 3402 if (tmp & 0x80) 3403 cPtr->SyncResetIgn = TRUE; 3404 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3405 "Synchronous reset %signored.\n", 3406 (cPtr->SyncResetIgn ? "" : "not ")); 3407 } 3408 3409 cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1); 3410 if (cPtr->ClockMulFactor != 1) 3411 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3412 "Clocks scaled by %d\n", cPtr->ClockMulFactor); 3413 /* We use a programmable clock */ 3414 switch (cPtr->Chipset) { 3415 case CHIPS_CT65520: 3416 case CHIPS_CT65525: 3417 case CHIPS_CT65530: 3418 NoClocks = 4; /* Some number */ 3419 cPtr->ClockType = OLD_STYLE | TYPE_HW; 3420 break; 3421 default: 3422 if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) { 3423 NoClocks = 5; /* Some number */ 3424 cPtr->ClockType = NEW_STYLE | TYPE_HW; 3425 } else { 3426 NoClocks = 26; /* Some number */ 3427 cPtr->ClockType = NEW_STYLE | TYPE_PROGRAMMABLE; 3428 pScrn->progClock = TRUE; 3429 } 3430 } 3431 3432 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 3433 pScrn->numClocks = NoClocks; 3434 SaveClk->Clock = ((cPtr->PanelType & ChipsLCDProbed) ? 3435 LCD_TEXT_CLK_FREQ : CRT_TEXT_CLK_FREQ); 3436 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n"); 3437 } else { /* TYPE_PROGRAMMABLE */ 3438 SaveClk->Clock = chipsGetHWClock(pScrn); 3439 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n", 3440 SaveClk->Clock); 3441 if (!cPtr->pEnt->device->numclocks) { 3442 pScrn->numClocks = NoClocks; 3443 xf86GetClocks(pScrn, NoClocks, chipsClockSelect, 3444 chipsProtect, chipsBlankScreen, 3445 cPtr->IOBase + 0x0A, 0x08, 1, 28322); 3446 from = X_PROBED; 3447 } else { 3448 pScrn->numClocks = cPtr->pEnt->device->numclocks; 3449 if (pScrn->numClocks > NoClocks) { 3450 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3451 "Too many Clocks specified in configuration file.\n"); 3452 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3453 "\t\tAt most %d clocks may be specified\n", NoClocks); 3454 pScrn->numClocks = NoClocks; 3455 } 3456 for (i = 0; i < pScrn->numClocks; i++) 3457 pScrn->clock[i] = cPtr->pEnt->device->clock[i]; 3458 from = X_CONFIG; 3459 } 3460 xf86ShowClocks(pScrn, from); 3461 } 3462 /* Set the min pixel clock */ 3463 /* XXX Guess, need to check this */ 3464 cPtr->MinClock = 11000 / cPtr->ClockMulFactor; 3465 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n", 3466 (float)(cPtr->MinClock / 1000.)); 3467 /* Set the max pixel clock */ 3468 switch (cPtr->Chipset) { 3469 case CHIPS_CT65546: 3470 case CHIPS_CT65548: 3471 /* max VCLK is 80 MHz, max MCLK is 75 MHz for CT65548 */ 3472 /* It is not sure for CT65546, but it works with 60 nsec EDODRAM */ 3473 cPtr->MaxClock = 80000 / cPtr->ClockMulFactor; 3474 break; 3475 default: 3476 if ((cPtr->readXR(cPtr, 0x6C)) & 2) { 3477 /*5V Vcc */ 3478 cPtr->MaxClock = 68000 / cPtr->ClockMulFactor; 3479 } else { 3480 /*3.3V Vcc */ 3481 cPtr->MaxClock = 56000 / cPtr->ClockMulFactor; 3482 } 3483 } 3484 3485 if (cPtr->pEnt->device->dacSpeeds[0]) { 3486 int speed = 0; 3487 switch (pScrn->bitsPerPixel) { 3488 case 1: 3489 case 4: 3490 case 8: 3491 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8]; 3492 break; 3493 case 16: 3494 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16]; 3495 break; 3496 case 24: 3497 speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24]; 3498 break; 3499 } 3500 if (speed == 0) 3501 cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0]; 3502 from = X_CONFIG; 3503 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3504 "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n", 3505 (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.)); 3506 cPtr->MaxClock = speed; 3507 } else { 3508 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3509 "Max pixel clock is %7.3f MHz\n", 3510 (float)(cPtr->MaxClock / 1000.)); 3511 } 3512 3513 /* FP clock */ 3514 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 3515 double real = 0; 3516 3517 switch(bytesPerPixel) { 3518 case 1: 3519 xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8, 3520 OPTUNITS_MHZ, &real); 3521 break; 3522 case 2: 3523 xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16, 3524 OPTUNITS_MHZ, &real); 3525 break; 3526 case 3: 3527 xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24, 3528 OPTUNITS_MHZ, &real); 3529 break; 3530 } 3531 3532 if (real > 0) { 3533 int val; 3534 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3535 "FP clock %7.3f MHz requested\n",real); 3536 val = (int) (real * 1000.); 3537 if (val && (val >= cPtr->MinClock) 3538 && (val <= cPtr->MaxClock)) 3539 cPtr->FPclock = val * cPtr->ClockMulFactor; 3540 else if (val > cPtr->MaxClock) 3541 cPtr->FPclock = (int)((float)cPtr->MaxClock 3542 * cPtr->ClockMulFactor * 0.9); 3543 else 3544 cPtr->FPclock = 0; /* special value */ 3545 } else 3546 cPtr->FPclock = 0; /* special value */ 3547 3548 if (cPtr->FPclock) 3549 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3550 "FP clock set to %7.3f MHz\n", 3551 (float)(cPtr->FPclock / 1000.)); 3552 } else { 3553 if (xf86IsOptionSet(cPtr->Options, OPTION_SET_MCLK)) 3554 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3555 "FP clock option not supported for this chipset\n"); 3556 } 3557 3558 /* Memory Clock */ 3559 if (cPtr->ClockType & TYPE_PROGRAMMABLE) { 3560 double real; 3561 3562 switch (cPtr->Chipset) { 3563 case CHIPS_CT65546: 3564 case CHIPS_CT65548: 3565 /* max MCLK is 75 MHz for CT65548 */ 3566 cPtr->MemClock.Max = 75000; 3567 break; 3568 default: 3569 if ((cPtr->readXR(cPtr, 0x6C)) & 2) { 3570 /*5V Vcc */ 3571 cPtr->MemClock.Max = 68000; 3572 } else { 3573 /*3.3V Vcc */ 3574 cPtr->MemClock.Max = 56000; 3575 } 3576 } 3577 3578 if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK, 3579 OPTUNITS_MHZ, &real)) { 3580 int mclk = (int)(real * 1000.0); 3581 if (mclk <= cPtr->MemClock.Max) { 3582 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3583 "Using memory clock of %7.3f MHz\n", 3584 (float)(mclk/1000.)); 3585 cPtr->MemClock.Clk = mclk; 3586 } else { 3587 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3588 "Memory clock of %7.3f MHz exceeds limit of " 3589 "%7.3f MHz\n",(float)(mclk/1000.), 3590 (float)(cPtr->MemClock.Max/1000.)); 3591 cPtr->MemClock.Clk = cPtr->MemClock.Max * 0.9; 3592 } 3593 } else 3594 cPtr->MemClock.Clk = 0; 3595 } else 3596 if (xf86IsOptionSet(cPtr->Options, OPTION_SET_MCLK)) 3597 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3598 "Memory clock option not supported for this chipset\n"); 3599 3600 if (xf86LoadSubModule(pScrn, "ddc")) { 3601 if (cPtr->pVbe) 3602 xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(cPtr->pVbe, NULL))); 3603 } 3604 return TRUE; 3605} 3606 3607 3608/* Mandatory */ 3609static Bool 3610CHIPSEnterVT(VT_FUNC_ARGS_DECL) 3611{ 3612 SCRN_INFO_PTR(arg); 3613 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3614 CHIPSEntPtr cPtrEnt; 3615 3616 if (cPtr->Flags & ChipsDualChannelSupport) { 3617 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3618 CHIPSEntityIndex)->ptr; 3619 DUALOPEN; 3620 } 3621 /* Should we re-save the text mode on each VT enter? */ 3622 if(!chipsModeInit(pScrn, pScrn->currentMode)) 3623 return FALSE; 3624 if ((cPtr->Flags & ChipsVideoSupport) 3625 && (cPtr->Flags & ChipsLinearSupport)) 3626 CHIPSResetVideo(pScrn); 3627 3628 /*usleep(50000);*/ 3629 chipsHWCursorOn(cPtr, pScrn); 3630 /* cursor settle delay */ 3631 usleep(50000); 3632 CHIPSAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 3633 usleep(50000); 3634 return TRUE; 3635} 3636 3637/* Mandatory */ 3638static void 3639CHIPSLeaveVT(VT_FUNC_ARGS_DECL) 3640{ 3641 SCRN_INFO_PTR(arg); 3642 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3643 CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn); 3644 CHIPSEntPtr cPtrEnt; 3645 3646 /* Invalidate the cached acceleration registers */ 3647 cAcl->planemask = -1; 3648 cAcl->fgColor = -1; 3649 cAcl->bgColor = -1; 3650 3651 if (cPtr->Flags & ChipsDualChannelSupport) { 3652 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3653 CHIPSEntityIndex)->ptr; 3654 if (cPtr->UseDualChannel) 3655 DUALREOPEN; 3656 DUALCLOSE; 3657 } else { 3658 chipsHWCursorOff(cPtr, pScrn); 3659 chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg, 3660#ifdef AVOID_VGAHW 3661 FALSE); 3662#else 3663 TRUE); 3664#endif 3665 chipsLock(pScrn); 3666 } 3667} 3668 3669 3670static void 3671chipsLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 3672 VisualPtr pVisual) 3673{ 3674 vgaHWPtr hwp = VGAHWPTR(pScrn); 3675 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3676 int i, index, shift ; 3677 CHIPSEntPtr cPtrEnt; 3678 3679 shift = (pScrn->depth == 15) ? 3 : 0; 3680 3681 if (cPtr->UseDualChannel) { 3682 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3683 CHIPSEntityIndex)->ptr; 3684 DUALREOPEN; 3685 } 3686 3687 for (i = 0; i < numColors; i++) { 3688 index = indices[i]; 3689 hwp->writeDacWriteAddr(hwp,index << shift); 3690 DACDelay(hwp); 3691 hwp->writeDacData(hwp, colors[index].red); 3692 DACDelay(hwp); 3693 hwp->writeDacData(hwp, colors[index].green); 3694 DACDelay(hwp); 3695 hwp->writeDacData(hwp, colors[index].blue); 3696 DACDelay(hwp); 3697 } 3698 3699 if (cPtr->UseDualChannel && 3700 (! xf86IsEntityShared(pScrn->entityList[0]))) { 3701 unsigned int IOSS, MSS; 3702 IOSS = cPtr->readIOSS(cPtr); 3703 MSS = cPtr->readMSS(cPtr); 3704 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3705 IOSS_PIPE_B)); 3706 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 3707 3708 for (i = 0; i < numColors; i++) { 3709 index = indices[i]; 3710 hwp->writeDacWriteAddr(hwp,index << shift); 3711 DACDelay(hwp); 3712 hwp->writeDacData(hwp, colors[index].red); 3713 DACDelay(hwp); 3714 hwp->writeDacData(hwp, colors[index].green); 3715 DACDelay(hwp); 3716 hwp->writeDacData(hwp, colors[index].blue); 3717 DACDelay(hwp); 3718 } 3719 cPtr->writeIOSS(cPtr, IOSS); 3720 cPtr->writeMSS(cPtr, hwp, MSS); 3721 } 3722 3723 /* This shouldn't be necessary, but we'll play safe. */ 3724 hwp->disablePalette(hwp); 3725} 3726 3727static void 3728chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, 3729 LOCO *colors, VisualPtr pVisual) 3730{ 3731 vgaHWPtr hwp = VGAHWPTR(pScrn); 3732 CHIPSPtr cPtr = CHIPSPTR(pScrn); 3733 CHIPSEntPtr cPtrEnt; 3734 3735 int i, index; 3736 3737 if (cPtr->UseDualChannel) { 3738 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3739 CHIPSEntityIndex)->ptr; 3740 DUALREOPEN; 3741 } 3742 3743 for (i = 0; i < numColors; i++) { 3744 index = indices[i]; 3745 hwp->writeDacWriteAddr(hwp, index << 2); 3746 DACDelay(hwp); 3747 hwp->writeDacData(hwp, colors[index >> 1].red); 3748 DACDelay(hwp); 3749 hwp->writeDacData(hwp, colors[index].green); 3750 DACDelay(hwp); 3751 hwp->writeDacData(hwp, colors[index >> 1].blue); 3752 DACDelay(hwp); 3753 } 3754 3755 3756 if (cPtr->UseDualChannel && 3757 (! xf86IsEntityShared(pScrn->entityList[0]))) { 3758 unsigned int IOSS, MSS; 3759 IOSS = cPtr->readIOSS(cPtr); 3760 MSS = cPtr->readMSS(cPtr); 3761 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3762 IOSS_PIPE_B)); 3763 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 3764 3765 for (i = 0; i < numColors; i++) { 3766 index = indices[i]; 3767 hwp->writeDacWriteAddr(hwp, index << 2); 3768 DACDelay(hwp); 3769 hwp->writeDacData(hwp, colors[index >> 1].red); 3770 DACDelay(hwp); 3771 hwp->writeDacData(hwp, colors[index].green); 3772 DACDelay(hwp); 3773 hwp->writeDacData(hwp, colors[index >> 1].blue); 3774 DACDelay(hwp); 3775 } 3776 3777 cPtr->writeIOSS(cPtr, IOSS); 3778 cPtr->writeMSS(cPtr, hwp, MSS); 3779 } 3780 3781 /* This shouldn't be necessary, but we'll play safe. */ 3782 hwp->disablePalette(hwp); 3783} 3784 3785/* Mandatory */ 3786static Bool 3787CHIPSScreenInit(SCREEN_INIT_ARGS_DECL) 3788{ 3789 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 3790 vgaHWPtr hwp; 3791 CHIPSPtr cPtr; 3792 CHIPSACLPtr cAcl; 3793 int ret; 3794 int init_picture = 0; 3795 VisualPtr visual; 3796 int allocatebase, freespace, currentaddr; 3797#ifndef XSERVER_LIBPCIACCESS 3798 unsigned int racflag = 0; 3799#endif 3800 unsigned char *FBStart; 3801 int height, width, displayWidth; 3802 CHIPSEntPtr cPtrEnt = NULL; 3803#ifdef DEBUG 3804 ErrorF("CHIPSScreenInit\n"); 3805#endif 3806 3807 /* 3808 * we need to get the ScrnInfoRec for this screen, so let's allocate 3809 * one first thing 3810 */ 3811 cPtr = CHIPSPTR(pScrn); 3812 cAcl = CHIPSACLPTR(pScrn); 3813 3814 hwp = VGAHWPTR(pScrn); 3815 hwp->MapSize = 0x10000; /* Standard 64k VGA window */ 3816 3817#ifndef AVOID_VGAHW 3818 /* Map the VGA memory */ 3819 if (!vgaHWMapMem(pScrn)) 3820 return FALSE; 3821#endif 3822 3823 /* Map the Chips memory and possible MMIO areas */ 3824 if (!chipsMapMem(pScrn)) 3825 return FALSE; 3826 3827 /* Setup the MMIO register access functions if need */ 3828 if (cPtr->UseFullMMIO && cPtr->MMIOBaseVGA) { 3829 CHIPSSetMmioExtFuncs(cPtr); 3830 CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBaseVGA, 0x0); 3831 } 3832 3833 if (cPtr->Flags & ChipsDualChannelSupport) { 3834 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 3835 CHIPSEntityIndex)->ptr; 3836 DUALOPEN; 3837 } 3838 3839#if defined(__arm__) && defined(___NetBSD__) 3840 if (strcmp(pScrn->currentMode->name,"PAL") == 0) { 3841 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using built-in PAL TV mode\n"); 3842 cPtr->TVMode = XMODE_PAL; 3843 } else if (strcmp(pScrn->currentMode->name,"SECAM") == 0){ 3844 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3845 "Using built-in SECAM TV mode\n"); 3846 cPtr->TVMode = XMODE_SECAM; 3847 } else if (strcmp(pScrn->currentMode->name,"NTSC") == 0) { 3848 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 3849 "Using built-in NTSC TV mode\n"); 3850 cPtr->TVMode = XMODE_NTSC; 3851 } else 3852 cPtr->TVMode = XMODE_RGB; 3853#endif 3854 3855 /* 3856 * next we save the current state and setup the first mode 3857 */ 3858 if ((cPtr->Flags & ChipsDualChannelSupport) && 3859 (! xf86IsEntityShared(pScrn->entityList[0]))) { 3860 unsigned int IOSS, MSS; 3861 IOSS = cPtr->readIOSS(cPtr); 3862 MSS = cPtr->readMSS(cPtr); 3863 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3864 IOSS_PIPE_A)); 3865 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_A)); 3866 chipsSave(pScrn, &hwp->SavedReg, &cPtr->SavedReg); 3867 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 3868 IOSS_PIPE_B)); 3869 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 3870 chipsSave(pScrn, &cPtr->VgaSavedReg2, &cPtr->SavedReg2); 3871 cPtr->writeIOSS(cPtr, IOSS); 3872 cPtr->writeMSS(cPtr, hwp, MSS); 3873 } else 3874 chipsSave(pScrn, &hwp->SavedReg, &cPtr->SavedReg); 3875 3876 if (!chipsModeInit(pScrn,pScrn->currentMode)) 3877 return FALSE; 3878 CHIPSSaveScreen(pScreen,SCREEN_SAVER_ON); 3879 CHIPSAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 3880 3881 /* 3882 * The next step is to setup the screen's visuals, and initialise the 3883 * framebuffer code. In cases where the framebuffer's default 3884 * choices for things like visual layouts and bits per RGB are OK, 3885 * this may be as simple as calling the framebuffer's ScreenInit() 3886 * function. If not, the visuals will need to be setup before calling 3887 * a fb ScreenInit() function and fixed up after. 3888 * 3889 * For most PC hardware at depths >= 8, the defaults that cfb uses 3890 * are not appropriate. In this driver, we fixup the visuals after. 3891 */ 3892 3893 /* 3894 * Reset visual list. 3895 */ 3896 miClearVisualTypes(); 3897 3898 /* Setup the visuals we support. */ 3899 if (!miSetVisualTypes(pScrn->depth, 3900 miGetDefaultVisualMask(pScrn->depth), 3901 pScrn->rgbBits, pScrn->defaultVisual)) 3902 return FALSE; 3903 miSetPixmapDepths (); 3904 3905 /* 3906 * Call the framebuffer layer's ScreenInit function, and fill in other 3907 * pScreen fields. 3908 */ 3909 if ((cPtr->Flags & ChipsShadowFB) && cPtr->Rotate) { 3910 height = pScrn->virtualX; 3911 width = pScrn->virtualY; 3912 } else { 3913 width = pScrn->virtualX; 3914 height = pScrn->virtualY; 3915 } 3916 3917 if(cPtr->Flags & ChipsShadowFB) { 3918 cPtr->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 3919 cPtr->ShadowPtr = malloc(cPtr->ShadowPitch * height); 3920 displayWidth = cPtr->ShadowPitch / (pScrn->bitsPerPixel >> 3); 3921 FBStart = cPtr->ShadowPtr; 3922 } else { 3923 cPtr->ShadowPtr = NULL; 3924 displayWidth = pScrn->displayWidth; 3925 FBStart = cPtr->FbBase; 3926 } 3927 3928 switch (pScrn->bitsPerPixel) { 3929#ifdef HAVE_XF1BPP 3930 case 1: 3931 ret = xf1bppScreenInit(pScreen, FBStart, 3932 width,height, 3933 pScrn->xDpi, pScrn->yDpi, 3934 displayWidth); 3935 break; 3936#endif 3937#ifdef HAVE_XF4BPP 3938 case 4: 3939 ret = xf4bppScreenInit(pScreen, FBStart, 3940 width,height, 3941 pScrn->xDpi, pScrn->yDpi, 3942 displayWidth); 3943 break; 3944#endif 3945 case 16: 3946 default: 3947 ret = fbScreenInit(pScreen, FBStart, 3948 width,height, 3949 pScrn->xDpi, pScrn->yDpi, 3950 displayWidth,pScrn->bitsPerPixel); 3951 init_picture = 1; 3952 break; 3953 } 3954 3955 if (!ret) 3956 return FALSE; 3957 3958#if X_BYTE_ORDER == X_BIG_ENDIAN 3959 /* TODO : find a better way to do this */ 3960 if (pScrn->depth == 24) { 3961 int dummy ; 3962 /* Fixup RGB ordering in 24 BPP */ 3963 dummy = pScrn->offset.red ; 3964 pScrn->offset.red = pScrn->offset.blue; 3965 pScrn->offset.blue = dummy ; 3966 3967 dummy = pScrn->mask.red ; 3968 pScrn->mask.red = pScrn->mask.blue; 3969 pScrn->mask.blue = dummy ; 3970 } 3971#endif 3972 3973 if (pScrn->depth > 8) { 3974 /* Fixup RGB ordering */ 3975 visual = pScreen->visuals + pScreen->numVisuals; 3976 while (--visual >= pScreen->visuals) { 3977 if ((visual->class | DynamicClass) == DirectColor) { 3978 visual->offsetRed = pScrn->offset.red; 3979 visual->offsetGreen = pScrn->offset.green; 3980 visual->offsetBlue = pScrn->offset.blue; 3981 visual->redMask = pScrn->mask.red; 3982 visual->greenMask = pScrn->mask.green; 3983 visual->blueMask = pScrn->mask.blue; 3984 } 3985 } 3986 } 3987 3988 /* must be after RGB ordering fixed */ 3989 if (init_picture) 3990 fbPictureInit (pScreen, 0, 0); 3991 3992 xf86SetBlackWhitePixels(pScreen); 3993 3994 cPtr->BlockHandler = pScreen->BlockHandler; 3995 pScreen->BlockHandler = chipsBlockHandler; 3996 3997 if ( (pScrn->depth >= 8)) 3998 CHIPSDGAInit(pScreen); 3999 4000 cPtr->HWCursorShown = FALSE; 4001 4002#if defined(USE_MIBANK) 4003 if (!(cPtr->Flags & ChipsLinearSupport)) { 4004 miBankInfoPtr pBankInfo; 4005 4006 /* Setup the vga banking variables */ 4007 pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1); 4008 if (pBankInfo == NULL) 4009 return FALSE; 4010 4011#if defined(__arm__) 4012 cPtr->Bank = -1; 4013#endif 4014 pBankInfo->pBankA = hwp->Base; 4015 pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x08000; 4016 pBankInfo->BankSize = 0x08000; 4017 pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth; 4018 4019 if (IS_HiQV(cPtr)) { 4020 pBankInfo->pBankB = hwp->Base; 4021 pBankInfo->BankSize = 0x10000; 4022 if (pScrn->bitsPerPixel < 8) { 4023 pBankInfo->SetSourceBank = 4024 (miBankProcPtr)CHIPSHiQVSetReadWritePlanar; 4025 pBankInfo->SetDestinationBank = 4026 (miBankProcPtr)CHIPSHiQVSetReadWritePlanar; 4027 pBankInfo->SetSourceAndDestinationBanks = 4028 (miBankProcPtr)CHIPSHiQVSetReadWritePlanar; 4029 } else { 4030 pBankInfo->SetSourceBank = 4031 (miBankProcPtr)CHIPSHiQVSetReadWrite; 4032 pBankInfo->SetDestinationBank = 4033 (miBankProcPtr)CHIPSHiQVSetReadWrite; 4034 pBankInfo->SetSourceAndDestinationBanks = 4035 (miBankProcPtr)CHIPSHiQVSetReadWrite; 4036 } 4037 } else { 4038 if (IS_Wingine(cPtr)) { 4039 if (pScrn->bitsPerPixel < 8) { 4040 pBankInfo->SetSourceBank = 4041 (miBankProcPtr)CHIPSWINSetReadPlanar; 4042 pBankInfo->SetDestinationBank = 4043 (miBankProcPtr)CHIPSWINSetWritePlanar; 4044 pBankInfo->SetSourceAndDestinationBanks = 4045 (miBankProcPtr)CHIPSWINSetReadWritePlanar; 4046 } else { 4047 pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSWINSetRead; 4048 pBankInfo->SetDestinationBank = 4049 (miBankProcPtr)CHIPSWINSetWrite; 4050 pBankInfo->SetSourceAndDestinationBanks = 4051 (miBankProcPtr)CHIPSWINSetReadWrite; 4052 } 4053 } else { 4054 if (pScrn->bitsPerPixel < 8) { 4055 pBankInfo->SetSourceBank = 4056 (miBankProcPtr)CHIPSSetReadPlanar; 4057 pBankInfo->SetDestinationBank = 4058 (miBankProcPtr)CHIPSSetWritePlanar; 4059 pBankInfo->SetSourceAndDestinationBanks = 4060 (miBankProcPtr)CHIPSSetReadWritePlanar; 4061 } else { 4062 pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSSetRead; 4063 pBankInfo->SetDestinationBank = 4064 (miBankProcPtr)CHIPSSetWrite; 4065 pBankInfo->SetSourceAndDestinationBanks = 4066 (miBankProcPtr)CHIPSSetReadWrite; 4067 } 4068 } 4069 } 4070 if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, 4071 pScrn->displayWidth, pBankInfo)) { 4072 free(pBankInfo); 4073 pBankInfo = NULL; 4074 return FALSE; 4075 } 4076 xf86SetBackingStore(pScreen); 4077 4078 /* Initialise cursor functions */ 4079 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 4080 4081 } else 4082#endif /* USE_MIBANK */ 4083 { 4084 /* !!! Only support linear addressing for now. This might change */ 4085 /* Setup pointers to free space in video ram */ 4086#define CHIPSALIGN(size, align) (currentaddr - ((currentaddr - size) & ~align)) 4087 allocatebase = (pScrn->videoRam<<10) - cPtr->FrameBufferSize; 4088 4089 if (pScrn->bitsPerPixel < 8) 4090 freespace = allocatebase - pScrn->displayWidth * 4091 pScrn->virtualY / 2; 4092 else 4093 freespace = allocatebase - pScrn->displayWidth * 4094 pScrn->virtualY * (pScrn->bitsPerPixel >> 3); 4095 4096 if ((cPtr->Flags & ChipsDualChannelSupport) && 4097 (cPtr->SecondCrtc == TRUE)) { 4098 currentaddr = allocatebase + cPtrEnt->masterFbMapSize; 4099 } else 4100 currentaddr = allocatebase; 4101 if (serverGeneration == 1) 4102 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 4103 "%d bytes off-screen memory available\n", freespace); 4104 4105 /* 4106 * Allocate video memory to store the hardware cursor. Allocate 1kB 4107 * vram to the cursor, with 1kB alignment for 6554x's and 4kb alignment 4108 * for 65550's. Wingine cursor is stored in registers and so no memory 4109 * is needed. 4110 */ 4111 if (cAcl->UseHWCursor) { 4112 cAcl->CursorAddress = -1; 4113 if (IS_HiQV(cPtr)) { 4114 if (CHIPSALIGN(1024, 0xFFF) <= freespace) { 4115 currentaddr -= CHIPSALIGN(1024, 0xFFF); 4116 freespace -= CHIPSALIGN(1024, 0xFFF); 4117 cAcl->CursorAddress = currentaddr; 4118 } 4119 } else if (IS_Wingine(cPtr)) { 4120 cAcl->CursorAddress = 0; 4121 } else if (CHIPSALIGN(1024, 0x3FF) <= freespace) { 4122 currentaddr -= CHIPSALIGN(1024, 0x3FF); 4123 freespace -= CHIPSALIGN(1024, 0x3FF); 4124 cAcl->CursorAddress = currentaddr; 4125 } 4126 if (cAcl->CursorAddress == -1) 4127 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4128 "Too little space for H/W cursor.\n"); 4129 } 4130 4131 cAcl->CacheEnd = currentaddr; 4132 4133 /* Setup the acceleration primitives */ 4134 /* Calculate space needed of offscreen pixmaps etc. */ 4135 if (cPtr->Flags & ChipsAccelSupport) { 4136 /* 4137 * A scratch area is now allocated in the video ram. This is used 4138 * at 8 and 16 bpp to simulate a planemask with a complex ROP, and 4139 * at 24 and 32 bpp to aid in accelerating solid fills 4140 */ 4141 cAcl->ScratchAddress = -1; 4142 switch (pScrn->bitsPerPixel) { 4143 case 8: 4144 if (CHIPSALIGN(64, 0x3F) <= freespace) { 4145 currentaddr -= CHIPSALIGN(64, 0x3F); 4146 freespace -= CHIPSALIGN(64, 0x3F); 4147 cAcl->ScratchAddress = currentaddr; 4148 } 4149 break; 4150 case 16: 4151 if (CHIPSALIGN(128, 0x7F) <= freespace) { 4152 currentaddr -= CHIPSALIGN(128, 0x7F); 4153 freespace -= CHIPSALIGN(128, 0x7F); 4154 cAcl->ScratchAddress = currentaddr; 4155 } 4156 break; 4157 case 24: 4158 /* One scanline of data used for solid fill */ 4159 if (!IS_HiQV(cPtr)) { 4160 if (CHIPSALIGN(3 * (pScrn->displayWidth + 4), 0x3) 4161 <= freespace) { 4162 currentaddr -= CHIPSALIGN(3 * (pScrn->displayWidth 4163 + 4), 0x3); 4164 freespace -= CHIPSALIGN(3 * (pScrn->displayWidth + 4), 4165 0x3); 4166 cAcl->ScratchAddress = currentaddr; 4167 } 4168 } 4169 break; 4170 case 32: 4171 /* 16bpp 8x8 mono pattern fill for solid fill. QWORD aligned */ 4172 if (IS_HiQV(cPtr)) { 4173 if (CHIPSALIGN(8, 0x7) <= freespace) { 4174 currentaddr -= CHIPSALIGN(8, 0x7); 4175 freespace -= CHIPSALIGN(8, 0x7); 4176 cAcl->ScratchAddress = currentaddr; 4177 } 4178 } 4179 break; 4180 } 4181 4182 /* Setup the boundaries of the pixmap cache */ 4183 cAcl->CacheStart = currentaddr - freespace; 4184 cAcl->CacheEnd = currentaddr; 4185 4186 if (cAcl->CacheStart >= cAcl->CacheEnd) { 4187 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4188 "Too little space for pixmap cache.\n"); 4189 cAcl->CacheStart = 0; 4190 cAcl->CacheEnd = 0; 4191 } 4192 4193 if (IS_HiQV(cPtr)) 4194 cAcl->BltDataWindow = (unsigned char *)cPtr->MMIOBase 4195 + 0x10000L; 4196 else 4197 cAcl->BltDataWindow = cPtr->FbBase; 4198 4199 } 4200 /* 4201 * Initialize FBManager: 4202 * we do even with no acceleration enabled 4203 * so that video support can allocate space. 4204 */ 4205 4206 { 4207 BoxRec AvailFBArea; 4208 AvailFBArea.x1 = 0; 4209 AvailFBArea.y1 = 0; 4210 AvailFBArea.x2 = pScrn->displayWidth; 4211 AvailFBArea.y2 = cAcl->CacheEnd / 4212 (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 4213 4214 xf86InitFBManager(pScreen, &AvailFBArea); 4215 } 4216 if (cPtr->Flags & ChipsAccelSupport) { 4217 if (IS_HiQV(cPtr)) { 4218#ifdef HAVE_XAA_H 4219 CHIPSHiQVAccelInit(pScreen); 4220#else 4221 CHIPSInitEXA(pScreen); 4222#endif 4223 } 4224#ifdef HAVE_XAA_H 4225 else if (cPtr->UseMMIO) { 4226 CHIPSMMIOAccelInit(pScreen); 4227 } else { 4228 CHIPSAccelInit(pScreen); 4229 } 4230#endif 4231 } 4232 xf86SetBackingStore(pScreen); 4233#ifdef ENABLE_SILKEN_MOUSE 4234 xf86SetSilkenMouse(pScreen); 4235#endif 4236 4237 /* Initialise cursor functions */ 4238 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 4239 4240 if ((cAcl->UseHWCursor) && (cAcl->CursorAddress != -1)) { 4241 /* HW cursor functions */ 4242 if (!CHIPSCursorInit(pScreen)) { 4243 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4244 "Hardware cursor initialization failed\n"); 4245 return FALSE; 4246 } 4247 } 4248 } 4249 4250 if (cPtr->Flags & ChipsShadowFB) { 4251 RefreshAreaFuncPtr refreshArea = chipsRefreshArea; 4252 4253 if(cPtr->Rotate) { 4254 if (!cPtr->PointerMoved) { 4255 cPtr->PointerMoved = pScrn->PointerMoved; 4256 pScrn->PointerMoved = chipsPointerMoved; 4257 } 4258 4259 switch(pScrn->bitsPerPixel) { 4260 case 8: refreshArea = chipsRefreshArea8; break; 4261 case 16: refreshArea = chipsRefreshArea16; break; 4262 case 24: refreshArea = chipsRefreshArea24; break; 4263 case 32: refreshArea = chipsRefreshArea32; break; 4264 } 4265 } 4266 ShadowFBInit(pScreen, refreshArea); 4267 } 4268 4269 /* Initialise default colourmap */ 4270 if (!miCreateDefColormap(pScreen)) 4271 return FALSE; 4272 4273 if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, 4274 (pScrn->depth == 16 ? chipsLoadPalette16 : chipsLoadPalette), 4275 NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) 4276 return FALSE; 4277 4278#ifndef XSERVER_LIBPCIACCESS 4279 racflag = RAC_COLORMAP; 4280 if (cAcl->UseHWCursor) 4281 racflag |= RAC_CURSOR; 4282 racflag |= (RAC_FB | RAC_VIEWPORT); 4283 /* XXX Check if I/O and Mem flags need to be the same. */ 4284 pScrn->racIoFlags = pScrn->racMemFlags = racflag; 4285#endif 4286#ifdef ENABLE_SILKEN_MOUSE 4287 xf86SetSilkenMouse(pScreen); 4288#endif 4289 4290 if ((cPtr->Flags & ChipsVideoSupport) 4291 && (cPtr->Flags & ChipsLinearSupport)) { 4292 CHIPSInitVideo(pScreen); 4293 } 4294 4295 pScreen->SaveScreen = CHIPSSaveScreen; 4296 4297 /* Setup DPMS mode */ 4298 if (cPtr->Flags & ChipsDPMSSupport) 4299 xf86DPMSInit(pScreen, (DPMSSetProcPtr)chipsDisplayPowerManagementSet, 4300 0); 4301 4302 /* Wrap the current CloseScreen function */ 4303 cPtr->CloseScreen = pScreen->CloseScreen; 4304 pScreen->CloseScreen = CHIPSCloseScreen; 4305 4306 /* Report any unused options (only for the first generation) */ 4307 if (serverGeneration == 1) { 4308 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 4309 } 4310 4311 return TRUE; 4312} 4313 4314/* Mandatory */ 4315Bool 4316CHIPSSwitchMode(SWITCH_MODE_ARGS_DECL) 4317{ 4318 SCRN_INFO_PTR(arg); 4319 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4320 CHIPSEntPtr cPtrEnt; 4321 4322#ifdef DEBUG 4323 ErrorF("CHIPSSwitchMode\n"); 4324#endif 4325 if (cPtr->UseDualChannel) { 4326 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4327 CHIPSEntityIndex)->ptr; 4328 DUALREOPEN; 4329 } 4330 4331 return chipsModeInit(pScrn, mode); 4332} 4333 4334/* Mandatory */ 4335void 4336CHIPSAdjustFrame(ADJUST_FRAME_ARGS_DECL) 4337{ 4338 SCRN_INFO_PTR(arg); 4339 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4340 CHIPSEntPtr cPtrEnt; 4341 4342 int Base; 4343 vgaHWPtr hwp = VGAHWPTR(pScrn); 4344 unsigned char tmp; 4345 4346 if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHOWCACHE, FALSE) && y) { 4347 int lastline = cPtr->FbMapSize / 4348 ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8); 4349 lastline -= pScrn->currentMode->VDisplay; 4350 y += pScrn->virtualY - 1; 4351 if (y > lastline) y = lastline; 4352 } 4353 4354 Base = y * pScrn->displayWidth + x; 4355 4356 /* calculate base bpp dep. */ 4357 switch (pScrn->bitsPerPixel) { 4358 case 1: 4359 case 4: 4360 Base >>= 3; 4361 break; 4362 case 16: 4363 Base >>= 1; 4364 break; 4365 case 24: 4366 if (!IS_HiQV(cPtr)) 4367 Base = (Base >> 2) * 3; 4368 else 4369 Base = (Base >> 3) * 6; /* 65550 seems to need 64bit alignment */ 4370 break; 4371 case 32: 4372 break; 4373 default: /* 8bpp */ 4374 Base >>= 2; 4375 break; 4376 } 4377 4378 if (cPtr->UseDualChannel) { 4379 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4380 CHIPSEntityIndex)->ptr; 4381 DUALREOPEN; 4382 } 4383 4384 /* write base to chip */ 4385 /* 4386 * These are the generic starting address registers. 4387 */ 4388 chipsFixResume(pScrn); 4389 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 4390 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 4391 if (IS_HiQV(cPtr)) { 4392 if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1) 4393 hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80); 4394 } else { 4395 tmp = cPtr->readXR(cPtr, 0x0C); 4396 cPtr->writeXR(cPtr, 0x0C, ((Base & (IS_Wingine(cPtr) ? 0x0F0000 : 4397 0x030000)) >> 16) | (tmp & 0xF8)); 4398 } 4399 4400 if (cPtr->UseDualChannel && 4401 (! xf86IsEntityShared(pScrn->entityList[0]))) { 4402 unsigned int IOSS, MSS; 4403 IOSS = cPtr->readIOSS(cPtr); 4404 MSS = cPtr->readMSS(cPtr); 4405 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 4406 IOSS_PIPE_B)); 4407 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 4408 4409 chipsFixResume(pScrn); 4410 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 4411 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 4412 if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1) 4413 hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80); 4414 4415 cPtr->writeIOSS(cPtr, IOSS); 4416 cPtr->writeMSS(cPtr, hwp, MSS); 4417 } 4418 4419} 4420 4421/* Mandatory */ 4422static Bool 4423CHIPSCloseScreen(CLOSE_SCREEN_ARGS_DECL) 4424{ 4425 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 4426 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4427 CHIPSEntPtr cPtrEnt; 4428 4429 if(pScrn->vtSema){ /*§§§*/ 4430 if (cPtr->Flags & ChipsDualChannelSupport) { 4431 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4432 CHIPSEntityIndex)->ptr; 4433 if (cPtr->UseDualChannel) 4434 DUALREOPEN; 4435 DUALCLOSE; 4436 } else { 4437 chipsHWCursorOff(cPtr, pScrn); 4438 chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg, 4439#ifdef AVOID_VGAHW 4440 FALSE); 4441#else 4442 TRUE); 4443#endif 4444 chipsLock(pScrn); 4445 } 4446 chipsUnmapMem(pScrn); 4447 } 4448 4449 if (xf86IsEntityShared(pScrn->entityList[0])) { 4450 DevUnion *pPriv; 4451 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], CHIPSEntityIndex); 4452 cPtrEnt = pPriv->ptr; 4453 cPtrEnt->refCount--; 4454 } 4455#ifdef HAVE_XAA_H 4456 if (cPtr->AccelInfoRec) 4457 XAADestroyInfoRec(cPtr->AccelInfoRec); 4458#endif 4459 if (cPtr->CursorInfoRec) 4460 xf86DestroyCursorInfoRec(cPtr->CursorInfoRec); 4461 free(cPtr->ShadowPtr); 4462 free(cPtr->DGAModes); 4463 pScrn->vtSema = FALSE; 4464 if(cPtr->BlockHandler) 4465 pScreen->BlockHandler = cPtr->BlockHandler; 4466 4467 pScreen->CloseScreen = cPtr->CloseScreen; /*§§§*/ 4468 xf86ClearPrimInitDone(pScrn->entityList[0]); 4469 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);/*§§§*/ 4470} 4471 4472/* Optional */ 4473static void 4474CHIPSFreeScreen(FREE_SCREEN_ARGS_DECL) 4475{ 4476 SCRN_INFO_PTR(arg); 4477 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 4478 vgaHWFreeHWRec(pScrn); 4479 CHIPSFreeRec(pScrn); 4480} 4481 4482/* Optional */ 4483static ModeStatus 4484CHIPSValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 4485{ 4486 SCRN_INFO_PTR(arg); 4487 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4488 4489 /* The tests here need to be expanded */ 4490 if ((mode->Flags & V_INTERLACE) && (cPtr->PanelType & ChipsLCD)) 4491 return MODE_NO_INTERLACE; 4492 if ((cPtr->PanelType & ChipsLCD) 4493 && !xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE) 4494 && ((cPtr->PanelSize.HDisplay < mode->HDisplay) 4495 || (cPtr->PanelSize.VDisplay < mode->VDisplay))) 4496 return MODE_PANEL; 4497 4498 return MODE_OK; 4499} 4500 4501/* 4502 * DPMS Control registers 4503 * 4504 * XR73 6554x and 64300 (what about 65535?) 4505 * XR61 6555x 4506 * 0 HSync Powerdown data 4507 * 1 HSync Select 1=Powerdown 4508 * 2 VSync Powerdown data 4509 * 3 VSync Select 1=Powerdown 4510 */ 4511 4512static void 4513chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 4514 int flags) 4515{ 4516 vgaHWPtr hwp = VGAHWPTR(pScrn); 4517 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4518 CHIPSEntPtr cPtrEnt; 4519 4520 unsigned char dpmsreg, seqreg, lcdoff, tmp; 4521 4522 if (!pScrn->vtSema) 4523 return; 4524 4525#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 8 4526 xf86EnableAccess(pScrn); 4527#endif 4528 switch (PowerManagementMode) { 4529 case DPMSModeOn: 4530 /* Screen: On; HSync: On, VSync: On */ 4531 dpmsreg = 0x00; 4532 seqreg = 0x00; 4533 lcdoff = 0x0; 4534 break; 4535 case DPMSModeStandby: 4536 /* Screen: Off; HSync: Off, VSync: On */ 4537 dpmsreg = 0x02; 4538 seqreg = 0x20; 4539 lcdoff = 0x0; 4540 break; 4541 case DPMSModeSuspend: 4542 /* Screen: Off; HSync: On, VSync: Off */ 4543 dpmsreg = 0x08; 4544 seqreg = 0x20; 4545 lcdoff = 0x1; 4546 break; 4547 case DPMSModeOff: 4548 /* Screen: Off; HSync: Off, VSync: Off */ 4549 dpmsreg = 0x0A; 4550 seqreg = 0x20; 4551 lcdoff = 0x1; 4552 break; 4553 default: 4554 return; 4555 } 4556 4557 if (cPtr->UseDualChannel) { 4558 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4559 CHIPSEntityIndex)->ptr; 4560 DUALREOPEN; 4561 } 4562 4563 seqreg |= hwp->readSeq(hwp, 0x01) & ~0x20; 4564 hwp->writeSeq(hwp, 0x01, seqreg); 4565 if (IS_HiQV(cPtr)) { 4566 tmp = cPtr->readXR(cPtr, 0x61); 4567 cPtr->writeXR(cPtr, 0x61, (tmp & 0xF0) | dpmsreg); 4568 } else { 4569 tmp = cPtr->readXR(cPtr, 0x73); 4570 cPtr->writeXR(cPtr, 0x73, (tmp & 0xF0) | dpmsreg); 4571 } 4572 4573 /* Turn off the flat panel */ 4574 if (cPtr->PanelType & ChipsLCDProbed) { 4575 if (IS_HiQV(cPtr)) { 4576 if (cPtr->Chipset == CHIPS_CT69030) { 4577#if 0 4578 /* Where is this for the 69030?? */ 4579 tmp = cPtr->readFR(cPtr, 0x05); 4580 if (lcdoff) 4581 cPtr->writeFR(cPtr, 0x05, tmp | 0x08); 4582 else 4583 cPtr->writeFR(cPtr, 0x05, tmp & 0xF7); 4584#endif 4585 } else { 4586 tmp = cPtr->readFR(cPtr, 0x05); 4587 if (lcdoff) 4588 cPtr->writeFR(cPtr, 0x05, tmp | 0x08); 4589 else 4590 cPtr->writeFR(cPtr, 0x05, tmp & 0xF7); 4591 } 4592 } else { 4593 tmp = cPtr->readXR(cPtr, 0x52); 4594 if (lcdoff) 4595 cPtr->writeXR(cPtr, 0x52, tmp | 0x08); 4596 else 4597 cPtr->writeXR(cPtr, 0x52, tmp & 0xF7); 4598 } 4599 } 4600} 4601 4602static Bool 4603CHIPSSaveScreen(ScreenPtr pScreen, int mode) 4604{ 4605 ScrnInfoPtr pScrn = NULL; /* §§§ */ 4606 Bool unblank; 4607 4608 unblank = xf86IsUnblank(mode); 4609 4610 if (pScreen != NULL) 4611 pScrn = xf86ScreenToScrn(pScreen); 4612 4613 if (unblank) 4614 SetTimeSinceLastInputEvent(); 4615 4616 if ((pScrn != NULL) && pScrn->vtSema) { /* §§§ */ 4617 chipsBlankScreen(pScrn, unblank); 4618 } 4619 return (TRUE); 4620} 4621 4622static Bool 4623chipsClockSelect(ScrnInfoPtr pScrn, int no) 4624{ 4625 CHIPSClockReg TmpClock; 4626 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4627 4628 switch (no) { 4629 case CLK_REG_SAVE: 4630 chipsClockSave(pScrn, &cPtr->SaveClock); 4631 break; 4632 4633 case CLK_REG_RESTORE: 4634 chipsClockLoad(pScrn, &cPtr->SaveClock); 4635 break; 4636 4637 default: 4638 if (!chipsClockFind(pScrn, NULL, no, &TmpClock)) 4639 return (FALSE); 4640 chipsClockLoad(pScrn, &TmpClock); 4641 } 4642 return (TRUE); 4643} 4644 4645/* 4646 * 4647 * Fout = (Fref * 4 * M) / (PSN * N * (1 << P) ) 4648 * Fvco = (Fref * 4 * M) / (PSN * N) 4649 * where 4650 * M = XR31+2 4651 * N = XR32+2 4652 * P = XR30[3:1] 4653 * PSN = XR30[0]? 1:4 4654 * 4655 * constraints: 4656 * 4 MHz <= Fref <= 20 MHz (typ. 14.31818 MHz) 4657 * 150 kHz <= Fref/(PSN * N) <= 2 MHz 4658 * 48 MHz <= Fvco <= 220 MHz 4659 * 2 < M < 128 4660 * 2 < N < 128 4661 */ 4662 4663static void 4664chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock) 4665{ 4666 unsigned char tmp; 4667 vgaHWPtr hwp = VGAHWPTR(pScrn); 4668 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4669 unsigned char Type = cPtr->ClockType; 4670 CHIPSEntPtr cPtrEnt; 4671 4672 Clock->msr = hwp->readMiscOut(hwp)&0xFE; /* save standard VGA clock reg */ 4673 switch (Type & GET_STYLE) { 4674 case HiQV_STYLE: 4675 /* save alternate clock select reg.*/ 4676 /* The 69030 FP clock select is at FR01 instead */ 4677 if (cPtr->UseDualChannel) { 4678 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4679 CHIPSEntityIndex)->ptr; 4680 DUALREOPEN; 4681 } 4682 4683 if (cPtr->Flags & ChipsDualChannelSupport) 4684 Clock->fr03 = cPtr->readFR(cPtr, 0x01); 4685 else 4686 Clock->fr03 = cPtr->readFR(cPtr, 0x03); 4687 if (!Clock->Clock) { /* save HiQV console clock */ 4688 tmp = cPtr->CRTclkInx << 2; 4689 cPtr->CRTClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp); 4690 cPtr->CRTClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp); 4691 cPtr->CRTClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp); 4692 cPtr->CRTClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp); 4693 tmp = cPtr->FPclkInx << 2; 4694 cPtr->FPClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp); 4695 cPtr->FPClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp); 4696 cPtr->FPClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp); 4697 cPtr->FPClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp); 4698 } 4699 break; 4700 case OLD_STYLE: 4701 Clock->fcr = hwp->readFCR(hwp); 4702 Clock->xr02 = cPtr->readXR(cPtr, 0x02); 4703 Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/ 4704 break; 4705 case WINGINE_1_STYLE: 4706 case WINGINE_2_STYLE: 4707 break; 4708 case NEW_STYLE: 4709 Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/ 4710 Clock->xr33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK sel reg.*/ 4711 break; 4712 } 4713#ifdef DEBUG 4714 ErrorF("saved \n"); 4715#endif 4716} 4717 4718static Bool 4719chipsClockFind(ScrnInfoPtr pScrn, DisplayModePtr mode, 4720 int no, CHIPSClockPtr Clock ) 4721{ 4722 vgaHWPtr hwp = VGAHWPTR(pScrn); 4723 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4724 unsigned char Type = cPtr->ClockType; 4725 CHIPSEntPtr cPtrEnt; 4726 4727 if (no > (pScrn->numClocks - 1)) 4728 return (FALSE); 4729 4730 if (cPtr->UseDualChannel) { 4731 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 4732 CHIPSEntityIndex)->ptr; 4733 DUALREOPEN; 4734 } 4735 4736 switch (Type & GET_STYLE) { 4737 case HiQV_STYLE: 4738 Clock->msr = cPtr->CRTclkInx << 2; 4739 Clock->fr03 = cPtr->FPclkInx << 2; 4740 Clock->Clock = mode ? mode->Clock : 0; 4741 if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 4742 Clock->FPClock = mode ? mode->Clock : 0; 4743 } else 4744 Clock->FPClock = cPtr->FPclock; 4745 break; 4746 case NEW_STYLE: 4747 if (Type & TYPE_HW) { 4748 Clock->msr = (no == 4 ? 3 << 2: (no & 0x01) << 2); 4749 Clock->xr54 = Clock->msr; 4750 Clock->xr33 = no > 1 ? 0x80 : 0; 4751 } else { 4752 Clock->msr = 3 << 2; 4753 Clock->xr33 = 0; 4754 Clock->xr54 = Clock->msr; 4755 /* update panel type in case somebody switched. 4756 * This should be handled more generally: 4757 * On mode switch DDC should be reread, all 4758 * display dependent data should be reevaluated. 4759 * This will be built in when we start Display 4760 * HotPlug support. 4761 * Until then we have to do it here as somebody 4762 * might have switched displays on us and we only 4763 * have one programmable clock which needs to 4764 * be shared for CRT and LCD. 4765 */ 4766 chipsSetPanelType(cPtr); 4767 { 4768 Bool fp_m; 4769 if (cPtr->Options 4770 && xf86GetOptValBool(cPtr->Options, OPTION_FP_MODE, &fp_m)) { 4771 if (fp_m) 4772 cPtr->PanelType |= ChipsLCD; 4773 else 4774 cPtr->PanelType = ~ChipsLCD; 4775 } 4776 } 4777 4778 if ((cPtr->PanelType & ChipsLCD) && cPtr->FPclock) 4779 Clock->Clock = cPtr->FPclock; 4780 else 4781 Clock->Clock = mode ? mode->SynthClock : 0; 4782 } 4783 break; 4784 case OLD_STYLE: 4785 if (no > 3) { 4786 Clock->msr = 3 << 2; 4787 Clock->fcr = no & 0x03; 4788 Clock->xr02 = 0; 4789 Clock->xr54 = Clock->msr & (Clock->fcr << 4); 4790 } else { 4791 Clock->msr = (no << 2) & 0x4; 4792 Clock->fcr = 0; 4793 Clock->xr02 = no & 0x02; 4794 Clock->xr54 = Clock->msr; 4795 } 4796 break; 4797 case WINGINE_1_STYLE: 4798 Clock->msr = no << 2; 4799 case WINGINE_2_STYLE: 4800 if (Type & TYPE_HW) { 4801 Clock->msr = (no == 2 ? 3 << 2: (no & 0x01) << 2); 4802 Clock->xr33 = 0; 4803 } else { 4804 Clock->msr = 3 << 2; 4805 Clock->xr33 = 0; 4806 Clock->Clock = mode ? mode->SynthClock : 0; 4807 } 4808 break; 4809 } 4810 Clock->msr |= (hwp->readMiscOut(hwp) & 0xF2); 4811 4812#ifdef DEBUG 4813 ErrorF("found\n"); 4814#endif 4815 return (TRUE); 4816} 4817 4818 4819static int 4820chipsGetHWClock(ScrnInfoPtr pScrn) 4821{ 4822 vgaHWPtr hwp = VGAHWPTR(pScrn); 4823 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4824 unsigned char Type = cPtr->ClockType; 4825 unsigned char tmp, tmp1; 4826 4827 if (!(Type & TYPE_HW)) 4828 return 0; /* shouldn't happen */ 4829 4830 switch (Type & GET_STYLE) { 4831 case WINGINE_1_STYLE: 4832 return ((hwp->readMiscOut(hwp) & 0x0C) >> 2); 4833 case WINGINE_2_STYLE: 4834 tmp = ((hwp->readMiscOut(hwp) & 0x04) >> 2); 4835 return (tmp > 2) ? 2 : tmp; 4836 case OLD_STYLE: 4837 if (!(cPtr->PanelType & ChipsLCDProbed)) 4838 tmp = hwp->readMiscOut(hwp); 4839 else 4840 tmp = cPtr->readXR(cPtr, 0x54); 4841 if (tmp & 0x08) { 4842 if (!(cPtr->PanelType & ChipsLCDProbed)) 4843 tmp = hwp->readFCR(hwp) & 0x03; 4844 else 4845 tmp = (tmp >> 4) & 0x03; 4846 return (tmp + 4); 4847 } else { 4848 tmp = (tmp >> 2) & 0x01; 4849 tmp1 = cPtr->readXR(cPtr, 0x02); 4850 return (tmp + (tmp1 & 0x02)); 4851 } 4852 case NEW_STYLE: 4853 if (cPtr->PanelType & ChipsLCDProbed) { 4854 tmp = cPtr->readXR(cPtr, 0x54); 4855 } else 4856 tmp = hwp->readMiscOut(hwp); 4857 tmp = (tmp & 0x0C) >> 2; 4858 if (tmp > 1) return 4; 4859 tmp1 = cPtr->readXR(cPtr, 0x33); 4860 tmp1 = (tmp1 & 0x80) >> 6; /* iso mode 25.175/28.322 or 32/36 MHz */ 4861 return (tmp + tmp1); /* ^=0 ^=1 ^=4 ^=5 */ 4862 default: /* we should never get here */ 4863 return (0); 4864 } 4865} 4866 4867static void 4868chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock) 4869{ 4870 vgaHWPtr hwp = VGAHWPTR(pScrn); 4871 CHIPSPtr cPtr = CHIPSPTR(pScrn); 4872 unsigned char Type = cPtr->ClockType; 4873 volatile unsigned char tmp, tmpmsr, tmpfcr, tmp02; 4874 volatile unsigned char tmp33, tmp54, tmpf03; 4875 unsigned char vclk[3]; 4876 4877 tmpmsr = hwp->readMiscOut(hwp); /* read msr, needed for all styles */ 4878 4879 switch (Type & GET_STYLE) { 4880 case HiQV_STYLE: 4881 /* save alternate clock select reg. */ 4882 /* The 69030 FP clock select is at FR01 instead */ 4883 if (cPtr->Flags & ChipsDualChannelSupport) { 4884 tmpf03 = cPtr->readFR(cPtr, 0x01); 4885 } else 4886 tmpf03 = cPtr->readFR(cPtr, 0x03); 4887 /* select fixed clock 0 before tampering with VCLK select */ 4888 hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) | 4889 cPtr->SuspendHack.vgaIOBaseFlag); 4890 /* The 69030 FP clock select is at FR01 instead */ 4891 if (cPtr->Flags & ChipsDualChannelSupport) { 4892 cPtr->writeFR(cPtr, 0x01, (tmpf03 & ~0x0C) | 0x04); 4893 } else 4894 cPtr->writeFR(cPtr, 0x03, (tmpf03 & ~0x0C) | 0x04); 4895 if (!Clock->Clock) { /* Hack to load saved console clock */ 4896 tmp = cPtr->CRTclkInx << 2; 4897 cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->CRTClk[0] & 0xFF)); 4898 cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->CRTClk[1] & 0xFF)); 4899 cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->CRTClk[2] & 0xFF)); 4900 cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->CRTClk[3] & 0xFF)); 4901 4902 if (cPtr->FPClkModified) { 4903 usleep(10000); /* let VCO stabilize */ 4904 tmp = cPtr->FPclkInx << 2; 4905 cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->FPClk[0] & 0xFF)); 4906 cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->FPClk[1] & 0xFF)); 4907 cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->FPClk[2] & 0xFF)); 4908 cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->FPClk[3] & 0xFF)); 4909 } 4910 } else { 4911 /* 4912 * Don't use the extra 2 bits in the M, N registers available 4913 * on the HiQV, so write zero to 0xCA 4914 */ 4915 chipsCalcClock(pScrn, Clock->Clock, vclk); 4916 tmp = cPtr->CRTclkInx << 2; 4917 cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF)); 4918 cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF)); 4919 cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0); 4920 cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF)); 4921 if (Clock->FPClock) { 4922 usleep(10000); /* let VCO stabilize */ 4923 chipsCalcClock(pScrn, Clock->FPClock, vclk); 4924 tmp = cPtr->FPclkInx << 2; 4925 cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF)); 4926 cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF)); 4927 cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0); 4928 cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF)); 4929 cPtr->FPClkModified = TRUE; 4930 } 4931 } 4932 usleep(10000); /* Let VCO stabilise */ 4933 /* The 69030 FP clock select is at FR01 instead */ 4934 if (cPtr->Flags & ChipsDualChannelSupport) { 4935 cPtr->writeFR(cPtr, 0x01, ((tmpf03 & ~0x0C) | 4936 (Clock->fr03 & 0x0C))); 4937 } else 4938 cPtr->writeFR(cPtr, 0x03, ((tmpf03 & ~0x0C) | 4939 (Clock->fr03 & 0x0C))); 4940 break; 4941 case WINGINE_1_STYLE: 4942 break; 4943 case WINGINE_2_STYLE: 4944 /* Only write to soft clock registers if we really need to */ 4945 if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) { 4946 /* select fixed clock 0 before tampering with VCLK select */ 4947 hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) | 4948 cPtr->SuspendHack.vgaIOBaseFlag); 4949 chipsCalcClock(pScrn, Clock->Clock, vclk); 4950 tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */ 4951 cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20); 4952 cPtr->writeXR(cPtr, 0x30, vclk[0]); 4953 cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */ 4954 cPtr->writeXR(cPtr, 0x32, vclk[2]); 4955 /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/ 4956 usleep(10000); /* Let VCO stabilise */ 4957 } 4958 break; 4959 case OLD_STYLE: 4960 tmp02 = cPtr->readXR(cPtr, 0x02); 4961 tmp54 = cPtr->readXR(cPtr, 0x54); 4962 tmpfcr = hwp->readFCR(hwp); 4963 cPtr->writeXR(cPtr, 0x02, ((tmp02 & ~0x02) | (Clock->xr02 & 0x02))); 4964 cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF0) | (Clock->xr54 & ~0xF0))); 4965 hwp->writeFCR(hwp, (tmpfcr & ~0x03) & Clock->fcr); 4966 break; 4967 case NEW_STYLE: 4968 tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */ 4969 tmp54 = cPtr->readXR(cPtr, 0x54); 4970 /* Only write to soft clock registers if we really need to */ 4971 if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) { 4972 /* select fixed clock 0 before tampering with VCLK select */ 4973 hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) | 4974 cPtr->SuspendHack.vgaIOBaseFlag); 4975 cPtr->writeXR(cPtr, 0x54, (tmp54 & 0xF3)); 4976 /* if user wants to set the memory clock, do it first */ 4977 if (cPtr->MemClock.Clk) { 4978 chipsCalcClock(pScrn, cPtr->MemClock.Clk, vclk); 4979 /* close eyes, hold breath ....*/ 4980 cPtr->writeXR(cPtr, 0x33, tmp33 | 0x20); 4981 cPtr->writeXR(cPtr, 0x30, vclk[0]); 4982 cPtr->writeXR(cPtr, 0x31, vclk[1]); 4983 cPtr->writeXR(cPtr, 0x32, vclk[2]); 4984 usleep(10000); 4985 } 4986 chipsCalcClock(pScrn, Clock->Clock, vclk); 4987 cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20); 4988 cPtr->writeXR(cPtr, 0x30, vclk[0]); 4989 cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */ 4990 cPtr->writeXR(cPtr, 0x32, vclk[2]); 4991 /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/ 4992 usleep(10000); /* Let VCO stabilise */ 4993 } 4994 cPtr->writeXR(cPtr, 0x33, ((tmp33 & ~0x80) | (Clock->xr33 & 0x80))); 4995 cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF3) | (Clock->xr54 & ~0xF3))); 4996 break; 4997 } 4998 hwp->writeMiscOut(hwp, (Clock->msr & 0xFE) | 4999 cPtr->SuspendHack.vgaIOBaseFlag); 5000#ifdef DEBUG 5001 ErrorF("restored\n"); 5002#endif 5003} 5004 5005/* 5006 * This is Ken Raeburn's <raeburn@raeburn.org> clock 5007 * calculation code just modified a little bit to fit in here. 5008 */ 5009 5010static void 5011chipsCalcClock(ScrnInfoPtr pScrn, int Clock, unsigned char *vclk) 5012{ 5013 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5014 int M, N, P = 0, PSN = 0, PSNx = 0; 5015 5016 int bestM = 0, bestN = 0, bestP = 0, bestPSN = 0; 5017 double abest = 42; 5018#ifdef DEBUG 5019 double bestFout = 0; 5020#endif 5021 double target; 5022 5023 double Fvco, Fout; 5024 double error, aerror; 5025 5026 int M_min = 3; 5027 5028 /* Hack to deal with problem of Toshiba 720CDT clock */ 5029 int M_max = (IS_HiQV(cPtr) && cPtr->Chipset != CHIPS_CT69000 && 5030 cPtr->Chipset != CHIPS_CT69030) ? 63 : 127; 5031 5032 /* @@@ < CHIPS_CT690x0 ?? */ 5033 5034 /* Other parameters available on the 65548 but not the 65545, and 5035 * not documented in the Clock Synthesizer doc in rev 1.0 of the 5036 * 65548 datasheet: 5037 * 5038 * + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545) 5039 * 1, VCO divider loop uses divide by 16 5040 * 5041 * + XR30[5] = 1, reference clock is divided by 5 5042 * 5043 * Other parameters available on the 65550 and not on the 65545 5044 * 5045 * + XRCB[2] = 0, VCO divider loop uses divide by 4 (same as 65545) 5046 * 1, VCO divider loop uses divide by 16 5047 * 5048 * + XRCB[1] = 1, reference clock is divided by 5 5049 * 5050 * + XRCB[7] = Vclk = Mclk 5051 * 5052 * + XRCA[0:1] = 2 MSB of a 10 bit M-Divisor 5053 * 5054 * + XRCA[4:5] = 2 MSB of a 10 bit N-Divisor 5055 * 5056 * I haven't put in any support for those here. For simplicity, 5057 * they should be set to 0 on the 65548, and left untouched on 5058 * earlier chips. 5059 * 5060 * Other parameters available on the 690x0 5061 * 5062 * + The 690x0 has no reference clock divider, so PSN must 5063 * always be 1. 5064 * XRCB[0:1] are reserved according to the data book 5065 */ 5066 5067 5068 target = Clock * 1000; 5069 5070 /* @@@ >= CHIPS_CT690x0 ?? */ 5071 for (PSNx = ((cPtr->Chipset == CHIPS_CT69000) || 5072 (cPtr->Chipset == CHIPS_CT69030)) ? 1 : 0; PSNx <= 1; PSNx++) { 5073 int low_N, high_N; 5074 double Fref4PSN; 5075 5076 PSN = PSNx ? 1 : 4; 5077 5078 low_N = 3; 5079 high_N = 127; 5080 5081 while (Fref / (PSN * low_N) > (((cPtr->Chipset == CHIPS_CT69000) || 5082 (cPtr->Chipset == CHIPS_CT69030)) ? 5.0e6 : 2.0e6)) 5083 low_N++; 5084 while (Fref / (PSN * high_N) < 150.0e3) 5085 high_N--; 5086 5087 Fref4PSN = Fref * 4 / PSN; 5088 for (N = low_N; N <= high_N; N++) { 5089 double tmp = Fref4PSN / N; 5090 5091 /* @@@ < CHIPS_CT690x0 ?? */ 5092 for (P = (IS_HiQV(cPtr) && (cPtr->Chipset != CHIPS_CT69000) && 5093 (cPtr->Chipset != CHIPS_CT69030)) ? 1 : 0; 5094 P <= 5; P++) { 5095 /* to force post divisor on Toshiba 720CDT */ 5096 double Fvco_desired = target * (1 << P); 5097 double M_desired = Fvco_desired / tmp; 5098 5099 /* Which way will M_desired be rounded? Do all three just to 5100 * be safe. */ 5101 int M_low = M_desired - 1; 5102 int M_hi = M_desired + 1; 5103 5104 if (M_hi < M_min || M_low > M_max) 5105 continue; 5106 5107 if (M_low < M_min) 5108 M_low = M_min; 5109 if (M_hi > M_max) 5110 M_hi = M_max; 5111 5112 for (M = M_low; M <= M_hi; M++) { 5113 Fvco = tmp * M; 5114 /* @@@ >= CHIPS_CT690x0 ?? */ 5115 if (Fvco <= ((cPtr->Chipset == CHIPS_CT69000 || 5116 cPtr->Chipset == CHIPS_CT69030) ? 100.0e6 : 48.0e6)) 5117 continue; 5118 if (Fvco > 220.0e6) 5119 break; 5120 5121 Fout = Fvco / (1 << P); 5122 5123 error = (target - Fout) / target; 5124 5125 aerror = (error < 0) ? -error : error; 5126 if (aerror < abest) { 5127 abest = aerror; 5128 bestM = M; 5129 bestN = N; 5130 bestP = P; 5131 bestPSN = PSN; 5132#ifdef DEBUG 5133 bestFout = Fout; 5134#endif 5135 } 5136 } 5137 } 5138 } 5139 } 5140 /* @@@ >= CHIPS_CT690x0 ?? */ 5141 vclk[0] = (bestP << (IS_HiQV(cPtr) ? 4 : 1)) + 5142 (((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030)) 5143 ? 0 : (bestPSN == 1)); 5144 vclk[1] = bestM - 2; 5145 vclk[2] = bestN - 2; 5146#ifdef DEBUG 5147 ErrorF("Freq. selected: %.2f MHz, vclk[0]=%X, vclk[1]=%X, vclk[2]=%X\n", 5148 (float)(Clock / 1000.), vclk[0], vclk[1], vclk[2]); 5149 ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6); 5150#endif 5151} 5152 5153static void 5154chipsSave(ScrnInfoPtr pScrn, vgaRegPtr VgaSave, CHIPSRegPtr ChipsSave) 5155{ 5156 vgaHWPtr hwp = VGAHWPTR(pScrn); 5157 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5158 int i; 5159 unsigned char tmp; 5160#ifdef DEBUG 5161 ErrorF("chipsSave\n"); 5162#endif 5163 5164 /* set registers that we can program the controller */ 5165 /* bank 0 */ 5166 if (IS_HiQV(cPtr)) { 5167 cPtr->writeXR(cPtr, 0x0E, 0x00); 5168 } else { 5169 cPtr->writeXR(cPtr, 0x10, 0x00); 5170 cPtr->writeXR(cPtr, 0x11, 0x00); 5171 tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */ 5172 cPtr->writeXR(cPtr, 0x0C, tmp); 5173 } 5174 chipsFixResume(pScrn); 5175 tmp = cPtr->readXR(cPtr, 0x02); 5176 cPtr->writeXR(cPtr, 0x02, tmp & ~0x18); 5177 /* get generic registers */ 5178#ifdef AVOID_VGAHW 5179 vgaHWSave(pScrn, VgaSave, VGA_SR_CMAP | VGA_SR_MODE); 5180#else 5181 vgaHWSave(pScrn, VgaSave, VGA_SR_ALL); 5182#endif 5183 /* save clock */ 5184 chipsClockSave(pScrn, &ChipsSave->Clock); 5185 5186 /* save extended registers */ 5187 if (IS_HiQV(cPtr)) { 5188 for (i = 0; i < 0xFF; i++) { 5189#ifdef SAR04 5190 /* Save SAR04 multimedia register correctly */ 5191 if (i == 0x4F) 5192 cPtr->writeXR(cPtr, 0x4E, 0x04); 5193#endif 5194 ChipsSave->XR[i] = cPtr->readXR(cPtr,i); 5195#ifdef DEBUG 5196 ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]); 5197#endif 5198 } 5199 for (i = 0; i < 0x80; i++) { 5200 ChipsSave->FR[i] = cPtr->readFR(cPtr, i); 5201#ifdef DEBUG 5202 ErrorF("FS%X - %X\n", i, ChipsSave->FR[i]); 5203#endif 5204 } 5205 for (i = 0; i < 0x80; i++) { 5206 ChipsSave->MR[i] = cPtr->readMR(cPtr, i); 5207#ifdef DEBUG 5208 ErrorF("MS%X - %X\n", i, ChipsSave->FR[i]); 5209#endif 5210 } 5211 /* Save CR0-CR40 even though we don't use them, so they can be 5212 * printed */ 5213 for (i = 0x0; i < 0x80; i++) { 5214 ChipsSave->CR[i] = hwp->readCrtc(hwp, i); 5215#ifdef DEBUG 5216 ErrorF("CS%X - %X\n", i, ChipsSave->CR[i]); 5217#endif 5218 } 5219 } else { 5220 for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */ 5221 ChipsSave->XR[i] = cPtr->readXR(cPtr, i); 5222#ifdef DEBUG 5223 ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]); 5224#endif 5225 } 5226 } 5227} 5228 5229Bool 5230chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 5231{ 5232 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5233#ifdef DEBUG 5234 ErrorF("chipsModeInit\n"); 5235#endif 5236#if 0 5237 *(int*)0xFFFFFF0 = 0; 5238 ErrorF("done\n"); 5239#endif 5240 5241 chipsUnlock(pScrn); 5242 chipsFixResume(pScrn); 5243 5244 if (cPtr->Accel.UseHWCursor) 5245 cPtr->Flags |= ChipsHWCursor; 5246 else 5247 cPtr->Flags &= ~ChipsHWCursor; 5248 /* 5249 * We need to delay cursor loading after resetting the video mode 5250 * to give the engine a chance to recover. 5251 */ 5252 cPtr->cursorDelay = TRUE; 5253 5254 if (IS_HiQV(cPtr)) 5255 return chipsModeInitHiQV(pScrn, mode); 5256 else if (IS_Wingine(cPtr)) 5257 return chipsModeInitWingine(pScrn, mode); 5258 else 5259 return chipsModeInit655xx(pScrn, mode); 5260} 5261 5262/* 5263 * The timing register of the C&T FP chipsets are organized 5264 * as follows: 5265 * The chipsets have two sets of timing registers: 5266 * the standard horizontal and vertical timing registers for 5267 * display size, blank start, sync start, sync end, blank end 5268 * and total size at their default VGA locations and extensions 5269 * and the alternate horizontal and vertical timing registers for 5270 * display size, sync start, sync end and total size. 5271 * In LCD and mixed (LCD+CRT) mode the alternate timing registers 5272 * control the timing. The alternate horizontal and vertical display 5273 * size registers are set to the physical pixel size of the display. 5274 * Normally the alternalte registers are set by the BIOS to optimized 5275 * values. 5276 * While the horizontal an vertical refresh rates are fixed independent 5277 * of the visible display size to ensure optimal performance of both 5278 * displays they can be adapted to the screen resolution and CRT 5279 * requirements in CRT mode by programming the standard timing registers 5280 * in the VGA fashion. 5281 * In LCD and mixed mode the _standard_ horizontal and vertical display 5282 * size registers control the size of the _visible_ part of the display 5283 * in contast to the _physical_ size of the display which is specified 5284 * by the _alternate_ horizontal and vertical display size registers. 5285 * The size of the visible should always be equal or less than the 5286 * physical size. 5287 * For the 69030 chipsets, the CRT and LCD display channels are separate 5288 * and so can be driven independently. 5289 */ 5290static Bool 5291chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode) 5292{ 5293 int i; 5294 int lcdHTotal, lcdHDisplay; 5295 int lcdVTotal, lcdVDisplay; 5296 int lcdHRetraceStart, lcdHRetraceEnd; 5297 int lcdVRetraceStart, lcdVRetraceEnd; 5298 int lcdHSyncStart; 5299 vgaHWPtr hwp = VGAHWPTR(pScrn); 5300 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5301 CHIPSRegPtr ChipsNew; 5302 vgaRegPtr ChipsStd; 5303 unsigned int tmp; 5304 5305 ChipsNew = &cPtr->ModeReg; 5306 ChipsStd = &hwp->ModeReg; 5307 5308 5309 /* 5310 * Possibly fix up the panel size, if the manufacture is stupid 5311 * enough to set it incorrectly in text modes 5312 */ 5313 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 5314 cPtr->PanelSize.HDisplay = mode->CrtcHDisplay; 5315 cPtr->PanelSize.VDisplay = mode->CrtcVDisplay; 5316 } 5317 5318 /* generic init */ 5319 if (!vgaHWInit(pScrn, mode)) { 5320 ErrorF("bomb 1\n"); 5321 return (FALSE); 5322 } 5323 pScrn->vtSema = TRUE; 5324 5325 /* init clock */ 5326 if (!chipsClockFind(pScrn, mode, mode->ClockIndex, &ChipsNew->Clock)) { 5327 ErrorF("bomb 2\n"); 5328 return (FALSE); 5329 } 5330 5331 /* Give Warning if the dual display mode will cause problems */ 5332 /* Note 64bit wide memory bus assumed (as in 69000 and 69030 */ 5333 if (cPtr->UseDualChannel && ((cPtr->SecondCrtc == TRUE) || 5334 (cPtr->Flags & ChipsDualRefresh))) { 5335 if (((ChipsNew->Clock.FPClock + ChipsNew->Clock.Clock) * 5336 (max(1, pScrn->bitsPerPixel >> 3) + 5337 ((cPtr->FrameBufferSize && (cPtr->PanelType & ChipsLCD)) ? 5338 1 : 0)) / (8 * 0.7)) > cPtr->MemClock.Max) { 5339 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5340 "Memory bandwidth requirements exceeded by dual-channel\n"); 5341 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5342 " mode. Display might be corrupted!!!\n"); 5343 } 5344 } 5345 5346 /* get C&T Specific Registers */ 5347 for (i = 0; i < 0xFF; i++) { 5348#ifdef SAR04 5349 /* Save SAR04 multimedia register correctly */ 5350 if (i == 0x4F) 5351 cPtr->writeXR(cPtr, 0x4E, 0x04); 5352#endif 5353 ChipsNew->XR[i] = cPtr->readXR(cPtr, i); 5354 } 5355 for (i = 0; i < 0x80; i++) { 5356 ChipsNew->FR[i] = cPtr->readFR(cPtr, i); 5357 } 5358 for (i = 0; i < 0x80; i++) { 5359 ChipsNew->MR[i] = cPtr->readMR(cPtr, i); 5360 } 5361 for (i = 0x30; i < 0x80; i++) { /* These are the CT extended CRT regs */ 5362 ChipsNew->CR[i] = hwp->readCrtc(hwp, i); 5363 } 5364 5365 /* 5366 * Here all of the other fields of 'ChipsNew' get filled in, to 5367 * handle the SVGA extended registers. It is also allowable 5368 * to override generic registers whenever necessary. 5369 */ 5370 5371 /* some generic settings */ 5372 if (pScrn->depth == 1) { 5373 ChipsStd->Attribute[0x10] = 0x03; /* mode */ 5374 } else { 5375 ChipsStd->Attribute[0x10] = 0x01; /* mode */ 5376 } 5377 ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */ 5378 ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */ 5379 ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ 5380 5381 ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */ 5382 5383 /* set virtual screen width */ 5384 tmp = pScrn->displayWidth >> 3; 5385 if (pScrn->bitsPerPixel == 16) { 5386 tmp <<= 1; /* double the width of the buffer */ 5387 } else if (pScrn->bitsPerPixel == 24) { 5388 tmp += tmp << 1; 5389 } else if (pScrn->bitsPerPixel == 32) { 5390 tmp <<= 2; 5391 } else if (pScrn->bitsPerPixel < 8) { 5392 tmp >>= 1; 5393 } 5394 ChipsStd->CRTC[0x13] = tmp & 0xFF; 5395 ChipsNew->CR[0x41] = (tmp >> 8) & 0x0F; 5396 5397 /* Set paging mode on the HiQV32 architecture, if required */ 5398 if (!(cPtr->Flags & ChipsLinearSupport) || (pScrn->bitsPerPixel < 8)) 5399 ChipsNew->XR[0x0A] |= 0x1; 5400 5401#if X_BYTE_ORDER == X_BIG_ENDIAN 5402 ChipsNew->XR[0x0A] &= 0xCF; 5403 if (pScrn->bitsPerPixel == 16) { 5404 if (!cPtr->dualEndianAp) 5405 ChipsNew->XR[0x0A] |= 0x10; 5406 } 5407#endif 5408 ChipsNew->XR[0x09] |= 0x1; /* Enable extended CRT registers */ 5409 ChipsNew->XR[0x0E] = 0; /* Single map */ 5410 ChipsNew->XR[0x40] |= 0x2; /* Don't wrap at 256kb */ 5411 ChipsNew->XR[0x81] &= 0xF8; 5412 if (pScrn->bitsPerPixel >= 8) { 5413 ChipsNew->XR[0x40] |= 0x1; /* High Resolution. XR40[1] reserved? */ 5414 ChipsNew->XR[0x81] |= 0x2; /* 256 Color Video */ 5415 } 5416 ChipsNew->XR[0x80] |= 0x10; /* Enable cursor output on P0 and P1 */ 5417 if (pScrn->depth > 1) { 5418 if (pScrn->rgbBits == 8) 5419 ChipsNew->XR[0x80] |= 0x80; 5420 else 5421 ChipsNew->XR[0x80] &= ~0x80; 5422 } 5423 5424 if ((cPtr->MemClock.Clk - cPtr->MemClock.ProbedClk) > 50U) { 5425 /* set mem clk */ 5426 ChipsNew->XR[0xCC] = cPtr->MemClock.xrCC; 5427 ChipsNew->XR[0xCD] = cPtr->MemClock.xrCD; 5428 ChipsNew->XR[0xCE] = cPtr->MemClock.xrCE; 5429 } 5430 5431 /* Set the 69030 dual channel settings */ 5432 if (cPtr->Flags & ChipsDualChannelSupport) { 5433 ChipsNew->FR[0x01] &= 0xFC; 5434 if ((cPtr->SecondCrtc == FALSE) && (cPtr->PanelType & ChipsLCD)) 5435 ChipsNew->FR[0x01] |= 0x02; 5436 else 5437 ChipsNew->FR[0x01] |= 0x01; 5438 ChipsNew->FR[0x02] &= 0xCC; 5439 if ((cPtr->SecondCrtc == TRUE) || (cPtr->Flags & ChipsDualRefresh)) 5440 ChipsNew->FR[0x02] |= 0x01; /* Set DAC to pipe B */ 5441 else 5442 ChipsNew->FR[0x02] &= 0xFE; /* Set DAC to pipe A */ 5443 5444 if (cPtr->PanelType & ChipsLCD) 5445 ChipsNew->FR[0x02] |= 0x20; /* Enable the LCD output */ 5446 if (cPtr->PanelType & ChipsCRT) 5447 ChipsNew->FR[0x02] |= 0x10; /* Enable the CRT output */ 5448 } 5449 5450 /* linear specific */ 5451 if (cPtr->Flags & ChipsLinearSupport) { 5452 ChipsNew->XR[0x0A] |= 0x02; /* Linear Addressing Mode */ 5453 ChipsNew->XR[0x20] = 0x0; /*BitBLT Draw Mode for 8 */ 5454 ChipsNew->XR[0x05] = 5455 (unsigned char)((cPtr->FbAddress >> 16) & 0xFF); 5456 ChipsNew->XR[0x06] = 5457 (unsigned char)((cPtr->FbAddress >> 24) & 0xFF); 5458 } 5459 5460 /* panel timing */ 5461 /* By default don't set panel timings, but allow it as an option */ 5462 if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 5463 lcdHTotal = (mode->CrtcHTotal >> 3) - 5; 5464 lcdHDisplay = (cPtr->PanelSize.HDisplay >> 3) - 1; 5465 lcdHRetraceStart = (mode->CrtcHSyncStart >> 3); 5466 lcdHRetraceEnd = (mode->CrtcHSyncEnd >> 3); 5467 lcdHSyncStart = lcdHRetraceStart - 2; 5468 5469 lcdVTotal = mode->CrtcVTotal - 2; 5470 lcdVDisplay = cPtr->PanelSize.VDisplay - 1; 5471 lcdVRetraceStart = mode->CrtcVSyncStart; 5472 lcdVRetraceEnd = mode->CrtcVSyncEnd; 5473 5474 ChipsNew->FR[0x20] = lcdHDisplay & 0xFF; 5475 ChipsNew->FR[0x21] = lcdHRetraceStart & 0xFF; 5476 ChipsNew->FR[0x25] = ((lcdHRetraceStart & 0xF00) >> 4) | 5477 ((lcdHDisplay & 0xF00) >> 8); 5478 ChipsNew->FR[0x22] = lcdHRetraceEnd & 0x1F; 5479 ChipsNew->FR[0x23] = lcdHTotal & 0xFF; 5480 ChipsNew->FR[0x24] = (lcdHSyncStart >> 3) & 0xFF; 5481 ChipsNew->FR[0x26] = (ChipsNew->FR[0x26] & ~0x1F) 5482 | ((lcdHTotal & 0xF00) >> 8) 5483 | (((lcdHSyncStart >> 3) & 0x100) >> 4); 5484 ChipsNew->FR[0x27] &= 0x7F; 5485 5486 ChipsNew->FR[0x30] = lcdVDisplay & 0xFF; 5487 ChipsNew->FR[0x31] = lcdVRetraceStart & 0xFF; 5488 ChipsNew->FR[0x35] = ((lcdVRetraceStart & 0xF00) >> 4) 5489 | ((lcdVDisplay & 0xF00) >> 8); 5490 ChipsNew->FR[0x32] = lcdVRetraceEnd & 0x0F; 5491 ChipsNew->FR[0x33] = lcdVTotal & 0xFF; 5492 ChipsNew->FR[0x34] = (lcdVTotal - lcdVRetraceStart) & 0xFF; 5493 ChipsNew->FR[0x36] = ((lcdVTotal & 0xF00) >> 8) | 5494 (((lcdVTotal - lcdVRetraceStart) & 0x700) >> 4); 5495 ChipsNew->FR[0x37] |= 0x80; 5496 } 5497 5498 /* Set up the extended CRT registers of the HiQV32 chips */ 5499 ChipsNew->CR[0x30] = ((mode->CrtcVTotal - 2) & 0xF00) >> 8; 5500 ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8; 5501 ChipsNew->CR[0x32] = (mode->CrtcVSyncStart & 0xF00) >> 8; 5502 ChipsNew->CR[0x33] = (mode->CrtcVBlankStart & 0xF00) >> 8; 5503 if ((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030)) { 5504 /* The 690xx has overflow bits for the horizontal values as well */ 5505 ChipsNew->CR[0x38] = (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8; 5506 ChipsNew->CR[0x3C] = vgaHWHBlankKGA(mode, ChipsStd, 8, 0) << 6; 5507 } else 5508 vgaHWHBlankKGA(mode, ChipsStd, 6, 0); 5509 vgaHWVBlankKGA(mode, ChipsStd, 8, 0); 5510 5511 ChipsNew->CR[0x40] |= 0x80; 5512 5513 /* centering/stretching */ 5514 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) { 5515 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, FALSE)) { 5516 ChipsNew->FR[0x40] &= 0xDF; /* Disable Horizontal stretching */ 5517 ChipsNew->FR[0x48] &= 0xFB; /* Disable vertical stretching */ 5518 ChipsNew->XR[0xA0] = 0x10; /* Disable cursor stretching */ 5519 } else { 5520 ChipsNew->FR[0x40] |= 0x21; /* Enable Horizontal stretching */ 5521 ChipsNew->FR[0x48] |= 0x05; /* Enable vertical stretching */ 5522 ChipsNew->XR[0xA0] = 0x70; /* Enable cursor stretching */ 5523 if (cPtr->Accel.UseHWCursor 5524 && cPtr->PanelSize.HDisplay && cPtr->PanelSize.VDisplay 5525 && (cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) 5526 && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) { 5527 if(cPtr->Accel.UseHWCursor) 5528 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 5529 "Disabling HW Cursor on stretched LCD\n"); 5530 cPtr->Flags &= ~ChipsHWCursor; 5531 } 5532 } 5533 } 5534 5535 if (xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_CENTER, TRUE)) { 5536 ChipsNew->FR[0x40] |= 0x3; /* Enable Horizontal centering */ 5537 ChipsNew->FR[0x48] |= 0x3; /* Enable Vertical centering */ 5538 } else { 5539 ChipsNew->FR[0x40] &= 0xFD; /* Disable Horizontal centering */ 5540 ChipsNew->FR[0x48] &= 0xFD; /* Disable Vertical centering */ 5541 } 5542 5543 /* sync on green */ 5544 if (xf86ReturnOptValBool(cPtr->Options, OPTION_SYNC_ON_GREEN, FALSE)) 5545 ChipsNew->XR[0x82] |=0x02; 5546 5547 /* software mode flag */ 5548 ChipsNew->XR[0xE2] = chipsVideoMode((pScrn->depth), (cPtr->PanelType & ChipsLCD) ? 5549 min(mode->CrtcHDisplay, cPtr->PanelSize.HDisplay) : 5550 mode->CrtcHDisplay, mode->CrtcVDisplay); 5551#ifdef DEBUG 5552 ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0xE2]); 5553#endif 5554 5555 /* sync. polarities */ 5556 if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 5557 && (mode->Flags & (V_PVSYNC | V_NVSYNC))) { 5558 if (mode->Flags & (V_PHSYNC | V_NHSYNC)) { 5559 if (mode->Flags & V_PHSYNC) 5560 ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */ 5561 else 5562 ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */ 5563 } 5564 if (mode->Flags & (V_PVSYNC | V_NVSYNC)) { 5565 if (mode->Flags & V_PVSYNC) 5566 ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */ 5567 else 5568 ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */ 5569 } 5570 } 5571 if (mode->Flags & (V_PCSYNC | V_NCSYNC)) { 5572 ChipsNew->FR[0x0B] |= 0x20; 5573 if (mode->Flags & V_PCSYNC) { 5574 ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */ 5575 ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */ 5576 ChipsStd->MiscOutReg &= 0x7F; 5577 ChipsStd->MiscOutReg &= 0xBF; 5578 } else { 5579 ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */ 5580 ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */ 5581 ChipsStd->MiscOutReg |= 0x40; 5582 ChipsStd->MiscOutReg |= 0x80; 5583 } 5584 } 5585 /* bpp depend */ 5586 if (pScrn->bitsPerPixel == 16) { 5587 ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x4; 5588 if (cPtr->Flags & ChipsGammaSupport) 5589 ChipsNew->XR[0x82] |= 0x0C; 5590 /* 16bpp = 5-5-5 */ 5591 ChipsNew->FR[0x10] |= 0x0C; /*Colour Panel */ 5592 ChipsNew->XR[0x20] = 0x10; /*BitBLT Draw Mode for 16 bpp */ 5593 if (pScrn->weight.green != 5) 5594 ChipsNew->XR[0x81] |= 0x01; /*16bpp */ 5595 } else if (pScrn->bitsPerPixel == 24) { 5596 ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x6; 5597 if (cPtr->Flags & ChipsGammaSupport) 5598 ChipsNew->XR[0x82] |= 0x0C; 5599 /* 24bpp colour */ 5600 ChipsNew->XR[0x20] = 0x20; /*BitBLT Draw Mode for 24 bpp */ 5601 } else if (pScrn->bitsPerPixel == 32) { 5602 ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x7; 5603 if (cPtr->Flags & ChipsGammaSupport) 5604 ChipsNew->XR[0x82] |= 0x0C; 5605 /* 32bpp colour */ 5606 ChipsNew->XR[0x20] = 0x10; /*BitBLT Mode for 16bpp used at 32bpp */ 5607 } 5608 5609 /*CRT only */ 5610 if (!(cPtr->PanelType & ChipsLCD)) { 5611 if (mode->Flags & V_INTERLACE) { 5612 ChipsNew->CR[0x70] = 0x80 /* set interlace */ 5613 | (((((mode->CrtcHDisplay >> 3) - 1) >> 1) - 6) & 0x7F); 5614 /* 5615 ** Double VDisplay to get back the full screen value, otherwise 5616 ** you only see half the picture. 5617 */ 5618 mode->CrtcVDisplay = mode->VDisplay; 5619 tmp = ChipsStd->CRTC[7] & ~0x42; 5620 ChipsStd->CRTC[7] = (tmp | 5621 ((((mode->CrtcVDisplay -1) & 0x100) >> 7 ) | 5622 (((mode->CrtcVDisplay -1) & 0x200) >> 3 ))); 5623 ChipsStd->CRTC[0x12] = (mode->CrtcVDisplay -1) & 0xFF; 5624 ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8; 5625 } else { 5626 ChipsNew->CR[0x70] &= ~0x80; /* unset interlace */ 5627 } 5628 } 5629 5630#if defined(__arm__) && defined(___NetBSD__) 5631 if (cPtr->TVMode != XMODE_RGB) { 5632 /* 5633 * Put the console into TV Out mode. 5634 */ 5635 xf86SetTVOut(cPtr->TVMode); 5636 5637 ChipsNew->CR[0x72] = (mode->CrtcHTotal >> 1) >> 3;/* First horizontal 5638 * serration pulse */ 5639 ChipsNew->CR[0x73] = mode->CrtcHTotal >> 3; /* Second pulse */ 5640 ChipsNew->CR[0x74] = (((mode->HSyncEnd - mode->HSyncStart) >> 3) - 1) 5641 & 0x1F; /* equalization pulse */ 5642 5643 if (cPtr->TVMode == XMODE_PAL || cPtr->TVMode == XMODE_SECAM) { 5644 ChipsNew->CR[0x71] = 0xA0; /* PAL support with blanking delay */ 5645 } else { 5646 ChipsNew->CR[0x71] = 0x20; /* NTSC support with blanking delay */ 5647 } 5648 } else { /* XMODE_RGB */ 5649 /* 5650 * Put the console into RGB Out mode. 5651 */ 5652 xf86SetRGBOut(); 5653 } 5654#endif 5655 5656 /* STN specific */ 5657 if (IS_STN(cPtr->PanelType)) { 5658 ChipsNew->FR[0x11] &= ~0x03; /* FRC clear */ 5659 ChipsNew->FR[0x11] &= ~0x8C; /* Dither clear */ 5660 ChipsNew->FR[0x11] |= 0x01; /* 16 frame FRC */ 5661 ChipsNew->FR[0x11] |= 0x84; /* Dither */ 5662 if ((cPtr->Flags & ChipsTMEDSupport) && 5663 !xf86ReturnOptValBool(cPtr->Options, OPTION_NO_TMED, FALSE)) { 5664 ChipsNew->FR[0x73] &= 0x4F; /* Clear TMED */ 5665 ChipsNew->FR[0x73] |= 0x80; /* Enable TMED */ 5666 ChipsNew->FR[0x73] |= 0x30; /* TMED 256 Shades of RGB */ 5667 } 5668 if (cPtr->PanelType & ChipsDD) /* Shift Clock Mask. Use to get */ 5669 ChipsNew->FR[0x12] |= 0x4; /* rid of line in DSTN screens */ 5670 } 5671 5672 /* 5673 * The zero position of the overlay does not align with the zero 5674 * position of the display. The skew is dependent on the depth, 5675 * display type and refresh rate. Calculate the skew before setting 5676 * the X and Y dimensions of the overlay. These values are needed 5677 * both by the overlay and XvImages. So calculate and store them 5678 */ 5679 if (cPtr->PanelType & ChipsLCD) { 5680 cPtr->OverlaySkewX = (((ChipsNew->FR[0x23] & 0xFF) 5681 - (ChipsNew->FR[0x20] & 0xFF) + 3) << 3) 5682 - 1; 5683 cPtr->OverlaySkewY = (ChipsNew->FR[0x33] 5684 + ((ChipsNew->FR[0x36] & 0xF) << 8) 5685 - (ChipsNew->FR[0x31] & 0xF0) 5686 - (ChipsNew->FR[0x32] & 0x0F) 5687 - ((ChipsNew->FR[0x35] & 0xF0) << 4)); 5688 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, FALSE) 5689 && xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_CENTER, TRUE)) 5690 { 5691 if (cPtr->PanelSize.HDisplay > mode->CrtcHDisplay) 5692 cPtr->OverlaySkewX += (cPtr->PanelSize.HDisplay - 5693 mode->CrtcHDisplay) / 2; 5694 if (cPtr->PanelSize.VDisplay > mode->CrtcVDisplay) 5695 cPtr->OverlaySkewY += (cPtr->PanelSize.VDisplay - 5696 mode->CrtcVDisplay) / 2; 5697 } 5698 } else { 5699 cPtr->OverlaySkewX = mode->CrtcHTotal - mode->CrtcHBlankStart - 9; 5700 cPtr->OverlaySkewY = mode->CrtcVTotal - mode->CrtcVSyncEnd - 1; 5701 5702 if (mode->Flags & V_INTERLACE) { 5703 /* 5704 * This handles 1024 and 1280 interlaced modes only. Its 5705 * pretty arbitrary, but its what C&T recommends 5706 */ 5707#if 0 5708 if (mode->CrtcHDisplay == 1024) 5709 cPtr->OverlaySkewY += 5; 5710 else if (mode->CrtcHDisplay == 1280) 5711#endif 5712 cPtr->OverlaySkewY *= 2; 5713 5714 } 5715 } 5716 5717 /* mask for viewport granularity */ 5718 5719 switch (pScrn->bitsPerPixel) { 5720 case 8: 5721 cPtr->viewportMask = ~7U; 5722 break; 5723 case 16: 5724 cPtr->viewportMask = ~3U; 5725 break; 5726 case 24: 5727 cPtr->viewportMask = ~7U; 5728 break; 5729 case 32: 5730 cPtr->viewportMask = ~0U; 5731 break; 5732 default: 5733 cPtr->viewportMask = ~7U; 5734 } 5735 5736 /* Turn off multimedia by default as it degrades performance */ 5737 ChipsNew->XR[0xD0] &= 0x0f; 5738 5739 if (cPtr->Flags & ChipsVideoSupport) { 5740#if 0 /* if we do this even though video isn't playing we kill performance */ 5741 ChipsNew->XR[0xD0] |= 0x10; /* Force the Multimedia engine on */ 5742#endif 5743#ifdef SAR04 5744 ChipsNew->XR[0x4F] = 0x2A; /* SAR04 >352 pixel overlay width */ 5745#endif 5746 ChipsNew->MR[0x3C] &= 0x18; /* Ensure that the overlay is off */ 5747 cPtr->VideoZoomMax = 0x100; 5748 5749 if (cPtr->Chipset == CHIPS_CT65550) { 5750 tmp = cPtr->readXR(cPtr, 0x04); 5751 if (tmp < 0x02) /* 65550 ES0 has */ 5752 cPtr->VideoZoomMax = 0x40; /* 0x40 max zoom */ 5753 } 5754 } 5755 5756 /* Program the registers */ 5757 /*vgaHWProtect(pScrn, TRUE);*/ 5758 5759 if (cPtr->Chipset <= CHIPS_CT69000) { 5760 ChipsNew->FR[0x01] &= ~0x03; 5761 if (cPtr->PanelType & ChipsLCD) 5762 ChipsNew->FR[0x01] |= 0x02; 5763 else 5764 ChipsNew->FR[0x01] |= 0x01; 5765 } 5766 if ((cPtr->Flags & ChipsDualChannelSupport) && 5767 (!xf86IsEntityShared(pScrn->entityList[0]))) { 5768 unsigned char IOSS, MSS, tmpfr01; 5769 5770 5771 IOSS = cPtr->readIOSS(cPtr); 5772 MSS = cPtr->readMSS(cPtr); 5773 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 5774 IOSS_PIPE_A)); 5775 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | 5776 MSS_PIPE_A)); 5777 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 5778 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 5779 IOSS_PIPE_B)); 5780 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | 5781 MSS_PIPE_B)); 5782 /* 5783 * Hack:: Force Pipe-B on for dual refresh, and off elsewise 5784 */ 5785 tmpfr01 = ChipsNew->FR[0x01]; 5786 ChipsNew->FR[0x01] &= 0xFC; 5787 if (cPtr->UseDualChannel) 5788 ChipsNew->FR[0x01] |= 0x01; 5789 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 5790 ChipsNew->FR[0x01] = tmpfr01; 5791 cPtr->writeIOSS(cPtr, IOSS); 5792 cPtr->writeMSS(cPtr, hwp, MSS); 5793 } else { 5794 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 5795 } 5796 5797 /*vgaHWProtect(pScrn, FALSE);*/ 5798 usleep(100000); /* prevents cursor corruption seen on a TECRA 510 */ 5799 5800 return(TRUE); 5801} 5802 5803static Bool 5804chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode) 5805{ 5806 int i, bytesPerPixel; 5807 vgaHWPtr hwp = VGAHWPTR(pScrn); 5808 CHIPSPtr cPtr = CHIPSPTR(pScrn); 5809 CHIPSRegPtr ChipsNew; 5810 vgaRegPtr ChipsStd; 5811 unsigned int tmp; 5812 5813 ChipsNew = &cPtr->ModeReg; 5814 ChipsStd = &hwp->ModeReg; 5815 5816 bytesPerPixel = pScrn->bitsPerPixel >> 3; 5817 5818 /* 5819 * This chipset seems to have problems if 5820 * HBlankEnd is chosen equals HTotal 5821 */ 5822 if (!mode->CrtcHAdjusted) 5823 mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2); 5824 5825 /* correct the timings for 16/24 bpp */ 5826 if (pScrn->bitsPerPixel == 16) { 5827 if (!mode->CrtcHAdjusted) { 5828 mode->CrtcHDisplay++; 5829 mode->CrtcHDisplay <<= 1; 5830 mode->CrtcHDisplay--; 5831 mode->CrtcHSyncStart <<= 1; 5832 mode->CrtcHSyncEnd <<= 1; 5833 mode->CrtcHBlankStart <<= 1; 5834 mode->CrtcHBlankEnd <<= 1; 5835 mode->CrtcHTotal <<= 1; 5836 mode->CrtcHAdjusted = TRUE; 5837 } 5838 } else if (pScrn->bitsPerPixel == 24) { 5839 if (!mode->CrtcHAdjusted) { 5840 mode->CrtcHDisplay++; 5841 mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1); 5842 mode->CrtcHDisplay--; 5843 mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1); 5844 mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1); 5845 mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1); 5846 mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1); 5847 mode->CrtcHTotal += ((mode->CrtcHTotal) << 1); 5848 mode->CrtcHAdjusted = TRUE; 5849 } 5850 } 5851 5852 /* generic init */ 5853 if (!vgaHWInit(pScrn, mode)) { 5854 ErrorF("bomb 3\n"); 5855 return (FALSE); 5856 } 5857 pScrn->vtSema = TRUE; 5858 5859 /* init clock */ 5860 if (!chipsClockFind(pScrn, mode, mode->ClockIndex, &ChipsNew->Clock)) { 5861 ErrorF("bomb 4\n"); 5862 return (FALSE); 5863 } 5864 5865 /* get C&T Specific Registers */ 5866 for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */ 5867 ChipsNew->XR[i] = cPtr->readXR(cPtr, i); 5868 } 5869 5870 /* some generic settings */ 5871 if (pScrn->bitsPerPixel == 1) { 5872 ChipsStd->Attribute[0x10] = 0x03; /* mode */ 5873 } else { 5874 ChipsStd->Attribute[0x10] = 0x01; /* mode */ 5875 } 5876 ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */ 5877 ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */ 5878 ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ 5879 5880 ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */ 5881 5882 5883 /* set virtual screen width */ 5884 if (pScrn->bitsPerPixel >= 8) 5885 ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3; 5886 else 5887 ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4; 5888 5889 5890 /* set C&T Specific Registers */ 5891 /* set virtual screen width */ 5892 if (pScrn->bitsPerPixel >= 8) 5893 tmp = (pScrn->displayWidth >> 4) * bytesPerPixel; 5894 else 5895 tmp = (pScrn->displayWidth >> 5); 5896 ChipsNew->XR[0x0D] = (tmp & 0x80) >> 5; 5897 5898 ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */ 5899 /* XR04: Memory control 1 */ 5900 /* bit 2: Memory Wraparound */ 5901 /* Enable CRTC addr counter bits 16-17 if set */ 5902 5903 ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */ 5904 ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */ 5905 /* XR0B: CPU paging */ 5906 /* bit 0: Memory mapping mode */ 5907 /* VGA compatible if 0 (default) */ 5908 /* Extended mode (mapping for > 256 kB mem) if 1 */ 5909 /* bit 1: CPU single/dual mapping */ 5910 /* 0, CPU uses only a single map to access (default) */ 5911 /* 1, CPU uses two maps to access */ 5912 /* bit 2: CPU address divide by 4 */ 5913 5914 ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */ 5915 ChipsNew->XR[0x11] = 0; /* XR11: High map */ 5916 ChipsNew->XR[0x0C] &= ~0x50; /* MSB for XR10 & XR11 */ 5917 if (pScrn->bitsPerPixel >= 8) { 5918 ChipsNew->XR[0x28] |= 0x10; /* 256-color video */ 5919 } else { 5920 ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */ 5921 } 5922 /* set up extended display timings */ 5923 /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */ 5924 ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) 5925 | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) 5926 | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) 5927 | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2) 5928 | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4) 5929 | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1); 5930 5931 5932 ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 ) 5933 | (((mode->CrtcVDisplay -1) & 0x400) >> 9 ) 5934 | ((mode->CrtcVSyncStart & 0x400) >> 8 ) 5935 | (((mode->CrtcVBlankStart) & 0x400) >> 6 ); 5936 5937 /* set video mode */ 5938 ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->depth, mode->CrtcHDisplay, mode->CrtcVDisplay); 5939#ifdef DEBUG 5940 ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]); 5941#endif 5942 5943 /* set some linear specific registers */ 5944 if (cPtr->Flags & ChipsLinearSupport) { 5945 /* enable linear addressing */ 5946 ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */ 5947 ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */ 5948 5949 ChipsNew->XR[0x08] = 5950 (unsigned char)((cPtr->FbAddress >> 16) & 0xFF); 5951 ChipsNew->XR[0x09] = 5952 (unsigned char)((cPtr->FbAddress >> 24) & 0xFF); 5953 5954 /* general setup */ 5955 ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */ 5956 } 5957 5958 /* common general setup */ 5959 ChipsNew->XR[0x52] |= 0x01; /* Refresh count */ 5960 ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */ 5961 ChipsNew->XR[0x02] &= 0xE7; /* Attr. Cont. default access */ 5962 /* use ext. regs. for hor. in dual */ 5963 ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */ 5964 5965 /* bpp depend */ 5966 /*XR06: Palette control */ 5967 /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */ 5968 /* bit 1: Internal DAC disable */ 5969 /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */ 5970 /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */ 5971 /* bit 4: Enable PC Video Overlay on colour key */ 5972 /* bit 5: Bypass Internal VGA palette */ 5973 /* bit 7-6: Colour reduction select, 0 for NTSC (default), */ 5974 /* 1 for Equivalent weighting, 2 for green only, */ 5975 /* 3 for Colour w/o reduction */ 5976 /* XR50 Panel Format Register 1 */ 5977 /* bit 1-0: Frame Rate Control; 00, No FRC; */ 5978 /* 01, 16-frame FRC for colour STN and monochrome */ 5979 /* 10, 2-frame FRC for colour TFT or monochrome; */ 5980 /* 11, reserved */ 5981 /* bit 3-2: Dither Enable */ 5982 /* 00, disable dithering; 01, enable dithering */ 5983 /* for 256 mode */ 5984 /* 10, enable dithering for all modes; 11, reserved */ 5985 /* bit6-4: Clock Divide (CD) */ 5986 /* 000, Shift Clock Freq = Dot Clock Freq; */ 5987 /* 001, SClk = DClk/2; 010 SClk = DClk/4; */ 5988 /* 011, SClk = DClk/8; 100 SClk = DClk/16; */ 5989 /* bit 7: TFT data width */ 5990 /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */ 5991 if (pScrn->bitsPerPixel == 16) { 5992 ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */ 5993 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 5994 ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */ 5995 if (pScrn->weight.green != 5) 5996 ChipsNew->XR[0x06] |= 0x08; /*16bpp */ 5997 } else if (pScrn->bitsPerPixel == 24) { 5998 ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */ 5999 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6000 } 6001 6002 /*CRT only: interlaced mode */ 6003 if (mode->Flags & V_INTERLACE) { 6004 ChipsNew->XR[0x28] |= 0x20; /* set interlace */ 6005 /* empirical value */ 6006 tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1) 6007 - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 )); 6008 ChipsNew->XR[0x19] = tmp & 0xFF; 6009 ChipsNew->XR[0x17] |= ((tmp & 0x100) >> 1); /* overflow */ 6010 ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */ 6011 } else { 6012 ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */ 6013 ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */ 6014 } 6015 6016 /* Program the registers */ 6017 /*vgaHWProtect(pScrn, TRUE);*/ 6018 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 6019 /*vgaHWProtect(pScrn, FALSE);*/ 6020 6021 return (TRUE); 6022} 6023 6024static Bool 6025chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode) 6026{ 6027 int i, bytesPerPixel; 6028 int lcdHTotal, lcdHDisplay; 6029 int lcdVTotal, lcdVDisplay; 6030 int lcdHRetraceStart, lcdHRetraceEnd; 6031 int lcdVRetraceStart, lcdVRetraceEnd; 6032 int HSyncStart, HDisplay; 6033 int CrtcHDisplay; 6034 vgaHWPtr hwp = VGAHWPTR(pScrn); 6035 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6036 CHIPSRegPtr ChipsNew; 6037 vgaRegPtr ChipsStd; 6038 unsigned int tmp; 6039 6040 ChipsNew = &cPtr->ModeReg; 6041 ChipsStd = &hwp->ModeReg; 6042 6043 bytesPerPixel = pScrn->bitsPerPixel >> 3; 6044 6045 /* 6046 * Possibly fix up the panel size, if the manufacture is stupid 6047 * enough to set it incorrectly in text modes 6048 */ 6049 if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) { 6050 cPtr->PanelSize.HDisplay = mode->CrtcHDisplay; 6051 cPtr->PanelSize.VDisplay = mode->CrtcVDisplay; 6052 } 6053 6054 /* 6055 * This chipset seems to have problems if 6056 * HBlankEnd is chosen equals HTotal 6057 */ 6058 if (!mode->CrtcHAdjusted) 6059 mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2); 6060 6061 /* correct the timings for 16/24 bpp */ 6062 if (pScrn->bitsPerPixel == 16) { 6063 if (!mode->CrtcHAdjusted) { 6064 mode->CrtcHDisplay++; 6065 mode->CrtcHDisplay <<= 1; 6066 mode->CrtcHDisplay--; 6067 mode->CrtcHSyncStart <<= 1; 6068 mode->CrtcHSyncEnd <<= 1; 6069 mode->CrtcHBlankStart <<= 1; 6070 mode->CrtcHBlankEnd <<= 1; 6071 mode->CrtcHTotal <<= 1; 6072 mode->CrtcHAdjusted = TRUE; 6073 } 6074 } else if (pScrn->bitsPerPixel == 24) { 6075 if (!mode->CrtcHAdjusted) { 6076 mode->CrtcHDisplay++; 6077 mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1); 6078 mode->CrtcHDisplay--; 6079 mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1); 6080 mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1); 6081 mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1); 6082 mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1); 6083 mode->CrtcHTotal += ((mode->CrtcHTotal) << 1); 6084 mode->CrtcHAdjusted = TRUE; 6085 } 6086 } 6087 6088 /* store orig. HSyncStart needed for flat panel mode */ 6089 HSyncStart = mode->CrtcHSyncStart / (pScrn->bitsPerPixel >= 8 ? 6090 bytesPerPixel : 1 ) - 16; 6091 HDisplay = (mode->CrtcHDisplay + 1) / (pScrn->bitsPerPixel >= 8 ? 6092 bytesPerPixel : 1 ); 6093 6094 /* generic init */ 6095 if (!vgaHWInit(pScrn, mode)) { 6096 ErrorF("bomb 5\n"); 6097 return (FALSE); 6098 } 6099 pScrn->vtSema = TRUE; 6100 6101 /* init clock */ 6102 if (!chipsClockFind(pScrn, mode, mode->ClockIndex, &ChipsNew->Clock)) { 6103 ErrorF("bomb 6\n"); 6104 return (FALSE); 6105 } 6106 6107 /* get C&T Specific Registers */ 6108 for (i = 0; i < 0x80; i++) { 6109 ChipsNew->XR[i] = cPtr->readXR(cPtr, i); 6110 } 6111 6112 /* some generic settings */ 6113 if (pScrn->bitsPerPixel == 1) { 6114 ChipsStd->Attribute[0x10] = 0x03; /* mode */ 6115 } else { 6116 ChipsStd->Attribute[0x10] = 0x01; /* mode */ 6117 } 6118 ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */ 6119 ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */ 6120 ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ 6121 6122 ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */ 6123 6124 /* set virtual screen width */ 6125 if (pScrn->bitsPerPixel >= 8) 6126 ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3; 6127 else 6128 ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4; 6129 6130 6131 /* set C&T Specific Registers */ 6132 /* set virtual screen width */ 6133 ChipsNew->XR[0x1E] = ChipsStd->CRTC[0x13]; /* alternate offset */ 6134 /*databook is not clear about 0x1E might be needed for 65520/30 */ 6135 if (pScrn->bitsPerPixel >= 8) 6136 tmp = (pScrn->displayWidth * bytesPerPixel) >> 2; 6137 else 6138 tmp = pScrn->displayWidth >> 3; 6139 ChipsNew->XR[0x0D] = (tmp & 0x01) | ((tmp << 1) & 0x02) ; 6140 6141 ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */ 6142 /* XR04: Memory control 1 */ 6143 /* bit 2: Memory Wraparound */ 6144 /* Enable CRTC addr counter bits 16-17 if set */ 6145 6146 ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */ 6147 ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */ 6148 /* XR0B: CPU paging */ 6149 /* bit 0: Memory mapping mode */ 6150 /* VGA compatible if 0 (default) */ 6151 /* Extended mode (mapping for > 256 kB mem) if 1 */ 6152 /* bit 1: CPU single/dual mapping */ 6153 /* 0, CPU uses only a single map to access (default) */ 6154 /* 1, CPU uses two maps to access */ 6155 /* bit 2: CPU address divide by 4 */ 6156 6157 ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */ 6158 ChipsNew->XR[0x11] = 0; /* XR11: High map */ 6159 if (pScrn->bitsPerPixel >= 8) { 6160 ChipsNew->XR[0x28] |= 0x10; /* 256-color video */ 6161 } else { 6162 ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */ 6163 } 6164 /* set up extended display timings */ 6165 if (!(cPtr->PanelType & ChipsLCD)) { 6166 /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */ 6167 ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) 6168 | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) 6169 | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) 6170 | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2) 6171 | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4) 6172 | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1); 6173 6174 ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 ) 6175 | (((mode->CrtcVDisplay -1) & 0x400) >> 9 ) 6176 | ((mode->CrtcVSyncStart & 0x400) >> 8 ) 6177 | (((mode->CrtcVBlankStart) & 0x400) >> 6 ); 6178 } else { 6179 /* horizontal timing registers */ 6180 /* in LCD/dual mode use saved bios values to derive timing values if 6181 * not told otherwise */ 6182 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 6183 lcdHTotal = cPtr->PanelSize.HTotal; 6184 lcdHRetraceStart = cPtr->PanelSize.HRetraceStart; 6185 lcdHRetraceEnd = cPtr->PanelSize.HRetraceEnd; 6186 if (pScrn->bitsPerPixel == 16) { 6187 lcdHRetraceStart <<= 1; 6188 lcdHRetraceEnd <<= 1; 6189 lcdHTotal <<= 1; 6190 } else if (pScrn->bitsPerPixel == 24) { 6191 lcdHRetraceStart += (lcdHRetraceStart << 1); 6192 lcdHRetraceEnd += (lcdHRetraceEnd << 1); 6193 lcdHTotal += (lcdHTotal << 1); 6194 } 6195 lcdHRetraceStart -=8; /* HBlank = HRetrace - 1: for */ 6196 lcdHRetraceEnd -=8; /* compatibility with vgaHW.c */ 6197 } else { 6198 /* use modeline values if bios values don't work */ 6199 lcdHTotal = mode->CrtcHTotal; 6200 lcdHRetraceStart = mode->CrtcHSyncStart; 6201 lcdHRetraceEnd = mode->CrtcHSyncEnd; 6202 } 6203 /* The chip takes the size of the visible display area from the 6204 * CRTC values. We use bios screensize for LCD in LCD/dual mode 6205 * wether or not we use modeline for LCD. This way we can specify 6206 * always specify a smaller than default display size on LCD 6207 * by writing it to the CRTC registers. */ 6208 lcdHDisplay = cPtr->PanelSize.HDisplay; 6209 if (pScrn->bitsPerPixel == 16) { 6210 lcdHDisplay++; 6211 lcdHDisplay <<= 1; 6212 lcdHDisplay--; 6213 } else if (pScrn->bitsPerPixel == 24) { 6214 lcdHDisplay++; 6215 lcdHDisplay += (lcdHDisplay << 1); 6216 lcdHDisplay--; 6217 } 6218 lcdHTotal = (lcdHTotal >> 3) - 5; 6219 lcdHDisplay = (lcdHDisplay >> 3) - 1; 6220 lcdHRetraceStart = (lcdHRetraceStart >> 3); 6221 lcdHRetraceEnd = (lcdHRetraceEnd >> 3); 6222 /* This ugly hack is needed because CR01 and XR1C share the 8th bit!*/ 6223 CrtcHDisplay = ((mode->CrtcHDisplay >> 3) - 1); 6224 if ((lcdHDisplay & 0x100) != (CrtcHDisplay & 0x100)) { 6225 xf86ErrorF("This display configuration might cause problems !\n"); 6226 lcdHDisplay = 255; 6227 } 6228 6229 /* now init register values */ 6230 ChipsNew->XR[0x17] = (((lcdHTotal) & 0x100) >> 8) 6231 | ((lcdHDisplay & 0x100) >> 7) 6232 | ((lcdHRetraceStart & 0x100) >> 6) 6233 | (((lcdHRetraceEnd) & 0x20) >> 2); 6234 6235 ChipsNew->XR[0x19] = lcdHRetraceStart & 0xFF; 6236 ChipsNew->XR[0x1A] = lcdHRetraceEnd & 0x1F; 6237 6238 /* XR1B: Alternate horizontal total */ 6239 /* used in all flat panel mode with horiz. compression disabled, */ 6240 /* CRT CGA text and graphic modes and Hercules graphics mode */ 6241 /* similar to CR00, actual value - 5 */ 6242 ChipsNew->XR[0x1B] = lcdHTotal & 0xFF; 6243 6244 /*XR1C: Alternate horizontal blank start (CRT mode) */ 6245 /* /horizontal panel size (FP mode) */ 6246 /* FP horizontal panel size (FP mode), */ 6247 /* actual value - 1 (in characters unit) */ 6248 /* CRT horizontal blank start (CRT mode) */ 6249 /* similar to CR02, actual value - 1 */ 6250 ChipsNew->XR[0x1C] = lcdHDisplay & 0xFF; 6251 6252 if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) { 6253 /* for ext. packed pixel mode on 64520/64530 */ 6254 /* no need to rescale: used only in 65530 */ 6255 ChipsNew->XR[0x21] = lcdHRetraceStart & 0xFF; 6256 ChipsNew->XR[0x22] = lcdHRetraceEnd & 0x1F; 6257 ChipsNew->XR[0x23] = lcdHTotal & 0xFF; 6258 6259 /* vertical timing registers */ 6260 lcdVTotal = mode->CrtcVTotal - 2; 6261 lcdVDisplay = cPtr->PanelSize.VDisplay - 1; 6262 lcdVRetraceStart = mode->CrtcVSyncStart; 6263 lcdVRetraceEnd = mode->CrtcVSyncEnd; 6264 6265 ChipsNew->XR[0x64] = lcdVTotal & 0xFF; 6266 ChipsNew->XR[0x66] = lcdVRetraceStart & 0xFF; 6267 ChipsNew->XR[0x67] = lcdVRetraceEnd & 0x0F; 6268 ChipsNew->XR[0x68] = lcdVDisplay & 0xFF; 6269 ChipsNew->XR[0x65] = ((lcdVTotal & 0x100) >> 8) 6270 | ((lcdVDisplay & 0x100) >> 7) 6271 | ((lcdVRetraceStart & 0x100) >> 6) 6272 | ((lcdVRetraceStart & 0x400) >> 7) 6273 | ((lcdVTotal & 0x400) >> 6) 6274 | ((lcdVTotal & 0x200) >> 4) 6275 | ((lcdVDisplay & 0x200) >> 3) 6276 | ((lcdVRetraceStart & 0x200) >> 2); 6277 6278 /* 6279 * These are important: 0x2C specifies the numbers of lines 6280 * (hsync pulses) between vertical blank start and vertical 6281 * line total, 0x2D specifies the number of clock ticks? to 6282 * horiz. blank start ( caution ! 16bpp/24bpp modes: that's 6283 * why we need HSyncStart - can't use mode->CrtcHSyncStart) 6284 */ 6285 tmp = ((cPtr->PanelType & ChipsDD) && !(ChipsNew->XR[0x6F] & 0x02)) 6286 ? 1 : 0; /* double LP delay, FLM: 2 lines iff DD+no acc*/ 6287 /* Currently we support 2 FLM schemes: #1: FLM coincides with 6288 * VTotal ie. the delay is programmed to the difference bet- 6289 * ween lctVTotal and lcdVRetraceStart. #2: FLM coincides 6290 * lcdVRetraceStart - in this case FLM delay will be turned 6291 * off. To decide which scheme to use we compare the value of 6292 * XR2C set by the bios to the two schemes. The one that fits 6293 * better will be used. 6294 */ 6295 6296 if ((unsigned)ChipsNew->XR[0x2C] < ((cPtr->PanelSize.VTotal - 6297 cPtr->PanelSize.VRetraceStart - tmp - 1) - 6298 ChipsNew->XR[0x2C])) 6299 ChipsNew->XR[0x2F] |= 0x80; /* turn FLM delay off */ 6300 ChipsNew->XR[0x2C] = lcdVTotal - lcdVRetraceStart - tmp; 6301 /*ChipsNew->XR[0x2D] = (HSyncStart >> (3 - tmp)) & 0xFF;*/ 6302 ChipsNew->XR[0x2D] = (HDisplay >> (3 - tmp)) & 0xFF; 6303 ChipsNew->XR[0x2F] = (ChipsNew->XR[0x2F] & 0xDF) 6304 | (((HSyncStart >> (3 - tmp)) & 0x100) >> 3); 6305 } 6306 6307 /* set stretching/centering */ 6308 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) { 6309 ChipsNew->XR[0x51] |= 0x40; /* enable FP compensation */ 6310 ChipsNew->XR[0x55] |= 0x01; /* enable horiz. compensation */ 6311 ChipsNew->XR[0x57] |= 0x01; /* enable horiz. compensation */ 6312 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, 6313 FALSE)) { 6314 if (mode->CrtcHDisplay < 1489) /* HWBug */ 6315 ChipsNew->XR[0x55] |= 0x02; /* enable auto h-centering */ 6316 else { 6317 ChipsNew->XR[0x55] &= 0xFD; /* disable auto h-centering */ 6318 if (pScrn->bitsPerPixel == 24) /* ? */ 6319 ChipsNew->XR[0x56] = (lcdHDisplay - CrtcHDisplay) >> 1; 6320 } 6321 } else { 6322 ChipsNew->XR[0x55] &= 0xFD; /* disable h-centering */ 6323 ChipsNew->XR[0x56] = 0; 6324 } 6325 ChipsNew->XR[0x57] = 0x03; /* enable v-comp disable v-stretch */ 6326 if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, 6327 FALSE)) { 6328 ChipsNew->XR[0x55] |= 0x20; /* enable h-comp disable h-double*/ 6329 ChipsNew->XR[0x57] |= 0x60; /* Enable vertical stretching */ 6330 tmp = (mode->CrtcVDisplay / (cPtr->PanelSize.VDisplay - 6331 mode->CrtcVDisplay + 1)); 6332 if (tmp) { 6333 if (cPtr->PanelSize.HDisplay 6334 && cPtr->PanelSize.VDisplay 6335 && (cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) 6336 && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) { 6337 /* Possible H/W bug? */ 6338 if(cPtr->Accel.UseHWCursor) 6339 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 6340 "Disabling HW Cursor on stretched LCD\n"); 6341 cPtr->Flags &= ~ChipsHWCursor; 6342 } 6343 } 6344 if (cPtr->Flags & ChipsHWCursor) 6345 tmp = (tmp == 0 ? 1 : tmp); /* Bug when doubling */ 6346 ChipsNew->XR[0x5A] = tmp > 0x0F ? 0 : (unsigned char)tmp; 6347 } else { 6348 ChipsNew->XR[0x55] &= 0xDF; /* disable h-comp, h-double */ 6349 ChipsNew->XR[0x57] &= 0x9F; /* disable vertical stretching */ 6350 } 6351 } 6352 } 6353 6354 /* set video mode */ 6355 ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->depth, (cPtr->PanelType & ChipsLCD) ? 6356 min(HDisplay, cPtr->PanelSize.HDisplay) : HDisplay,cPtr->PanelSize.VDisplay); 6357#ifdef DEBUG 6358 ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]); 6359#endif 6360 6361 /* set some linear specific registers */ 6362 if (cPtr->Flags & ChipsLinearSupport) { 6363 /* enable linear addressing */ 6364 ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */ 6365 ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */ 6366 if (cPtr->Chipset == CHIPS_CT65535) 6367 ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 17); 6368 else if (cPtr->Chipset > CHIPS_CT65535) 6369 ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 20); 6370 else { 6371 /* Its probably set correctly by BIOS anyway. Leave it alone */ 6372 /* 65525 - 65530 require XR04[6] set for greater than 512k of */ 6373 /* ram. We only correct obvious bugs; VL probably uses MEMR/MEMW*/ 6374 if (cPtr->Bus == ChipsISA) 6375 ChipsNew->XR[0x04] &= ~0x40; /* A19 sceme */ 6376 if (pScrn->videoRam > 512) 6377 ChipsNew->XR[0x04] |= 0x40; /* MEMR/MEMW sceme */ 6378 } 6379 6380 /* general setup */ 6381 ChipsNew->XR[0x03] |= 0x08; /* High bandwidth on 65548 */ 6382 ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */ 6383 } 6384 6385 /* common general setup */ 6386 ChipsNew->XR[0x52] |= 0x01; /* Refresh count */ 6387 ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */ 6388 ChipsNew->XR[0x02] |= 0x01; /* 16bit CPU Memory Access */ 6389 ChipsNew->XR[0x02] &= 0xE3; /* Attr. Cont. default access */ 6390 /* use ext. regs. for hor. in dual */ 6391 ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */ 6392 6393 /* PCI */ 6394 if (cPtr->Bus == ChipsPCI) 6395 ChipsNew->XR[0x03] |= 0x40; /*PCI burst */ 6396 6397 /* sync. polarities */ 6398 if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) 6399 && (mode->Flags & (V_PVSYNC | V_NVSYNC))) { 6400 if (mode->Flags & (V_PHSYNC | V_NHSYNC)) { 6401 if (mode->Flags & V_PHSYNC) { 6402 ChipsNew->XR[0x55] &= 0xBF; /* CRT Hsync positive */ 6403 } else { 6404 ChipsNew->XR[0x55] |= 0x40; /* CRT Hsync negative */ 6405 } 6406 } 6407 if (mode->Flags & (V_PVSYNC | V_NVSYNC)) { 6408 if (mode->Flags & V_PVSYNC) { 6409 ChipsNew->XR[0x55] &= 0x7F; /* CRT Vsync positive */ 6410 } else { 6411 ChipsNew->XR[0x55] |= 0x80; /* CRT Vsync negative */ 6412 } 6413 } 6414 } 6415 6416 /* bpp depend */ 6417 /*XR06: Palette control */ 6418 /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */ 6419 /* bit 1: Internal DAC disable */ 6420 /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */ 6421 /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */ 6422 /* bit 4: Enable PC Video Overlay on colour key */ 6423 /* bit 5: Bypass Internal VGA palette */ 6424 /* bit 7-6: Colour reduction select, 0 for NTSC (default), */ 6425 /* 1 for Equivalent weighting, 2 for green only, */ 6426 /* 3 for Colour w/o reduction */ 6427 /* XR50 Panel Format Register 1 */ 6428 /* bit 1-0: Frame Rate Control; 00, No FRC; */ 6429 /* 01, 16-frame FRC for colour STN and monochrome */ 6430 /* 10, 2-frame FRC for colour TFT or monochrome; */ 6431 /* 11, reserved */ 6432 /* bit 3-2: Dither Enable */ 6433 /* 00, disable dithering; 01, enable dithering */ 6434 /* for 256 mode */ 6435 /* 10, enable dithering for all modes; 11, reserved */ 6436 /* bit6-4: Clock Divide (CD) */ 6437 /* 000, Shift Clock Freq = Dot Clock Freq; */ 6438 /* 001, SClk = DClk/2; 010 SClk = DClk/4; */ 6439 /* 011, SClk = DClk/8; 100 SClk = DClk/16; */ 6440 /* bit 7: TFT data width */ 6441 /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */ 6442 if (pScrn->bitsPerPixel == 16) { 6443 ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */ 6444 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6445 ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */ 6446 if (pScrn->weight.green != 5) 6447 ChipsNew->XR[0x06] |= 0x08; /*16bpp */ 6448 } else if (pScrn->bitsPerPixel == 24) { 6449 ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */ 6450 ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */ 6451 if (xf86ReturnOptValBool(cPtr->Options, OPTION_18_BIT_BUS, FALSE)) { 6452 ChipsNew->XR[0x50] &= 0x7F; /*18 bit TFT data width */ 6453 } else { 6454 ChipsNew->XR[0x50] |= 0x80; /*24 bit TFT data width */ 6455 } 6456 } 6457 6458 /*CRT only: interlaced mode */ 6459 if (!(cPtr->PanelType & ChipsLCD)) { 6460 if (mode->Flags & V_INTERLACE){ 6461 ChipsNew->XR[0x28] |= 0x20; /* set interlace */ 6462 /* empirical value */ 6463 tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1) 6464 - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 )); 6465 if(cPtr->Chipset < CHIPS_CT65535) 6466 ChipsNew->XR[0x19] = tmp & 0xFF; 6467 else 6468 ChipsNew->XR[0x29] = tmp & 0xFF; 6469 ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */ 6470 } else { 6471 ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */ 6472 ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */ 6473 } 6474 } 6475 6476 /* STN specific */ 6477 if (IS_STN(cPtr->PanelType)) { 6478 ChipsNew->XR[0x50] &= ~0x03; /* FRC clear */ 6479 ChipsNew->XR[0x50] |= 0x01; /* 16 frame FRC */ 6480 ChipsNew->XR[0x50] &= ~0x0C; /* Dither clear */ 6481 ChipsNew->XR[0x50] |= 0x08; /* Dither all modes */ 6482 if (cPtr->Chipset == CHIPS_CT65548) { 6483 ChipsNew->XR[0x03] |= 0x20; /* CRT I/F priority */ 6484 ChipsNew->XR[0x04] |= 0x10; /* RAS precharge 65548 */ 6485 } 6486 } 6487 6488 /* This stuff was empirically derived several years ago. Not sure its 6489 * still needed, and I'd love to get rid of it as its ugly 6490 */ 6491 switch (cPtr->Chipset) { 6492 case CHIPS_CT65545: /*jet mini *//*DEC HighNote Ultra DSTN */ 6493 ChipsNew->XR[0x03] |= 0x10; /* do not hold off CPU for palette acc*/ 6494 break; 6495 case CHIPS_CT65546: /*CT 65546, only for Toshiba */ 6496 ChipsNew->XR[0x05] |= 0x80; /* EDO RAM enable */ 6497 break; 6498 } 6499 6500 if (cPtr->PanelType & ChipsLCD) 6501 ChipsNew->XR[0x51] |= 0x04; 6502 else 6503 ChipsNew->XR[0x51] &= ~0x04; 6504 6505 /* Program the registers */ 6506 /*vgaHWProtect(pScrn, TRUE);*/ 6507 chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE); 6508 /*vgaHWProtect(pScrn, FALSE);*/ 6509 6510 return (TRUE); 6511} 6512 6513static void 6514chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, CHIPSRegPtr ChipsReg, 6515 Bool restoreFonts) 6516{ 6517 vgaHWPtr hwp = VGAHWPTR(pScrn); 6518 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6519 unsigned char tmp = 0; 6520 6521 /*vgaHWProtect(pScrn, TRUE);*/ 6522 6523 /* set registers so that we can program the controller */ 6524 if (IS_HiQV(cPtr)) { 6525 cPtr->writeXR(cPtr, 0x0E, 0x00); 6526 if (cPtr->Flags & ChipsDualChannelSupport) { 6527 tmp = cPtr->readFR(cPtr, 0x01); /* Disable pipeline */ 6528 cPtr->writeFR(cPtr, 0x01, (tmp & 0xFC)); 6529 cPtr->writeFR(cPtr, 0x02, 0x00); /* CRT/FP off */ 6530 } 6531 } else { 6532 cPtr->writeXR(cPtr, 0x10, 0x00); 6533 cPtr->writeXR(cPtr, 0x11, 0x00); 6534 tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */ 6535 cPtr->writeXR(cPtr, 0x0C, tmp); 6536 cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect all registers */ 6537 tmp = cPtr->readXR(cPtr, 0x14); 6538 cPtr->writeXR(cPtr, 0x14, tmp & ~0x20); /* enable vsync on ST01 */ 6539 } 6540 6541 chipsFixResume(pScrn); 6542 6543 /* 6544 * Wait for vsync if sequencer is running - stop sequencer. 6545 * Only do if sync reset is ignored. Dual pipeline capable 6546 * chips have pipeline forced off here, so we don't care. 6547 */ 6548 if ((cPtr->SyncResetIgn) && (!(cPtr->Flags & ChipsDualChannelSupport))) { 6549 while (((hwp->readST01(hwp)) & 0x08) == 0x08); /* VSync off */ 6550 while (((hwp->readST01(hwp)) & 0x08) == 0x00); /* VSync on */ 6551 hwp->writeSeq(hwp, 0x07, 0x00); /* reset hsync - just in case... */ 6552 } 6553 6554 /* set the clock */ 6555 chipsClockLoad(pScrn, &ChipsReg->Clock); 6556 /* chipsClockLoad() sets this so we don't want vgaHWRestore() change it */ 6557 VgaReg->MiscOutReg = inb(cPtr->PIOBase + 0x3CC); 6558 6559 /* set extended regs */ 6560 chipsRestoreExtendedRegs(pScrn, ChipsReg); 6561#if 0 6562 /* if people complain about lock ups or blank screens -- re-enable */ 6563 /* set CRTC registers - do it before sequencer restarts */ 6564 for (i=0; i<25; i++) 6565 hwp->writeCrtc(hwp, i, VgaReg->CRTC[i]); 6566#endif 6567 /* set generic registers */ 6568 /* 6569 * Enabling writing to the colourmap causes 69030's to lock. 6570 * Anyone care to explain to me why ???? 6571 */ 6572 if (cPtr->Flags & ChipsDualChannelSupport) { 6573 /* Enable pipeline if needed */ 6574 cPtr->writeFR(cPtr, 0x01, ChipsReg->FR[0x01]); 6575 cPtr->writeFR(cPtr, 0x02, ChipsReg->FR[0x02]); 6576 vgaHWRestore(pScrn, VgaReg, VGA_SR_MODE | 6577 (restoreFonts ? VGA_SR_FONTS : 0)); 6578 } else { 6579 vgaHWRestore(pScrn, VgaReg, VGA_SR_MODE | VGA_SR_CMAP | 6580 (restoreFonts ? VGA_SR_FONTS : 0)); 6581 } 6582 6583 /* set stretching registers */ 6584 if (IS_HiQV(cPtr)) { 6585 chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40], 6586 (unsigned char)ChipsReg->FR[0x48]); 6587#if 0 6588 /* if people report about stretching not working -- re-enable */ 6589 /* why twice ? : 6590 * sometimes the console is not well restored even if these registers 6591 * are good, re-write the registers works around it 6592 */ 6593 chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40], 6594 (unsigned char)ChipsReg->FR[0x48]); 6595#endif 6596 } else if (!IS_Wingine(cPtr)) 6597 chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->XR[0x55], 6598 (unsigned char)ChipsReg->XR[0x57]); 6599 6600 /* perform a synchronous reset */ 6601 if (!cPtr->SyncResetIgn) { 6602 if (!IS_HiQV(cPtr)) { 6603 /* enable synchronous reset on 655xx */ 6604 tmp = cPtr->readXR(cPtr, 0x0E); 6605 cPtr->writeXR(cPtr, 0x0E, tmp & 0x7F); 6606 } 6607 hwp->writeSeq(hwp, 0x00, 0x01); 6608 usleep(10000); 6609 hwp->writeSeq(hwp, 0x00, 0x03); 6610 if (!IS_HiQV(cPtr)) 6611 cPtr->writeXR(cPtr, 0x0E, tmp); 6612 } 6613 /* Flag valid start address, if using CRT extensions */ 6614 if (IS_HiQV(cPtr) && (ChipsReg->XR[0x09] & 0x1) == 0x1) { 6615 tmp = hwp->readCrtc(hwp, 0x40); 6616 hwp->writeCrtc(hwp, 0x40, tmp | 0x80); 6617 } 6618 6619 /* Fix resume again here, as Nozomi seems to need it */ 6620 chipsFixResume(pScrn); 6621 /*vgaHWProtect(pScrn, FALSE);*/ 6622 6623#if 0 6624 /* Enable pipeline if needed */ 6625 if (cPtr->Flags & ChipsDualChannelSupport) { 6626 cPtr->writeFR(cPtr, 0x01, ChipsReg->FR[0x01]); 6627 cPtr->writeFR(cPtr, 0x02, ChipsReg->FR[0x02]); 6628 } 6629#endif 6630} 6631 6632static void 6633chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs) 6634{ 6635 vgaHWPtr hwp = VGAHWPTR(pScrn); 6636 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6637 int i; 6638 unsigned char tmp; 6639 6640 if (IS_HiQV(cPtr)) { 6641 /* set extended regs */ 6642 for (i = 0; i < 0x43; i++) { 6643 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6644 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6645 } 6646 6647 /* Set SAR04 multimedia register correctly */ 6648 if ((cPtr->Flags & ChipsVideoSupport)) { 6649#ifdef SAR04 6650 cPtr->writeXR(cPtr, 0x4E, 0x04); 6651 if (cPtr->readXR(cPtr, 0x4F) != Regs->XR[0x4F]) 6652 cPtr->writeXR(cPtr, 0x4F, Regs->XR[0x4F]); 6653#endif 6654 } 6655 6656 /* Don't touch reserved memory control registers */ 6657 for (i = 0x50; i < 0xBF; i++) { 6658 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6659 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6660 } 6661 /* Don't touch VCLK regs, but fix up MClk */ 6662 6663 /* set mem clock */ 6664 tmp = cPtr->readXR(cPtr, 0xCE); /* Select Fixed MClk before */ 6665 cPtr->writeXR(cPtr, 0xCE, tmp & 0x7F); 6666 if ((cPtr->readXR(cPtr, 0xCC)) != Regs->XR[0xCC]) 6667 cPtr->writeXR(cPtr, 0xCC, Regs->XR[0xCC]); 6668 if ((cPtr->readXR(cPtr, 0xCD)) != Regs->XR[0xCD]) 6669 cPtr->writeXR(cPtr, 0xCD, Regs->XR[0xCD]); 6670 if ((cPtr->readXR(cPtr, 0xCE)) != Regs->XR[0xCE]) 6671 cPtr->writeXR(cPtr, 0xCE, Regs->XR[0xCE]); 6672 6673 /* set flat panel regs. */ 6674 for (i = 0xD0; i < 0xFF; i++) { 6675 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6676 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6677 } 6678 6679 for (i = 0; i < 0x80; i++) { 6680 /* Don't touch alternate clock select reg. */ 6681 if ((i == 0x01) && (cPtr->Chipset == CHIPS_CT69030)) { 6682 /* restore the non clock bits */ 6683 tmp = cPtr->readFR(cPtr, 0x01); 6684 cPtr->writeFR(cPtr, 0x01, ((Regs->FR[0x01] & 0xF0) | 6685 (tmp & ~0xF0))); 6686 continue; 6687 } 6688 6689 if ((i == 0x02) && (cPtr->Chipset == CHIPS_CT69030)) 6690 /* keep pipeline disabled till we are ready */ 6691 continue; 6692 6693 if ((i == 0x03) && (cPtr->Chipset != CHIPS_CT69030)) { 6694 /* restore the non clock bits */ 6695 tmp = cPtr->readFR(cPtr, 0x03); 6696 cPtr->writeFR(cPtr, 0x03, ((Regs->FR[0x03] & 0xC3) | 6697 (tmp & ~0xC3))); 6698 continue; 6699 } 6700 6701 if ((i > 0x03) && (cPtr->Chipset != CHIPS_CT69030) && 6702 (cPtr->SecondCrtc == TRUE)) 6703 continue; 6704 6705 if ( (i == 0x40) || (i==0x48)) { 6706 /* !! set stretching but disable compensation */ 6707 cPtr->writeFR(cPtr, i, Regs->FR[i] & 0xFE); 6708 continue ; /* some registers must be set before FR40/FR48 */ 6709 } 6710 if ((cPtr->readFR(cPtr, i)) != Regs->FR[i]) { 6711 cPtr->writeFR(cPtr, i, Regs->FR[i]); 6712 } 6713 } 6714 6715 /* set the multimedia regs */ 6716 for (i = 0x02; i < 0x80; i++) { 6717 if ( (i == 0x43) || (i == 0x44)) 6718 continue; 6719 if ((cPtr->readMR(cPtr, i)) != Regs->MR[i]) 6720 cPtr->writeMR(cPtr, i, Regs->MR[i]); 6721 } 6722 6723 /* set extended crtc regs. */ 6724 for (i = 0x30; i < 0x80; i++) { 6725 if ((hwp->readCrtc(hwp, i)) != Regs->CR[i]) 6726 hwp->writeCrtc(hwp, i, Regs->CR[i]); 6727 } 6728 } else { 6729 /* set extended regs. */ 6730 for (i = 0; i < 0x30; i++) { 6731 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6732 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6733 } 6734 cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect just in case ... */ 6735 /* Don't touch MCLK/VCLK regs. */ 6736 for (i = 0x34; i < 0x54; i++) { 6737 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6738 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6739 } 6740 tmp = cPtr->readXR(cPtr, 0x54); /* restore the non clock bits */ 6741 cPtr->writeXR(cPtr, 0x54, ((Regs->XR[0x54] & 0xF3) | (tmp & ~0xF3))); 6742 cPtr->writeXR(cPtr, 0x55, Regs->XR[0x55] & 0xFE); /* h-comp off */ 6743 cPtr->writeXR(cPtr, 0x56, Regs->XR[0x56]); 6744 cPtr->writeXR(cPtr, 0x57, Regs->XR[0x57] & 0xFE); /* v-comp off */ 6745 for (i=0x58; i < 0x7D; i++) {/* don't touch XR7D and XR7F on WINGINE */ 6746 if ((cPtr->readXR(cPtr, i)) != Regs->XR[i]) 6747 cPtr->writeXR(cPtr, i, Regs->XR[i]); 6748 } 6749 } 6750#ifdef DEBUG 6751 /* debug - dump out all the extended registers... */ 6752 if (IS_HiQV(cPtr)) { 6753 for (i = 0; i < 0xFF; i++) { 6754 ErrorF("XR%X - %X : %X\n", i, Regs->XR[i], 6755 cPtr->readXR(cPtr, i)); 6756 } 6757 for (i = 0; i < 0x80; i++) { 6758 ErrorF("FR%X - %X : %X\n", i, Regs->FR[i], 6759 cPtr->readFR(cPtr, i)); 6760 } 6761 } else { 6762 for (i = 0; i < 0x80; i++) { 6763 ErrorF("XR%X - %X : %X\n", i, Regs->XR[i], 6764 cPtr->readXR(cPtr, i)); 6765 } 6766 } 6767#endif 6768} 6769 6770static void 6771chipsRestoreStretching(ScrnInfoPtr pScrn, unsigned char ctHorizontalStretch, 6772 unsigned char ctVerticalStretch) 6773{ 6774 unsigned char tmp; 6775 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6776 6777 /* write to regs. */ 6778 if (IS_HiQV(cPtr)) { 6779 tmp = cPtr->readFR(cPtr, 0x48); 6780 cPtr->writeFR(cPtr, 0x48, (tmp & 0xFE) | (ctVerticalStretch & 0x01)); 6781 tmp = cPtr->readFR(cPtr, 0x40); 6782 cPtr->writeFR(cPtr, 0x40, (tmp & 0xFE) | (ctHorizontalStretch & 0x01)); 6783 } else { 6784 tmp = cPtr->readXR(cPtr, 0x55); 6785 cPtr->writeXR(cPtr, 0x55, (tmp & 0xFE) | (ctHorizontalStretch & 0x01)); 6786 tmp = cPtr->readXR(cPtr, 0x57); 6787 cPtr->writeXR(cPtr, 0x57, (tmp & 0xFE) | (ctVerticalStretch & 0x01)); 6788 } 6789 6790 usleep(20000); /* to be active */ 6791} 6792 6793static int 6794chipsVideoMode(int depth, int displayHSize, 6795 int displayVSize) 6796{ 6797 /* 4 bpp 8 bpp 16 bpp 18 bpp 24 bpp 32 bpp */ 6798 /* 640 0x20 0x30 0x40 - 0x50 - */ 6799 /* 800 0x22 0x32 0x42 - 0x52 - */ 6800 /*1024 0x24 0x34 0x44 - 0x54 - for 1024x768 */ 6801 /*1024 - 0x36 0x47 - 0x56 - for 1024x600 */ 6802 /*1152 0x27 0x37 0x47 - 0x57 - */ 6803 /*1280 0x28 0x38 0x49 - - - */ 6804 /*1600 0x2C 0x3C 0x4C 0x5D - - */ 6805 /*This value is only for BIOS.... */ 6806 6807 int videoMode = 0; 6808 6809 switch (depth) { 6810 case 1: 6811 case 4: 6812 videoMode = 0x20; 6813 break; 6814 case 8: 6815 videoMode = 0x30; 6816 break; 6817 case 15: 6818 videoMode = 0x40; 6819 break; 6820 case 16: 6821 videoMode = 0x41; 6822 break; 6823 default: 6824 videoMode = 0x50; 6825 break; 6826 } 6827 6828 switch (displayHSize) { 6829 case 800: 6830 videoMode |= 0x02; 6831 break; 6832 case 1024: 6833 videoMode |= 0x04; 6834 if(displayVSize < 768) 6835 videoMode |= 0x02; 6836 break; 6837 case 1152: 6838 videoMode |= 0x07; 6839 break; 6840 case 1280: 6841 videoMode |= 0x08; 6842 break; 6843 case 1600: 6844 videoMode |= 0x0C; /*0x0A??*/ 6845 break; 6846 } 6847 6848 return videoMode; 6849} 6850 6851 6852/* 6853 * Map the framebuffer and MMIO memory. 6854 */ 6855 6856static Bool 6857chipsMapMem(ScrnInfoPtr pScrn) 6858{ 6859 CHIPSPtr cPtr = CHIPSPTR(pScrn); 6860 vgaHWPtr hwp = VGAHWPTR(pScrn); 6861 CHIPSEntPtr cPtrEnt; 6862 6863 if (cPtr->Flags & ChipsLinearSupport) { 6864 if (cPtr->UseMMIO) { 6865 if (IS_HiQV(cPtr)) { 6866#ifndef XSERVER_LIBPCIACCESS 6867 if (cPtr->pEnt->location.type == BUS_PCI) 6868 cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, 6869 VIDMEM_MMIO_32BIT,cPtr->PciTag, cPtr->IOAddress, 6870 0x20000L); 6871 else 6872 cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, 6873 VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x20000L); 6874#else 6875 { 6876 int err; 6877 void** result = (void**)&cPtr->MMIOBase; 6878 6879 if (cPtr->pEnt->location.type == BUS_PCI) { 6880 err = pci_device_map_range(cPtr->PciInfo, 6881 cPtr->IOAddress, 6882 0x20000L, 6883 PCI_DEV_MAP_FLAG_WRITABLE, 6884 result); 6885 } else { 6886 *result = mmap(NULL, 6887 0x00020000U, 6888 PROT_READ | PROT_WRITE, 6889 MAP_SHARED, 6890 xf86Info.consoleFd, 6891 cPtr->IOAddress); 6892 err = (*result == MAP_FAILED); 6893 } 6894 if (err) { 6895 xf86Msg(X_ERROR, "PCI mmap registers failed\n"); 6896 return FALSE; 6897 } 6898 } 6899#endif 6900 } else { 6901#ifndef XSERVER_LIBPCIACCESS 6902 if (cPtr->pEnt->location.type == BUS_PCI) 6903 cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, 6904 VIDMEM_MMIO_32BIT, cPtr->PciTag, cPtr->IOAddress, 6905 0x10000L); 6906 else 6907 cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, 6908 VIDMEM_MMIO_32BIT, cPtr->IOAddress, 0x10000L); 6909#else 6910 { 6911 int err; 6912 void** result = (void**)&cPtr->MMIOBase; 6913 6914 if (cPtr->pEnt->location.type == BUS_PCI) { 6915 err = pci_device_map_range(cPtr->PciInfo, 6916 cPtr->IOAddress, 6917 0x10000L, 6918 PCI_DEV_MAP_FLAG_WRITABLE, 6919 result); 6920 } else { 6921 *result = mmap(NULL, 6922 0x00010000U, 6923 PROT_READ | PROT_WRITE, 6924 MAP_SHARED, 6925 xf86Info.consoleFd, 6926 cPtr->IOAddress); 6927 err = (*result == MAP_FAILED); 6928 } 6929 if (err) { 6930 xf86Msg(X_ERROR, "PCI mmap failed\n"); 6931 return FALSE; 6932 } 6933 } 6934#endif 6935 } 6936 6937 if (cPtr->MMIOBase == NULL) 6938 return FALSE; 6939 } 6940 if (cPtr->FbMapSize) { 6941 unsigned long Addr = (unsigned long)cPtr->FbAddress; 6942 unsigned int Map = cPtr->FbMapSize; 6943#ifdef XSERVER_LIBPCIACCESS 6944 int err; 6945 void** result; 6946#endif 6947 6948 if ((cPtr->Flags & ChipsDualChannelSupport) && 6949 (xf86IsEntityShared(pScrn->entityList[0]))) { 6950 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 6951 CHIPSEntityIndex)->ptr; 6952 if (cPtr->SecondCrtc == FALSE) { 6953 Addr = cPtrEnt->masterFbAddress; 6954 Map = cPtrEnt->masterFbMapSize; 6955 } else { 6956 Addr = cPtrEnt->slaveFbAddress; 6957 Map = cPtrEnt->slaveFbMapSize; 6958 } 6959 } 6960 6961#ifndef XSERVER_LIBPCIACCESS 6962 if (cPtr->pEnt->location.type == BUS_PCI) 6963 cPtr->FbBase = xf86MapPciMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER, 6964 cPtr->PciTag, Addr, Map); 6965 6966 else 6967 cPtr->FbBase = xf86MapVidMem(pScrn->scrnIndex,VIDMEM_FRAMEBUFFER, 6968 Addr, Map); 6969#else 6970 result = (void**)&cPtr->FbBase; 6971 if (cPtr->pEnt->location.type == BUS_PCI) { 6972 err = pci_device_map_range(cPtr->PciInfo, 6973 Addr, 6974 Map, 6975 PCI_DEV_MAP_FLAG_WRITABLE | 6976 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 6977 result); 6978 } else 6979 *result = mmap(NULL, 6980 Map, 6981 PROT_READ | PROT_WRITE, 6982 MAP_SHARED, 6983 xf86Info.consoleFd, 6984 Addr); 6985 err = (*result == MAP_FAILED); 6986 if (err) { 6987 xf86Msg(X_ERROR, "PCI mmap fb failed\n"); 6988 return FALSE; 6989 } 6990#endif 6991 if (cPtr->FbBase == NULL) 6992 return FALSE; 6993 } 6994 if (cPtr->Flags & ChipsFullMMIOSupport) { 6995#ifndef XSERVER_LIBPCIACCESS 6996 cPtr->MMIOBaseVGA = xf86MapPciMem(pScrn->scrnIndex, 6997 VIDMEM_MMIO,cPtr->PciTag, 6998 cPtr->IOAddress, 0x2000L); 6999#else 7000 cPtr->MMIOBaseVGA = cPtr->MMIOBase; 7001#endif 7002 /* 69030 MMIO Fix. 7003 * 7004 * The hardware lets us map the PipeB data registers 7005 * into the MMIO address space normally occupied by PipeA, 7006 * but it doesn't allow remapping of the index registers. 7007 * So we're forced to map a separate MMIO space for each 7008 * pipe and to toggle between them as necessary. -GHB 7009 */ 7010 if (cPtr->Flags & ChipsDualChannelSupport) 7011 { 7012#ifndef XSERVER_LIBPCIACCESS 7013 cPtr->MMIOBasePipeB = xf86MapPciMem(pScrn->scrnIndex, 7014 VIDMEM_MMIO,cPtr->PciTag, 7015 cPtr->IOAddress + 0x800000, 0x2000L); 7016#else 7017 void** result = (void**)&cPtr->MMIOBasePipeB; 7018 int err = pci_device_map_range(cPtr->PciInfo, 7019 cPtr->IOAddress + 0x800000, 7020 0x2000L, 7021 PCI_DEV_MAP_FLAG_WRITABLE, 7022 result); 7023 if (err) 7024 return FALSE; 7025#endif 7026 } 7027 7028 cPtr->MMIOBasePipeA = cPtr->MMIOBaseVGA; 7029 } 7030 } else { 7031 /* In paged mode Base is the VGA window at 0xA0000 */ 7032 cPtr->FbBase = hwp->Base; 7033 } 7034 7035 return TRUE; 7036} 7037 7038 7039/* 7040 * Unmap the framebuffer and MMIO memory. 7041 */ 7042 7043static Bool 7044chipsUnmapMem(ScrnInfoPtr pScrn) 7045{ 7046 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7047 7048 if (cPtr->Flags & ChipsLinearSupport) { 7049 if (IS_HiQV(cPtr)) { 7050#ifndef XSERVER_LIBPCIACCESS 7051 if (cPtr->MMIOBase) 7052 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase, 7053 0x20000); 7054 if (cPtr->MMIOBasePipeB) 7055 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBasePipeB, 7056 0x20000); 7057#else 7058 if (cPtr->MMIOBase) 7059 pci_device_unmap_range(cPtr->PciInfo, cPtr->MMIOBase, 0x20000); 7060 7061 if (cPtr->MMIOBasePipeB) 7062 pci_device_unmap_range(cPtr->PciInfo, cPtr->MMIOBasePipeB, 0x2000); 7063 7064#endif 7065 cPtr->MMIOBasePipeB = NULL; 7066 } else { 7067#ifndef XSERVER_LIBPCIACCESS 7068 if (cPtr->MMIOBase) 7069 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase, 7070 0x10000); 7071#else 7072 if (cPtr->MMIOBase) 7073 pci_device_unmap_range(cPtr->PciInfo, cPtr->MMIOBase, 0x10000); 7074#endif 7075 } 7076 cPtr->MMIOBase = NULL; 7077#ifndef XSERVER_LIBPCIACCESS 7078 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->FbBase, 7079 cPtr->FbMapSize); 7080#else 7081 pci_device_unmap_range(cPtr->PciInfo, cPtr->FbBase, cPtr->FbMapSize); 7082#endif 7083 } 7084 cPtr->FbBase = NULL; 7085 7086 return TRUE; 7087} 7088 7089static void 7090chipsProtect(ScrnInfoPtr pScrn, Bool on) 7091{ 7092 vgaHWProtect(pScrn, on); 7093} 7094 7095static void 7096chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank) 7097{ 7098 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7099 vgaHWPtr hwp = VGAHWPTR(pScrn); 7100 unsigned char scrn; 7101 CHIPSEntPtr cPtrEnt; 7102 7103 if (cPtr->UseDualChannel) { 7104 cPtrEnt = xf86GetEntityPrivate(pScrn->entityList[0], 7105 CHIPSEntityIndex)->ptr; 7106 DUALREOPEN; 7107 } 7108 7109 /* fix things that could be messed up by suspend/resume */ 7110 if (!IS_HiQV(cPtr)) 7111 cPtr->writeXR(cPtr, 0x15, 0x00); 7112 7113 scrn = hwp->readSeq(hwp, 0x01); 7114 7115 if (unblank) { 7116 scrn &= 0xDF; /* enable screen */ 7117 } else { 7118 scrn |= 0x20; /* blank screen */ 7119 } 7120 7121 /* synchronous reset - stop counters */ 7122 if (!cPtr->SyncResetIgn) { 7123 hwp->writeSeq(hwp, 0x00, 0x01); 7124 } 7125 7126 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 7127 7128 /* end reset - start counters */ 7129 if (!cPtr->SyncResetIgn) { 7130 hwp->writeSeq(hwp, 0x00, 0x03); 7131 } 7132 7133 if ((cPtr->UseDualChannel) && 7134 (! xf86IsEntityShared(pScrn->entityList[0]))) { 7135 unsigned int IOSS, MSS; 7136 IOSS = cPtr->readIOSS(cPtr); 7137 MSS = cPtr->readMSS(cPtr); 7138 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 7139 IOSS_PIPE_B)); 7140 cPtr->writeMSS(cPtr, hwp, ((cPtr->storeMSS & MSS_MASK) | MSS_PIPE_B)); 7141 7142 /* fix things that could be messed up by suspend/resume */ 7143 if (!IS_HiQV(cPtr)) 7144 cPtr->writeXR(cPtr, 0x15, 0x00); 7145 7146 scrn = hwp->readSeq(hwp, 0x01); 7147 7148 if (unblank) { 7149 scrn &= 0xDF; /* enable screen */ 7150 } else { 7151 scrn |= 0x20; /* blank screen */ 7152 } 7153 7154 /* synchronous reset - stop counters */ 7155 if (!cPtr->SyncResetIgn) { 7156 hwp->writeSeq(hwp, 0x00, 0x01); 7157 } 7158 7159 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 7160 7161 /* end reset - start counters */ 7162 if (!cPtr->SyncResetIgn) { 7163 hwp->writeSeq(hwp, 0x00, 0x03); 7164 } 7165 7166 cPtr->writeIOSS(cPtr, IOSS); 7167 cPtr->writeMSS(cPtr, hwp, MSS); 7168 } 7169 7170} 7171 7172static void 7173chipsLock(ScrnInfoPtr pScrn) 7174{ 7175 vgaHWPtr hwp = VGAHWPTR(pScrn); 7176 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7177 unsigned char tmp; 7178 7179 vgaHWLock(hwp); 7180 7181 if (!IS_HiQV(cPtr)) { 7182 /* group protection attribute controller access */ 7183 cPtr->writeXR(cPtr, 0x15, cPtr->SuspendHack.xr15); 7184 tmp = cPtr->readXR(cPtr, 0x02); 7185 cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18) | cPtr->SuspendHack.xr02); 7186 tmp = cPtr->readXR(cPtr, 0x14); 7187 cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20) | cPtr->SuspendHack.xr14); 7188 7189 /* reset 32 bit register access */ 7190 if (cPtr->Chipset > CHIPS_CT65540) { 7191 tmp = cPtr->readXR(cPtr, 0x03); 7192 cPtr->writeXR(cPtr, 0x03, (tmp & ~0x0A) | cPtr->SuspendHack.xr03); 7193 } 7194 } 7195} 7196 7197static void 7198chipsUnlock(ScrnInfoPtr pScrn) 7199{ 7200 vgaHWPtr hwp = VGAHWPTR(pScrn); 7201 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7202 unsigned char tmp; 7203 7204 if (!IS_HiQV(cPtr)) { 7205 /* group protection attribute controller access */ 7206 cPtr->writeXR(cPtr, 0x15, 0x00); 7207 tmp = cPtr->readXR(cPtr, 0x02); 7208 cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18)); 7209 tmp = cPtr->readXR(cPtr, 0x14); 7210 cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20)); 7211 /* enable 32 bit register access */ 7212 if (cPtr->Chipset > CHIPS_CT65540) { 7213 cPtr->writeXR(cPtr, 0x03, cPtr->SuspendHack.xr03 | 0x0A); 7214 } 7215 } 7216 vgaHWUnlock(hwp); 7217} 7218 7219static void 7220chipsHWCursorOn(CHIPSPtr cPtr, ScrnInfoPtr pScrn) 7221{ 7222 /* enable HW cursor */ 7223 if (cPtr->HWCursorShown) { 7224 if (IS_HiQV(cPtr)) { 7225 cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF); 7226 if (cPtr->UseDualChannel && 7227 (! xf86IsEntityShared(pScrn->entityList[0]))) { 7228 unsigned int IOSS, MSS; 7229 IOSS = cPtr->readIOSS(cPtr); 7230 MSS = cPtr->readMSS(cPtr); 7231 cPtr->writeIOSS(cPtr, ((cPtr->storeIOSS & IOSS_MASK) | 7232 IOSS_PIPE_B)); 7233 cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), ((cPtr->storeMSS & 7234 MSS_MASK) | MSS_PIPE_B)); 7235 cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF); 7236 cPtr->writeIOSS(cPtr, IOSS); 7237 cPtr->writeMSS(cPtr, VGAHWPTR(pScrn), MSS); 7238 } 7239 } else { 7240 HW_DEBUG(0x8); 7241 if (cPtr->UseMMIO) { 7242 MMIOmeml(DR(0x8)) = cPtr->HWCursorContents; 7243 } else { 7244 outl(cPtr->PIOBase + DR(0x8), cPtr->HWCursorContents); 7245 } 7246 } 7247 } 7248} 7249 7250static void 7251chipsHWCursorOff(CHIPSPtr cPtr, ScrnInfoPtr pScrn) 7252{ 7253 /* disable HW cursor */ 7254 if (cPtr->HWCursorShown) { 7255 if (IS_HiQV(cPtr)) { 7256 cPtr->HWCursorContents = cPtr->readXR(cPtr, 0xA0); 7257 cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xF8); 7258 } else { 7259 HW_DEBUG(0x8); 7260 if (cPtr->UseMMIO) { 7261 cPtr->HWCursorContents = MMIOmeml(DR(0x8)); 7262 /* Below used to be MMIOmemw() change back if problem!!! */ 7263 /* Also see ct_cursor.c */ 7264 MMIOmeml(DR(0x8)) = cPtr->HWCursorContents & 0xFFFE; 7265 } else { 7266 cPtr->HWCursorContents = inl(cPtr->PIOBase + DR(0x8)); 7267 outw(cPtr->PIOBase + DR(0x8), cPtr->HWCursorContents & 0xFFFE); 7268 } 7269 } 7270 } 7271} 7272 7273void 7274chipsFixResume(ScrnInfoPtr pScrn) 7275{ 7276 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7277 vgaHWPtr hwp = VGAHWPTR(pScrn); 7278 unsigned char tmp; 7279 7280 /* fix things that could be messed up by suspend/resume */ 7281 if (!IS_HiQV(cPtr)) 7282 cPtr->writeXR(cPtr, 0x15, 0x00); 7283 tmp = hwp->readMiscOut(hwp); 7284 hwp->writeMiscOut(hwp, (tmp & 0xFE) | cPtr->SuspendHack.vgaIOBaseFlag); 7285 tmp = hwp->readCrtc(hwp, 0x11); 7286 hwp->writeCrtc(hwp, 0x11, (tmp & 0x7F)); 7287} 7288 7289static char 7290chipsTestDACComp(ScrnInfoPtr pScrn, unsigned char a, unsigned char b, 7291 unsigned char c) 7292{ 7293 vgaHWPtr hwp = VGAHWPTR(pScrn); 7294 unsigned char type; 7295 7296 hwp->writeDacWriteAddr(hwp, 0x00); 7297 while ((hwp->readST01(hwp)) & 0x08){}; /* wait for vsync to end */ 7298 while (!((hwp->readST01(hwp)) & 0x08)){}; /* wait for new vsync */ 7299 hwp->writeDacData(hwp, a); /* set pattern */ 7300 hwp->writeDacData(hwp, b); 7301 hwp->writeDacData(hwp, c); 7302 while (!(hwp->readST01(hwp) & 0x01)){}; /* wait for hsync to end */ 7303 while (hwp->readST01(hwp) & 0x01){}; /* wait for hsync to end */ 7304 type = hwp->readST00(hwp); /* read comparator */ 7305 return (type & 0x10); 7306} 7307 7308static int 7309chipsProbeMonitor(ScrnInfoPtr pScrn) 7310{ 7311 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7312 vgaHWPtr hwp = VGAHWPTR(pScrn); 7313 unsigned char dacmask; 7314 unsigned char dacdata[3]; 7315 unsigned char xr1, xr2; 7316 int type = 2; /* no monitor */ 7317 unsigned char IOSS=0, MSS=0, tmpfr02=0, tmpfr01a=0, tmpfr01b=0; 7318 7319 /* Dual channel display, enable both pipelines */ 7320 if (cPtr->Flags & ChipsDualChannelSupport) { 7321 IOSS = cPtr->readIOSS(cPtr); 7322 MSS = cPtr->readMSS(cPtr); 7323 tmpfr02 = cPtr->readFR(cPtr,0x02); 7324 cPtr->writeFR(cPtr, 0x02, (tmpfr02 & 0xCF)); /* CRT/FP off */ 7325 usleep(1000); 7326 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_A)); 7327 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_A)); 7328 tmpfr01a = cPtr->readFR(cPtr,0x01); 7329 if ((tmpfr01a & 0x3) != 0x01) 7330 cPtr->writeFR(cPtr, 0x01, ((tmpfr01a & 0xFC) | 0x1)); 7331 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_B)); 7332 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_B)); 7333 tmpfr01b = cPtr->readFR(cPtr,0x01); 7334 if ((tmpfr01b & 0x3) != 0x01) 7335 cPtr->writeFR(cPtr, 0x01, ((tmpfr01b & 0xFC) | 0x1)); 7336 cPtr->writeIOSS(cPtr, IOSS); 7337 cPtr->writeMSS(cPtr, hwp, MSS); 7338 cPtr->writeFR(cPtr, 0x02, (tmpfr02 & 0xCF) | 0x10); /* CRT on/FP off*/ 7339 } 7340 7341 dacmask = hwp->readDacMask(hwp); /* save registers */ 7342 hwp->writeDacMask(hwp, 0x00); 7343 hwp->writeDacReadAddr(hwp, 0x00); 7344 7345 dacdata[0]=hwp->readDacData(hwp); 7346 dacdata[1]=hwp->readDacData(hwp); 7347 dacdata[2]=hwp->readDacData(hwp); 7348 7349 if (!IS_HiQV(cPtr)) { 7350 xr1 = cPtr->readXR(cPtr, 0x06); 7351 xr2 = cPtr->readXR(cPtr, 0x1F); 7352 cPtr->writeXR(cPtr, 0x06, xr1 & 0xF1); /* turn on dac */ 7353 cPtr->writeXR(cPtr, 0x1F, xr2 & 0x7F); /* enable comp */ 7354 } else { 7355 xr1 = cPtr->readXR(cPtr, 0x81); 7356 xr2 = cPtr->readXR(cPtr, 0xD0); 7357 cPtr->writeXR(cPtr, 0x81,(xr1 & 0xF0)); 7358 cPtr->writeXR(cPtr, 0xD0,(xr2 | 0x03)); 7359 } 7360 if (chipsTestDACComp(pScrn, 0x12,0x12,0x12)) { /* test patterns */ 7361 if (chipsTestDACComp(pScrn,0x14,0x14,0x14)) /* taken from */ 7362 if (!chipsTestDACComp(pScrn,0x2D,0x14,0x14)) /* BIOS */ 7363 if (!chipsTestDACComp(pScrn,0x14,0x2D,0x14)) 7364 if (!chipsTestDACComp(pScrn,0x14,0x14,0x2D)) 7365 if (!chipsTestDACComp(pScrn,0x2D,0x2D,0x2D)) 7366 type = 0; /* color monitor */ 7367 } else { 7368 if (chipsTestDACComp(pScrn,0x04,0x12,0x04)) 7369 if (!chipsTestDACComp(pScrn,0x1E,0x12,0x04)) 7370 if (!chipsTestDACComp(pScrn,0x04,0x2D,0x04)) 7371 if (!chipsTestDACComp(pScrn,0x1E,0x16,0x15)) 7372 if (chipsTestDACComp(pScrn,0x00,0x00,0x00)) 7373 type = 1; /* monochrome */ 7374 } 7375 7376 hwp->writeDacWriteAddr(hwp, 0x00); /* restore registers */ 7377 hwp->writeDacData(hwp, dacdata[0]); 7378 hwp->writeDacData(hwp, dacdata[1]); 7379 hwp->writeDacData(hwp, dacdata[2]); 7380 hwp->writeDacMask(hwp, dacmask); 7381 if (!IS_HiQV(cPtr)) { 7382 cPtr->writeXR(cPtr,0x06,xr1); 7383 cPtr->writeXR(cPtr,0x1F,xr2); 7384 } else { 7385 cPtr->writeXR(cPtr,0x81,xr1); 7386 cPtr->writeXR(cPtr,0xD0,xr2); 7387 } 7388 7389 if (cPtr->Flags & ChipsDualChannelSupport) { 7390 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_A)); 7391 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_A)); 7392 cPtr->writeFR(cPtr, 0x01, tmpfr01a); 7393 cPtr->writeIOSS(cPtr, ((IOSS & IOSS_MASK) | IOSS_PIPE_B)); 7394 cPtr->writeMSS(cPtr, hwp, ((MSS & MSS_MASK) | MSS_PIPE_B)); 7395 cPtr->writeFR(cPtr, 0x01, tmpfr01b); 7396 usleep(1000); 7397 cPtr->writeIOSS(cPtr, IOSS); 7398 cPtr->writeMSS(cPtr, hwp, MSS); 7399 cPtr->writeFR(cPtr, 0x02, tmpfr02); 7400 } 7401 7402 return type; 7403} 7404 7405static int 7406chipsSetMonitor(ScrnInfoPtr pScrn) 7407{ 7408 int tmp= chipsProbeMonitor(pScrn); 7409 7410 switch (tmp) { 7411 case 0: 7412 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Color monitor detected\n"); 7413 break; 7414 case 1: 7415 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Monochrome monitor detected\n"); 7416 break; 7417 default: 7418 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No monitor detected\n"); 7419 } 7420 return (tmp); 7421} 7422 7423static void 7424chipsSetPanelType(CHIPSPtr cPtr) 7425{ 7426 CARD8 tmp; 7427 7428 if (IS_HiQV(cPtr)) { 7429 if (cPtr->Chipset == CHIPS_CT69030) { 7430 tmp = cPtr->readFR(cPtr, 0x00); 7431 if (tmp & 0x20) { 7432 /* FR02: DISPLAY TYPE REGISTER */ 7433 /* FR02[4] = CRT, FR02[5] = FlatPanel */ 7434 tmp = cPtr->readFR(cPtr, 0x02); 7435 if (tmp & 0x10) 7436 cPtr->PanelType |= ChipsCRT; 7437 if (tmp & 0x20) 7438 cPtr->PanelType |= ChipsLCD | ChipsLCDProbed; 7439 } else { 7440 cPtr->PanelType |= ChipsCRT; 7441 } 7442 } else { 7443 /* test LCD */ 7444 /* FR01: DISPLAY TYPE REGISTER */ 7445 /* FR01[1:0]: Display Type, 01 = CRT, 10 = FlatPanel */ 7446 /* LCD */ 7447 tmp = cPtr->readFR(cPtr, 0x01); 7448 if ((tmp & 0x03) == 0x02) { 7449 cPtr->PanelType |= ChipsLCD | ChipsLCDProbed; 7450 } 7451 tmp = cPtr->readXR(cPtr,0xD0); 7452 if (tmp & 0x01) { 7453 cPtr->PanelType |= ChipsCRT; 7454 } 7455 } 7456 } else { 7457 tmp = cPtr->readXR(cPtr, 0x51); 7458 /* test LCD */ 7459 /* XR51: DISPLAY TYPE REGISTER */ 7460 /* XR51[2]: Display Type, 0 = CRT, 1 = FlatPanel */ 7461 if (tmp & 0x04) { 7462 cPtr->PanelType |= ChipsLCD | ChipsLCDProbed; 7463 } 7464 if ((cPtr->readXR(cPtr, 0x06)) & 0x02) { 7465 cPtr->PanelType |= ChipsCRT; 7466 } 7467 } 7468} 7469 7470static void 7471chipsBlockHandler (BLOCKHANDLER_ARGS_DECL) 7472{ 7473 SCREEN_PTR(arg); 7474 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7475 CHIPSPtr cPtr = CHIPSPTR(pScrn); 7476 7477 pScreen->BlockHandler = cPtr->BlockHandler; 7478 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 7479 pScreen->BlockHandler = chipsBlockHandler; 7480 7481 if(cPtr->VideoTimerCallback) { 7482 UpdateCurrentTime(); 7483 (*cPtr->VideoTimerCallback)(pScrn, currentTime.milliseconds); 7484 } 7485} 7486