aboutsummaryrefslogblamecommitdiffstats
blob: b140aa589613b56f0162ff30ec73c520d071904b (plain) (tree)



































                                                                              
                    














                                                    
                                    
                        







                                        
                                                            










                                           



                                                              




                     





                                 







                                                                   



                                     



                                


                                     














                                                                                    

                   
                          
 
                 


















































































                                                                                                             
                                             



           
/*
 * Copyright (c) 2014, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/eventfd.h>
#include <pthread.h>

#include "memplugin.h"
#include "libdce.h"

#include <xf86drm.h>
#include <omap_drm.h>
#include <omap_drmif.h>
#include <utils/Log.h>


#define LINUX_PAGE_SIZE 4096
#define INVALID_DRM_FD (-1)

int                    OmapDrm_FD  = INVALID_DRM_FD;
struct omap_device    *OmapDev     = NULL;
extern pthread_mutex_t    ipc_mutex;
extern int is_ipc_ready;

int memplugin_open()
{
    if (OmapDev)
        return MEM_EOK;

    /* Open omapdrm device */
    if( OmapDrm_FD == INVALID_DRM_FD ) {
	OmapDrm_FD = open("/dev/dri/renderD128", O_RDWR, 0);
        if(OmapDrm_FD <= 0) {
            ALOGE("omapdrm open failed\n");
            return MEM_EOPEN_FAILURE;
        }
    }
    OmapDev = omap_device_new(OmapDrm_FD);
    if(OmapDev == NULL) {
        close(OmapDrm_FD);
        return MEM_EOPEN_FAILURE;
    }

    pthread_mutexattr_t attr;
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&ipc_mutex, &attr);

    return MEM_EOK;
}

int memplugin_close()
{
    if (OmapDev) {
        omap_device_del(OmapDev);
        OmapDev = NULL;
    }

    if (OmapDrm_FD > 0) {
        close(OmapDrm_FD);
        OmapDrm_FD = INVALID_DRM_FD;
    }

    /* this ipc client is not associated with any codec engine
    * this channel is used only for GEM buffer register/unregister,
    * hence call deinit with -1 for the engine table index
    */

    /*Acquire permission to use IPC*/
    pthread_mutex_lock(&ipc_mutex);

    if (is_ipc_ready) {
        dce_ipc_deinit(IPU, -1);
        is_ipc_ready = 0;
    }

    /*Relinquish IPC*/
    pthread_mutex_unlock(&ipc_mutex);

    return MEM_EOK;
}


void *memplugin_alloc(int sz, int height, MemRegion region, int align, int flags)
{
    MemHeader        *h = NULL;
    struct omap_bo   *bo = omap_bo_new(OmapDev, sz + sizeof(MemHeader), OMAP_BO_WC);

    if( !bo ) {
        return (NULL);
    }

    h = omap_bo_map(bo);

    h->ptr = h + 1;
    memset(H2P(h), 0, sz);

    h->size = sz;
    /* get the fd from drm which needs to be closed by memplugin_free */
    h->dma_buf_fd = omap_bo_dmabuf(bo);
    h->region = region;
    h->flags = flags;/*Beware: This is a bit field.*/
    h->handle = (void*)bo;
    h->offset = 0;

    dce_buf_lock(1, (size_t *)&(h->dma_buf_fd));

    return (H2P(h));

}

void memplugin_free(void *ptr)
{
    if( ptr ) {
        MemHeader   *h = P2H(ptr);
        if( h->dma_buf_fd ) {
            dce_buf_unlock(1, (size_t *)&(h->dma_buf_fd));
            /* close the file descriptor */
            close(h->dma_buf_fd);
        }
        /*Finally, Delete the buffer object*/
        omap_bo_del((struct omap_bo *)h->handle);
        ptr = NULL;
    }

    return;
}

int32_t memplugin_share(void *ptr)
{
    if (!ptr)
        return MEM_EINVALID_INPUT;

    MemHeader *h = P2H(ptr);
    return h->dma_buf_fd;

}

void *memplugin_alloc_noheader(MemHeader *memHdr, int sz, int height, MemRegion region, int align, int flags)
{
    MemHeader *h = memHdr;
    if (!memHdr)
        return NULL;

    struct omap_bo   *bo = omap_bo_new(OmapDev, sz, OMAP_BO_WC);

    if( !bo ) {
        return (NULL);
    }

    h->ptr = omap_bo_map(bo);

    memset(h->ptr, 0, sz);

    h->size = sz;
    h->handle = (void *)bo;
    /* get the fd from drm which needs to be closed by memplugin_free */
    h->dma_buf_fd = omap_bo_dmabuf(bo);
    h->region = region;
    h->flags = flags;/*Beware: This is a bit field.*/
    h->offset = 0;

    dce_buf_lock(1, (size_t *)&(h->dma_buf_fd));

    return (h->ptr);

}

void memplugin_free_noheader(MemHeader *memHdr)
{
    if (!memHdr)
        return;

    MemHeader *h = memHdr;
    if( h->dma_buf_fd ) {
        dce_buf_unlock(1, (size_t *)&(h->dma_buf_fd));
        /* close the file descriptor */
        close(h->dma_buf_fd);
    }

    /*Finally, Delete the buffer object*/
    omap_bo_del((struct omap_bo *)h->handle);

    return;
}