ct_dga.c revision c06b6b69
1c06b6b69Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c,v 1.3tsi Exp $ */ 2c06b6b69Smrg 3c06b6b69Smrg#ifdef HAVE_CONFIG_H 4c06b6b69Smrg#include "config.h" 5c06b6b69Smrg#endif 6c06b6b69Smrg 7c06b6b69Smrg#include "xf86.h" 8c06b6b69Smrg#include "xf86_OSproc.h" 9c06b6b69Smrg#include "xf86Pci.h" 10c06b6b69Smrg#include "xf86PciInfo.h" 11c06b6b69Smrg#include "xaa.h" 12c06b6b69Smrg#include "xaalocal.h" 13c06b6b69Smrg#include "ct_driver.h" 14c06b6b69Smrg#include "dgaproc.h" 15c06b6b69Smrg 16c06b6b69Smrg 17c06b6b69Smrgstatic Bool CHIPS_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 18c06b6b69Smrg int *, int *, int *); 19c06b6b69Smrgstatic Bool CHIPS_SetMode(ScrnInfoPtr, DGAModePtr); 20c06b6b69Smrgstatic int CHIPS_GetViewport(ScrnInfoPtr); 21c06b6b69Smrgstatic void CHIPS_SetViewport(ScrnInfoPtr, int, int, int); 22c06b6b69Smrgstatic void CHIPS_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 23c06b6b69Smrgstatic void CHIPS_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 24c06b6b69Smrg#if 0 25c06b6b69Smrgstatic void CHIPS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 26c06b6b69Smrg unsigned long); 27c06b6b69Smrg#endif 28c06b6b69Smrg 29c06b6b69Smrgstatic 30c06b6b69SmrgDGAFunctionRec CHIPS_DGAFuncs = { 31c06b6b69Smrg CHIPS_OpenFramebuffer, 32c06b6b69Smrg NULL, 33c06b6b69Smrg CHIPS_SetMode, 34c06b6b69Smrg CHIPS_SetViewport, 35c06b6b69Smrg CHIPS_GetViewport, 36c06b6b69Smrg CHIPSSync, 37c06b6b69Smrg CHIPS_FillRect, 38c06b6b69Smrg CHIPS_BlitRect, 39c06b6b69Smrg#if 0 40c06b6b69Smrg CHIPS_BlitTransRect 41c06b6b69Smrg#else 42c06b6b69Smrg NULL 43c06b6b69Smrg#endif 44c06b6b69Smrg}; 45c06b6b69Smrg 46c06b6b69Smrgstatic 47c06b6b69SmrgDGAFunctionRec CHIPS_MMIODGAFuncs = { 48c06b6b69Smrg CHIPS_OpenFramebuffer, 49c06b6b69Smrg NULL, 50c06b6b69Smrg CHIPS_SetMode, 51c06b6b69Smrg CHIPS_SetViewport, 52c06b6b69Smrg CHIPS_GetViewport, 53c06b6b69Smrg CHIPSMMIOSync, 54c06b6b69Smrg CHIPS_FillRect, 55c06b6b69Smrg CHIPS_BlitRect, 56c06b6b69Smrg#if 0 57c06b6b69Smrg CHIPS_BlitTransRect 58c06b6b69Smrg#else 59c06b6b69Smrg NULL 60c06b6b69Smrg#endif 61c06b6b69Smrg}; 62c06b6b69Smrg 63c06b6b69Smrgstatic 64c06b6b69SmrgDGAFunctionRec CHIPS_HiQVDGAFuncs = { 65c06b6b69Smrg CHIPS_OpenFramebuffer, 66c06b6b69Smrg NULL, 67c06b6b69Smrg CHIPS_SetMode, 68c06b6b69Smrg CHIPS_SetViewport, 69c06b6b69Smrg CHIPS_GetViewport, 70c06b6b69Smrg CHIPSHiQVSync, 71c06b6b69Smrg CHIPS_FillRect, 72c06b6b69Smrg CHIPS_BlitRect, 73c06b6b69Smrg#if 0 74c06b6b69Smrg CHIPS_BlitTransRect 75c06b6b69Smrg#else 76c06b6b69Smrg NULL 77c06b6b69Smrg#endif 78c06b6b69Smrg}; 79c06b6b69Smrg 80c06b6b69Smrg 81c06b6b69SmrgBool 82c06b6b69SmrgCHIPSDGAInit(ScreenPtr pScreen) 83c06b6b69Smrg{ 84c06b6b69Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 85c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 86c06b6b69Smrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 87c06b6b69Smrg DisplayModePtr pMode, firstMode; 88c06b6b69Smrg int Bpp = pScrn->bitsPerPixel >> 3; 89c06b6b69Smrg int num = 0; 90c06b6b69Smrg Bool oneMore; 91c06b6b69Smrg int imlines = (pScrn->videoRam * 1024) / 92c06b6b69Smrg (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); 93c06b6b69Smrg 94c06b6b69Smrg pMode = firstMode = pScrn->modes; 95c06b6b69Smrg 96c06b6b69Smrg while(pMode) { 97c06b6b69Smrg 98c06b6b69Smrg if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 99c06b6b69Smrg newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); 100c06b6b69Smrg oneMore = TRUE; 101c06b6b69Smrg } else { 102c06b6b69Smrg newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); 103c06b6b69Smrg oneMore = FALSE; 104c06b6b69Smrg } 105c06b6b69Smrg 106c06b6b69Smrg if(!newmodes) { 107c06b6b69Smrg xfree(modes); 108c06b6b69Smrg return FALSE; 109c06b6b69Smrg } 110c06b6b69Smrg modes = newmodes; 111c06b6b69Smrg 112c06b6b69SmrgSECOND_PASS: 113c06b6b69Smrg 114c06b6b69Smrg currentMode = modes + num; 115c06b6b69Smrg num++; 116c06b6b69Smrg 117c06b6b69Smrg currentMode->mode = pMode; 118c06b6b69Smrg currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 119c06b6b69Smrg if(cPtr->Flags & ChipsAccelSupport) 120c06b6b69Smrg currentMode->flags |= (cPtr->Flags & ChipsAccelSupport) 121c06b6b69Smrg ? (DGA_FILL_RECT | DGA_BLIT_RECT) : 0; 122c06b6b69Smrg if(pMode->Flags & V_DBLSCAN) 123c06b6b69Smrg currentMode->flags |= DGA_DOUBLESCAN; 124c06b6b69Smrg if(pMode->Flags & V_INTERLACE) 125c06b6b69Smrg currentMode->flags |= DGA_INTERLACED; 126c06b6b69Smrg currentMode->byteOrder = pScrn->imageByteOrder; 127c06b6b69Smrg currentMode->depth = pScrn->depth; 128c06b6b69Smrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 129c06b6b69Smrg currentMode->red_mask = pScrn->mask.red; 130c06b6b69Smrg currentMode->green_mask = pScrn->mask.green; 131c06b6b69Smrg currentMode->blue_mask = pScrn->mask.blue; 132c06b6b69Smrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 133c06b6b69Smrg currentMode->viewportWidth = pMode->HDisplay; 134c06b6b69Smrg currentMode->viewportHeight = pMode->VDisplay; 135c06b6b69Smrg currentMode->xViewportStep = 1; 136c06b6b69Smrg currentMode->yViewportStep = 1; 137c06b6b69Smrg currentMode->viewportFlags = DGA_FLIP_RETRACE | DGA_FLIP_IMMEDIATE; 138c06b6b69Smrg currentMode->offset = 0; 139c06b6b69Smrg currentMode->address = cPtr->FbBase; 140c06b6b69Smrg 141c06b6b69Smrg if(oneMore) { /* first one is narrow width */ 142c06b6b69Smrg currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 143c06b6b69Smrg currentMode->imageWidth = pMode->HDisplay; 144c06b6b69Smrg currentMode->imageHeight = imlines; 145c06b6b69Smrg currentMode->pixmapWidth = currentMode->imageWidth; 146c06b6b69Smrg currentMode->pixmapHeight = currentMode->imageHeight; 147c06b6b69Smrg currentMode->maxViewportX = currentMode->imageWidth - 148c06b6b69Smrg currentMode->viewportWidth; 149c06b6b69Smrg /* this might need to get clamped to some maximum */ 150c06b6b69Smrg currentMode->maxViewportY = currentMode->imageHeight - 151c06b6b69Smrg currentMode->viewportHeight; 152c06b6b69Smrg oneMore = FALSE; 153c06b6b69Smrg goto SECOND_PASS; 154c06b6b69Smrg } else { 155c06b6b69Smrg currentMode->bytesPerScanline = 156c06b6b69Smrg ((pScrn->displayWidth * Bpp) + 3) & ~3L; 157c06b6b69Smrg currentMode->imageWidth = pScrn->displayWidth; 158c06b6b69Smrg currentMode->imageHeight = imlines; 159c06b6b69Smrg currentMode->pixmapWidth = currentMode->imageWidth; 160c06b6b69Smrg currentMode->pixmapHeight = currentMode->imageHeight; 161c06b6b69Smrg currentMode->maxViewportX = currentMode->imageWidth - 162c06b6b69Smrg currentMode->viewportWidth; 163c06b6b69Smrg /* this might need to get clamped to some maximum */ 164c06b6b69Smrg currentMode->maxViewportY = currentMode->imageHeight - 165c06b6b69Smrg currentMode->viewportHeight; 166c06b6b69Smrg } 167c06b6b69Smrg 168c06b6b69Smrg pMode = pMode->next; 169c06b6b69Smrg if(pMode == firstMode) 170c06b6b69Smrg break; 171c06b6b69Smrg } 172c06b6b69Smrg 173c06b6b69Smrg cPtr->numDGAModes = num; 174c06b6b69Smrg cPtr->DGAModes = modes; 175c06b6b69Smrg 176c06b6b69Smrg if (IS_HiQV(cPtr)) { 177c06b6b69Smrg return DGAInit(pScreen, &CHIPS_HiQVDGAFuncs, modes, num); 178c06b6b69Smrg } else { 179c06b6b69Smrg if(!cPtr->UseMMIO) { 180c06b6b69Smrg return DGAInit(pScreen, &CHIPS_DGAFuncs, modes, num); 181c06b6b69Smrg } else { 182c06b6b69Smrg return DGAInit(pScreen, &CHIPS_MMIODGAFuncs, modes, num); 183c06b6b69Smrg } 184c06b6b69Smrg } 185c06b6b69Smrg} 186c06b6b69Smrg 187c06b6b69Smrg 188c06b6b69Smrgstatic Bool 189c06b6b69SmrgCHIPS_SetMode( 190c06b6b69Smrg ScrnInfoPtr pScrn, 191c06b6b69Smrg DGAModePtr pMode 192c06b6b69Smrg){ 193c06b6b69Smrg static int OldDisplayWidth[MAXSCREENS]; 194c06b6b69Smrg int index = pScrn->pScreen->myNum; 195c06b6b69Smrg 196c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 197c06b6b69Smrg 198c06b6b69Smrg if (!pMode) { /* restore the original mode */ 199c06b6b69Smrg /* put the ScreenParameters back */ 200c06b6b69Smrg if (cPtr->DGAactive) { 201c06b6b69Smrg pScrn->displayWidth = OldDisplayWidth[index]; 202c06b6b69Smrg pScrn->EnterVT(pScrn->scrnIndex,0); 203c06b6b69Smrg 204c06b6b69Smrg cPtr->DGAactive = FALSE; 205c06b6b69Smrg } 206c06b6b69Smrg } else { 207c06b6b69Smrg if(!cPtr->DGAactive) { /* save the old parameters */ 208c06b6b69Smrg OldDisplayWidth[index] = pScrn->displayWidth; 209c06b6b69Smrg pScrn->LeaveVT(pScrn->scrnIndex,0); 210c06b6b69Smrg cPtr->DGAactive = TRUE; 211c06b6b69Smrg } 212c06b6b69Smrg 213c06b6b69Smrg pScrn->displayWidth = pMode->bytesPerScanline / 214c06b6b69Smrg (pMode->bitsPerPixel >> 3); 215c06b6b69Smrg 216c06b6b69Smrg CHIPSSwitchMode(index, pMode->mode, 0); 217c06b6b69Smrg } 218c06b6b69Smrg 219c06b6b69Smrg return TRUE; 220c06b6b69Smrg} 221c06b6b69Smrg 222c06b6b69Smrg 223c06b6b69Smrg 224c06b6b69Smrgstatic int 225c06b6b69SmrgCHIPS_GetViewport( 226c06b6b69Smrg ScrnInfoPtr pScrn 227c06b6b69Smrg){ 228c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 229c06b6b69Smrg 230c06b6b69Smrg return cPtr->DGAViewportStatus; 231c06b6b69Smrg} 232c06b6b69Smrg 233c06b6b69Smrgstatic void 234c06b6b69SmrgCHIPS_SetViewport( 235c06b6b69Smrg ScrnInfoPtr pScrn, 236c06b6b69Smrg int x, int y, 237c06b6b69Smrg int flags 238c06b6b69Smrg ){ 239c06b6b69Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 240c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 241c06b6b69Smrg 242c06b6b69Smrg if (flags & DGA_FLIP_RETRACE) { 243c06b6b69Smrg while ((hwp->readST01(hwp)) & 0x08){}; 244c06b6b69Smrg while (!(hwp->readST01(hwp)) & 0x08){}; 245c06b6b69Smrg } 246c06b6b69Smrg 247c06b6b69Smrg CHIPSAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 248c06b6b69Smrg cPtr->DGAViewportStatus = 0; /* CHIPSAdjustFrame loops until finished */ 249c06b6b69Smrg} 250c06b6b69Smrg 251c06b6b69Smrgstatic void 252c06b6b69SmrgCHIPS_FillRect ( 253c06b6b69Smrg ScrnInfoPtr pScrn, 254c06b6b69Smrg int x, int y, int w, int h, 255c06b6b69Smrg unsigned long color 256c06b6b69Smrg){ 257c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 258c06b6b69Smrg 259c06b6b69Smrg if(cPtr->AccelInfoRec) { 260c06b6b69Smrg (*cPtr->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 261c06b6b69Smrg (*cPtr->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 262c06b6b69Smrg SET_SYNC_FLAG(cPtr->AccelInfoRec); 263c06b6b69Smrg } 264c06b6b69Smrg} 265c06b6b69Smrg 266c06b6b69Smrgstatic void 267c06b6b69SmrgCHIPS_BlitRect( 268c06b6b69Smrg ScrnInfoPtr pScrn, 269c06b6b69Smrg int srcx, int srcy, 270c06b6b69Smrg int w, int h, 271c06b6b69Smrg int dstx, int dsty 272c06b6b69Smrg){ 273c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 274c06b6b69Smrg 275c06b6b69Smrg if(cPtr->AccelInfoRec) { 276c06b6b69Smrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 277c06b6b69Smrg int ydir = (srcy < dsty) ? -1 : 1; 278c06b6b69Smrg 279c06b6b69Smrg (*cPtr->AccelInfoRec->SetupForScreenToScreenCopy)( 280c06b6b69Smrg pScrn, xdir, ydir, GXcopy, ~0, -1); 281c06b6b69Smrg (*cPtr->AccelInfoRec->SubsequentScreenToScreenCopy)( 282c06b6b69Smrg pScrn, srcx, srcy, dstx, dsty, w, h); 283c06b6b69Smrg SET_SYNC_FLAG(cPtr->AccelInfoRec); 284c06b6b69Smrg } 285c06b6b69Smrg} 286c06b6b69Smrg 287c06b6b69Smrg#if 0 288c06b6b69Smrgstatic void 289c06b6b69SmrgCHIPS_BlitTransRect( 290c06b6b69Smrg ScrnInfoPtr pScrn, 291c06b6b69Smrg int srcx, int srcy, 292c06b6b69Smrg int w, int h, 293c06b6b69Smrg int dstx, int dsty, 294c06b6b69Smrg unsigned long color 295c06b6b69Smrg){ 296c06b6b69Smrg /* this one should be separate since the XAA function would 297c06b6b69Smrg prohibit usage of ~0 as the key */ 298c06b6b69Smrg} 299c06b6b69Smrg#endif 300c06b6b69Smrg 301c06b6b69Smrgstatic Bool 302c06b6b69SmrgCHIPS_OpenFramebuffer( 303c06b6b69Smrg ScrnInfoPtr pScrn, 304c06b6b69Smrg char **name, 305c06b6b69Smrg unsigned char **mem, 306c06b6b69Smrg int *size, 307c06b6b69Smrg int *offset, 308c06b6b69Smrg int *flags 309c06b6b69Smrg){ 310c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 311c06b6b69Smrg 312c06b6b69Smrg *name = NULL; /* no special device */ 313c06b6b69Smrg *mem = (unsigned char*)cPtr->FbAddress; 314c06b6b69Smrg *size = cPtr->FbMapSize; 315c06b6b69Smrg *offset = 0; 316c06b6b69Smrg *flags = DGA_NEED_ROOT; 317c06b6b69Smrg 318c06b6b69Smrg return TRUE; 319c06b6b69Smrg} 320