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