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