trident_dac.c revision 95b296d0
195b296d0Smrg/* 295b296d0Smrg * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. 395b296d0Smrg * 495b296d0Smrg * Permission to use, copy, modify, distribute, and sell this software and its 595b296d0Smrg * documentation for any purpose is hereby granted without fee, provided that 695b296d0Smrg * the above copyright notice appear in all copies and that both that 795b296d0Smrg * copyright notice and this permission notice appear in supporting 895b296d0Smrg * documentation, and that the name of Alan Hourihane not be used in 995b296d0Smrg * advertising or publicity pertaining to distribution of the software without 1095b296d0Smrg * specific, written prior permission. Alan Hourihane makes no representations 1195b296d0Smrg * about the suitability of this software for any purpose. It is provided 1295b296d0Smrg * "as is" without express or implied warranty. 1395b296d0Smrg * 1495b296d0Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1595b296d0Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1695b296d0Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1795b296d0Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1895b296d0Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1995b296d0Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2095b296d0Smrg * PERFORMANCE OF THIS SOFTWARE. 2195b296d0Smrg * 2295b296d0Smrg * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 2395b296d0Smrg */ 2495b296d0Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.79 2003/11/03 05:11:42 tsi Exp $ */ 2595b296d0Smrg 2695b296d0Smrg#ifdef HAVE_CONFIG_H 2795b296d0Smrg#include "config.h" 2895b296d0Smrg#endif 2995b296d0Smrg 3095b296d0Smrg#include "xf86.h" 3195b296d0Smrg#include "xf86_OSproc.h" 3295b296d0Smrg#include "xf86Version.h" 3395b296d0Smrg#include "xf86PciInfo.h" 3495b296d0Smrg#include "xf86Pci.h" 3595b296d0Smrg 3695b296d0Smrg#include "vgaHW.h" 3795b296d0Smrg 3895b296d0Smrg#include "trident.h" 3995b296d0Smrg#include "trident_regs.h" 4095b296d0Smrg 4195b296d0Smrg 4295b296d0Smrgstatic biosMode bios1[] = { 4395b296d0Smrg { 640, 480, 0x11 } 4495b296d0Smrg}; 4595b296d0Smrg 4695b296d0Smrgstatic biosMode bios4[] = { 4795b296d0Smrg { 320, 200, 0xd }, 4895b296d0Smrg { 640, 200, 0xe }, 4995b296d0Smrg { 640, 350, 0x11 }, 5095b296d0Smrg { 640, 480, 0x12 }, 5195b296d0Smrg { 800, 600, 0x5b }, 5295b296d0Smrg { 1024, 768 , 0x5f }, 5395b296d0Smrg { 1280, 1024, 0x63 }, 5495b296d0Smrg { 1600, 1200, 0x65 } 5595b296d0Smrg}; 5695b296d0Smrg 5795b296d0Smrgstatic biosMode bios8[] = { 5895b296d0Smrg { 320, 200, 0x13 }, 5995b296d0Smrg { 640, 400, 0x5c }, 6095b296d0Smrg { 640, 480, 0x5d }, 6195b296d0Smrg { 720, 480, 0x60 }, 6295b296d0Smrg { 800, 600, 0x5e }, 6395b296d0Smrg { 1024, 768, 0x62 }, 6495b296d0Smrg { 1280, 1024, 0x64 }, 6595b296d0Smrg { 1600, 1200, 0x66 } 6695b296d0Smrg}; 6795b296d0Smrg 6895b296d0Smrgstatic biosMode bios15[] = { 6995b296d0Smrg { 640, 400, 0x72 }, 7095b296d0Smrg { 640, 480, 0x74 }, 7195b296d0Smrg { 720, 480, 0x70 }, 7295b296d0Smrg { 800, 600, 0x76 }, 7395b296d0Smrg { 1024, 768, 0x78 }, 7495b296d0Smrg { 1280, 1024, 0x7a }, 7595b296d0Smrg { 1600, 1200, 0x7c } 7695b296d0Smrg}; 7795b296d0Smrg 7895b296d0Smrgstatic biosMode bios16[] = { 7995b296d0Smrg { 640, 400, 0x73 }, 8095b296d0Smrg { 640, 480, 0x75 }, 8195b296d0Smrg { 720, 480, 0x71 }, 8295b296d0Smrg { 800, 600, 0x77 }, 8395b296d0Smrg { 1024, 768, 0x79 }, 8495b296d0Smrg { 1280, 1024, 0x7b }, 8595b296d0Smrg { 1600, 1200, 0x7d } 8695b296d0Smrg}; 8795b296d0Smrg 8895b296d0Smrgstatic biosMode bios24[] = { 8995b296d0Smrg { 640, 400, 0x6b }, 9095b296d0Smrg { 640, 480, 0x6c }, 9195b296d0Smrg { 720, 480, 0x61 }, 9295b296d0Smrg { 800, 600, 0x6d }, 9395b296d0Smrg { 1024, 768, 0x6e } 9495b296d0Smrg}; 9595b296d0Smrg 9695b296d0Smrgstatic newModes newModeRegs [] = { 9795b296d0Smrg { 320, 200, 0x13, 0x30 }, 9895b296d0Smrg { 640, 480, 0x13, 0x61 }, 9995b296d0Smrg { 800, 600, 0x13, 0x62 }, 10095b296d0Smrg { 1024, 768, 0x31, 0x63 }, 10195b296d0Smrg { 1280, 1024, 0x7b, 0x64 }, 10295b296d0Smrg { 1400, 1050, 0x11, 0x7b } 10395b296d0Smrg}; 10495b296d0Smrg 10595b296d0Smrgint 10695b296d0SmrgTridentFindMode(int xres, int yres, int depth) 10795b296d0Smrg{ 10895b296d0Smrg int xres_s; 10995b296d0Smrg int i, size; 11095b296d0Smrg biosMode *mode; 11195b296d0Smrg 11295b296d0Smrg switch (depth) { 11395b296d0Smrg case 8: 11495b296d0Smrg size = sizeof(bios8) / sizeof(biosMode); 11595b296d0Smrg mode = bios8; 11695b296d0Smrg break; 11795b296d0Smrg case 15: 11895b296d0Smrg size = sizeof(bios15) / sizeof(biosMode); 11995b296d0Smrg mode = bios15; 12095b296d0Smrg break; 12195b296d0Smrg case 16: 12295b296d0Smrg size = sizeof(bios16) / sizeof(biosMode); 12395b296d0Smrg mode = bios16; 12495b296d0Smrg break; 12595b296d0Smrg case 24: 12695b296d0Smrg size = sizeof(bios24) / sizeof(biosMode); 12795b296d0Smrg mode = bios24; 12895b296d0Smrg break; 12995b296d0Smrg default: 13095b296d0Smrg return 0; 13195b296d0Smrg } 13295b296d0Smrg 13395b296d0Smrg for (i = 0; i < size; i++) { 13495b296d0Smrg if (xres <= mode[i].x_res) { 13595b296d0Smrg xres_s = mode[i].x_res; 13695b296d0Smrg for (; i < size; i++) { 13795b296d0Smrg if (mode[i].x_res != xres_s) 13895b296d0Smrg return mode[i-1].mode; 13995b296d0Smrg if (yres <= mode[i].y_res) 14095b296d0Smrg return mode[i].mode; 14195b296d0Smrg } 14295b296d0Smrg } 14395b296d0Smrg } 14495b296d0Smrg return mode[size - 1].mode; 14595b296d0Smrg} 14695b296d0Smrg 14795b296d0Smrgstatic void 14895b296d0SmrgTridentFindNewMode(int xres, int yres, CARD8 *gr5a, CARD8 *gr5c) 14995b296d0Smrg{ 15095b296d0Smrg int xres_s; 15195b296d0Smrg int i, size; 15295b296d0Smrg 15395b296d0Smrg size = sizeof(newModeRegs) / sizeof(newModes); 15495b296d0Smrg 15595b296d0Smrg for (i = 0; i < size; i++) { 15695b296d0Smrg if (xres <= newModeRegs[i].x_res) { 15795b296d0Smrg xres_s = newModeRegs[i].x_res; 15895b296d0Smrg for (; i < size; i++) { 15995b296d0Smrg if (newModeRegs[i].x_res != xres_s 16095b296d0Smrg || yres <= newModeRegs[i].y_res) { 16195b296d0Smrg *gr5a = newModeRegs[i].GR5a; 16295b296d0Smrg *gr5c = newModeRegs[i].GR5c; 16395b296d0Smrg return; 16495b296d0Smrg } 16595b296d0Smrg } 16695b296d0Smrg } 16795b296d0Smrg } 16895b296d0Smrg *gr5a = newModeRegs[size - 1].GR5a; 16995b296d0Smrg *gr5c = newModeRegs[size - 1].GR5c; 17095b296d0Smrg return; 17195b296d0Smrg} 17295b296d0Smrg 17395b296d0Smrgstatic void 17495b296d0SmrgtridentSetBrightnessAndGamma(TRIDENTRegPtr tridentReg, 17595b296d0Smrg Bool on, double exp,int brightness) 17695b296d0Smrg{ 17795b296d0Smrg int pivots[] = {0,3,15,63,255}; 17895b296d0Smrg 17995b296d0Smrg double slope; 18095b296d0Smrg double y_0; 18195b296d0Smrg double x, x_prev = 0, y, y_prev = 0; 18295b296d0Smrg int i; 18395b296d0Smrg CARD8 i_slopes[4]; 18495b296d0Smrg CARD8 intercepts[4]; 18595b296d0Smrg 18695b296d0Smrg if (!on) { 18795b296d0Smrg tridentReg->tridentRegs3C4[0xB4] &= ~0x80; 18895b296d0Smrg return; 18995b296d0Smrg } 19095b296d0Smrg 19195b296d0Smrg for (i = 0; i < 4; i++) { 19295b296d0Smrg x = pivots[i + 1] / 255.0; 19395b296d0Smrg y = pow(x,exp); 19495b296d0Smrg slope = (y - y_prev) / (x - x_prev); 19595b296d0Smrg y_0 = y - x * slope; 19695b296d0Smrg { 19795b296d0Smrg#define RND(x) ((((x) - (int) (x)) < 0.5) ? (int)(x) : (int)(x) + 1) 19895b296d0Smrg int val = slope; 19995b296d0Smrg if (val > 7) 20095b296d0Smrg i_slopes[i] = (3 << 4) | (RND(slope) & 0xf); 20195b296d0Smrg else if (val > 3) 20295b296d0Smrg i_slopes[i] = (2 << 4) | (RND(slope * 2) & 0xf); 20395b296d0Smrg else if (val > 1) 20495b296d0Smrg i_slopes[i] = (1 << 4) | (RND(slope * 4) & 0xf); 20595b296d0Smrg else 20695b296d0Smrg i_slopes[i] = (RND(slope * 8) & 0xf); 20795b296d0Smrg#undef RND 20895b296d0Smrg } 20995b296d0Smrg intercepts[i] = (char)(y_0 * 256 / 4); 21095b296d0Smrg x_prev = x; 21195b296d0Smrg y_prev = y; 21295b296d0Smrg } 21395b296d0Smrg 21495b296d0Smrg tridentReg->tridentRegs3C4[0xB4] = 0x80 | i_slopes[0]; 21595b296d0Smrg tridentReg->tridentRegs3C4[0xB5] = i_slopes[1]; 21695b296d0Smrg tridentReg->tridentRegs3C4[0xB6] = i_slopes[2]; 21795b296d0Smrg tridentReg->tridentRegs3C4[0xB7] = i_slopes[3]; 21895b296d0Smrg tridentReg->tridentRegs3C4[0xB8] = (intercepts[0] + brightness); 21995b296d0Smrg tridentReg->tridentRegs3C4[0xB9] = (intercepts[1] + brightness); 22095b296d0Smrg tridentReg->tridentRegs3C4[0xBA] = (intercepts[2] + brightness); 22195b296d0Smrg tridentReg->tridentRegs3C4[0xBB] = (intercepts[3] + brightness); 22295b296d0Smrg} 22395b296d0Smrg 22495b296d0SmrgBool 22595b296d0SmrgTridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 22695b296d0Smrg{ 22795b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 22895b296d0Smrg TRIDENTRegPtr pReg = &pTrident->ModeReg; 22995b296d0Smrg 23095b296d0Smrg int vgaIOBase; 23195b296d0Smrg int offset = 0; 23295b296d0Smrg int clock = pTrident->currentClock; 23395b296d0Smrg CARD8 protect = 0; 23495b296d0Smrg Bool fullSize = FALSE; 23595b296d0Smrg 23695b296d0Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 23795b296d0Smrg vgaRegPtr regp = &hwp->ModeReg; 23895b296d0Smrg vgaRegPtr vgaReg = &hwp->ModeReg; 23995b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 24095b296d0Smrg 24195b296d0Smrg /* Unprotect */ 24295b296d0Smrg if (pTrident->Chipset > PROVIDIA9685) { 24395b296d0Smrg OUTB(0x3C4, Protection); 24495b296d0Smrg protect = INB(0x3C5); 24595b296d0Smrg OUTB(0x3C5, 0x92); 24695b296d0Smrg } 24795b296d0Smrg 24895b296d0Smrg OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */ 24995b296d0Smrg 25095b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] = 0x00; 25195b296d0Smrg pReg->tridentRegsDAC[0x00] = 0x00; 25295b296d0Smrg pReg->tridentRegs3C4[NewMode2] = 0x20; 25395b296d0Smrg OUTB(0x3CE, MiscExtFunc); 25495b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0; 25595b296d0Smrg pReg->tridentRegs3x4[GraphEngReg] = 0x00; 25695b296d0Smrg pReg->tridentRegs3x4[PreEndControl] = 0; 25795b296d0Smrg pReg->tridentRegs3x4[PreEndFetch] = 0; 25895b296d0Smrg 25995b296d0Smrg pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400)>>4) | 26095b296d0Smrg (((mode->CrtcVTotal - 2) & 0x400) >> 3) | 26195b296d0Smrg ((mode->CrtcVSyncStart & 0x400) >> 5) | 26295b296d0Smrg (((mode->CrtcVDisplay - 1) & 0x400) >> 6)| 26395b296d0Smrg 0x08; 26495b296d0Smrg 26595b296d0Smrg pReg->tridentRegs3x4[HorizOverflow] = ((mode->CrtcHTotal & 0x800) >> 11) | 26695b296d0Smrg ((mode->CrtcHBlankStart & 0x800)>>7); 26795b296d0Smrg 26895b296d0Smrg if (pTrident->IsCyber) { 26995b296d0Smrg Bool LCDActive; 27095b296d0Smrg#ifdef READOUT 27195b296d0Smrg Bool ShadowModeActive; 27295b296d0Smrg#endif 27395b296d0Smrg int i = pTrident->lcdMode; 27495b296d0Smrg#ifdef READOUT 27595b296d0Smrg OUTB(0x3CE, CyberControl); 27695b296d0Smrg ShadowModeActive = ((INB(0x3CF) & 0x81) == 0x81); 27795b296d0Smrg#endif 27895b296d0Smrg OUTB(0x3CE, FPConfig); 27995b296d0Smrg pReg->tridentRegs3CE[FPConfig] = INB(0x3CF); 28095b296d0Smrg if (pTrident->dspOverride) { 28195b296d0Smrg if (pTrident->dspOverride & LCD_ACTIVE) { 28295b296d0Smrg pReg->tridentRegs3CE[FPConfig] |= 0x10; 28395b296d0Smrg LCDActive = TRUE; 28495b296d0Smrg } else { 28595b296d0Smrg pReg->tridentRegs3CE[FPConfig] &= ~0x10; 28695b296d0Smrg LCDActive = FALSE; 28795b296d0Smrg } 28895b296d0Smrg if (pTrident->dspOverride & CRT_ACTIVE) 28995b296d0Smrg pReg->tridentRegs3CE[FPConfig] |= 0x20; 29095b296d0Smrg else 29195b296d0Smrg pReg->tridentRegs3CE[FPConfig] &= ~0x20; 29295b296d0Smrg } else { 29395b296d0Smrg LCDActive = (pReg->tridentRegs3CE[FPConfig] & 0x10); 29495b296d0Smrg } 29595b296d0Smrg 29695b296d0Smrg OUTB(0x3CE, CyberEnhance); 29795b296d0Smrg#if 0 29895b296d0Smrg pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF); 29995b296d0Smrg#else 30095b296d0Smrg pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF) & 0x8F; 30195b296d0Smrg if (mode->CrtcVDisplay > 1024) 30295b296d0Smrg pReg->tridentRegs3CE[CyberEnhance] |= 0x50; 30395b296d0Smrg else 30495b296d0Smrg if (mode->CrtcVDisplay > 768) 30595b296d0Smrg pReg->tridentRegs3CE[CyberEnhance] |= 0x30; 30695b296d0Smrg else 30795b296d0Smrg if (mode->CrtcVDisplay > 600) 30895b296d0Smrg pReg->tridentRegs3CE[CyberEnhance] |= 0x20; 30995b296d0Smrg else 31095b296d0Smrg if (mode->CrtcVDisplay > 480) 31195b296d0Smrg pReg->tridentRegs3CE[CyberEnhance] |= 0x10; 31295b296d0Smrg#endif 31395b296d0Smrg OUTB(0x3CE, CyberControl); 31495b296d0Smrg pReg->tridentRegs3CE[CyberControl] = INB(0x3CF); 31595b296d0Smrg 31695b296d0Smrg OUTB(0x3CE,HorStretch); 31795b296d0Smrg pReg->tridentRegs3CE[HorStretch] = INB(0x3CF); 31895b296d0Smrg OUTB(0x3CE,VertStretch); 31995b296d0Smrg pReg->tridentRegs3CE[VertStretch] = INB(0x3CF); 32095b296d0Smrg 32195b296d0Smrg#ifdef READOUT 32295b296d0Smrg if ((!((pReg->tridentRegs3CE[VertStretch] & 1) || 32395b296d0Smrg (pReg->tridentRegs3CE[HorStretch] & 1))) 32495b296d0Smrg && (!LCDActive || ShadowModeActive)) 32595b296d0Smrg { 32695b296d0Smrg unsigned char tmp; 32795b296d0Smrg 32895b296d0Smrg SHADOW_ENABLE(tmp); 32995b296d0Smrg OUTB(vgaIOBase + 4,0); 33095b296d0Smrg pReg->tridentRegs3x4[0x0] = INB(vgaIOBase + 5); 33195b296d0Smrg OUTB(vgaIOBase + 4,3); 33295b296d0Smrg pReg->tridentRegs3x4[0x3] = INB(vgaIOBase + 5); 33395b296d0Smrg OUTB(vgaIOBase + 4,4); 33495b296d0Smrg pReg->tridentRegs3x4[0x4] = INB(vgaIOBase + 5); 33595b296d0Smrg OUTB(vgaIOBase + 4,5); 33695b296d0Smrg pReg->tridentRegs3x4[0x5] = INB(vgaIOBase + 5); 33795b296d0Smrg OUTB(vgaIOBase + 4,0x6); 33895b296d0Smrg pReg->tridentRegs3x4[0x6] = INB(vgaIOBase + 5); 33995b296d0Smrg SHADOW_RESTORE(tmp); 34095b296d0Smrg } else 34195b296d0Smrg#endif 34295b296d0Smrg { 34395b296d0Smrg if (i != 0xff) { 34495b296d0Smrg pReg->tridentRegs3x4[0x0] = LCD[i].shadow_0; 34595b296d0Smrg pReg->tridentRegs3x4[0x1] = regp->CRTC[1]; 34695b296d0Smrg pReg->tridentRegs3x4[0x2] = regp->CRTC[2]; 34795b296d0Smrg pReg->tridentRegs3x4[0x3] = LCD[i].shadow_3; 34895b296d0Smrg pReg->tridentRegs3x4[0x4] = LCD[i].shadow_4; 34995b296d0Smrg pReg->tridentRegs3x4[0x5] = LCD[i].shadow_5; 35095b296d0Smrg pReg->tridentRegs3x4[0x6] = LCD[i].shadow_6; 35195b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1, 35295b296d0Smrg "Overriding Horizontal timings.\n"); 35395b296d0Smrg } 35495b296d0Smrg } 35595b296d0Smrg 35695b296d0Smrg if (i != 0xff) { 35795b296d0Smrg pReg->tridentRegs3x4[0x7] = LCD[i].shadow_7; 35895b296d0Smrg pReg->tridentRegs3x4[0x10] = LCD[i].shadow_10; 35995b296d0Smrg pReg->tridentRegs3x4[0x11] = LCD[i].shadow_11; 36095b296d0Smrg pReg->tridentRegs3x4[0x12] = regp->CRTC[0x12]; 36195b296d0Smrg pReg->tridentRegs3x4[0x15] = regp->CRTC[0x15]; 36295b296d0Smrg pReg->tridentRegs3x4[0x16] = LCD[i].shadow_16; 36395b296d0Smrg if (LCDActive) { 36495b296d0Smrg /* use current screen size not panel size for display area */ 36595b296d0Smrg pReg->tridentRegs3x4[CRTHiOrd] = 36695b296d0Smrg (pReg->tridentRegs3x4[CRTHiOrd] & 0x10) 36795b296d0Smrg | (LCD[i].shadow_HiOrd & ~0x10); 36895b296d0Smrg } 36995b296d0Smrg 37095b296d0Smrg fullSize = (mode->HDisplay == LCD[i].display_x) 37195b296d0Smrg && (mode->VDisplay == LCD[i].display_y); 37295b296d0Smrg } 37395b296d0Smrg 37495b296d0Smrg /* copy over common bits from normal VGA */ 37595b296d0Smrg 37695b296d0Smrg pReg->tridentRegs3x4[0x7] &= ~0x4A; 37795b296d0Smrg pReg->tridentRegs3x4[0x7] |= (vgaReg->CRTC[0x7] & 0x4A); 37895b296d0Smrg if (LCDActive && fullSize) { 37995b296d0Smrg regp->CRTC[0] = pReg->tridentRegs3x4[0]; 38095b296d0Smrg regp->CRTC[3] = pReg->tridentRegs3x4[3]; 38195b296d0Smrg regp->CRTC[4] = pReg->tridentRegs3x4[4]; 38295b296d0Smrg regp->CRTC[5] = pReg->tridentRegs3x4[5]; 38395b296d0Smrg regp->CRTC[6] = pReg->tridentRegs3x4[6]; 38495b296d0Smrg regp->CRTC[7] = pReg->tridentRegs3x4[7]; 38595b296d0Smrg regp->CRTC[0x10] = pReg->tridentRegs3x4[0x10]; 38695b296d0Smrg regp->CRTC[0x11] = pReg->tridentRegs3x4[0x11]; 38795b296d0Smrg regp->CRTC[0x16] = pReg->tridentRegs3x4[0x16]; 38895b296d0Smrg } 38995b296d0Smrg if (LCDActive && !fullSize) { 39095b296d0Smrg /* 39195b296d0Smrg * Set negative h/vsync polarity to center display nicely 39295b296d0Smrg * Seems to work on several systems. 39395b296d0Smrg */ 39495b296d0Smrg regp->MiscOutReg |= 0xC0; 39595b296d0Smrg /* 39695b296d0Smrg * If the LCD is active and we don't fill the entire screen 39795b296d0Smrg * and the previous mode was stretched we may need help from 39895b296d0Smrg * the BIOS to set all registers for the unstreched mode. 39995b296d0Smrg */ 40095b296d0Smrg pTrident->doInit = ((pReg->tridentRegs3CE[HorStretch] & 1) 40195b296d0Smrg || (pReg->tridentRegs3CE[VertStretch] & 1)); 40295b296d0Smrg pReg->tridentRegs3CE[CyberControl] |= 0x81; 40395b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow on\n"); 40495b296d0Smrg } else { 40595b296d0Smrg pReg->tridentRegs3CE[CyberControl] &= 0x7E; 40695b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow off\n"); 40795b296d0Smrg } 40895b296d0Smrg if (pTrident->FPDelay < 6) { 40995b296d0Smrg pReg->tridentRegs3CE[CyberControl] &= 0xC7; 41095b296d0Smrg pReg->tridentRegs3CE[CyberControl] |= (pTrident->FPDelay + 2) << 3; 41195b296d0Smrg } 41295b296d0Smrg 41395b296d0Smrg if (pTrident->CyberShadow) { 41495b296d0Smrg pReg->tridentRegs3CE[CyberControl] &= 0x7E; 41595b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Forcing Shadow off\n"); 41695b296d0Smrg } 41795b296d0Smrg 41895b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing shadow registers:" 41995b296d0Smrg " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 42095b296d0Smrg pReg->tridentRegs3x4[0], pReg->tridentRegs3x4[3], 42195b296d0Smrg pReg->tridentRegs3x4[4], pReg->tridentRegs3x4[5]); 42295b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing registers: " 42395b296d0Smrg " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", 42495b296d0Smrg regp->CRTC[0], regp->CRTC[1], regp->CRTC[2], 42595b296d0Smrg regp->CRTC[3], regp->CRTC[4], regp->CRTC[5]); 42695b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing shadow registers: " 42795b296d0Smrg "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" 42895b296d0Smrg " 0x%2.2x (0x%2.2x)\n", 42995b296d0Smrg pReg->tridentRegs3x4[6], pReg->tridentRegs3x4[7], 43095b296d0Smrg pReg->tridentRegs3x4[0x10],pReg->tridentRegs3x4[0x11], 43195b296d0Smrg pReg->tridentRegs3x4[0x16], 43295b296d0Smrg pReg->tridentRegs3x4[CRTHiOrd]); 43395b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing registers: " 43495b296d0Smrg "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " 43595b296d0Smrg "0x%2.2x 0x%2.2x 0x%2.2x\n", 43695b296d0Smrg regp->CRTC[6], regp->CRTC[7], regp->CRTC[0x10], 43795b296d0Smrg regp->CRTC[0x11],regp->CRTC[0x12], 43895b296d0Smrg regp->CRTC[0x14],regp->CRTC[0x16]); 43995b296d0Smrg 44095b296d0Smrg 44195b296d0Smrg /* disable stretching, enable centering for default sizes */ 44295b296d0Smrg pReg->tridentRegs3CE[VertStretch] &= 0x7C; 44395b296d0Smrg switch (mode->VDisplay) { 44495b296d0Smrg case 768: 44595b296d0Smrg case 600: 44695b296d0Smrg case 480: 44795b296d0Smrg case 240: 44895b296d0Smrg pReg->tridentRegs3CE[VertStretch] |= 0x80; 44995b296d0Smrg } 45095b296d0Smrg pReg->tridentRegs3CE[HorStretch] &= 0x7C; 45195b296d0Smrg switch (mode->HDisplay) { 45295b296d0Smrg case 1024: 45395b296d0Smrg case 800: 45495b296d0Smrg case 640: 45595b296d0Smrg case 320: 45695b296d0Smrg pReg->tridentRegs3CE[HorStretch] |= 0x80; 45795b296d0Smrg } 45895b296d0Smrg#if 1 45995b296d0Smrg { 46095b296d0Smrg int mul = pScrn->bitsPerPixel >> 3; 46195b296d0Smrg int val; 46295b296d0Smrg 46395b296d0Smrg if (!mul) mul = 1; 46495b296d0Smrg 46595b296d0Smrg /* this is what my BIOS does */ 46695b296d0Smrg val = (mode->HDisplay * mul / 8) + 16; 46795b296d0Smrg 46895b296d0Smrg pReg->tridentRegs3x4[PreEndControl] = ((val >> 8) < 2 ? 2 :0) 46995b296d0Smrg | ((val >> 8) & 0x01); 47095b296d0Smrg pReg->tridentRegs3x4[PreEndFetch] = val & 0xff; 47195b296d0Smrg } 47295b296d0Smrg#else 47395b296d0Smrg OUTB(vgaIOBase + 4,PreEndControl); 47495b296d0Smrg pReg->tridentRegs3x4[PreEndControl] = INB(vgaIOBase + 5); 47595b296d0Smrg OUTB(vgaIOBase + 4,PreEndFetch); 47695b296d0Smrg pReg->tridentRegs3x4[PreEndFetch] = INB(vgaIOBase + 5); 47795b296d0Smrg#endif 47895b296d0Smrg /* set mode */ 47995b296d0Smrg if (pTrident->Chipset < BLADEXP) { 48095b296d0Smrg pReg->tridentRegs3CE[BiosMode] = TridentFindMode( 48195b296d0Smrg mode->HDisplay, 48295b296d0Smrg mode->VDisplay, 48395b296d0Smrg pScrn->depth); 48495b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, 48595b296d0Smrg "Setting BIOS Mode: %x for: %ix%i\n", 48695b296d0Smrg pReg->tridentRegs3CE[BiosMode], 48795b296d0Smrg mode->HDisplay, 48895b296d0Smrg mode->VDisplay); 48995b296d0Smrg } else { 49095b296d0Smrg TridentFindNewMode(mode->HDisplay, 49195b296d0Smrg mode->VDisplay, 49295b296d0Smrg &pReg->tridentRegs3CE[BiosNewMode1], 49395b296d0Smrg &pReg->tridentRegs3CE[BiosNewMode2]); 49495b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, 49595b296d0Smrg "Setting BIOS Mode Regs: %x %x for: %ix%i\n", 49695b296d0Smrg pReg->tridentRegs3CE[BiosNewMode1], 49795b296d0Smrg pReg->tridentRegs3CE[BiosNewMode2], 49895b296d0Smrg mode->HDisplay, 49995b296d0Smrg mode->VDisplay); 50095b296d0Smrg }; 50195b296d0Smrg 50295b296d0Smrg /* no stretch */ 50395b296d0Smrg if (pTrident->Chipset == CYBERBLADEXPAI1 50495b296d0Smrg || pTrident->Chipset == BLADEXP) 50595b296d0Smrg pReg->tridentRegs3CE[BiosReg] = 8; 50695b296d0Smrg else 50795b296d0Smrg pReg->tridentRegs3CE[BiosReg] = 0; 50895b296d0Smrg 50995b296d0Smrg if (pTrident->CyberStretch) { 51095b296d0Smrg pReg->tridentRegs3CE[VertStretch] |= 0x01; 51195b296d0Smrg pReg->tridentRegs3CE[HorStretch] |= 0x01; 51295b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Enabling StretchMode\n"); 51395b296d0Smrg } 51495b296d0Smrg } 51595b296d0Smrg 51695b296d0Smrg /* Enable Chipset specific options */ 51795b296d0Smrg switch (pTrident->Chipset) { 51895b296d0Smrg case XP5: 51995b296d0Smrg case CYBERBLADEXP4: 52095b296d0Smrg case CYBERBLADEXPAI1: 52195b296d0Smrg case BLADEXP: 52295b296d0Smrg case CYBERBLADEI7: 52395b296d0Smrg case CYBERBLADEI7D: 52495b296d0Smrg case CYBERBLADEI1: 52595b296d0Smrg case CYBERBLADEI1D: 52695b296d0Smrg case CYBERBLADEAI1: 52795b296d0Smrg case CYBERBLADEAI1D: 52895b296d0Smrg case CYBERBLADEE4: 52995b296d0Smrg case BLADE3D: 53095b296d0Smrg OUTB(vgaIOBase + 4, RAMDACTiming); 53195b296d0Smrg pReg->tridentRegs3x4[RAMDACTiming] = INB(vgaIOBase + 5) | 0x0F; 53295b296d0Smrg /* Fall Through */ 53395b296d0Smrg case CYBER9520: 53495b296d0Smrg case CYBER9525DVD: 53595b296d0Smrg case CYBER9397DVD: 53695b296d0Smrg case CYBER9397: 53795b296d0Smrg case IMAGE975: 53895b296d0Smrg case IMAGE985: 53995b296d0Smrg case CYBER9388: 54095b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x10; 54195b296d0Smrg if (!pReg->tridentRegs3x4[PreEndControl]) 54295b296d0Smrg pReg->tridentRegs3x4[PreEndControl] = 0x01; 54395b296d0Smrg if (!pReg->tridentRegs3x4[PreEndFetch]) 54495b296d0Smrg pReg->tridentRegs3x4[PreEndFetch] = 0xFF; 54595b296d0Smrg /* Fall Through */ 54695b296d0Smrg case PROVIDIA9685: 54795b296d0Smrg case CYBER9385: 54895b296d0Smrg pReg->tridentRegs3x4[Enhancement0] = 0x40; 54995b296d0Smrg /* Fall Through */ 55095b296d0Smrg case PROVIDIA9682: 55195b296d0Smrg case CYBER9382: 55295b296d0Smrg if (pTrident->UsePCIRetry) 55395b296d0Smrg pReg->tridentRegs3x4[PCIRetry] = 0xDF; 55495b296d0Smrg else 55595b296d0Smrg pReg->tridentRegs3x4[PCIRetry] = 0x1F; 55695b296d0Smrg /* Fall Through */ 55795b296d0Smrg case TGUI9660: 55895b296d0Smrg case TGUI9680: 55995b296d0Smrg if (pTrident->MUX && pScrn->bitsPerPixel == 8) { 56095b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */ 56195b296d0Smrg pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */ 56295b296d0Smrg pReg->tridentRegsDAC[0x00] |= 0x20; /* mux mode */ 56395b296d0Smrg } 56495b296d0Smrg } 56595b296d0Smrg 56695b296d0Smrg /* Defaults for all trident chipsets follows */ 56795b296d0Smrg switch (pScrn->bitsPerPixel) { 56895b296d0Smrg case 8: 56995b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 57095b296d0Smrg offset = pScrn->displayWidth >> 3; 57195b296d0Smrg break; 57295b296d0Smrg case 16: 57395b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 57495b296d0Smrg offset = pScrn->displayWidth >> 2; 57595b296d0Smrg if (pScrn->depth == 15) 57695b296d0Smrg pReg->tridentRegsDAC[0x00] = 0x10; 57795b296d0Smrg else 57895b296d0Smrg pReg->tridentRegsDAC[0x00] = 0x30; 57995b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] = 0x04; 58095b296d0Smrg /* Reload with any chipset specific stuff here */ 58195b296d0Smrg if (pTrident->Chipset >= TGUI9660) 58295b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] |= 0x01; 58395b296d0Smrg if (pTrident->Chipset == TGUI9440AGi) { 58495b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;/*Clock Division / 2*/ 58595b296d0Smrg clock *= 2; /* Double the clock */ 58695b296d0Smrg } 58795b296d0Smrg break; 58895b296d0Smrg case 24: 58995b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 59095b296d0Smrg offset = (pScrn->displayWidth * 3) >> 3; 59195b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] = 0x29; 59295b296d0Smrg pReg->tridentRegsDAC[0x00] = 0xD0; 59395b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 || 59495b296d0Smrg pTrident->Chipset == XP5 || 59595b296d0Smrg pTrident->Chipset == CYBERBLADEE4) { 59695b296d0Smrg OUTB(vgaIOBase+ 4, New32); 59795b296d0Smrg pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) & 0x7F; 59895b296d0Smrg } 59995b296d0Smrg break; 60095b296d0Smrg case 32: 60195b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x02; 60295b296d0Smrg if (pTrident->Chipset != CYBERBLADEXP4 60395b296d0Smrg && pTrident->Chipset != BLADEXP 60495b296d0Smrg && pTrident->Chipset != XP5 60595b296d0Smrg && pTrident->Chipset != CYBERBLADEE4 60695b296d0Smrg && pTrident->Chipset != CYBERBLADEXPAI1) { 60795b296d0Smrg /* Clock Division by 2*/ 60895b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; 60995b296d0Smrg clock *= 2; /* Double the clock */ 61095b296d0Smrg } 61195b296d0Smrg offset = pScrn->displayWidth >> 1; 61295b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] = 0x09; 61395b296d0Smrg pReg->tridentRegsDAC[0x00] = 0xD0; 61495b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 61595b296d0Smrg || pTrident->Chipset == BLADEXP 61695b296d0Smrg || pTrident->Chipset == XP5 61795b296d0Smrg || pTrident->Chipset == CYBERBLADEE4 61895b296d0Smrg || pTrident->Chipset == CYBERBLADEXPAI1) { 61995b296d0Smrg OUTB(vgaIOBase+ 4, New32); 62095b296d0Smrg pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) | 0x80; 62195b296d0Smrg /* With new mode 32bpp we set the packed flag */ 62295b296d0Smrg pReg->tridentRegs3x4[PixelBusReg] |= 0x20; 62395b296d0Smrg } 62495b296d0Smrg break; 62595b296d0Smrg } 62695b296d0Smrg pReg->tridentRegs3x4[Offset] = offset & 0xFF; 62795b296d0Smrg 62895b296d0Smrg { 62995b296d0Smrg CARD8 a, b; 63095b296d0Smrg TGUISetClock(pScrn, clock, &a, &b); 63195b296d0Smrg pReg->tridentRegsClock[0x00] = (regp->MiscOutReg & 0xF3) | 0x08; 63295b296d0Smrg pReg->tridentRegsClock[0x01] = a; 63395b296d0Smrg pReg->tridentRegsClock[0x02] = b; 63495b296d0Smrg if (pTrident->MCLK > 0) { 63595b296d0Smrg TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b); 63695b296d0Smrg pReg->tridentRegsClock[0x03] = a; 63795b296d0Smrg pReg->tridentRegsClock[0x04] = b; 63895b296d0Smrg } 63995b296d0Smrg } 64095b296d0Smrg 64195b296d0Smrg pReg->tridentRegs3C4[NewMode1] = 0xC0; 64295b296d0Smrg pReg->tridentRegs3C4[Protection] = 0x92; 64395b296d0Smrg 64495b296d0Smrg pReg->tridentRegs3x4[LinearAddReg] = 0; 64595b296d0Smrg if (pTrident->Linear) { 64695b296d0Smrg /* This is used for VLB, when we support it again in 4.0 */ 64795b296d0Smrg if (pTrident->Chipset < CYBER9385) 64895b296d0Smrg pReg->tridentRegs3x4[LinearAddReg] |= 64995b296d0Smrg ((pTrident->FbAddress >> 24) << 6)| 65095b296d0Smrg ((pTrident->FbAddress >> 20) & 0x0F); 65195b296d0Smrg /* Turn on linear mapping */ 65295b296d0Smrg pReg->tridentRegs3x4[LinearAddReg] |= 0x20; 65395b296d0Smrg } else { 65495b296d0Smrg pReg->tridentRegs3CE[MiscExtFunc] |= 0x04; 65595b296d0Smrg } 65695b296d0Smrg 65795b296d0Smrg pReg->tridentRegs3x4[CRTCModuleTest] = 65895b296d0Smrg (mode->Flags & V_INTERLACE ? 0x84 : 0x80); 65995b296d0Smrg 66095b296d0Smrg OUTB(vgaIOBase+ 4, InterfaceSel); 66195b296d0Smrg pReg->tridentRegs3x4[InterfaceSel] = INB(vgaIOBase + 5) | 0x40; 66295b296d0Smrg 66395b296d0Smrg OUTB(vgaIOBase+ 4, Performance); 66495b296d0Smrg pReg->tridentRegs3x4[Performance] = INB(vgaIOBase + 5); 66595b296d0Smrg if (pTrident->Chipset < BLADEXP) 66695b296d0Smrg pReg->tridentRegs3x4[Performance] |= 0x10; 66795b296d0Smrg 66895b296d0Smrg OUTB(vgaIOBase+ 4, DRAMControl); 66995b296d0Smrg if (pTrident->Chipset >= CYBER9388) 67095b296d0Smrg pReg->tridentRegs3x4[DRAMControl] = INB(vgaIOBase + 5) | 0x10; 67195b296d0Smrg 67295b296d0Smrg if (pTrident->IsCyber && !pTrident->MMIOonly) 67395b296d0Smrg pReg->tridentRegs3x4[DRAMControl] |= 0x20; 67495b296d0Smrg 67595b296d0Smrg if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) { 67695b296d0Smrg OUTB(vgaIOBase + 4, ClockControl); 67795b296d0Smrg pReg->tridentRegs3x4[ClockControl] = INB(vgaIOBase + 5) | 0x01; 67895b296d0Smrg } 67995b296d0Smrg 68095b296d0Smrg OUTB(vgaIOBase+ 4, AddColReg); 68195b296d0Smrg pReg->tridentRegs3x4[AddColReg] = INB(vgaIOBase + 5) & 0xEF; 68295b296d0Smrg pReg->tridentRegs3x4[AddColReg] |= (offset & 0x100) >> 4; 68395b296d0Smrg 68495b296d0Smrg if (pTrident->Chipset >= TGUI9660) { 68595b296d0Smrg pReg->tridentRegs3x4[AddColReg] &= 0xDF; 68695b296d0Smrg pReg->tridentRegs3x4[AddColReg] |= (offset & 0x200) >> 4; 68795b296d0Smrg } 68895b296d0Smrg 68995b296d0Smrg if (IsPciCard && UseMMIO) { 69095b296d0Smrg if (!pTrident->NoAccel) 69195b296d0Smrg pReg->tridentRegs3x4[GraphEngReg] |= 0x80; 69295b296d0Smrg } else { 69395b296d0Smrg if (!pTrident->NoAccel) 69495b296d0Smrg pReg->tridentRegs3x4[GraphEngReg] |= 0x82; 69595b296d0Smrg } 69695b296d0Smrg 69795b296d0Smrg OUTB(0x3CE, MiscIntContReg); 69895b296d0Smrg pReg->tridentRegs3CE[MiscIntContReg] = INB(0x3CF) | 0x04; 69995b296d0Smrg 70095b296d0Smrg /* Fix hashing problem in > 8bpp on 9320 chipset */ 70195b296d0Smrg if (pTrident->Chipset == CYBER9320 && pScrn->bitsPerPixel > 8) 70295b296d0Smrg pReg->tridentRegs3CE[MiscIntContReg] &= ~0x80; 70395b296d0Smrg 70495b296d0Smrg OUTB(vgaIOBase+ 4, PCIReg); 70595b296d0Smrg if (IsPciCard && UseMMIO) 70695b296d0Smrg pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF9; 70795b296d0Smrg else 70895b296d0Smrg pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF8; 70995b296d0Smrg 71095b296d0Smrg /* Enable PCI Bursting on capable chips */ 71195b296d0Smrg if (pTrident->Chipset >= TGUI9660) { 71295b296d0Smrg if(pTrident->UsePCIBurst) { 71395b296d0Smrg pReg->tridentRegs3x4[PCIReg] |= 0x06; 71495b296d0Smrg } else { 71595b296d0Smrg pReg->tridentRegs3x4[PCIReg] &= 0xF9; 71695b296d0Smrg } 71795b296d0Smrg } 71895b296d0Smrg 71995b296d0Smrg if (pTrident->Chipset >= CYBER9388) { 72095b296d0Smrg if (pTrident->GammaBrightnessOn) 72195b296d0Smrg xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1, 72295b296d0Smrg "Setting Gamma: %f Brightness: %i\n", 72395b296d0Smrg pTrident->gamma, pTrident->brightness); 72495b296d0Smrg tridentSetBrightnessAndGamma(pReg, 72595b296d0Smrg pTrident->GammaBrightnessOn, 72695b296d0Smrg pTrident->gamma, pTrident->brightness); 72795b296d0Smrg } 72895b296d0Smrg 72995b296d0Smrg /* Video */ 73095b296d0Smrg OUTB(0x3C4,0x20); 73195b296d0Smrg pReg->tridentRegs3C4[SSetup] = INB(0x3C5) | 0x4; 73295b296d0Smrg pReg->tridentRegs3C4[SKey] = 0x00; 73395b296d0Smrg pReg->tridentRegs3C4[SPKey] = 0xC0; 73495b296d0Smrg OUTB(0x3C4,0x12); 73595b296d0Smrg pReg->tridentRegs3C4[Threshold] = INB(0x3C5); 73695b296d0Smrg if (pScrn->bitsPerPixel > 16) 73795b296d0Smrg pReg->tridentRegs3C4[Threshold] = 73895b296d0Smrg (pReg->tridentRegs3C4[Threshold] & 0xf0) | 0x2; 73995b296d0Smrg 74095b296d0Smrg /* restore */ 74195b296d0Smrg if (pTrident->Chipset > PROVIDIA9685) { 74295b296d0Smrg OUTB(0x3C4, Protection); 74395b296d0Smrg OUTB(0x3C5, protect); 74495b296d0Smrg } 74595b296d0Smrg 74695b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 || 74795b296d0Smrg pTrident->Chipset == XP5) 74895b296d0Smrg pReg->tridentRegs3CE[DisplayEngCont] = 0x08; 74995b296d0Smrg 75095b296d0Smrg /* Avoid lockup on Blade3D, PCI Retry is permanently on */ 75195b296d0Smrg if (pTrident->Chipset == BLADE3D) 75295b296d0Smrg pReg->tridentRegs3x4[PCIRetry] = 0x9F; 75395b296d0Smrg 75495b296d0Smrg return(TRUE); 75595b296d0Smrg} 75695b296d0Smrg 75795b296d0Smrgvoid 75895b296d0SmrgTridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) 75995b296d0Smrg{ 76095b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 76195b296d0Smrg int vgaIOBase; 76295b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 76395b296d0Smrg 76495b296d0Smrg if (pTrident->Chipset > PROVIDIA9685) { 76595b296d0Smrg OUTB(0x3C4, Protection); 76695b296d0Smrg OUTB(0x3C5, 0x92); 76795b296d0Smrg } 76895b296d0Smrg#if 0 76995b296d0Smrg if (pTrident->doInit && pTrident->Int10) { 77095b296d0Smrg OUTW_3CE(BiosReg); 77195b296d0Smrg } 77295b296d0Smrg#endif 77395b296d0Smrg /* Goto New Mode */ 77495b296d0Smrg OUTB(0x3C4, 0x0B); 77595b296d0Smrg (void) INB(0x3C5); 77695b296d0Smrg 77795b296d0Smrg /* Unprotect registers */ 77895b296d0Smrg OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1); 77995b296d0Smrg 78095b296d0Smrg (void) INB(0x3C8); 78195b296d0Smrg (void) INB(0x3C6); 78295b296d0Smrg (void) INB(0x3C6); 78395b296d0Smrg (void) INB(0x3C6); 78495b296d0Smrg (void) INB(0x3C6); 78595b296d0Smrg OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]); 78695b296d0Smrg (void) INB(0x3C8); 78795b296d0Smrg 78895b296d0Smrg OUTW_3x4(CRTCModuleTest); 78995b296d0Smrg OUTW_3x4(LinearAddReg); 79095b296d0Smrg OUTW_3C4(NewMode2); 79195b296d0Smrg OUTW_3x4(CursorControl); 79295b296d0Smrg OUTW_3x4(CRTHiOrd); 79395b296d0Smrg OUTW_3x4(HorizOverflow); 79495b296d0Smrg OUTW_3x4(AddColReg); 79595b296d0Smrg OUTW_3x4(GraphEngReg); 79695b296d0Smrg OUTW_3x4(Performance); 79795b296d0Smrg OUTW_3x4(InterfaceSel); 79895b296d0Smrg OUTW_3x4(DRAMControl); 79995b296d0Smrg OUTW_3x4(PixelBusReg); 80095b296d0Smrg OUTW_3x4(PCIReg); 80195b296d0Smrg OUTW_3x4(PCIRetry); 80295b296d0Smrg OUTW_3CE(MiscIntContReg); 80395b296d0Smrg OUTW_3CE(MiscExtFunc); 80495b296d0Smrg OUTW_3x4(Offset); 80595b296d0Smrg if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) 80695b296d0Smrg OUTW_3x4(ClockControl); 80795b296d0Smrg if (pTrident->Chipset >= CYBER9388) { 80895b296d0Smrg OUTW_3C4(Threshold); 80995b296d0Smrg OUTW_3C4(SSetup); 81095b296d0Smrg OUTW_3C4(SKey); 81195b296d0Smrg OUTW_3C4(SPKey); 81295b296d0Smrg OUTW_3x4(PreEndControl); 81395b296d0Smrg OUTW_3x4(PreEndFetch); 81495b296d0Smrg OUTW_3C4(GBslope1); 81595b296d0Smrg OUTW_3C4(GBslope2); 81695b296d0Smrg OUTW_3C4(GBslope3); 81795b296d0Smrg OUTW_3C4(GBslope4); 81895b296d0Smrg OUTW_3C4(GBintercept1); 81995b296d0Smrg OUTW_3C4(GBintercept2); 82095b296d0Smrg OUTW_3C4(GBintercept3); 82195b296d0Smrg OUTW_3C4(GBintercept4); 82295b296d0Smrg } 82395b296d0Smrg if (pTrident->Chipset >= CYBER9385) OUTW_3x4(Enhancement0); 82495b296d0Smrg if (pTrident->Chipset >= BLADE3D) OUTW_3x4(RAMDACTiming); 82595b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 || 82695b296d0Smrg pTrident->Chipset == XP5 || 82795b296d0Smrg pTrident->Chipset == CYBERBLADEE4) OUTW_3x4(New32); 82895b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 || 82995b296d0Smrg pTrident->Chipset == XP5) OUTW_3CE(DisplayEngCont); 83095b296d0Smrg if (pTrident->IsCyber) { 83195b296d0Smrg CARD8 tmp; 83295b296d0Smrg 83395b296d0Smrg OUTW_3CE(VertStretch); 83495b296d0Smrg OUTW_3CE(HorStretch); 83595b296d0Smrg if (pTrident->Chipset < BLADEXP) { 83695b296d0Smrg OUTW_3CE(BiosMode); 83795b296d0Smrg } else { 83895b296d0Smrg OUTW_3CE(BiosNewMode1); 83995b296d0Smrg OUTW_3CE(BiosNewMode2); 84095b296d0Smrg }; 84195b296d0Smrg OUTW_3CE(BiosReg); 84295b296d0Smrg OUTW_3CE(FPConfig); 84395b296d0Smrg OUTW_3CE(CyberControl); 84495b296d0Smrg OUTW_3CE(CyberEnhance); 84595b296d0Smrg SHADOW_ENABLE(tmp); 84695b296d0Smrg OUTW_3x4(0x0); 84795b296d0Smrg if (pTrident->shadowNew) { 84895b296d0Smrg OUTW_3x4(0x1); 84995b296d0Smrg OUTW_3x4(0x2); 85095b296d0Smrg } 85195b296d0Smrg OUTW_3x4(0x3); 85295b296d0Smrg OUTW_3x4(0x4); 85395b296d0Smrg OUTW_3x4(0x5); 85495b296d0Smrg OUTW_3x4(0x6); 85595b296d0Smrg OUTW_3x4(0x7); 85695b296d0Smrg OUTW_3x4(0x10); 85795b296d0Smrg OUTW_3x4(0x11); 85895b296d0Smrg if (pTrident->shadowNew) { 85995b296d0Smrg OUTW_3x4(0x12); 86095b296d0Smrg OUTW_3x4(0x15); 86195b296d0Smrg } 86295b296d0Smrg OUTW_3x4(0x16); 86395b296d0Smrg SHADOW_RESTORE(tmp); 86495b296d0Smrg } 86595b296d0Smrg 86695b296d0Smrg if (Is3Dchip) { 86795b296d0Smrg#ifdef READOUT 86895b296d0Smrg if (!pTrident->DontSetClock) 86995b296d0Smrg#endif 87095b296d0Smrg { 87195b296d0Smrg OUTW(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow); 87295b296d0Smrg OUTW(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh); 87395b296d0Smrg } 87495b296d0Smrg if (pTrident->MCLK > 0) { 87595b296d0Smrg OUTW(0x3C4,(tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow); 87695b296d0Smrg OUTW(0x3C4,(tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh); 87795b296d0Smrg } 87895b296d0Smrg } else { 87995b296d0Smrg#ifdef READOUT 88095b296d0Smrg if (!pTrident->DontSetClock) 88195b296d0Smrg#endif 88295b296d0Smrg { 88395b296d0Smrg OUTB(0x43C8, tridentReg->tridentRegsClock[0x01]); 88495b296d0Smrg OUTB(0x43C9, tridentReg->tridentRegsClock[0x02]); 88595b296d0Smrg } 88695b296d0Smrg if (pTrident->MCLK > 0) { 88795b296d0Smrg OUTB(0x43C6, tridentReg->tridentRegsClock[0x03]); 88895b296d0Smrg OUTB(0x43C7, tridentReg->tridentRegsClock[0x04]); 88995b296d0Smrg } 89095b296d0Smrg } 89195b296d0Smrg#ifdef READOUT 89295b296d0Smrg if (!pTrident->DontSetClock) 89395b296d0Smrg#endif 89495b296d0Smrg { 89595b296d0Smrg OUTB(0x3C2, tridentReg->tridentRegsClock[0x00]); 89695b296d0Smrg } 89795b296d0Smrg 89895b296d0Smrg if (pTrident->Chipset > PROVIDIA9685) { 89995b296d0Smrg OUTB(0x3C4, Protection); 90095b296d0Smrg OUTB(0x3C5, tridentReg->tridentRegs3C4[Protection]); 90195b296d0Smrg } 90295b296d0Smrg 90395b296d0Smrg OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8)| NewMode1); 90495b296d0Smrg} 90595b296d0Smrg 90695b296d0Smrgvoid 90795b296d0SmrgTridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) 90895b296d0Smrg{ 90995b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 91095b296d0Smrg int vgaIOBase; 91195b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 91295b296d0Smrg 91395b296d0Smrg /* Goto New Mode */ 91495b296d0Smrg OUTB(0x3C4, 0x0B); 91595b296d0Smrg (void) INB(0x3C5); 91695b296d0Smrg 91795b296d0Smrg INB_3C4(NewMode1); 91895b296d0Smrg if (pTrident->Chipset > PROVIDIA9685) 91995b296d0Smrg INB_3C4(Protection); 92095b296d0Smrg 92195b296d0Smrg /* Unprotect registers */ 92295b296d0Smrg OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1); 92395b296d0Smrg if (pTrident->Chipset > PROVIDIA9685) 92495b296d0Smrg OUTW(0x3C4, (0x92 << 8) | Protection); 92595b296d0Smrg 92695b296d0Smrg INB_3x4(Offset); 92795b296d0Smrg INB_3x4(LinearAddReg); 92895b296d0Smrg INB_3x4(CRTCModuleTest); 92995b296d0Smrg INB_3x4(CRTHiOrd); 93095b296d0Smrg INB_3x4(HorizOverflow); 93195b296d0Smrg INB_3x4(Performance); 93295b296d0Smrg INB_3x4(InterfaceSel); 93395b296d0Smrg INB_3x4(DRAMControl); 93495b296d0Smrg INB_3x4(AddColReg); 93595b296d0Smrg INB_3x4(PixelBusReg); 93695b296d0Smrg INB_3x4(GraphEngReg); 93795b296d0Smrg INB_3x4(PCIReg); 93895b296d0Smrg INB_3x4(PCIRetry); 93995b296d0Smrg if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) 94095b296d0Smrg INB_3x4(ClockControl); 94195b296d0Smrg if (pTrident->Chipset >= CYBER9388) { 94295b296d0Smrg INB_3C4(Threshold); 94395b296d0Smrg INB_3C4(SSetup); 94495b296d0Smrg INB_3C4(SKey); 94595b296d0Smrg INB_3C4(SPKey); 94695b296d0Smrg INB_3x4(PreEndControl); 94795b296d0Smrg INB_3x4(PreEndFetch); 94895b296d0Smrg INB_3C4(GBslope1); 94995b296d0Smrg INB_3C4(GBslope2); 95095b296d0Smrg INB_3C4(GBslope3); 95195b296d0Smrg INB_3C4(GBslope4); 95295b296d0Smrg INB_3C4(GBintercept1); 95395b296d0Smrg INB_3C4(GBintercept2); 95495b296d0Smrg INB_3C4(GBintercept3); 95595b296d0Smrg INB_3C4(GBintercept4); 95695b296d0Smrg } 95795b296d0Smrg if (pTrident->Chipset >= CYBER9385) INB_3x4(Enhancement0); 95895b296d0Smrg if (pTrident->Chipset >= BLADE3D) INB_3x4(RAMDACTiming); 95995b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 || 96095b296d0Smrg pTrident->Chipset == XP5 || 96195b296d0Smrg pTrident->Chipset == CYBERBLADEE4) INB_3x4(New32); 96295b296d0Smrg if (pTrident->Chipset == CYBERBLADEXP4 || 96395b296d0Smrg pTrident->Chipset == XP5) INB_3CE(DisplayEngCont); 96495b296d0Smrg if (pTrident->IsCyber) { 96595b296d0Smrg CARD8 tmp; 96695b296d0Smrg INB_3CE(VertStretch); 96795b296d0Smrg INB_3CE(HorStretch); 96895b296d0Smrg if (pTrident->Chipset < BLADEXP) { 96995b296d0Smrg INB_3CE(BiosMode); 97095b296d0Smrg } else { 97195b296d0Smrg INB_3CE(BiosNewMode1); 97295b296d0Smrg INB_3CE(BiosNewMode2); 97395b296d0Smrg } 97495b296d0Smrg INB_3CE(BiosReg); 97595b296d0Smrg INB_3CE(FPConfig); 97695b296d0Smrg INB_3CE(CyberControl); 97795b296d0Smrg INB_3CE(CyberEnhance); 97895b296d0Smrg SHADOW_ENABLE(tmp); 97995b296d0Smrg INB_3x4(0x0); 98095b296d0Smrg if (pTrident->shadowNew) { 98195b296d0Smrg INB_3x4(0x1); 98295b296d0Smrg INB_3x4(0x2); 98395b296d0Smrg } 98495b296d0Smrg INB_3x4(0x3); 98595b296d0Smrg INB_3x4(0x4); 98695b296d0Smrg INB_3x4(0x5); 98795b296d0Smrg INB_3x4(0x6); 98895b296d0Smrg INB_3x4(0x7); 98995b296d0Smrg INB_3x4(0x10); 99095b296d0Smrg INB_3x4(0x11); 99195b296d0Smrg if (pTrident->shadowNew) { 99295b296d0Smrg INB_3x4(0x12); 99395b296d0Smrg INB_3x4(0x15); 99495b296d0Smrg } 99595b296d0Smrg INB_3x4(0x16); 99695b296d0Smrg SHADOW_RESTORE(tmp); 99795b296d0Smrg } 99895b296d0Smrg 99995b296d0Smrg /* save cursor registers */ 100095b296d0Smrg INB_3x4(CursorControl); 100195b296d0Smrg 100295b296d0Smrg INB_3CE(MiscExtFunc); 100395b296d0Smrg INB_3CE(MiscIntContReg); 100495b296d0Smrg 100595b296d0Smrg (void) INB(0x3C8); 100695b296d0Smrg (void) INB(0x3C6); 100795b296d0Smrg (void) INB(0x3C6); 100895b296d0Smrg (void) INB(0x3C6); 100995b296d0Smrg (void) INB(0x3C6); 101095b296d0Smrg tridentReg->tridentRegsDAC[0x00] = INB(0x3C6); 101195b296d0Smrg (void) INB(0x3C8); 101295b296d0Smrg 101395b296d0Smrg tridentReg->tridentRegsClock[0x00] = INB(0x3CC); 101495b296d0Smrg if (Is3Dchip) { 101595b296d0Smrg OUTB(0x3C4, ClockLow); 101695b296d0Smrg tridentReg->tridentRegsClock[0x01] = INB(0x3C5); 101795b296d0Smrg OUTB(0x3C4, ClockHigh); 101895b296d0Smrg tridentReg->tridentRegsClock[0x02] = INB(0x3C5); 101995b296d0Smrg if (pTrident->MCLK > 0) { 102095b296d0Smrg OUTB(0x3C4, MCLKLow); 102195b296d0Smrg tridentReg->tridentRegsClock[0x03] = INB(0x3C5); 102295b296d0Smrg OUTB(0x3C4, MCLKHigh); 102395b296d0Smrg tridentReg->tridentRegsClock[0x04] = INB(0x3C5); 102495b296d0Smrg } 102595b296d0Smrg } else { 102695b296d0Smrg tridentReg->tridentRegsClock[0x01] = INB(0x43C8); 102795b296d0Smrg tridentReg->tridentRegsClock[0x02] = INB(0x43C9); 102895b296d0Smrg if (pTrident->MCLK > 0) { 102995b296d0Smrg tridentReg->tridentRegsClock[0x03] = INB(0x43C6); 103095b296d0Smrg tridentReg->tridentRegsClock[0x04] = INB(0x43C7); 103195b296d0Smrg } 103295b296d0Smrg } 103395b296d0Smrg 103495b296d0Smrg INB_3C4(NewMode2); 103595b296d0Smrg 103695b296d0Smrg /* Protect registers */ 103795b296d0Smrg OUTW_3C4(NewMode1); 103895b296d0Smrg} 103995b296d0Smrg 104095b296d0Smrgstatic void 104195b296d0SmrgTridentShowCursor(ScrnInfoPtr pScrn) 104295b296d0Smrg{ 104395b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 104495b296d0Smrg int vgaIOBase; 104595b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 104695b296d0Smrg 104795b296d0Smrg /* 64x64 */ 104895b296d0Smrg OUTW(vgaIOBase + 4, 0xC150); 104995b296d0Smrg} 105095b296d0Smrg 105195b296d0Smrgstatic void 105295b296d0SmrgTridentHideCursor(ScrnInfoPtr pScrn) { 105395b296d0Smrg int vgaIOBase; 105495b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 105595b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 105695b296d0Smrg 105795b296d0Smrg OUTW(vgaIOBase + 4, 0x4150); 105895b296d0Smrg} 105995b296d0Smrg 106095b296d0Smrgstatic void 106195b296d0SmrgTridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 106295b296d0Smrg{ 106395b296d0Smrg int vgaIOBase; 106495b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 106595b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 106695b296d0Smrg 106795b296d0Smrg if (x < 0) { 106895b296d0Smrg OUTW(vgaIOBase + 4, (-x)<<8 | 0x46); 106995b296d0Smrg x = 0; 107095b296d0Smrg } else 107195b296d0Smrg OUTW(vgaIOBase + 4, 0x0046); 107295b296d0Smrg 107395b296d0Smrg if (y < 0) { 107495b296d0Smrg OUTW(vgaIOBase + 4, (-y)<<8 | 0x47); 107595b296d0Smrg y = 0; 107695b296d0Smrg } else 107795b296d0Smrg OUTW(vgaIOBase + 4, 0x0047); 107895b296d0Smrg 107995b296d0Smrg OUTW(vgaIOBase + 4, (x&0xFF)<<8 | 0x40); 108095b296d0Smrg OUTW(vgaIOBase + 4, (x&0x0F00) | 0x41); 108195b296d0Smrg OUTW(vgaIOBase + 4, (y&0xFF)<<8 | 0x42); 108295b296d0Smrg OUTW(vgaIOBase + 4, (y&0x0F00) | 0x43); 108395b296d0Smrg} 108495b296d0Smrg 108595b296d0Smrgstatic void 108695b296d0SmrgTridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 108795b296d0Smrg{ 108895b296d0Smrg int vgaIOBase; 108995b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 109095b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 109195b296d0Smrg OUTW(vgaIOBase + 4, (fg & 0x000000FF)<<8 | 0x48); 109295b296d0Smrg OUTW(vgaIOBase + 4, (fg & 0x0000FF00) | 0x49); 109395b296d0Smrg OUTW(vgaIOBase + 4, (fg & 0x00FF0000)>>8 | 0x4A); 109495b296d0Smrg OUTW(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B); 109595b296d0Smrg OUTW(vgaIOBase + 4, (bg & 0x000000FF)<<8 | 0x4C); 109695b296d0Smrg OUTW(vgaIOBase + 4, (bg & 0x0000FF00) | 0x4D); 109795b296d0Smrg OUTW(vgaIOBase + 4, (bg & 0x00FF0000)>>8 | 0x4E); 109895b296d0Smrg OUTW(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F); 109995b296d0Smrg} 110095b296d0Smrg 110195b296d0Smrgstatic void 110295b296d0SmrgTridentLoadCursorImage( 110395b296d0Smrg ScrnInfoPtr pScrn, 110495b296d0Smrg CARD8 *src 110595b296d0Smrg) 110695b296d0Smrg{ 110795b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 110895b296d0Smrg int vgaIOBase; 110995b296d0Smrg int programmed_offset = pTrident->CursorOffset / 1024; 111095b296d0Smrg vgaIOBase = VGAHWPTR(pScrn)->IOBase; 111195b296d0Smrg 111295b296d0Smrg memcpy((CARD8 *)pTrident->FbBase + pTrident->CursorOffset, 111395b296d0Smrg src, pTrident->CursorInfoRec->MaxWidth * 111495b296d0Smrg pTrident->CursorInfoRec->MaxHeight / 4); 111595b296d0Smrg 111695b296d0Smrg OUTW(vgaIOBase + 4, ((programmed_offset & 0xFF) << 8) | 0x44); 111795b296d0Smrg OUTW(vgaIOBase + 4, (programmed_offset & 0xFF00) | 0x45); 111895b296d0Smrg} 111995b296d0Smrg 112095b296d0Smrgstatic Bool 112195b296d0SmrgTridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 112295b296d0Smrg{ 112395b296d0Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 112495b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 112595b296d0Smrg 112695b296d0Smrg if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE; 112795b296d0Smrg 112895b296d0Smrg if (!pTrident->HWCursor) return FALSE; 112995b296d0Smrg 113095b296d0Smrg return TRUE; 113195b296d0Smrg} 113295b296d0Smrg 113395b296d0Smrg#define CURSOR_WIDTH 64 113495b296d0Smrg#define CURSOR_HEIGHT 64 113595b296d0Smrg#define CURSOR_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) 113695b296d0Smrg 113795b296d0SmrgBool 113895b296d0SmrgTridentHWCursorInit(ScreenPtr pScreen) 113995b296d0Smrg{ 114095b296d0Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 114195b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 114295b296d0Smrg xf86CursorInfoPtr infoPtr; 114395b296d0Smrg FBAreaPtr fbarea; 114495b296d0Smrg int width; 114595b296d0Smrg int width_bytes; 114695b296d0Smrg int height; 114795b296d0Smrg int size_bytes; 114895b296d0Smrg 114995b296d0Smrg size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT; 115095b296d0Smrg width = pScrn->displayWidth; 115195b296d0Smrg width_bytes = width * (pScrn->bitsPerPixel / 8); 115295b296d0Smrg height = (size_bytes + width_bytes - 1) / width_bytes; 115395b296d0Smrg fbarea = xf86AllocateOffscreenArea(pScreen, 115495b296d0Smrg width, 115595b296d0Smrg height, 115695b296d0Smrg 1024, 115795b296d0Smrg NULL, 115895b296d0Smrg NULL, 115995b296d0Smrg NULL); 116095b296d0Smrg 116195b296d0Smrg if (!fbarea) { 116295b296d0Smrg pTrident->CursorOffset = 0; 116395b296d0Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 116495b296d0Smrg "Hardware cursor disabled" 116595b296d0Smrg " due to insufficient offscreen memory\n"); 116695b296d0Smrg return FALSE; 116795b296d0Smrg } else { 116895b296d0Smrg pTrident->CursorOffset = CURSOR_ALIGN((fbarea->box.x1 + 116995b296d0Smrg fbarea->box.y1 * width) * 117095b296d0Smrg pScrn->bitsPerPixel / 8, 117195b296d0Smrg 1024); 117295b296d0Smrg } 117395b296d0Smrg 117495b296d0Smrg if ((pTrident->Chipset != CYBER9397DVD) && 117595b296d0Smrg (pTrident->Chipset < CYBERBLADEE4)) { 117695b296d0Smrg /* Can't deal with an offset more than 4MB - 4096 bytes */ 117795b296d0Smrg if (pTrident->CursorOffset >= ((4096*1024) - 4096)) { 117895b296d0Smrg pTrident->CursorOffset = 0; 117995b296d0Smrg xf86FreeOffscreenArea(fbarea); 118095b296d0Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 118195b296d0Smrg "Hardware cursor disabled" 118295b296d0Smrg " due to cursor offset constraints.\n"); 118395b296d0Smrg return FALSE; 118495b296d0Smrg } 118595b296d0Smrg } 118695b296d0Smrg 118795b296d0Smrg infoPtr = xf86CreateCursorInfoRec(); 118895b296d0Smrg if(!infoPtr) return FALSE; 118995b296d0Smrg 119095b296d0Smrg pTrident->CursorInfoRec = infoPtr; 119195b296d0Smrg 119295b296d0Smrg infoPtr->MaxWidth = 64; 119395b296d0Smrg infoPtr->MaxHeight = 64; 119495b296d0Smrg infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 119595b296d0Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 119695b296d0Smrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 | 119795b296d0Smrg ((pTrident->Chipset == CYBERBLADEXP4 || 119895b296d0Smrg pTrident->Chipset == BLADEXP || 119995b296d0Smrg pTrident->Chipset == XP5 || 120095b296d0Smrg pTrident->Chipset == CYBERBLADEE4) ? 120195b296d0Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP : 0); 120295b296d0Smrg infoPtr->SetCursorColors = TridentSetCursorColors; 120395b296d0Smrg infoPtr->SetCursorPosition = TridentSetCursorPosition; 120495b296d0Smrg infoPtr->LoadCursorImage = TridentLoadCursorImage; 120595b296d0Smrg infoPtr->HideCursor = TridentHideCursor; 120695b296d0Smrg infoPtr->ShowCursor = TridentShowCursor; 120795b296d0Smrg infoPtr->UseHWCursor = TridentUseHWCursor; 120895b296d0Smrg 120995b296d0Smrg return(xf86InitCursor(pScreen, infoPtr)); 121095b296d0Smrg} 121195b296d0Smrg 121295b296d0Smrgunsigned int 121395b296d0SmrgTridentddc1Read(ScrnInfoPtr pScrn) 121495b296d0Smrg{ 121595b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 121695b296d0Smrg int vgaIOBase = VGAHWPTR(pScrn)->IOBase; 121795b296d0Smrg CARD8 temp; 121895b296d0Smrg 121995b296d0Smrg /* New mode */ 122095b296d0Smrg OUTB(0x3C4, 0x0B); temp = INB(0x3C5); 122195b296d0Smrg 122295b296d0Smrg OUTB(0x3C4, NewMode1); 122395b296d0Smrg temp = INB(0x3C5); 122495b296d0Smrg OUTB(0x3C5, temp | 0x80); 122595b296d0Smrg 122695b296d0Smrg /* Define SDA as input */ 122795b296d0Smrg OUTW(vgaIOBase + 4, (0x04 << 8) | I2C); 122895b296d0Smrg 122995b296d0Smrg OUTW(0x3C4, (temp << 8) | NewMode1); 123095b296d0Smrg 123195b296d0Smrg /* Wait until vertical retrace is in progress. */ 123295b296d0Smrg while (INB(vgaIOBase + 0xA) & 0x08); 123395b296d0Smrg while (!(INB(vgaIOBase + 0xA) & 0x08)); 123495b296d0Smrg 123595b296d0Smrg /* Get the result */ 123695b296d0Smrg OUTB(vgaIOBase + 4, I2C); 123795b296d0Smrg return ( INB(vgaIOBase + 5) & 0x01 ); 123895b296d0Smrg} 123995b296d0Smrg 124095b296d0Smrgvoid TridentSetOverscan( 124195b296d0Smrg ScrnInfoPtr pScrn, 124295b296d0Smrg int overscan 124395b296d0Smrg){ 124495b296d0Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 124595b296d0Smrg 124695b296d0Smrg if (overscan < 0 || overscan > 255) 124795b296d0Smrg return; 124895b296d0Smrg 124995b296d0Smrg hwp->enablePalette(hwp); 125095b296d0Smrg hwp->writeAttr(hwp, OVERSCAN, overscan); 125195b296d0Smrg hwp->disablePalette(hwp); 125295b296d0Smrg} 125395b296d0Smrg 125495b296d0Smrgvoid TridentLoadPalette( 125595b296d0Smrg ScrnInfoPtr pScrn, 125695b296d0Smrg int numColors, 125795b296d0Smrg int *indicies, 125895b296d0Smrg LOCO *colors, 125995b296d0Smrg VisualPtr pVisual 126095b296d0Smrg){ 126195b296d0Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 126295b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 126395b296d0Smrg int i, index; 126495b296d0Smrg for(i = 0; i < numColors; i++) { 126595b296d0Smrg index = indicies[i]; 126695b296d0Smrg OUTB(0x3C6, 0xFF); 126795b296d0Smrg DACDelay(hwp); 126895b296d0Smrg OUTB(0x3c8, index); 126995b296d0Smrg DACDelay(hwp); 127095b296d0Smrg OUTB(0x3c9, colors[index].red); 127195b296d0Smrg DACDelay(hwp); 127295b296d0Smrg OUTB(0x3c9, colors[index].green); 127395b296d0Smrg DACDelay(hwp); 127495b296d0Smrg OUTB(0x3c9, colors[index].blue); 127595b296d0Smrg DACDelay(hwp); 127695b296d0Smrg } 127795b296d0Smrg} 1278