smi_crtc.c revision 7104f784
17104f784Smrg/* 27104f784SmrgCopyright (C) 2008 Francisco Jerez. All Rights Reserved. 37104f784Smrg 47104f784SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 57104f784Smrgthis software and associated documentation files (the "Software"), to deal in 67104f784Smrgthe Software without restriction, including without limitation the rights to 77104f784Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 87104f784Smrgof the Software, and to permit persons to whom the Software is furnished to do 97104f784Smrgso, subject to the following conditions: 107104f784Smrg 117104f784SmrgThe above copyright notice and this permission notice shall be included in all 127104f784Smrgcopies or substantial portions of the Software. 137104f784Smrg 147104f784SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157104f784SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 167104f784SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 177104f784SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 187104f784SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 197104f784SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 207104f784Smrg*/ 217104f784Smrg 227104f784Smrg#ifdef HAVE_CONFIG_H 237104f784Smrg#include "config.h" 247104f784Smrg#endif 257104f784Smrg 267104f784Smrg#include "smi.h" 277104f784Smrg#include "smi_crtc.h" 287104f784Smrg#include "smilynx.h" 297104f784Smrg#include "smi_501.h" 307104f784Smrg 317104f784Smrgstatic void 327104f784SmrgSMI_CrtcDPMS(xf86CrtcPtr crtc, 337104f784Smrg int mode) 347104f784Smrg{ 357104f784Smrg ENTER(); 367104f784Smrg 377104f784Smrg /* Nothing */ 387104f784Smrg 397104f784Smrg LEAVE(); 407104f784Smrg} 417104f784Smrg 427104f784Smrgstatic Bool 437104f784SmrgSMI_CrtcLock (xf86CrtcPtr crtc) 447104f784Smrg{ 457104f784Smrg ScrnInfoPtr pScrn = crtc->scrn; 467104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 477104f784Smrg 487104f784Smrg ENTER(); 497104f784Smrg 507104f784Smrg WaitIdle(); 517104f784Smrg 527104f784Smrg LEAVE(FALSE); 537104f784Smrg} 547104f784Smrg 557104f784Smrgstatic void 567104f784SmrgSMI_CrtcUnlock (xf86CrtcPtr crtc) 577104f784Smrg{ 587104f784Smrg ENTER(); 597104f784Smrg 607104f784Smrg /* Nothing */ 617104f784Smrg 627104f784Smrg LEAVE(); 637104f784Smrg} 647104f784Smrg 657104f784Smrgstatic Bool 667104f784SmrgSMI_CrtcModeFixup(xf86CrtcPtr crtc, 677104f784Smrg DisplayModePtr mode, 687104f784Smrg DisplayModePtr adjusted_mode) 697104f784Smrg{ 707104f784Smrg ENTER(); 717104f784Smrg 727104f784Smrg /* Nothing */ 737104f784Smrg 747104f784Smrg LEAVE(TRUE); 757104f784Smrg} 767104f784Smrg 777104f784Smrgstatic void 787104f784SmrgSMI_CrtcPrepare(xf86CrtcPtr crtc) 797104f784Smrg{ 807104f784Smrg ENTER(); 817104f784Smrg LEAVE(); 827104f784Smrg} 837104f784Smrg 847104f784Smrgstatic void 857104f784SmrgSMI_CrtcCommit(xf86CrtcPtr crtc) 867104f784Smrg{ 877104f784Smrg ENTER(); 887104f784Smrg 897104f784Smrg crtc->funcs->dpms(crtc,DPMSModeOn); 907104f784Smrg 917104f784Smrg LEAVE(); 927104f784Smrg} 937104f784Smrg 947104f784Smrgstatic void 957104f784SmrgSMI_CrtcGammaSet(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 967104f784Smrg int size) 977104f784Smrg{ 987104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); 997104f784Smrg int i; 1007104f784Smrg 1017104f784Smrg ENTER(); 1027104f784Smrg 1037104f784Smrg for(i=0; i<256; i++){ 1047104f784Smrg crtcPriv->lut_r[i] = red[i * size >> 8]; 1057104f784Smrg crtcPriv->lut_g[i] = green[i * size >> 8]; 1067104f784Smrg crtcPriv->lut_b[i] = blue[i * size >> 8]; 1077104f784Smrg } 1087104f784Smrg 1097104f784Smrg crtcPriv->load_lut(crtc); 1107104f784Smrg 1117104f784Smrg LEAVE(); 1127104f784Smrg} 1137104f784Smrg 1147104f784Smrgstatic void * 1157104f784SmrgSMI_CrtcShadowAllocate (xf86CrtcPtr crtc, int width, int height) 1167104f784Smrg{ 1177104f784Smrg ScrnInfoPtr pScrn = crtc->scrn; 1187104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1197104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); 1207104f784Smrg int offset, size; 1217104f784Smrg 1227104f784Smrg ENTER(); 1237104f784Smrg 1247104f784Smrg size = ((width * pSmi->Bpp + 15) & ~15) * height; 1257104f784Smrg offset = SMI_AllocateMemory(pScrn, &crtcPriv->shadowArea, size); 1267104f784Smrg 1277104f784Smrg if (!crtcPriv->shadowArea) 1287104f784Smrg LEAVE(NULL); 1297104f784Smrg 1307104f784Smrg LEAVE(pSmi->FBBase + offset); 1317104f784Smrg} 1327104f784Smrg 1337104f784Smrgstatic PixmapPtr 1347104f784SmrgSMI_CrtcShadowCreate (xf86CrtcPtr crtc, void *data, int width, int height) 1357104f784Smrg{ 1367104f784Smrg ScrnInfoPtr pScrn = crtc->scrn; 1377104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1387104f784Smrg int aligned_pitch; 1397104f784Smrg 1407104f784Smrg ENTER(); 1417104f784Smrg 1427104f784Smrg aligned_pitch = (width * pSmi->Bpp + 15) & ~15; 1437104f784Smrg 1447104f784Smrg LEAVE(GetScratchPixmapHeader(pScrn->pScreen,width,height,pScrn->depth, 1457104f784Smrg pScrn->bitsPerPixel,aligned_pitch,data)); 1467104f784Smrg} 1477104f784Smrg 1487104f784Smrgstatic void 1497104f784SmrgSMI_CrtcShadowDestroy (xf86CrtcPtr crtc, PixmapPtr pPixmap, void *data) 1507104f784Smrg{ 1517104f784Smrg ScrnInfoPtr pScrn = crtc->scrn; 1527104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1537104f784Smrg SMICrtcPrivatePtr crtcPriv = SMICRTC(crtc); 1547104f784Smrg 1557104f784Smrg ENTER(); 1567104f784Smrg 1577104f784Smrg if (pSmi->useEXA && pPixmap) 1587104f784Smrg FreeScratchPixmapHeader(pPixmap); 1597104f784Smrg 1607104f784Smrg if (crtcPriv->shadowArea) { 1617104f784Smrg SMI_FreeMemory(pScrn, crtcPriv->shadowArea); 1627104f784Smrg crtcPriv->shadowArea = NULL; 1637104f784Smrg } 1647104f784Smrg 1657104f784Smrg LEAVE(); 1667104f784Smrg} 1677104f784Smrg 1687104f784Smrgstatic void 1697104f784SmrgSMI_CrtcDestroy (xf86CrtcPtr crtc) 1707104f784Smrg{ 1717104f784Smrg ENTER(); 1727104f784Smrg 1737104f784Smrg xfree(SMICRTC(crtc)); 1747104f784Smrg xfree(crtc->funcs); 1757104f784Smrg 1767104f784Smrg LEAVE(); 1777104f784Smrg} 1787104f784Smrg 1797104f784Smrgstatic Bool 1807104f784SmrgSMI_CrtcConfigResize(ScrnInfoPtr pScrn, 1817104f784Smrg int width, 1827104f784Smrg int height) 1837104f784Smrg{ 1847104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 1857104f784Smrg xf86CrtcConfigPtr crtcConf = XF86_CRTC_CONFIG_PTR(pScrn); 1867104f784Smrg int i; 1877104f784Smrg xf86CrtcPtr crtc; 1887104f784Smrg 1897104f784Smrg ENTER(); 1907104f784Smrg 1917104f784Smrg /* Allocate another offscreen area and use it as screen, if it really has to be resized */ 1927104f784Smrg if(!pSmi->NoAccel && pSmi->useEXA && 1937104f784Smrg ( !pSmi->fbArea || width != pScrn->virtualX || height != pScrn->virtualY )){ 1947104f784Smrg int aligned_pitch = (width*pSmi->Bpp + 15) & ~15; 1957104f784Smrg 1967104f784Smrg ExaOffscreenArea* fbArea = exaOffscreenAlloc(pScrn->pScreen, aligned_pitch*height, 16, TRUE, NULL, NULL); 1977104f784Smrg if(!fbArea){ 1987104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1997104f784Smrg "SMI_CrtcConfigResize: Not enough memory to resize the framebuffer\n"); 2007104f784Smrg LEAVE(FALSE); 2017104f784Smrg } 2027104f784Smrg 2037104f784Smrg if(pSmi->fbArea) 2047104f784Smrg exaOffscreenFree(pScrn->pScreen, pSmi->fbArea); 2057104f784Smrg 2067104f784Smrg pSmi->fbArea = fbArea; 2077104f784Smrg pSmi->FBOffset = fbArea->offset; 2087104f784Smrg pScrn->fbOffset = pSmi->FBOffset + pSmi->fbMapOffset; 2097104f784Smrg 2107104f784Smrg pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen), 2117104f784Smrg -1,-1,-1,-1,-1, pSmi->FBBase + pSmi->FBOffset); 2127104f784Smrg 2137104f784Smrg if(pScrn->pixmapPrivate.ptr) 2147104f784Smrg /* The pixmap devPrivate just set may be overwritten by 2157104f784Smrg xf86EnableDisableFBAccess */ 2167104f784Smrg pScrn->pixmapPrivate.ptr = pSmi->FBBase + pSmi->FBOffset; 2177104f784Smrg 2187104f784Smrg /* Modify the screen pitch */ 2197104f784Smrg pScrn->displayWidth = aligned_pitch / pSmi->Bpp; 2207104f784Smrg pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen), 2217104f784Smrg -1, -1, -1, -1, aligned_pitch, NULL); 2227104f784Smrg 2237104f784Smrg /* Modify the screen dimensions */ 2247104f784Smrg pScrn->virtualX = width; 2257104f784Smrg pScrn->virtualY = height; 2267104f784Smrg pScrn->pScreen->ModifyPixmapHeader(pScrn->pScreen->GetScreenPixmap(pScrn->pScreen), 2277104f784Smrg width, height, -1, -1, 0, NULL); 2287104f784Smrg } 2297104f784Smrg 2307104f784Smrg /* Setup each crtc video processor */ 2317104f784Smrg for(i=0;i<crtcConf->num_crtc;i++){ 2327104f784Smrg crtc = crtcConf->crtc[i]; 2337104f784Smrg SMICRTC(crtc)->video_init(crtc); 2347104f784Smrg SMICRTC(crtc)->adjust_frame(crtc,crtc->x,crtc->y); 2357104f784Smrg } 2367104f784Smrg 2377104f784Smrg LEAVE(TRUE); 2387104f784Smrg} 2397104f784Smrg 2407104f784Smrgvoid 2417104f784SmrgSMI_CrtcFuncsInit_base(xf86CrtcFuncsPtr* crtcFuncs, SMICrtcPrivatePtr* crtcPriv){ 2427104f784Smrg *crtcFuncs = xnfcalloc(sizeof(xf86CrtcFuncsRec), 1); 2437104f784Smrg *crtcPriv = xnfcalloc(sizeof(SMICrtcPrivateRec), 1); 2447104f784Smrg 2457104f784Smrg (*crtcFuncs)->dpms = SMI_CrtcDPMS; 2467104f784Smrg (*crtcFuncs)->lock = SMI_CrtcLock; 2477104f784Smrg (*crtcFuncs)->unlock = SMI_CrtcUnlock; 2487104f784Smrg (*crtcFuncs)->mode_fixup = SMI_CrtcModeFixup; 2497104f784Smrg (*crtcFuncs)->prepare = SMI_CrtcPrepare; 2507104f784Smrg (*crtcFuncs)->commit = SMI_CrtcCommit; 2517104f784Smrg (*crtcFuncs)->gamma_set = SMI_CrtcGammaSet; 2527104f784Smrg (*crtcFuncs)->shadow_allocate = SMI_CrtcShadowAllocate; 2537104f784Smrg (*crtcFuncs)->shadow_create = SMI_CrtcShadowCreate; 2547104f784Smrg (*crtcFuncs)->shadow_destroy = SMI_CrtcShadowDestroy; 2557104f784Smrg (*crtcFuncs)->destroy = SMI_CrtcDestroy; 2567104f784Smrg} 2577104f784Smrg 2587104f784Smrgstatic xf86CrtcConfigFuncsRec SMI_CrtcConfigFuncs = { 2597104f784Smrg .resize = SMI_CrtcConfigResize 2607104f784Smrg}; 2617104f784Smrg 2627104f784SmrgBool 2637104f784SmrgSMI_CrtcPreInit(ScrnInfoPtr pScrn) 2647104f784Smrg{ 2657104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 2667104f784Smrg 2677104f784Smrg ENTER(); 2687104f784Smrg 2697104f784Smrg xf86CrtcConfigInit(pScrn,&SMI_CrtcConfigFuncs); 2707104f784Smrg 2717104f784Smrg xf86CrtcSetSizeRange(pScrn,128,128,4096,4096); 2727104f784Smrg 2737104f784Smrg if(SMI_MSOC_SERIES(pSmi->Chipset)){ 2747104f784Smrg LEAVE( SMI501_CrtcPreInit(pScrn) ); 2757104f784Smrg }else{ 2767104f784Smrg LEAVE( SMILynx_CrtcPreInit(pScrn) ); 2777104f784Smrg } 2787104f784Smrg} 279