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