static xf86MonPtr LgDoDDC(ScrnInfoPtr pScrn) { CirPtr pCir = CIRPTR(pScrn); xf86MonPtr MonInfo = NULL; /* Map the CIR memory and MMIO areas */ if (!CirMapMem(pCir, pScrn->scrnIndex)) return FALSE; #if LGuseI2C if (!LgI2CInit(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I2C initialization failed\n"); goto unmap_out; } /* Read and output monitor info using DDC2 over I2C bus */ MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pCir->I2CPtr1); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", (void *)MonInfo); xf86PrintEDID(MonInfo); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n\n"); #endif /* LGuseI2C */ xf86SetDDCproperties(pScrn, MonInfo); unmap_out: CirUnmapMem(pCir, pScrn->scrnIndex); return MonInfo; }
static void LgSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { const CirPtr pCir = CIRPTR(pScrn); const LgPtr pLg = LGPTR(pCir); /* * We have set the flag indicating that xdir must be one, * so we can assume that here. */ if (pLg->blitYDir == -1) { y1 += h - 1; y2 += h - 1; } if (pLg->blitTransparent) { /* We're doing a transparent blit. We'll need to point OP2 to the color compare mask. */ LgWaitQAvail(pCir, 4); LgSETTRANSMASK(x1, y1); } else { LgWaitQAvail(pCir, 3); } LgSETSRCXY(x1, y1); LgSETDSTXY(x2, y2); LgSETEXTENTS(w, h); }
static void AlpSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); int dest; int hh, ww; int pitch = pCir->pitch; ww = ((x2 - x1) * pScrn->bitsPerPixel / 8) - 1; hh = (y2 - y1) - 1; dest = y1 * pitch + x1 * pScrn->bitsPerPixel / 8; WAIT; /* Width */ outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); /* Height */ outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22); outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23); /* dest */ outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); if (!pCir->chip.alp->autoStart) outw(pCir->PIOReg, 0x0231); #ifdef ALP_DEBUG ErrorF("AlpSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n", x1, y1, x2 - x1, y2 - y1); #endif }
static void AlpDone(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); #ifdef ALP_DEBUG ErrorF("AlpDone\n"); #endif }
static void LgSync(ScrnInfoPtr pScrn) { const CirPtr pCir = CIRPTR(pScrn); #if 0 LgPtr pLg = LGPTR(pScrn); #endif while (!LgREADY()) ; }
static void LgSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { const CirPtr pCir = CIRPTR(pScrn); /* Wait for room in the command queue. */ LgWaitQAvail(pCir, 2); LgSETDSTXY(x, y); LgSETEXTENTS(w, h); }
static Bool AlpPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); AlpPtr pAlp = ALPPTR(pCir); int pitch = pCir->pitch; #ifdef ALP_DEBUG ErrorF("AlpSetupForSolidFill color=%x alu=%x planemask=%x\n", fg, alu, planemask); #endif WAIT; SetupForRop(alu); switch (pCir -> Chipset) { case PCI_CHIP_GD7548: /* The GD7548 does not (apparently) support solid filling directly, it always need an actual source. We therefore use it as a pattern fill with a solid pattern */ { int source = pAlp->monoPattern8x8; /* source = 8x8 solid mono pattern */ outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C); outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D); outw(pCir->PIOReg, ((source >> 8) & 0x3f00) | 0x2E); /* memset() may not be the fastest */ memset((char *)pCir->FbBase + pAlp->monoPattern8x8, 0xFF, 8); write_mem_barrier(); break; } default: /* GR33 = 0x04 => does not exist on GD7548 */ outw(pCir->PIOReg, 0x0433); } /* GR30 = color expansion, pattern copy */ /* Choses 8bpp / 16bpp color expansion */ outw(pCir->PIOReg, 0xC030 |((pScrn->bitsPerPixel - 8) << 9)); outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01); outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11); outw(pCir->PIOReg, ((fg >> 8) & 0xff00) | 0x13); outw(pCir->PIOReg, 0x15); /* Set dest pitch */ outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); return TRUE; }
static void AlpSync(ScreenPtr pScreen, int marker) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); #ifdef ALP_DEBUG ErrorF("AlpSync\n"); #endif WAIT_1; return; }
static void AlpCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) { ScreenPtr pScreen = pDstPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); int source, dest; int hh, ww; int decrement = 0; int pitch = pCir->pitch; ww = (width * pScrn->bitsPerPixel / 8) - 1; hh = height - 1; dest = dstY * pitch + dstX * pScrn->bitsPerPixel / 8; source = srcY * pitch + srcX * pScrn->bitsPerPixel / 8; if (dest > source) { decrement = 1 << 8; dest += hh * pitch + ww; source += hh * pitch + ww; } WAIT; outw(pCir->PIOReg, decrement | 0x30); /* Width */ outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20); outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21); /* Height */ outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22); outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23); /* source */ outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C); outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D); outw(pCir->PIOReg, ((source >> 8) & 0x3f00)| 0x2E); /* dest */ outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28); outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29); outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A); if (!pCir->chip.alp->autoStart) outw(pCir->PIOReg, 0x0231); #ifdef ALP_DEBUG ErrorF("AlpCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", srcX, srcY, dstX, dstY, width, height); ErrorF("AlpSCopy s=%d d=%d ww=%d hh=%d\n", source, dest, ww, hh); #endif }
Bool AlpI2CInit(ScrnInfoPtr pScrn) { CirPtr pCir = CIRPTR(pScrn); I2CBusPtr I2CPtr; #ifdef ALP_DEBUG ErrorF("AlpI2CInit\n"); #endif switch(pCir->Chipset) { case PCI_CHIP_GD5446: case PCI_CHIP_GD5480: break; default: return FALSE; } I2CPtr = xf86CreateI2CBusRec(); if (!I2CPtr) return FALSE; pCir->I2CPtr1 = I2CPtr; I2CPtr->BusName = "I2C bus 1"; I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = AlpI2CPutBits; I2CPtr->I2CGetBits = AlpI2CGetBits; I2CPtr->DriverPrivate.ptr = pCir; if (!xf86I2CBusInit(I2CPtr)) return FALSE; I2CPtr = xf86CreateI2CBusRec(); if (!I2CPtr) return FALSE; pCir->I2CPtr2 = I2CPtr; I2CPtr->BusName = "I2C bus 2"; I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = AlpI2CPutBits; I2CPtr->I2CGetBits = AlpI2CGetBits; I2CPtr->DriverPrivate.ptr = pCir; if (!xf86I2CBusInit(I2CPtr)) return FALSE; return TRUE; }
static void LgSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { const CirPtr pCir = CIRPTR(pScrn); color = LgExpandColor(color, pScrn->bitsPerPixel); LgWaitQAvail(pCir, 4); LgSETBACKGROUND(color); LgSETROP(lgRop[rop]); LgSETMODE(SCR2SCR | COLORFILL); LgSetBitmask(pCir, planemask); }
static void AlpAccelEngineInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); outw(pCir->PIOReg, 0x200E); /* enable writes to gr33 */ /* Setup things for autostart */ if (pCir->properties & ACCEL_AUTOSTART) { outw(pCir->PIOReg, 0x8031); /* enable autostart */ pCir->chip.alp->waitMsk = 0x10; pCir->chip.alp->autoStart = TRUE; } else { pCir->chip.alp->waitMsk = 0x1; pCir->chip.alp->autoStart = FALSE; } }
static Bool LgGetRec(ScrnInfoPtr pScrn) { CirPtr pCir; if (pScrn->driverPrivate != NULL) return TRUE; pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1); ((CirPtr)pScrn->driverPrivate)->chip.lg = xnfcalloc(sizeof(LgRec),1); /* Initialize it */ pCir = CIRPTR(pScrn); pCir->chip.lg->oldBitmask = 0x00000000; return TRUE; }
static Bool LgModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { vgaHWPtr hwp; CirPtr pCir; int width; Bool VDiv2 = FALSE; CARD16 clockData; LgLineDataPtr lineData; #ifdef LG_DEBUG ErrorF("LgModeInit %d bpp, %d %d %d %d %d %d %d %d %d\n", pScrn->bitsPerPixel, mode->Clock, mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal); ErrorF("LgModeInit: depth %d bits\n", pScrn->depth); #endif pCir = CIRPTR(pScrn); hwp = VGAHWPTR(pScrn); vgaHWUnlock(hwp); if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) { /* For non-interlaced vertical timing >= 1024, the vertical timings */ /* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */ if (!mode->CrtcVAdjusted) { mode->CrtcVDisplay >>= 1; mode->CrtcVSyncStart >>= 1; mode->CrtcVSyncEnd >>= 1; mode->CrtcVTotal >>= 1; mode->CrtcVAdjusted = TRUE; } VDiv2 = TRUE; }
/* * This function saves the video state. */ static void LgSave(ScrnInfoPtr pScrn) { CirPtr pCir = CIRPTR(pScrn); vgaHWPtr hwp = VGAHWPTR(pScrn); #ifdef LG_DEBUG ErrorF("LgSave\n"); #endif vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL); pCir->chip.lg->ModeReg.ExtVga[CR1A] = pCir->chip.lg->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A); pCir->chip.lg->ModeReg.ExtVga[CR1B] = pCir->chip.lg->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B); pCir->chip.lg->ModeReg.ExtVga[CR1D] = pCir->chip.lg->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D); pCir->chip.lg->ModeReg.ExtVga[CR1E] = pCir->chip.lg->SavedReg.ExtVga[CR1E] = hwp->readCrtc(hwp, 0x1E); pCir->chip.lg->ModeReg.ExtVga[SR07] = pCir->chip.lg->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07); pCir->chip.lg->ModeReg.ExtVga[SR0E] = pCir->chip.lg->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E); pCir->chip.lg->ModeReg.ExtVga[SR12] = pCir->chip.lg->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12); pCir->chip.lg->ModeReg.ExtVga[SR13] = pCir->chip.lg->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13); pCir->chip.lg->ModeReg.ExtVga[SR1E] = pCir->chip.lg->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E); pCir->chip.lg->ModeReg.FORMAT = pCir->chip.lg->SavedReg.FORMAT = memrw(0xC0); pCir->chip.lg->ModeReg.VSC = pCir->chip.lg->SavedReg.VSC = memrl(0x3FC); pCir->chip.lg->ModeReg.DTTC = pCir->chip.lg->SavedReg.DTTC = memrw(0xEA); if (pCir->Chipset == PCI_CHIP_GD5465) { pCir->chip.lg->ModeReg.TileCtrl = pCir->chip.lg->SavedReg.TileCtrl = memrw(0x2C4); } pCir->chip.lg->ModeReg.TILE = pCir->chip.lg->SavedReg.TILE = memrb(0x407); if (pCir->Chipset == PCI_CHIP_GD5465) pCir->chip.lg->ModeReg.BCLK = pCir->chip.lg->SavedReg.BCLK = memrb(0x2C0); else pCir->chip.lg->ModeReg.BCLK = pCir->chip.lg->SavedReg.BCLK = memrb(0x8C); pCir->chip.lg->ModeReg.CONTROL = pCir->chip.lg->SavedReg.CONTROL = memrw(0x402); }
Bool AlpEXAInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); AlpAccelEngineInit(pScreen); pCir->ExaDriver->exa_major = EXA_VERSION_MAJOR; pCir->ExaDriver->exa_minor = EXA_VERSION_MINOR; pCir->ExaDriver->memoryBase = (char *)pCir->FbBase + pScrn->fbOffset; pCir->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT; #if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3) pCir->ExaDriver->maxPitchBytes = 16320; #endif /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */ pCir->ExaDriver->pixmapPitchAlign = 32; pCir->ExaDriver->pixmapOffsetAlign = 32; pCir->ExaDriver->maxX = 2048; pCir->ExaDriver->maxY = 2048; pCir->ExaDriver->PrepareSolid = AlpPrepareSolid; pCir->ExaDriver->Solid = AlpSolid; pCir->ExaDriver->DoneSolid =AlpDone; pCir->ExaDriver->PrepareCopy = AlpPrepareCopy; pCir->ExaDriver->Copy = AlpCopy; pCir->ExaDriver->DoneCopy = AlpDone; pCir->ExaDriver->WaitMarker = AlpSync; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing EXA driver...\n"); if (!exaDriverInit(pScreen, pCir->ExaDriver)) { free(pCir->ExaDriver); return FALSE; } return TRUE; }
Bool LgI2CInit(ScrnInfoPtr pScrn) { CirPtr pCir = CIRPTR(pScrn); I2CBusPtr I2CPtr; #ifdef LG_DEBUG ErrorF("LgI2CInit\n"); #endif I2CPtr = xf86CreateI2CBusRec(); if (!I2CPtr) return FALSE; pCir->I2CPtr1 = I2CPtr; I2CPtr->BusName = "I2C bus 1"; I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = LgI2CPutBits; I2CPtr->I2CGetBits = LgI2CGetBits; I2CPtr->DriverPrivate.ptr = pCir; if (!xf86I2CBusInit(I2CPtr)) return FALSE; I2CPtr = xf86CreateI2CBusRec(); if (!I2CPtr) return FALSE; pCir->I2CPtr2 = I2CPtr; I2CPtr->BusName = "I2C bus 2"; I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = LgI2CPutBits; I2CPtr->I2CGetBits = LgI2CGetBits; I2CPtr->DriverPrivate.ptr = pCir; if (!xf86I2CBusInit(I2CPtr)) return FALSE; return TRUE; }
Bool LgXAAInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; CirPtr pCir = CIRPTR(pScrn); XAAInfoRecPtr XAAPtr; XAAPtr = XAACreateInfoRec(); if (!XAAPtr) return FALSE; /* * Solid color fills. */ XAAPtr->SetupForSolidFill = LgSetupForSolidFill; XAAPtr->SubsequentSolidFillRect = LgSubsequentSolidFillRect; XAAPtr->SubsequentSolidFillTrap = NULL; XAAPtr->SolidFillFlags = 0; /* * Screen-to-screen copies. */ XAAPtr->SetupForScreenToScreenCopy = LgSetupForScreenToScreenCopy; XAAPtr->SubsequentScreenToScreenCopy = LgSubsequentScreenToScreenCopy; /* Maybe ONLY_LEFT_TO_RIGHT_BITBLT or ONLY_TWO_BITBLT_DIRECTIONS? */ XAAPtr->ScreenToScreenCopyFlags = ONLY_LEFT_TO_RIGHT_BITBLT; /* * Miscellany. */ XAAPtr->Sync = LgSync; pCir->AccelInfoRec = XAAPtr; if (!XAAInit(pScreen, XAAPtr)) return FALSE; return TRUE; }
static Bool AlpPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask) { ScreenPtr pScreen = pSrcPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); CirPtr pCir = CIRPTR(pScrn); int pitch = pCir->pitch; #ifdef ALP_DEBUG ErrorF("AlpPrepareCopy xdir=%d ydir=%d alu=%x planemask=%x\n", xdir, ydir, alu, planemask); #endif WAIT; SetupForRop(alu); /* Set dest pitch */ outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24); outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25); /* Set source pitch */ outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x26); outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x27); return TRUE; }
static void LgSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int transparency_color) { int bltmode = 0; const CirPtr pCir = CIRPTR(pScrn); const LgPtr pLg = LGPTR(pCir); pLg->blitTransparent = (transparency_color != -1); pLg->blitYDir = ydir; LgWaitQAvail(pCir, 4); /* We set the rop up here because the LgSETROP macro conveniently (really -- it is convenient!) clears the transparency bits in DRAWDEF. We'll set those bits appropriatly later. */ LgSETROP(lgRop[rop]); if (ydir < 0) bltmode |= BLITUP; if (pLg->blitTransparent) { /* Gotta extend the transparency_color to the full 32-bit size of the register. */ transparency_color = LgExpandColor(transparency_color, pScrn->bitsPerPixel); bltmode |= COLORTRANS; LgSETBACKGROUND(transparency_color); LgSETTRANSPARENCY(TRANSEQ); } else { LgSETTRANSPARENCY(TRANSNONE); } LgSETMODE(SCR2SCR | COLORSRC | bltmode); LgSetBitmask(pCir, planemask); }
/* Mandatory */ Bool LgPreInit(ScrnInfoPtr pScrn, int flags) { CirPtr pCir; vgaHWPtr hwp; MessageType from; int i; ClockRangePtr clockRanges; int fbPCIReg, ioPCIReg; char *s; if (flags & PROBE_DETECT) { cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index ); return TRUE; } #ifdef LG_DEBUG ErrorF("LgPreInit\n"); #endif /* Check the number of entities, and fail if it isn't one. */ if (pScrn->numEntities != 1) return FALSE; /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; xf86LoaderReqSymLists(vgahwSymbols, NULL); /* * Allocate a vgaHWRec */ if (!vgaHWGetHWRec(pScrn)) return FALSE; hwp = VGAHWPTR(pScrn); vgaHWGetIOBase(hwp); /* Allocate the LgRec driverPrivate */ if (!LgGetRec(pScrn)) return FALSE; pCir = CIRPTR(pScrn); pCir->pScrn = pScrn; pCir->PIOReg = hwp->PIOOffset + 0x3CE; /* Get the entity, and make sure it is PCI. */ pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (pCir->pEnt->location.type != BUS_PCI) return FALSE; pCir->Chipset = pCir->pEnt->chipset; /* Find the PCI info for this screen */ pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index); pCir->PciTag = pciTag(pCir->PciInfo->bus, pCir->PciInfo->device, pCir->PciInfo->func); if (xf86LoadSubModule(pScrn, "int10")) { xf86Int10InfoPtr int10InfoPtr; xf86LoaderReqSymLists(int10Symbols, NULL); int10InfoPtr = xf86InitInt10(pCir->pEnt->index); if (int10InfoPtr) xf86FreeInt10(int10InfoPtr); } /* Set pScrn->monitor */ pScrn->monitor = pScrn->confScreen->monitor; /* * The first thing we should figure out is the depth, bpp, etc. * We support both 24bpp and 32bpp layouts, so indicate that. */ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb | SupportConvert32to24 | PreferConvert32to24)) { return FALSE; } /* Check that the returned depth is one we support */ switch (pScrn->depth) { case 8: case 15: case 16: case 24: case 32: /* OK */ break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported by this driver\n", pScrn->depth); return FALSE; } xf86PrintDepthBpp(pScrn); /* Get the depth24 pixmap format */ if (pScrn->depth == 24 && pix24bpp == 0) pix24bpp = xf86GetBppFromDepth(pScrn, 24); /* * This must happen after pScrn->display has been set because * xf86SetWeight references it. */ if (pScrn->depth > 8) { /* The defaults are OK for us */ rgb zeros = {0, 0, 0}; /* !!! I think we can force 5-6-5 weight for 16bpp here for the 5462. */ if (!xf86SetWeight(pScrn, zeros, zeros)) { return FALSE; } else { /* XXX check that weight returned is supported */ ; } } if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; /* Collect all of the relevant option flags (fill in pScrn->options) */ xf86CollectOptions(pScrn, NULL); /* Process the options */ if (!(pCir->Options = xalloc(sizeof(LgOptions)))) return FALSE; memcpy(pCir->Options, LgOptions, sizeof(LgOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options); pScrn->rgbBits = 6; from = X_DEFAULT; pCir->HWCursor = FALSE; if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor)) from = X_CONFIG; xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", pCir->HWCursor ? "HW" : "SW"); if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) { pCir->NoAccel = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); } if (pScrn->bitsPerPixel < 8) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot use in less than 8 bpp\n"); return FALSE; } /* * Set the ChipRev, allowing config file entries to * override. */ if (pCir->pEnt->device->chipRev >= 0) { pCir->ChipRev = pCir->pEnt->device->chipRev; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", pCir->ChipRev); } else { pCir->ChipRev = pCir->PciInfo->chipRev; } /* Cirrus swapped the FB and IO registers in the 5465 (by design). */ if (PCI_CHIP_GD5465 == pCir->Chipset) { fbPCIReg = 0; ioPCIReg = 1; } else { fbPCIReg = 1; ioPCIReg = 0; } /* Find the frame buffer base address */ if (pCir->pEnt->device->MemBase != 0) { /* Require that the config file value matches one of the PCI values. */ if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MemBase 0x%08lX doesn't match any PCI base register.\n", pCir->pEnt->device->MemBase); return FALSE; } pCir->FbAddress = pCir->pEnt->device->MemBase; from = X_CONFIG; } else { if (pCir->PciInfo->memBase[fbPCIReg] != 0) { pCir->FbAddress = pCir->PciInfo->memBase[fbPCIReg] & 0xff000000; from = X_PROBED; } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid FB address in PCI config space\n"); LgFreeRec(pScrn); return FALSE; } } xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", (unsigned long)pCir->FbAddress); /* Find the MMIO base address */ if (pCir->pEnt->device->IOBase != 0) { /* Require that the config file value matches one of the PCI values. */ if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IOBase 0x%08lX doesn't match any PCI base register.\n", pCir->pEnt->device->IOBase); return FALSE; } pCir->IOAddress = pCir->pEnt->device->IOBase; from = X_CONFIG; } else { if (pCir->PciInfo->memBase[ioPCIReg] != 0) { pCir->IOAddress = pCir->PciInfo->memBase[ioPCIReg] & 0xfffff000; from = X_PROBED; } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address in PCI config space\n"); } } xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", (unsigned long)pCir->IOAddress); /* * If the user has specified the amount of memory in the XF86Config * file, we respect that setting. */ if (pCir->pEnt->device->videoRam != 0) { pScrn->videoRam = pCir->pEnt->device->videoRam; from = X_CONFIG; } else { pScrn->videoRam = LgCountRam(pScrn); from = X_PROBED; } if (2048 == pScrn->videoRam) { /* Two-way interleaving */ pCir->chip.lg->memInterleave = 0x40; } else if (4096 == pScrn->videoRam || 8192 == pScrn->videoRam) { /* Four-way interleaving */ pCir->chip.lg->memInterleave = 0x80; } else { /* One-way interleaving */ pCir->chip.lg->memInterleave = 0x00; } xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam); pCir->FbMapSize = pScrn->videoRam * 1024; pCir->IoMapSize = 0x4000; /* 16K for moment, will increase */ pScrn->racIoFlags = RAC_COLORMAP #ifndef EXPERIMENTAL | RAC_VIEWPORT #endif ; xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr); /* Register the PCI-assigned resources. */ if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86RegisterResources() found resource conflicts\n"); return FALSE; } if (!xf86LoadSubModule(pScrn, "ddc")) { LgFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(ddcSymbols, NULL); #if LGuseI2C if (!xf86LoadSubModule(pScrn, "i2c")) { LgFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(i2cSymbols, NULL); #endif /* Read and print the monitor DDC information */ pScrn->monitor->DDC = LgDoDDC(pScrn); /* The gamma fields must be initialised when using the new cmap code */ if (pScrn->depth > 1) { Gamma zeros = {0.0, 0.0, 0.0}; if (!xf86SetGamma(pScrn, zeros)) return FALSE; } if (xf86GetOptValBool(pCir->Options, OPTION_SHADOW_FB,&pCir->shadowFB)) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", pCir->shadowFB ? "enabled" : "disabled"); if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) { if(!xf86NameCmp(s, "CW")) { /* accel is disabled below for shadowFB */ pCir->shadowFB = TRUE; pCir->rotate = 1; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen clockwise - acceleration disabled\n"); } else if(!xf86NameCmp(s, "CCW")) { pCir->shadowFB = TRUE; pCir->rotate = -1; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" "counter clockwise - acceleration disabled\n"); } else { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" "value for Option \"Rotate\"\n", s); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid options are \"CW\" or \"CCW\"\n"); } } if (pCir->shadowFB && !pCir->NoAccel) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW acceleration not supported with \"shadowFB\".\n"); pCir->NoAccel = TRUE; } if (pCir->rotate && pCir->HWCursor) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW cursor not supported with \"rotate\".\n"); pCir->HWCursor = FALSE; } /* We use a programmable clock */ pScrn->progClock = TRUE; /* XXX Set HW cursor use */ /* Set the min pixel clock */ pCir->MinClock = 12000; /* XXX Guess, need to check this */ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", pCir->MinClock / 1000); /* * If the user has specified ramdac speed in the XF86Config * file, we respect that setting. */ if (pCir->pEnt->device->dacSpeeds[0]) { ErrorF("Do not specify a Clocks line for Cirrus chips\n"); return FALSE; } else { int speed; int *p; switch (pCir->Chipset) { case PCI_CHIP_GD5462: p = gd5462_MaxClocks; break; case PCI_CHIP_GD5464: case PCI_CHIP_GD5464BD: p = gd5464_MaxClocks; break; case PCI_CHIP_GD5465: p = gd5465_MaxClocks; break; default: ErrorF("???\n"); return FALSE; } switch (pScrn->bitsPerPixel) { case 8: speed = p[1]; break; case 15: case 16: speed = p[2]; break; case 24: speed = p[3]; break; case 32: speed = p[4]; break; default: /* Should not get here */ speed = 0; break; } pCir->MaxClock = speed; from = X_PROBED; } xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", pCir->MaxClock / 1000); /* * Setup the ClockRanges, which describe what clock ranges are available, * and what sort of modes they can be used for. */ clockRanges = xnfcalloc(sizeof(ClockRange), 1); clockRanges->next = NULL; clockRanges->minClock = pCir->MinClock; clockRanges->maxClock = pCir->MaxClock; clockRanges->clockIndex = -1; /* programmable */ clockRanges->interlaceAllowed = FALSE; /* XXX check this */ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ clockRanges->ClockMulFactor = 1; clockRanges->ClockDivFactor = 1; clockRanges->PrivFlags = 0; /* Depending upon what sized tiles used, either 128 or 256. */ /* Aw, heck. Just say 128. */ pCir->Rounding = 128 >> pCir->BppShift; /* * xf86ValidateModes will check that the mode HTotal and VTotal values * don't exceed the chipset's limit if pScrn->maxHValue and * pScrn->maxVValue are set. Since our CIRValidMode() already takes * care of this, we don't worry about setting them here. */ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, LgLinePitches[pScrn->bitsPerPixel / 8 - 1], 0, 0, 128 * 8, 0, 0, /* Any virtual height is allowed. */ pScrn->display->virtualX, pScrn->display->virtualY, pCir->FbMapSize, LOOKUP_BEST_REFRESH); pCir->chip.lg->lineDataIndex = LgFindLineData(pScrn->displayWidth, pScrn->bitsPerPixel); if (i == -1) { LgFreeRec(pScrn); return FALSE; } /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrn); if (i == 0 || pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); LgFreeRec(pScrn); return FALSE; } /* * Set the CRTC parameters for all of the modes based on the type * of mode, and the chipset's interlace requirements. * * Calling this is required if the mode->Crtc* values are used by the * driver and if the driver doesn't provide code to set them. They * are not pre-initialised at all. */ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; /* Print the list of modes being used */ xf86PrintModes(pScrn); /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); /* Load bpp-specific modules */ switch (pScrn->bitsPerPixel) { case 8: case 16: case 24: case 32: if (xf86LoadSubModule(pScrn, "fb") == NULL) { LgFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(fbSymbols, NULL); break; } /* Load XAA if needed */ if (!pCir->NoAccel) { if (!xf86LoadSubModule(pScrn, "xaa")) { LgFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(xaaSymbols, NULL); } /* Load ramdac if needed */ if (pCir->HWCursor) { if (!xf86LoadSubModule(pScrn, "ramdac")) { LgFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(ramdacSymbols, NULL); } if (pCir->shadowFB) { if (!xf86LoadSubModule(pScrn, "shadowfb")) { LgFreeRec(pScrn); return FALSE; } xf86LoaderReqSymLists(shadowSymbols, NULL); } return TRUE; }