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