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