109885543Smrg/* 209885543SmrgCopyright (C) 2006 Dennis De Winter All Rights Reserved. 309885543SmrgCopyright (C) 2007 Alex Deucher All Rights Reserved. 409885543Smrg 509885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 609885543Smrgthis software and associated documentation files (the "Software"), to deal in 709885543Smrgthe Software without restriction, including without limitation the rights to 809885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 909885543Smrgof the Software, and to permit persons to whom the Software is furnished to do 1009885543Smrgso, subject to the following conditions: 1109885543Smrg 1209885543SmrgThe above copyright notice and this permission notice shall be included in all 1309885543Smrgcopies or substantial portions of the Software. 1409885543Smrg 1509885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1609885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 1709885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1809885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1909885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2009885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2109885543Smrg 2209885543Smrg*/ 2309885543Smrg 2409885543Smrg#ifdef HAVE_CONFIG_H 2509885543Smrg#include "config.h" 2609885543Smrg#endif 2709885543Smrg 2809885543Smrg#include "smi.h" 2909885543Smrg 307104f784Smrg#if SMI501_CLI_DEBUG 317104f784Smrg# include "smi_501.h" 327104f784Smrg# undef WRITE_DPR 337104f784Smrg# define WRITE_DPR(pSmi, dpr, data) \ 347104f784Smrg do { \ 357104f784Smrg if (pSmi->batch_active) \ 367104f784Smrg BATCH_LOAD_REG((pSmi->DPRBase - pSmi->MapBase) + \ 377104f784Smrg dpr, data); \ 387104f784Smrg else \ 397104f784Smrg MMIO_OUT32(pSmi->DPRBase, dpr, data); \ 407104f784Smrg DEBUG("DPR%02X = %08X\n", dpr, data); \ 417104f784Smrg } while (0) 427104f784Smrg#endif 4309885543Smrg 4409885543Smrgstatic void 4509885543SmrgSMI_EXASync(ScreenPtr pScreen, int marker); 4609885543Smrg 4709885543Smrgstatic Bool 4809885543SmrgSMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 4909885543Smrg int xdir, int ydir, int alu, Pixel planemask); 5009885543Smrg 5109885543Smrgstatic void 5209885543SmrgSMI_Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height); 5309885543Smrg 5409885543Smrgstatic void 5509885543SmrgSMI_DoneCopy(PixmapPtr pDstPixmap); 5609885543Smrg 5709885543Smrgstatic Bool 5809885543SmrgSMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg); 5909885543Smrg 6009885543Smrgstatic void 6109885543SmrgSMI_Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2); 6209885543Smrg 6309885543Smrgstatic void 6409885543SmrgSMI_DoneSolid(PixmapPtr pPixmap); 6509885543Smrg 6609885543SmrgBool 6709885543SmrgSMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); 6809885543Smrg 6909885543SmrgBool 7009885543SmrgSMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); 7109885543Smrg 727104f784Smrgstatic Bool 737104f784SmrgSMI_CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture); 747104f784Smrgstatic Bool 757104f784SmrgSMI_PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, 767104f784Smrg PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst); 777104f784Smrgstatic void 787104f784SmrgSMI_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 797104f784Smrg int dstX, int dstY, int width, int height); 807104f784Smrgstatic void 817104f784SmrgSMI730_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 827104f784Smrg int dstX, int dstY, int width, int height); 837104f784Smrgstatic void 847104f784SmrgSMI_DoneComposite(PixmapPtr pDst); 857104f784Smrg 867104f784Smrg 877104f784Smrg#define PIXMAP_FORMAT(pixmap) SMI_DEDataFormat(pixmap->drawable.bitsPerPixel) 887104f784Smrg#define PIXMAP_OFFSET(pixmap) IS_MSOC(pSmi) ? \ 897104f784Smrg exaGetPixmapOffset(pixmap) : exaGetPixmapOffset(pixmap) >> 3 907104f784Smrg 9109885543SmrgBool 9209885543SmrgSMI_EXAInit(ScreenPtr pScreen) 9309885543Smrg{ 94b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 9509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 9609885543Smrg 977104f784Smrg ENTER(); 9809885543Smrg 9909885543Smrg if (!(pSmi->EXADriverPtr = exaDriverAlloc())) { 10009885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate EXADriverRec.\n"); 1017104f784Smrg LEAVE(FALSE); 10209885543Smrg } 10309885543Smrg 1047104f784Smrg /* Require 2.1 semantics: 1057104f784Smrg Don't uninitialize the memory manager when swapping out */ 10609885543Smrg pSmi->EXADriverPtr->exa_major = 2; 1077104f784Smrg pSmi->EXADriverPtr->exa_minor = 1; 10809885543Smrg 10909885543Smrg SMI_EngineReset(pScrn); 11009885543Smrg 11109885543Smrg /* Memory Manager */ 1127104f784Smrg pSmi->EXADriverPtr->memoryBase = pSmi->FBBase; 1137104f784Smrg pSmi->EXADriverPtr->memorySize = pSmi->FBReserved; 1147104f784Smrg 1157104f784Smrg /* The framebuffer is allocated as an offscreen area with the 1167104f784Smrg memory manager (It makes easier further resizing) */ 1177104f784Smrg pSmi->EXADriverPtr->offScreenBase = 0; 11809885543Smrg 11909885543Smrg /* Flags */ 12009885543Smrg pSmi->EXADriverPtr->flags = EXA_TWO_BITBLT_DIRECTIONS; 12109885543Smrg if (pSmi->EXADriverPtr->memorySize > pSmi->EXADriverPtr->offScreenBase) { 12209885543Smrg /* Offscreen Pixmaps */ 12309885543Smrg pSmi->EXADriverPtr->flags |= EXA_OFFSCREEN_PIXMAPS; 12409885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1257104f784Smrg "EXA offscreen memory manager enabled.\n"); 1267104f784Smrg } 1277104f784Smrg else 12809885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 12909885543Smrg "Not enough video RAM for EXA offscreen memory manager.\n"); 13009885543Smrg 13109885543Smrg /* 12 bit coordinates */ 13209885543Smrg pSmi->EXADriverPtr->maxX = 4096; 13309885543Smrg pSmi->EXADriverPtr->maxY = 4096; 13409885543Smrg 1357104f784Smrg if (pScrn->bitsPerPixel == 24) { 1367104f784Smrg pSmi->EXADriverPtr->maxX = 4096 / 3; 1377104f784Smrg 1387104f784Smrg if (pSmi->Chipset == SMI_LYNX) { 1397104f784Smrg pSmi->EXADriverPtr->maxY = 4096 / 3; 1407104f784Smrg } 1417104f784Smrg } 1427104f784Smrg 14309885543Smrg pSmi->EXADriverPtr->pixmapPitchAlign = 16; 14409885543Smrg pSmi->EXADriverPtr->pixmapOffsetAlign = 8; 14509885543Smrg 14609885543Smrg /* Sync */ 14709885543Smrg pSmi->EXADriverPtr->WaitMarker = SMI_EXASync; 14809885543Smrg 14909885543Smrg /* Copy */ 15009885543Smrg pSmi->EXADriverPtr->PrepareCopy = SMI_PrepareCopy; 15109885543Smrg pSmi->EXADriverPtr->Copy = SMI_Copy; 15209885543Smrg pSmi->EXADriverPtr->DoneCopy = SMI_DoneCopy; 15309885543Smrg 15409885543Smrg /* Solid */ 15509885543Smrg pSmi->EXADriverPtr->PrepareSolid = SMI_PrepareSolid; 15609885543Smrg pSmi->EXADriverPtr->Solid = SMI_Solid; 15709885543Smrg pSmi->EXADriverPtr->DoneSolid = SMI_DoneSolid; 15809885543Smrg 15909885543Smrg#if 0 1607104f784Smrg /* DFS & UTS */ 16109885543Smrg pSmi->EXADriverPtr->UploadToScreen = SMI_UploadToScreen; 16209885543Smrg pSmi->EXADriverPtr->DownloadFromScreen = SMI_DownloadFromScreen; 16309885543Smrg#endif 16409885543Smrg 1657104f784Smrg /* Composite */ 1667104f784Smrg pSmi->EXADriverPtr->CheckComposite = SMI_CheckComposite; 1677104f784Smrg pSmi->EXADriverPtr->PrepareComposite = SMI_PrepareComposite; 1687104f784Smrg 1692ec8c4b4Smrg if (IS_MSOC(pSmi) || pSmi->Chipset == SMI_COUGAR3DR) 1707104f784Smrg pSmi->EXADriverPtr->Composite = SMI730_Composite; 1717104f784Smrg else 1727104f784Smrg pSmi->EXADriverPtr->Composite = SMI_Composite; 1732ec8c4b4Smrg 1747104f784Smrg pSmi->EXADriverPtr->DoneComposite = SMI_DoneComposite; 1757104f784Smrg 17609885543Smrg if(!exaDriverInit(pScreen, pSmi->EXADriverPtr)) { 17709885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "exaDriverInit failed.\n"); 1787104f784Smrg LEAVE(FALSE); 17909885543Smrg } 1807104f784Smrg 1817104f784Smrg 1827104f784Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA Acceleration enabled.\n"); 1837104f784Smrg 1847104f784Smrg LEAVE(TRUE); 18509885543Smrg} 18609885543Smrg 18709885543Smrgstatic void 18809885543SmrgSMI_EXASync(ScreenPtr pScreen, int marker) 18909885543Smrg{ 190b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 19109885543Smrg 1927104f784Smrg ENTER(); 19309885543Smrg 1947104f784Smrg SMI_AccelSync(pScrn); 19509885543Smrg 1967104f784Smrg LEAVE(); 19709885543Smrg} 19809885543Smrg 19909885543Smrg/* ----------------------------------------------------- EXA Copy ---------------------------------------------- */ 20009885543Smrg 20109885543SmrgCARD8 SMI_BltRop[16] = /* table stolen from KAA */ 20209885543Smrg{ 20309885543Smrg /* GXclear */ 0x00, /* 0 */ 20409885543Smrg /* GXand */ 0x88, /* src AND dst */ 20509885543Smrg /* GXandReverse */ 0x44, /* src AND NOT dst */ 20609885543Smrg /* GXcopy */ 0xCC, /* src */ 20709885543Smrg /* GXandInverted*/ 0x22, /* NOT src AND dst */ 20809885543Smrg /* GXnoop */ 0xAA, /* dst */ 20909885543Smrg /* GXxor */ 0x66, /* src XOR dst */ 21009885543Smrg /* GXor */ 0xEE, /* src OR dst */ 21109885543Smrg /* GXnor */ 0x11, /* NOT src AND NOT dst */ 21209885543Smrg /* GXequiv */ 0x99, /* NOT src XOR dst */ 21309885543Smrg /* GXinvert */ 0x55, /* NOT dst */ 21409885543Smrg /* GXorReverse */ 0xDD, /* src OR NOT dst */ 21509885543Smrg /* GXcopyInverted*/ 0x33, /* NOT src */ 21609885543Smrg /* GXorInverted */ 0xBB, /* NOT src OR dst */ 21709885543Smrg /* GXnand */ 0x77, /* NOT src OR NOT dst */ 21809885543Smrg /* GXset */ 0xFF, /* 1 */ 21909885543Smrg}; 22009885543Smrg 22109885543Smrgstatic Bool 22209885543SmrgSMI_PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, 22309885543Smrg int alu, Pixel planemask) 22409885543Smrg{ 225b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 22609885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 22709885543Smrg int src_pitch, dst_pitch; 22809885543Smrg unsigned long src_offset, dst_offset; 22909885543Smrg 2307104f784Smrg ENTER(); 2317104f784Smrg DEBUG("xdir=%d ydir=%d alu=%02X", xdir, ydir, alu); 23209885543Smrg 23309885543Smrg /* Bit Mask not supported > 16 bpp */ 23409885543Smrg if ((pSrcPixmap->drawable.bitsPerPixel > 16) && 2357104f784Smrg (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))) 2367104f784Smrg LEAVE(FALSE); 23709885543Smrg 23809885543Smrg /* calculate pitch in pixel unit */ 23909885543Smrg src_pitch = exaGetPixmapPitch(pSrcPixmap) / (pSrcPixmap->drawable.bitsPerPixel >> 3); 24009885543Smrg dst_pitch = exaGetPixmapPitch(pDstPixmap) / (pDstPixmap->drawable.bitsPerPixel >> 3); 24109885543Smrg /* calculate offset in 8 byte (64 bit) unit */ 2427104f784Smrg src_offset = PIXMAP_OFFSET(pSrcPixmap); 2437104f784Smrg dst_offset = PIXMAP_OFFSET(pDstPixmap); 24409885543Smrg 24509885543Smrg pSmi->AccelCmd = SMI_BltRop[alu] 24609885543Smrg | SMI_BITBLT 24709885543Smrg | SMI_QUICK_START; 24809885543Smrg 24909885543Smrg if (xdir < 0 || (ydir < 0)) { 25009885543Smrg pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT; 25109885543Smrg } 25209885543Smrg 25309885543Smrg if (pDstPixmap->drawable.bitsPerPixel == 24) { 25409885543Smrg src_pitch *= 3; 25509885543Smrg dst_pitch *= 3; 25609885543Smrg } 25709885543Smrg 2587104f784Smrg#if SMI501_CLI_DEBUG 2597104f784Smrg BATCH_BEGIN(7); 2607104f784Smrg#else 2617104f784Smrg WaitQueue(); 2627104f784Smrg#endif 2637104f784Smrg /* Destination and Source Window Widths */ 2647104f784Smrg WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 2657104f784Smrg /* Destination and Source Row Pitch */ 2667104f784Smrg WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 2677104f784Smrg 26809885543Smrg /* Bit Mask (planemask) - 16 bit only */ 26909885543Smrg if (pSrcPixmap->drawable.bitsPerPixel == 16) { 27009885543Smrg WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); 27109885543Smrg } else { 27209885543Smrg WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 27309885543Smrg } 27409885543Smrg /* Drawing engine data format */ 2757104f784Smrg WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pDstPixmap)); 27609885543Smrg /* Destination and Source Base Address (offset) */ 27709885543Smrg WRITE_DPR(pSmi, 0x40, src_offset); 27809885543Smrg WRITE_DPR(pSmi, 0x44, dst_offset); 27909885543Smrg 28009885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 2817104f784Smrg#if SMI501_CLI_DEBUG 2827104f784Smrg BATCH_END(); 2837104f784Smrg#endif 28409885543Smrg 2857104f784Smrg LEAVE(TRUE); 28609885543Smrg} 28709885543Smrg 28809885543Smrgstatic void 28909885543SmrgSMI_Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, 29009885543Smrg int dstY, int width, int height) 29109885543Smrg{ 292b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 29309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 29409885543Smrg 2957104f784Smrg ENTER(); 2967104f784Smrg DEBUG("srcX=%d srcY=%d dstX=%d dstY=%d width=%d height=%d\n", 2977104f784Smrg srcX, srcY, dstX, dstY, width, height); 29809885543Smrg 29909885543Smrg if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 30009885543Smrg srcX += width - 1; 30109885543Smrg srcY += height - 1; 30209885543Smrg dstX += width - 1; 30309885543Smrg dstY += height - 1; 30409885543Smrg } 30509885543Smrg 30609885543Smrg if (pDstPixmap->drawable.bitsPerPixel == 24) { 30709885543Smrg srcX *= 3; 30809885543Smrg dstX *= 3; 30909885543Smrg width *= 3; 31009885543Smrg 31109885543Smrg if (pSmi->Chipset == SMI_LYNX) { 31209885543Smrg srcY *= 3; 31309885543Smrg dstY *= 3; 31409885543Smrg } 31509885543Smrg 31609885543Smrg if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 31709885543Smrg srcX += 2; 31809885543Smrg dstX += 2; 31909885543Smrg } 32009885543Smrg } 32109885543Smrg 3227104f784Smrg#if SMI501_CLI_DEBUG 3237104f784Smrg BATCH_BEGIN(3); 3247104f784Smrg#else 3257104f784Smrg WaitQueue(); 3267104f784Smrg#endif 32709885543Smrg WRITE_DPR(pSmi, 0x00, (srcX << 16) + (srcY & 0xFFFF)); 32809885543Smrg WRITE_DPR(pSmi, 0x04, (dstX << 16) + (dstY & 0xFFFF)); 32909885543Smrg WRITE_DPR(pSmi, 0x08, (width << 16) + (height & 0xFFFF)); 3307104f784Smrg#if SMI501_CLI_DEBUG 3317104f784Smrg BATCH_END(); 3327104f784Smrg#endif 33309885543Smrg 3347104f784Smrg LEAVE(); 33509885543Smrg} 33609885543Smrg 33709885543Smrgstatic void 33809885543SmrgSMI_DoneCopy(PixmapPtr pDstPixmap) 33909885543Smrg{ 3407104f784Smrg ENTER(); 34109885543Smrg 3427104f784Smrg LEAVE(); 34309885543Smrg} 34409885543Smrg 34509885543Smrg/* ----------------------------------------------------- EXA Solid --------------------------------------------- */ 34609885543Smrg 34709885543SmrgCARD8 SMI_SolidRop[16] = /* table stolen from KAA */ 34809885543Smrg{ 34909885543Smrg /* GXclear */ 0x00, /* 0 */ 35009885543Smrg /* GXand */ 0xA0, /* src AND dst */ 35109885543Smrg /* GXandReverse */ 0x50, /* src AND NOT dst */ 35209885543Smrg /* GXcopy */ 0xF0, /* src */ 35309885543Smrg /* GXandInverted*/ 0x0A, /* NOT src AND dst */ 35409885543Smrg /* GXnoop */ 0xAA, /* dst */ 35509885543Smrg /* GXxor */ 0x5A, /* src XOR dst */ 35609885543Smrg /* GXor */ 0xFA, /* src OR dst */ 35709885543Smrg /* GXnor */ 0x05, /* NOT src AND NOT dst */ 35809885543Smrg /* GXequiv */ 0xA5, /* NOT src XOR dst */ 35909885543Smrg /* GXinvert */ 0x55, /* NOT dst */ 36009885543Smrg /* GXorReverse */ 0xF5, /* src OR NOT dst */ 36109885543Smrg /* GXcopyInverted*/ 0x0F, /* NOT src */ 36209885543Smrg /* GXorInverted */ 0xAF, /* NOT src OR dst */ 36309885543Smrg /* GXnand */ 0x5F, /* NOT src OR NOT dst */ 36409885543Smrg /* GXset */ 0xFF, /* 1 */ 36509885543Smrg}; 36609885543Smrg 36709885543Smrgstatic Bool 36809885543SmrgSMI_PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 36909885543Smrg{ 370b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 37109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 37209885543Smrg int dst_pitch; 37309885543Smrg unsigned long dst_offset; 37409885543Smrg 3757104f784Smrg ENTER(); 3767104f784Smrg DEBUG("alu=%02X\n", alu); 37709885543Smrg 37809885543Smrg /* HW ignores alpha */ 37909885543Smrg if (pPixmap->drawable.bitsPerPixel == 32) 3807104f784Smrg LEAVE(FALSE); 38109885543Smrg 38209885543Smrg /* Bit Mask not supported > 16 bpp */ 38309885543Smrg if ((pPixmap->drawable.bitsPerPixel > 16) && 3847104f784Smrg (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))) 3857104f784Smrg LEAVE(FALSE); 38609885543Smrg 38709885543Smrg /* calculate pitch in pixel unit */ 38809885543Smrg dst_pitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel >> 3); 38909885543Smrg /* calculate offset in 8 byte (64 bit) unit */ 3907104f784Smrg dst_offset = PIXMAP_OFFSET(pPixmap); 39109885543Smrg 39209885543Smrg pSmi->AccelCmd = SMI_SolidRop[alu] 39309885543Smrg | SMI_BITBLT 39409885543Smrg | SMI_QUICK_START; 39509885543Smrg 39609885543Smrg if (pPixmap->drawable.bitsPerPixel == 24) { 39709885543Smrg dst_pitch *= 3; 39809885543Smrg } 39909885543Smrg 4007104f784Smrg#if SMI501_CLI_DEBUG 4017104f784Smrg BATCH_BEGIN(10); 4027104f784Smrg#else 4037104f784Smrg WaitQueue(); 4047104f784Smrg#endif 4057104f784Smrg 4067104f784Smrg /* Destination Window Width */ 4077104f784Smrg WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); 4087104f784Smrg /* Destination Row Pitch */ 4097104f784Smrg WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (dst_pitch & 0xFFFF)); 4107104f784Smrg 41109885543Smrg /* Bit Mask (planemask) - 16 bit only */ 41209885543Smrg if (pPixmap->drawable.bitsPerPixel == 16) { 41309885543Smrg WRITE_DPR(pSmi, 0x28, planemask | 0xFFFF0000); 41409885543Smrg } else { 41509885543Smrg WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 41609885543Smrg } 41709885543Smrg 41809885543Smrg /* Drawing engine data format */ 4197104f784Smrg WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pPixmap)); 42009885543Smrg /* Source and Destination Base Address (offset) */ 42109885543Smrg WRITE_DPR(pSmi, 0x40, dst_offset); 42209885543Smrg WRITE_DPR(pSmi, 0x44, dst_offset); 42309885543Smrg /* Foreground Color */ 42409885543Smrg WRITE_DPR(pSmi, 0x14, fg); 42509885543Smrg /* Mono Pattern High and Low */ 42609885543Smrg WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF); 42709885543Smrg WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF); 42809885543Smrg 42909885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 4307104f784Smrg#if SMI501_CLI_DEBUG 4317104f784Smrg BATCH_END(); 4327104f784Smrg#endif 43309885543Smrg 4347104f784Smrg LEAVE(TRUE); 43509885543Smrg} 43609885543Smrg 43709885543Smrgstatic void 43809885543SmrgSMI_Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 43909885543Smrg{ 440b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 44109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 44209885543Smrg int w, h; 44309885543Smrg 4447104f784Smrg ENTER(); 4457104f784Smrg DEBUG("x1=%d y1=%d x2=%d y2=%d\n", x1, y1, x2, y2); 44609885543Smrg 44709885543Smrg w = (x2 - x1); 44809885543Smrg h = (y2 - y1); 44909885543Smrg 45009885543Smrg if (pPixmap->drawable.bitsPerPixel == 24) { 45109885543Smrg x1 *= 3; 45209885543Smrg w *= 3; 45309885543Smrg 45409885543Smrg if (pSmi->Chipset == SMI_LYNX) { 45509885543Smrg y1 *= 3; 45609885543Smrg } 45709885543Smrg } 45809885543Smrg 4597104f784Smrg#if SMI501_CLI_DEBUG 4607104f784Smrg BATCH_BEGIN(2); 4617104f784Smrg#else 4627104f784Smrg WaitQueue(); 4637104f784Smrg#endif 46409885543Smrg WRITE_DPR(pSmi, 0x04, (x1 << 16) | (y1 & 0xFFFF)); 46509885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 4667104f784Smrg#if SMI501_CLI_DEBUG 4677104f784Smrg BATCH_END(); 4687104f784Smrg#endif 46909885543Smrg 4707104f784Smrg LEAVE(); 47109885543Smrg} 47209885543Smrg 47309885543Smrgstatic void 47409885543SmrgSMI_DoneSolid(PixmapPtr pPixmap) 47509885543Smrg{ 4767104f784Smrg ENTER(); 47709885543Smrg 4787104f784Smrg LEAVE(); 47909885543Smrg} 48009885543Smrg 48109885543Smrg/* --------------------------------------- EXA DFS & UTS ---------------------------------------- */ 48209885543Smrg 48309885543SmrgBool 48409885543SmrgSMI_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 48509885543Smrg char *dst, int dst_pitch) 48609885543Smrg{ 48709885543Smrg unsigned char *src = pSrc->devPrivate.ptr; 48809885543Smrg int src_pitch = exaGetPixmapPitch(pSrc); 48909885543Smrg 4907104f784Smrg ENTER(); 4917104f784Smrg DEBUG("x=%d y=%d w=%d h=%d dst=%d dst_pitch=%d\n", 4927104f784Smrg x, y, w, h, dst, dst_pitch); 4937104f784Smrg 49409885543Smrg exaWaitSync(pSrc->drawable.pScreen); 49509885543Smrg 4967104f784Smrg src += (y * src_pitch) + (x * pSrc->drawable.bitsPerPixel/8); 4977104f784Smrg w *= pSrc->drawable.bitsPerPixel/8; 49809885543Smrg 49909885543Smrg while (h--) { 50009885543Smrg memcpy(dst, src, w); 50109885543Smrg src += src_pitch; 50209885543Smrg dst += dst_pitch; 50309885543Smrg } 50409885543Smrg 5057104f784Smrg LEAVE(TRUE); 50609885543Smrg} 50709885543Smrg 50809885543SmrgBool 50909885543SmrgSMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 51009885543Smrg char *src, int src_pitch) 51109885543Smrg{ 512b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 51309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 5147104f784Smrg int dst_pixelpitch, src_pixelpitch, align, aligned_pitch; 51509885543Smrg unsigned long dst_offset; 51609885543Smrg 5177104f784Smrg ENTER(); 5187104f784Smrg DEBUG("x=%d y=%d w=%d h=%d src=%d src_pitch=%d\n", 5197104f784Smrg x, y, w, h, src, src_pitch); 5207104f784Smrg 5217104f784Smrg if (pDst->drawable.bitsPerPixel == 24) { 5227104f784Smrg align = 16; 5237104f784Smrg } else { 5247104f784Smrg align = 128 / pDst->drawable.bitsPerPixel; 5257104f784Smrg } 5267104f784Smrg 5277104f784Smrg aligned_pitch = ((w*pDst->drawable.bitsPerPixel >> 3) + align - 1) & ~(align - 1); 52809885543Smrg 52909885543Smrg /* calculate pitch in pixel unit */ 5307104f784Smrg dst_pixelpitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); 5317104f784Smrg src_pixelpitch = src_pitch / (pDst->drawable.bitsPerPixel >> 3); 53209885543Smrg /* calculate offset in 8 byte (64 bit) unit */ 5337104f784Smrg dst_offset = PIXMAP_OFFSET(pDst); 53409885543Smrg 53509885543Smrg pSmi->AccelCmd = 0xCC /* GXcopy */ 53609885543Smrg | SMI_HOSTBLT_WRITE 53709885543Smrg | SMI_QUICK_START; 53809885543Smrg 5397104f784Smrg /* set clipping */ 5407104f784Smrg SMI_SetClippingRectangle(pScrn, x, y, x+w, y+h); 54109885543Smrg 5427104f784Smrg#if SMI501_CLI_DEBUG 5437104f784Smrg BATCH_BEGIN(9); 5447104f784Smrg#else 5457104f784Smrg WaitQueue(); 5467104f784Smrg#endif 5477104f784Smrg /* Destination and Source Window Widths */ 5487104f784Smrg WRITE_DPR(pSmi, 0x3C, (dst_pixelpitch << 16) | (src_pixelpitch & 0xFFFF)); 54909885543Smrg 55009885543Smrg if (pDst->drawable.bitsPerPixel == 24) { 55109885543Smrg x *= 3; 55209885543Smrg w *= 3; 5537104f784Smrg dst_pixelpitch *= 3; 55409885543Smrg if (pSmi->Chipset == SMI_LYNX) { 55509885543Smrg y *= 3; 55609885543Smrg } 55709885543Smrg } 55809885543Smrg 5597104f784Smrg /* Source and Destination Row Pitch */ 5607104f784Smrg WRITE_DPR(pSmi, 0x10, (dst_pixelpitch << 16) | (src_pixelpitch & 0xFFFF)); 56109885543Smrg /* Drawing engine data format */ 5627104f784Smrg WRITE_DPR(pSmi, 0x1C,PIXMAP_FORMAT(pDst)); 5637104f784Smrg /* Source and Destination Base Address (offset) */ 5647104f784Smrg WRITE_DPR(pSmi, 0x40, 0); 56509885543Smrg WRITE_DPR(pSmi, 0x44, dst_offset); 56609885543Smrg 56709885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 56809885543Smrg WRITE_DPR(pSmi, 0x00, 0); 5697104f784Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 57009885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 5717104f784Smrg#if SMI501_CLI_DEBUG 5727104f784Smrg BATCH_END(); 5737104f784Smrg#endif 57409885543Smrg 5757104f784Smrg while (h--) { 5767104f784Smrg memcpy(pSmi->DataPortBase, src, aligned_pitch); 5777104f784Smrg src += src_pitch; 57809885543Smrg } 57909885543Smrg 58009885543Smrg /* disable clipping */ 5817104f784Smrg SMI_DisableClipping(pScrn); 58209885543Smrg 58309885543Smrg exaWaitSync(pDst->drawable.pScreen); 58409885543Smrg 5857104f784Smrg LEAVE(TRUE); 5867104f784Smrg} 5877104f784Smrg 5887104f784Smrg/* --------------------------------------- EXA Composite ---------------------------------------- */ 5897104f784Smrg/* This is a very incomplete Composite implementation that only 5907104f784Smrg accelerates PictOpSrc with source coordinates transformation by 5917104f784Smrg using 2D Engine rotate-BITBLTs */ 59209885543Smrg 5937104f784Smrg#define SMI_ISROTATION_90(t) \ 5947104f784Smrg (t->matrix[0][0] == 0 && t->matrix[0][1] == xFixed1 && \ 5957104f784Smrg t->matrix[1][0] == -xFixed1 && t->matrix[1][1] == 0) 5967104f784Smrg 5977104f784Smrg#define SMI_ISROTATION_270(t) \ 5987104f784Smrg (t->matrix[0][0] == 0 && t->matrix[0][1] == -xFixed1 && \ 5997104f784Smrg t->matrix[1][0] == xFixed1 && t->matrix[1][1] == 0) 6007104f784Smrg 6017104f784Smrgstatic Bool 6027104f784SmrgSMI_CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) 6037104f784Smrg{ 6047104f784Smrg ENTER(); 6057104f784Smrg 6067104f784Smrg if(op!=PictOpSrc || pMaskPicture || 6077104f784Smrg pSrcPicture->repeatType || !pSrcPicture->transform) 6087104f784Smrg LEAVE(FALSE); 6097104f784Smrg 6107104f784Smrg if(!SMI_ISROTATION_90(pSrcPicture->transform) && 6117104f784Smrg !SMI_ISROTATION_270(pSrcPicture->transform)) 6127104f784Smrg LEAVE(FALSE); 6137104f784Smrg 6147104f784Smrg if(PICT_FORMAT_BPP(pSrcPicture->format) == 24) 6157104f784Smrg LEAVE(FALSE); 6167104f784Smrg 6177104f784Smrg LEAVE(TRUE); 61809885543Smrg} 61909885543Smrg 6207104f784Smrgstatic Bool 6217104f784SmrgSMI_PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, 6227104f784Smrg PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 6237104f784Smrg{ 624b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 6257104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 626f395c03eSmrg 627f395c03eSmrg if (!pSrc) return FALSE; 628f395c03eSmrg if (!pSrcPicture->pDrawable) return FALSE; 629f395c03eSmrg 6307104f784Smrg int src_pitch = exaGetPixmapPitch(pSrc) / (pSrc->drawable.bitsPerPixel >> 3); 6317104f784Smrg int dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); 6327104f784Smrg 6337104f784Smrg ENTER(); 6347104f784Smrg 6357104f784Smrg#if SMI501_CLI_DEBUG 6367104f784Smrg BATCH_BEGIN(7); 6377104f784Smrg#else 6387104f784Smrg WaitQueue(); 6397104f784Smrg#endif 6407104f784Smrg 6417104f784Smrg /* Destination and Source Window Widths */ 6427104f784Smrg WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 6437104f784Smrg 6447104f784Smrg /* Destination and Source Row Pitch */ 6457104f784Smrg WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (src_pitch & 0xFFFF)); 6467104f784Smrg 6477104f784Smrg /* Drawing engine data format */ 6487104f784Smrg WRITE_DPR(pSmi, 0x1C, PIXMAP_FORMAT(pDst)); 6497104f784Smrg 6507104f784Smrg /* DE Bit Mask */ 6517104f784Smrg WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF); 6527104f784Smrg 6537104f784Smrg /* Destination and Source Base Address (offset) */ 6547104f784Smrg WRITE_DPR(pSmi, 0x40, PIXMAP_OFFSET(pSrc)); 6557104f784Smrg WRITE_DPR(pSmi, 0x44, PIXMAP_OFFSET(pDst)); 6567104f784Smrg 6577104f784Smrg /* DE command*/ 6587104f784Smrg if(SMI_ISROTATION_90(pSrcPicture->transform)) 6597104f784Smrg WRITE_DPR(pSmi, 0x0C, 0xCC /*GXCopy*/ | SMI_ROTATE_BLT | 6607104f784Smrg SMI_ROTATE_CW | SMI_QUICK_START); 6617104f784Smrg else 6627104f784Smrg WRITE_DPR(pSmi, 0x0C, 0xCC /*GXCopy*/ | SMI_ROTATE_BLT | 6637104f784Smrg SMI_ROTATE_CCW | SMI_QUICK_START); 6647104f784Smrg 6657104f784Smrg#if SMI501_CLI_DEBUG 6667104f784Smrg BATCH_END(); 6677104f784Smrg#endif 6687104f784Smrg 6697104f784Smrg pSmi->renderTransform = pSrcPicture->transform; 6707104f784Smrg 6717104f784Smrg LEAVE(TRUE); 6727104f784Smrg} 6737104f784Smrg 6747104f784Smrgstatic void 6757104f784SmrgSMI_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 6767104f784Smrg int dstX, int dstY, int width, int height) 6777104f784Smrg{ 678b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 6797104f784Smrg SMIPtr pSmi = SMIPTR(pScrn); 6807104f784Smrg PictTransformPtr t = pSmi->renderTransform; 6817104f784Smrg PictVector v; 6827104f784Smrg 6837104f784Smrg ENTER(); 6847104f784Smrg 6857104f784Smrg if(SMI_ISROTATION_90(t)){ 6867104f784Smrg srcX=srcX+width; 6877104f784Smrg dstX=dstX+width-1; 6887104f784Smrg }else{ 6897104f784Smrg srcY=srcY+height; 6907104f784Smrg dstY=dstY+height-1; 6917104f784Smrg } 6927104f784Smrg 6937104f784Smrg v.vector[0] = IntToxFixed(srcX); 6947104f784Smrg v.vector[1] = IntToxFixed(srcY); 6957104f784Smrg v.vector[2] = xFixed1; 6967104f784Smrg PictureTransformPoint(t, &v); 6977104f784Smrg 6987104f784Smrg#if SMI501_CLI_DEBUG 6997104f784Smrg BATCH_BEGIN(3); 7007104f784Smrg#else 7017104f784Smrg WaitQueue(); 7027104f784Smrg#endif 7037104f784Smrg 7047104f784Smrg WRITE_DPR(pSmi, 0x00, (xFixedToInt(v.vector[0]) << 16) + (xFixedToInt(v.vector[1]) & 0xFFFF)); 7057104f784Smrg WRITE_DPR(pSmi, 0x04, (dstX << 16) + (dstY & 0xFFFF)); 7067104f784Smrg WRITE_DPR(pSmi, 0x08, (height << 16) + (width & 0xFFFF)); 7077104f784Smrg#if SMI501_CLI_DEBUG 7087104f784Smrg BATCH_END(); 7097104f784Smrg#endif 7107104f784Smrg 7117104f784Smrg LEAVE(); 7127104f784Smrg} 7137104f784Smrg 7147104f784Smrgstatic void 7157104f784SmrgSMI730_Composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 7167104f784Smrg int dstX, int dstY, int width, int height) 7177104f784Smrg{ 718b12e5c03Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 7192ec8c4b4Smrg SMIPtr pSmi = SMIPTR(pScrn); 7207104f784Smrg int maxPixels; 7217104f784Smrg 7227104f784Smrg ENTER(); 7237104f784Smrg 7242ec8c4b4Smrg /* Both SM501 and SM731 cannot rotate-blt more than a certain 7252ec8c4b4Smrg number of pixels. */ 7262ec8c4b4Smrg if(IS_MSOC(pSmi)) 7272ec8c4b4Smrg maxPixels = 128 / pDst->drawable.bitsPerPixel; 7282ec8c4b4Smrg else 7292ec8c4b4Smrg maxPixels = 1280 / pDst->drawable.bitsPerPixel; 7307104f784Smrg 7317104f784Smrg while(height>0){ 7327104f784Smrg SMI_Composite(pDst, srcX, srcY, maskX, maskY, dstX, dstY, width, min(height, maxPixels)); 7337104f784Smrg 7347104f784Smrg srcY += maxPixels; 7357104f784Smrg dstY += maxPixels; 7367104f784Smrg height -= maxPixels; 7377104f784Smrg } 7387104f784Smrg 7397104f784Smrg LEAVE(); 7407104f784Smrg} 7417104f784Smrg 7427104f784Smrgstatic void 7437104f784SmrgSMI_DoneComposite(PixmapPtr pDst) 7447104f784Smrg{ 7457104f784Smrg ENTER(); 7467104f784Smrg LEAVE(); 7477104f784Smrg} 748