1fc5a983dSmrg#ifdef HAVE_CONFIG_H 2fc5a983dSmrg#include "config.h" 3fc5a983dSmrg#endif 4fc5a983dSmrg 5fc5a983dSmrg#include "nv_local.h" 6fc5a983dSmrg#include "nv_include.h" 7fc5a983dSmrg#include "nv_type.h" 8fc5a983dSmrg#include "nv_proto.h" 9bd304fc0Smrg#ifdef HAVE_XAA_H 10fc5a983dSmrg#include "xaalocal.h" 11bd304fc0Smrg#endif 12fc5a983dSmrg#include "dgaproc.h" 13fc5a983dSmrg 14fc5a983dSmrg 15fc5a983dSmrgstatic Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 16fc5a983dSmrg int *, int *, int *); 17fc5a983dSmrgstatic Bool NV_SetMode(ScrnInfoPtr, DGAModePtr); 18fc5a983dSmrgstatic int NV_GetViewport(ScrnInfoPtr); 19fc5a983dSmrgstatic void NV_SetViewport(ScrnInfoPtr, int, int, int); 20bd304fc0Smrg#ifdef HAVE_XAA_H 21fc5a983dSmrgstatic void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 22fc5a983dSmrgstatic void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 23fc5a983dSmrgstatic void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 24fc5a983dSmrg unsigned long); 25bd304fc0Smrg#endif 26fc5a983dSmrg 27fc5a983dSmrgstatic 28fc5a983dSmrgDGAFunctionRec NV_DGAFuncs = { 29fc5a983dSmrg NV_OpenFramebuffer, 30fc5a983dSmrg NULL, 31fc5a983dSmrg NV_SetMode, 32fc5a983dSmrg NV_SetViewport, 33fc5a983dSmrg NV_GetViewport, 34fc5a983dSmrg NVSync, 35bd304fc0Smrg#ifdef HAVE_XAA_H 36fc5a983dSmrg NV_FillRect, 37fc5a983dSmrg NV_BlitRect, 38fc5a983dSmrg NV_BlitTransRect 39bd304fc0Smrg#else 40bd304fc0Smrg NULL, NULL, NULL 41bd304fc0Smrg#endif 42fc5a983dSmrg}; 43fc5a983dSmrg 44fc5a983dSmrg 45fc5a983dSmrg 46fc5a983dSmrgstatic DGAModePtr 47fc5a983dSmrgNVSetupDGAMode( 48fc5a983dSmrg ScrnInfoPtr pScrn, 49fc5a983dSmrg DGAModePtr modes, 50fc5a983dSmrg int *num, 51fc5a983dSmrg int bitsPerPixel, 52fc5a983dSmrg int depth, 53fc5a983dSmrg Bool pixmap, 54fc5a983dSmrg int secondPitch, 55fc5a983dSmrg unsigned long red, 56fc5a983dSmrg unsigned long green, 57fc5a983dSmrg unsigned long blue, 58fc5a983dSmrg short visualClass 59fc5a983dSmrg){ 60fc5a983dSmrg DisplayModePtr firstMode, pMode; 61fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 62fc5a983dSmrg DGAModePtr mode, newmodes; 63fc5a983dSmrg int size, pitch, Bpp = bitsPerPixel >> 3; 64fc5a983dSmrg 65fc5a983dSmrgSECOND_PASS: 66fc5a983dSmrg 67fc5a983dSmrg pMode = firstMode = pScrn->modes; 68fc5a983dSmrg 69fc5a983dSmrg while(1) { 70fc5a983dSmrg 71fc5a983dSmrg pitch = (pMode->HDisplay + 31) & ~31; 72fc5a983dSmrg size = pitch * Bpp * pMode->VDisplay; 73fc5a983dSmrg 74fc5a983dSmrg if((!secondPitch || (pitch != secondPitch)) && 75fc5a983dSmrg (size <= pNv->ScratchBufferStart)) { 76fc5a983dSmrg 77fc5a983dSmrg if(secondPitch) 78fc5a983dSmrg pitch = secondPitch; 79fc5a983dSmrg 806086d97eSmrg if(!(newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec)))) 81fc5a983dSmrg break; 82fc5a983dSmrg 83fc5a983dSmrg modes = newmodes; 84fc5a983dSmrg mode = modes + *num; 85fc5a983dSmrg 86fc5a983dSmrg mode->mode = pMode; 87fc5a983dSmrg mode->flags = DGA_CONCURRENT_ACCESS; 88fc5a983dSmrg 89fc5a983dSmrg if(pixmap) 90fc5a983dSmrg mode->flags |= DGA_PIXMAP_AVAILABLE; 91bd304fc0Smrg#ifdef HAVE_XAA_H 92fc5a983dSmrg if(!pNv->NoAccel) 93fc5a983dSmrg mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 94bd304fc0Smrg#endif 95fc5a983dSmrg if(pMode->Flags & V_DBLSCAN) 96fc5a983dSmrg mode->flags |= DGA_DOUBLESCAN; 97fc5a983dSmrg if(pMode->Flags & V_INTERLACE) 98fc5a983dSmrg mode->flags |= DGA_INTERLACED; 99fc5a983dSmrg mode->byteOrder = pScrn->imageByteOrder; 100fc5a983dSmrg mode->depth = depth; 101fc5a983dSmrg mode->bitsPerPixel = bitsPerPixel; 102fc5a983dSmrg mode->red_mask = red; 103fc5a983dSmrg mode->green_mask = green; 104fc5a983dSmrg mode->blue_mask = blue; 105fc5a983dSmrg mode->visualClass = visualClass; 106fc5a983dSmrg mode->viewportWidth = pMode->HDisplay; 107fc5a983dSmrg mode->viewportHeight = pMode->VDisplay; 108fc5a983dSmrg mode->xViewportStep = 4 / Bpp; 109fc5a983dSmrg mode->yViewportStep = 1; 110fc5a983dSmrg mode->viewportFlags = DGA_FLIP_RETRACE; 111fc5a983dSmrg mode->offset = 0; 112fc5a983dSmrg mode->address = pNv->FbStart; 113fc5a983dSmrg mode->bytesPerScanline = pitch * Bpp; 114fc5a983dSmrg mode->imageWidth = pitch; 115fc5a983dSmrg mode->imageHeight = pNv->ScratchBufferStart / 116fc5a983dSmrg mode->bytesPerScanline; 117fc5a983dSmrg mode->pixmapWidth = mode->imageWidth; 118fc5a983dSmrg mode->pixmapHeight = mode->imageHeight; 119fc5a983dSmrg mode->maxViewportX = mode->imageWidth - mode->viewportWidth; 120fc5a983dSmrg mode->maxViewportY = mode->imageHeight - mode->viewportHeight; 121fc5a983dSmrg (*num)++; 122fc5a983dSmrg } 123fc5a983dSmrg 124fc5a983dSmrg pMode = pMode->next; 125fc5a983dSmrg if(pMode == firstMode) 126fc5a983dSmrg break; 127fc5a983dSmrg } 128fc5a983dSmrg 129fc5a983dSmrg if(secondPitch) { 130fc5a983dSmrg secondPitch = 0; 131fc5a983dSmrg goto SECOND_PASS; 132fc5a983dSmrg } 133fc5a983dSmrg 134fc5a983dSmrg return modes; 135fc5a983dSmrg} 136fc5a983dSmrg 137fc5a983dSmrg 138fc5a983dSmrgBool 139fc5a983dSmrgNVDGAInit(ScreenPtr pScreen) 140fc5a983dSmrg{ 141bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 142fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 143fc5a983dSmrg DGAModePtr modes = NULL; 144fc5a983dSmrg int num = 0; 145fc5a983dSmrg 146fc5a983dSmrg /* 8 */ 147fc5a983dSmrg modes = NVSetupDGAMode (pScrn, modes, &num, 8, 8, 148fc5a983dSmrg (pScrn->bitsPerPixel == 8), 149fc5a983dSmrg (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, 150fc5a983dSmrg 0, 0, 0, PseudoColor); 151fc5a983dSmrg 152fc5a983dSmrg /* 15 */ 153fc5a983dSmrg modes = NVSetupDGAMode (pScrn, modes, &num, 16, 15, 154fc5a983dSmrg (pScrn->bitsPerPixel == 16), 155fc5a983dSmrg (pScrn->depth != 15) ? 0 : pScrn->displayWidth, 156fc5a983dSmrg 0x7c00, 0x03e0, 0x001f, TrueColor); 157fc5a983dSmrg 158fc5a983dSmrg /* 16 */ 159fc5a983dSmrg modes = NVSetupDGAMode (pScrn, modes, &num, 16, 16, 160fc5a983dSmrg (pScrn->bitsPerPixel == 16), 161fc5a983dSmrg (pScrn->depth != 16) ? 0 : pScrn->displayWidth, 162fc5a983dSmrg 0xf800, 0x07e0, 0x001f, TrueColor); 163fc5a983dSmrg 164fc5a983dSmrg /* 32 */ 165fc5a983dSmrg modes = NVSetupDGAMode (pScrn, modes, &num, 32, 24, 166fc5a983dSmrg (pScrn->bitsPerPixel == 32), 167fc5a983dSmrg (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, 168fc5a983dSmrg 0xff0000, 0x00ff00, 0x0000ff, TrueColor); 169fc5a983dSmrg 170fc5a983dSmrg pNv->numDGAModes = num; 171fc5a983dSmrg pNv->DGAModes = modes; 172fc5a983dSmrg 173fc5a983dSmrg return DGAInit(pScreen, &NV_DGAFuncs, modes, num); 174fc5a983dSmrg} 175fc5a983dSmrg 176fc5a983dSmrg 177fc5a983dSmrgstatic int 178fc5a983dSmrgBitsSet(unsigned long data) 179fc5a983dSmrg{ 180fc5a983dSmrg unsigned long mask; 181fc5a983dSmrg int set = 0; 182fc5a983dSmrg 183fc5a983dSmrg for(mask = 1; mask; mask <<= 1) 184fc5a983dSmrg if(mask & data) set++; 185fc5a983dSmrg 186fc5a983dSmrg return set; 187fc5a983dSmrg} 188fc5a983dSmrg 189fc5a983dSmrgstatic Bool 190fc5a983dSmrgNV_SetMode( 191fc5a983dSmrg ScrnInfoPtr pScrn, 192fc5a983dSmrg DGAModePtr pMode 193fc5a983dSmrg){ 194fc5a983dSmrg static NVFBLayout SavedLayouts[MAXSCREENS]; 195fc5a983dSmrg int index = pScrn->pScreen->myNum; 196fc5a983dSmrg 197fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 198fc5a983dSmrg 199fc5a983dSmrg if(!pMode) { /* restore the original mode */ 200fc5a983dSmrg if(pNv->DGAactive) 201fc5a983dSmrg memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout)); 202fc5a983dSmrg 203fc5a983dSmrg pScrn->currentMode = pNv->CurrentLayout.mode; 204bd304fc0Smrg NVSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 205bd304fc0Smrg NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 206fc5a983dSmrg pNv->DGAactive = FALSE; 207fc5a983dSmrg } else { 208fc5a983dSmrg if(!pNv->DGAactive) { /* save the old parameters */ 209fc5a983dSmrg memcpy(&SavedLayouts[index], &pNv->CurrentLayout, sizeof(NVFBLayout)); 210fc5a983dSmrg pNv->DGAactive = TRUE; 211fc5a983dSmrg } 212fc5a983dSmrg 213fc5a983dSmrg /* update CurrentLayout */ 214fc5a983dSmrg pNv->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; 215fc5a983dSmrg pNv->CurrentLayout.depth = pMode->depth; 216fc5a983dSmrg pNv->CurrentLayout.displayWidth = pMode->bytesPerScanline / 217fc5a983dSmrg (pMode->bitsPerPixel >> 3); 218fc5a983dSmrg pNv->CurrentLayout.weight.red = BitsSet(pMode->red_mask); 219fc5a983dSmrg pNv->CurrentLayout.weight.green = BitsSet(pMode->green_mask); 220fc5a983dSmrg pNv->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask); 221fc5a983dSmrg /* NVModeInit() will set the mode field */ 222bd304fc0Smrg NVSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 223fc5a983dSmrg } 224fc5a983dSmrg 225fc5a983dSmrg return TRUE; 226fc5a983dSmrg} 227fc5a983dSmrg 228fc5a983dSmrg 229fc5a983dSmrg 230fc5a983dSmrgstatic int 231fc5a983dSmrgNV_GetViewport( 232fc5a983dSmrg ScrnInfoPtr pScrn 233fc5a983dSmrg){ 234fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 235fc5a983dSmrg 236fc5a983dSmrg return pNv->DGAViewportStatus; 237fc5a983dSmrg} 238fc5a983dSmrg 239fc5a983dSmrgstatic void 240fc5a983dSmrgNV_SetViewport( 241fc5a983dSmrg ScrnInfoPtr pScrn, 242fc5a983dSmrg int x, int y, 243fc5a983dSmrg int flags 244fc5a983dSmrg){ 245fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 246fc5a983dSmrg 247bd304fc0Smrg NVAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 248fc5a983dSmrg 249fc5a983dSmrg while(VGA_RD08(pNv->PCIO, 0x3da) & 0x08); 250fc5a983dSmrg while(!(VGA_RD08(pNv->PCIO, 0x3da) & 0x08)); 251fc5a983dSmrg 252fc5a983dSmrg pNv->DGAViewportStatus = 0; 253fc5a983dSmrg} 254fc5a983dSmrg 255bd304fc0Smrg#ifdef HAVE_XAA_H 256fc5a983dSmrgstatic void 257fc5a983dSmrgNV_FillRect ( 258fc5a983dSmrg ScrnInfoPtr pScrn, 259fc5a983dSmrg int x, int y, int w, int h, 260fc5a983dSmrg unsigned long color 261fc5a983dSmrg){ 262fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 263fc5a983dSmrg 264fc5a983dSmrg if(!pNv->AccelInfoRec) return; 265fc5a983dSmrg 266fc5a983dSmrg (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 267fc5a983dSmrg (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 268fc5a983dSmrg 269fc5a983dSmrg SET_SYNC_FLAG(pNv->AccelInfoRec); 270fc5a983dSmrg} 271fc5a983dSmrg 272fc5a983dSmrgstatic void 273fc5a983dSmrgNV_BlitRect( 274fc5a983dSmrg ScrnInfoPtr pScrn, 275fc5a983dSmrg int srcx, int srcy, 276fc5a983dSmrg int w, int h, 277fc5a983dSmrg int dstx, int dsty 278fc5a983dSmrg){ 279fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 280fc5a983dSmrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 281fc5a983dSmrg int ydir = (srcy < dsty) ? -1 : 1; 282fc5a983dSmrg 283fc5a983dSmrg if(!pNv->AccelInfoRec) return; 284fc5a983dSmrg 285fc5a983dSmrg (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)( 286fc5a983dSmrg pScrn, xdir, ydir, GXcopy, ~0, -1); 287fc5a983dSmrg 288fc5a983dSmrg (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)( 289fc5a983dSmrg pScrn, srcx, srcy, dstx, dsty, w, h); 290fc5a983dSmrg 291fc5a983dSmrg SET_SYNC_FLAG(pNv->AccelInfoRec); 292fc5a983dSmrg} 293fc5a983dSmrg 294fc5a983dSmrg 295fc5a983dSmrgstatic void 296fc5a983dSmrgNV_BlitTransRect( 297fc5a983dSmrg ScrnInfoPtr pScrn, 298fc5a983dSmrg int srcx, int srcy, 299fc5a983dSmrg int w, int h, 300fc5a983dSmrg int dstx, int dsty, 301fc5a983dSmrg unsigned long color 302fc5a983dSmrg){ 303fc5a983dSmrg /* not implemented */ 304fc5a983dSmrg} 305bd304fc0Smrg#endif 306fc5a983dSmrg 307fc5a983dSmrgstatic Bool 308fc5a983dSmrgNV_OpenFramebuffer( 309fc5a983dSmrg ScrnInfoPtr pScrn, 310fc5a983dSmrg char **name, 311fc5a983dSmrg unsigned char **mem, 312fc5a983dSmrg int *size, 313fc5a983dSmrg int *offset, 314fc5a983dSmrg int *flags 315fc5a983dSmrg){ 316fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 317fc5a983dSmrg 318fc5a983dSmrg *name = NULL; /* no special device */ 319fc5a983dSmrg *mem = (unsigned char*)pNv->FbAddress; 320fc5a983dSmrg *size = pNv->FbMapSize; 321fc5a983dSmrg *offset = 0; 322fc5a983dSmrg *flags = DGA_NEED_ROOT; 323fc5a983dSmrg 324fc5a983dSmrg return TRUE; 325fc5a983dSmrg} 326