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