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