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