diff options
Diffstat (limited to 'src/mali_exa.c')
-rw-r--r-- | src/mali_exa.c | 523 |
1 files changed, 523 insertions, 0 deletions
diff --git a/src/mali_exa.c b/src/mali_exa.c new file mode 100644 index 0000000..5138e62 --- /dev/null +++ b/src/mali_exa.c @@ -0,0 +1,523 @@ +/* + * Copyright (C) 2010 ARM Limited. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "mali_exa.h" +#include "mali_fbdev.h" + +static struct mali_info mi; + +#ifdef USE_TRACING +#define TRACE_ENTER() xf86DrvMsg(mi.pScrn->scrnIndex, X_INFO, "%s: ENTER\n", __FUNCTION__) +#define TRACE_EXIT() xf86DrvMsg(mi.pScrn->scrnIndex, X_INFO, "%s: EXIT\n", __FUNCTION__) +#else +#define TRACE_ENTER() +#define TRACE_EXIT() +#endif + +#define MALI_EXA_FUNC(s) exa->s = mali ## s +#define IGNORE( a ) ( a = a ); +#define MALI_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) + +static int fd_fbdev = -1; + +static Bool maliPrepareSolid( PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg ) +{ + TRACE_ENTER(); + IGNORE( pPixmap ); + IGNORE( alu ); + IGNORE( planemask ); + IGNORE( fg ); + TRACE_EXIT(); + + return FALSE; +} + +static void maliSolid( PixmapPtr pPixmap, int x1, int y1, int x2, int y2 ) +{ + TRACE_ENTER(); + IGNORE( pPixmap ); + IGNORE( x1 ); + IGNORE( y1 ); + IGNORE( x2 ); + IGNORE( y2 ); + TRACE_EXIT(); +} + +static void maliDoneSolid( PixmapPtr pPixmap ) +{ + TRACE_ENTER(); + IGNORE( pPixmap ); + TRACE_EXIT(); +} + +static Bool maliPrepareCopy( PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask ) +{ + TRACE_ENTER(); + IGNORE( pSrcPixmap ); + IGNORE( pDstPixmap ); + IGNORE( xdir ); + IGNORE( ydir ); + IGNORE( alu ); + IGNORE( planemask ); + TRACE_EXIT(); + + return FALSE; +} + +static void maliCopy( PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height ) +{ + TRACE_ENTER(); + IGNORE( pDstPixmap ); + IGNORE( srcX ); + IGNORE( srcY ); + IGNORE( dstX ); + IGNORE( dstY ); + IGNORE( width ); + IGNORE( height ); + TRACE_EXIT(); +} + +static void maliDoneCopy( PixmapPtr pDstPixmap ) +{ + TRACE_ENTER(); + IGNORE( pDstPixmap ); + TRACE_EXIT(); +} + +static void maliWaitMarker( ScreenPtr pScreen, int marker ) +{ + TRACE_ENTER(); + IGNORE( pScreen ); + IGNORE( marker ); + TRACE_EXIT(); +} + +static void* maliCreatePixmap(ScreenPtr pScreen, int size, int align ) +{ + PrivPixmap *privPixmap = calloc(1, sizeof(PrivPixmap)); + + TRACE_ENTER(); + IGNORE( pScreen ); + IGNORE( size ); + IGNORE( align ); + privPixmap->bits_per_pixel = 0; + TRACE_EXIT(); + + return privPixmap; +} + +static void maliDestroyPixmap(ScreenPtr pScreen, void *driverPriv ) +{ + PrivPixmap *privPixmap = (PrivPixmap *)driverPriv; + + TRACE_ENTER(); + IGNORE( pScreen ); + if ( NULL != privPixmap->mem_info ) + { + ump_reference_release(privPixmap->mem_info->handle); + free( privPixmap->mem_info ); + privPixmap->mem_info = NULL; + free( privPixmap ); + } + TRACE_EXIT(); +} + +static Bool maliModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) +{ + unsigned int size; + PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPixmap); + mali_mem_info *mem_info; + + TRACE_ENTER(); + + if (!pPixmap) + { + TRACE_EXIT(); + return FALSE; + } + + miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); + + if (pPixData == mi.fb_virt) + { + ump_secure_id ump_id = UMP_INVALID_SECURE_ID; + + privPixmap->isFrameBuffer = TRUE; + + mem_info = privPixmap->mem_info; + if ( mem_info ) + { + TRACE_EXIT(); + return TRUE; + } + + /* create new mem_info for the on-screen buffer */ + mem_info = calloc(1, sizeof(*mem_info)); + if (!mem_info) + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] failed to allocate for memory metadata\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + + /* get the secure ID for the framebuffer */ + (void)ioctl( fd_fbdev, GET_UMP_SECURE_ID, &ump_id ); + + if ( UMP_INVALID_SECURE_ID == ump_id) + { + free( mem_info ); + privPixmap->mem_info = NULL; + xf86DrvMsg( mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] UMP failed to retrieve secure id\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + + mem_info->handle = ump_handle_create_from_secure_id( ump_id ); + if ( UMP_INVALID_MEMORY_HANDLE == mem_info->handle ) + { + xf86DrvMsg( mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] UMP failed to create handle from secure id\n", __FUNCTION__, __LINE__); + free( mem_info ); + privPixmap->mem_info = NULL; + TRACE_EXIT(); + return FALSE; + } + + size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height; + mem_info->usize = size; + + privPixmap->mem_info = mem_info; + if( bitsPerPixel != 0 ) privPixmap->bits_per_pixel = bitsPerPixel; + + TRACE_EXIT(); + return TRUE; + } + else + { + privPixmap->isFrameBuffer = FALSE; + } + + if ( pPixData ) + { + if ( privPixmap->mem_info != NULL ) + { + TRACE_EXIT(); + return TRUE; + } + + TRACE_EXIT(); + return FALSE; + } + + pPixmap->devKind = ( (pPixmap->drawable.width*pPixmap->drawable.bitsPerPixel) + 7 ) / 8; + pPixmap->devKind = MALI_ALIGN( pPixmap->devKind, 8 ); + + size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height; + + /* allocate pixmap data */ + mem_info = privPixmap->mem_info; + + if ( mem_info && mem_info->usize == size ) + { + TRACE_EXIT(); + return TRUE; + } + + if ( mem_info && mem_info->usize != 0 ) + { + ump_reference_release(mem_info->handle); + mem_info->handle = NULL; + memset(privPixmap, 0, sizeof(*privPixmap)); + + TRACE_EXIT(); + return TRUE; + } + + if (!size) + { + TRACE_EXIT(); + return TRUE; + } + + if ( NULL == mem_info ) + { + mem_info = calloc(1, sizeof(*mem_info)); + if (!mem_info) + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] failed to allocate memory metadata\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + } + + mem_info->handle = ump_ref_drv_allocate( size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR ); + if ( UMP_INVALID_MEMORY_HANDLE == mem_info->handle ) + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] failed to allocate UMP memory (%i bytes)\n", __FUNCTION__, __LINE__, size); + TRACE_EXIT(); + return FALSE; + } + + mem_info->usize = size; + privPixmap->mem_info = mem_info; + privPixmap->mem_info->usize = size; + privPixmap->bits_per_pixel = 16; + + TRACE_EXIT(); + + return TRUE; +} + +static Bool maliPixmapIsOffscreen( PixmapPtr pPix ) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPix); + + TRACE_ENTER(); + + if (pScreen->GetScreenPixmap(pScreen) == pPix ) + { + TRACE_EXIT(); + return TRUE; + } + + if ( privPixmap ) + { + TRACE_EXIT(); + return pPix->devPrivate.ptr ? FALSE : TRUE; + } + + TRACE_EXIT(); + + return FALSE; +} + +static Bool maliPrepareAccess(PixmapPtr pPix, int index) +{ + PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPix); + mali_mem_info *mem_info; + + TRACE_ENTER(); + IGNORE( index ); + + if ( !privPixmap ) + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] Failed to get private pixmap data\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + + + mem_info = privPixmap->mem_info; + if ( NULL != mem_info ) + { + if ( privPixmap->refs == 0 ) + { + privPixmap->addr = (unsigned long)ump_mapped_pointer_get( mem_info->handle ); + } + } + else + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] No mem_info on pixmap\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + + pPix->devPrivate.ptr = (void *)(privPixmap->addr); + if ( NULL == pPix->devPrivate.ptr ) + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] cpu address not set\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + + privPixmap->refs++; + TRACE_EXIT(); + + return TRUE; +} + +static void maliFinishAccess(PixmapPtr pPix, int index) +{ + PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPix); + mali_mem_info *mem_info; + + TRACE_ENTER(); + IGNORE( index ); + + if ( !privPixmap ) + { + TRACE_EXIT(); + return; + } + + if ( !pPix ) + { + TRACE_EXIT(); + return; + } + + mem_info = privPixmap->mem_info; + + if ( !privPixmap->isFrameBuffer ) + { + if ( privPixmap->refs == 1 ) + { + if ( NULL != mem_info ) ump_mapped_pointer_release( mem_info->handle ); + } + } + + pPix->devPrivate.ptr = NULL; + privPixmap->refs--; + + TRACE_EXIT(); +} + +static Bool maliCheckComposite( int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture ) +{ + TRACE_ENTER(); + IGNORE( op ); + IGNORE( pSrcPicture ); + IGNORE( pMaskPicture ); + IGNORE( pDstPicture ); + TRACE_EXIT(); + + return FALSE; +} + +static Bool maliPrepareComposite( int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrcPixmap, PixmapPtr pMask, PixmapPtr pDstPixmap ) +{ + TRACE_ENTER(); + IGNORE( op ); + IGNORE( pSrcPicture ); + IGNORE( pMaskPicture ); + IGNORE( pDstPicture ); + IGNORE( pSrcPixmap ); + IGNORE( pMask ); + IGNORE( pDstPixmap ); + TRACE_EXIT(); + + return FALSE; +} + +static void maliComposite( PixmapPtr pDstPixmap, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) +{ + TRACE_ENTER(); + IGNORE( pDstPixmap ); + IGNORE( srcX ); + IGNORE( srcY ); + IGNORE( maskX ); + IGNORE( maskY ); + IGNORE( dstX ); + IGNORE( dstY ); + IGNORE( width ); + IGNORE( height ); + TRACE_EXIT(); +} + +static void maliDoneComposite( PixmapPtr pDst ) +{ + TRACE_ENTER(); + IGNORE( pDst ); + TRACE_EXIT(); +} + + +static void maliDumpInfo() +{ + xf86DrvMsg(mi.pScrn->scrnIndex, X_INFO, "XRES: %i YRES: %i PHYS: 0x%x VIRT: 0x%x\n", mi.fb_xres, mi.fb_yres, (int)mi.fb_phys, (int)mi.fb_virt); +} + +Bool maliSetupExa( ScreenPtr pScreen, ExaDriverPtr exa, int xres, int yres, unsigned char *virt ) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MaliPtr fPtr = MALIPTR(pScrn); + + if ( NULL == exa ) return FALSE; + + memset(&mi, 0, sizeof(mi)); + mi.pScrn = pScrn; + mi.fb_xres = xres; + mi.fb_yres = yres; + mi.fb_phys = pScrn->memPhysBase; + mi.fb_virt = virt; + + TRACE_ENTER(); + + maliDumpInfo(); + + exa->exa_major = 2; + exa->exa_minor = 0; + exa->memoryBase = fPtr->fbmem; + exa->maxX = fPtr->fb_lcd_var.xres_virtual; + exa->maxY = fPtr->fb_lcd_var.yres_virtual; + exa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS | EXA_SUPPORTS_PREPARE_AUX; + exa->offScreenBase = (fPtr->fb_lcd_fix.line_length*fPtr->fb_lcd_var.yres); + exa->memorySize = fPtr->fb_lcd_fix.smem_len; + exa->pixmapOffsetAlign = 4096; + exa->pixmapPitchAlign = 8; + + fd_fbdev = fPtr->fb_lcd_fd; + + maliDumpInfo(); + + MALI_EXA_FUNC(PrepareSolid); + MALI_EXA_FUNC(Solid); + MALI_EXA_FUNC(DoneSolid); + + MALI_EXA_FUNC(PrepareCopy); + MALI_EXA_FUNC(Copy); + MALI_EXA_FUNC(DoneCopy); + + MALI_EXA_FUNC(CheckComposite); + MALI_EXA_FUNC(PrepareComposite); + MALI_EXA_FUNC(Composite); + MALI_EXA_FUNC(DoneComposite); + + MALI_EXA_FUNC(WaitMarker); + + MALI_EXA_FUNC(CreatePixmap); + MALI_EXA_FUNC(DestroyPixmap); + MALI_EXA_FUNC(ModifyPixmapHeader); + MALI_EXA_FUNC(PixmapIsOffscreen); + + MALI_EXA_FUNC(PrepareAccess); + MALI_EXA_FUNC(FinishAccess); + + if ( UMP_OK != ump_open() ) + { + xf86DrvMsg(mi.pScrn->scrnIndex, X_ERROR, "[%s:%d] failed to open UMP subsystem\n", __FUNCTION__, __LINE__); + TRACE_EXIT(); + return FALSE; + } + + + xf86DrvMsg(mi.pScrn->scrnIndex, X_INFO, "Mali EXA driver is loaded successfully\n"); + TRACE_EXIT(); + + return TRUE; +} |