/*
 * Project Name MFC DRIVER IN WINCE
 * Copyright  2009 Samsung Electronics Co, Ltd. All Rights Reserved.
 *
 * This file implements MFC driver.
 *
 * @name MFC DRIVER Module (MfcMemory.c)
 * @author Jiyoung Shin (idon.shin@samsung.com)
 * @date 2009/06/05
 */

#include <windows.h>
#include <bsp.h>
#include <ceddk.h>
#include "MfcMemory.h"
#include "MfcLogMsg.h"
#include "mfc_reg.h"
#include "MfcInterface.h"
#include "image_cfg.h"
#include "CMMAPI.h"

static volatile MFC_SFR   *virMFCSfr= NULL;
static volatile unsigned char     *virFWBuf= NULL;
static unsigned int phyFWAddr;

static void *Phy2VirAddrMapping(unsigned int phy_addr, int mem_size);
static BOOL MfcSfrMemMapping();
static BOOL MfcFWBufMemMapping();

static void *Phy2VirAddrMapping(unsigned int phy_addr, int mem_size)
{
    void *mappedAddr = NULL;

    mappedAddr = DrvLib_MapIoSpace(phy_addr, mem_size, FALSE);
    if (mappedAddr == NULL)
    {
        LOG_MSG(LOG_ERROR, "Phy2Vir_AddrMapping", "Mapping Failed [PA:0x%08x]\r\n", phy_addr);
        return FALSE;
    }
    return mappedAddr;
}


static BOOL MfcSfrMemMapping()
{
    virMFCSfr = (volatile MFC_SFR *)Phy2VirAddrMapping(GetSfrPhyAddr(), MFC_SFR_BUF_SIZE);
    
    if (virMFCSfr == NULL)
    {
        LOG_MSG(LOG_ERROR, "MfcSfrMapping", "For MFC_SFR: VirtualAlloc failed!\r\n");
        return FALSE;
    }

    return TRUE;
}


static BOOL MfcFWBufMemMapping()
{
    CMM_ALLOC_PRAM_T    CMMParam;
    HANDLE              hCMMOpen;
    int                 r;

    //CMM init
    hCMMOpen = CreateFile(L"CMM1:",
                            GENERIC_READ|GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL);
    if (hCMMOpen == INVALID_HANDLE_VALUE)
    {
        LOG_MSG(LOG_ERROR, "MfcFWBufMemMapping", "CMM Open failure\n");
        return FALSE;
    }
    
    // allocation of Y Frame buffer
    CMMParam.size = (unsigned int)MFC_FW_BUFF_SIZE;
    CMMParam.cacheFlag = 0;
    CMMParam.dramLocation = DRAM_0;

    r = DeviceIoControl(hCMMOpen, IOCTL_CODEC_MEM_ALLOC, (PBYTE)&CMMParam, 
                        sizeof(CMM_ALLOC_PRAM_T *), &virFWBuf, sizeof(virFWBuf), 
                        NULL, NULL);
    if(r == FALSE)
    {
        LOG_MSG(LOG_ERROR, "SsbSipMfcDecInit", "IOCTL_CODEC_MEM_ALLOC failed\n");
        return FALSE;
    }

    LOG_MSG(LOG_WARNING, "MfcFWBufMemMapping", "virFWBuf : %08x\n", virFWBuf);
    
    r = DeviceIoControl(hCMMOpen, IOCTL_CODEC_GET_PHY_ADDR, (PBYTE)virFWBuf, 
                        sizeof(virFWBuf), &phyFWAddr, sizeof(phyFWAddr), 
                        NULL, NULL);
    if(r == FALSE)
    {
        LOG_MSG(LOG_ERROR, "SsbSipMfcDecInit", "IOCTL_CODEC_GET_PHY_ADDR failed\n");
        return FALSE;
    }
    LOG_MSG(LOG_WARNING, "MfcFWBufMemMapping", "phyFWAddr : %08x\n", phyFWAddr);

    return TRUE;

}


BOOL MFCMemorySetup()
{

    BOOL ret_sfr, ret_dat;

    ret_sfr = MfcSfrMemMapping();
    if (ret_sfr == FALSE) {
        LOG_MSG(LOG_ERROR, "MfcMemorySetup", "MFC SFR Memory mapping fail!\r\n");
        return FALSE;
    }

    ret_dat = MfcFWBufMemMapping();
    if (ret_dat == FALSE) {
        LOG_MSG(LOG_ERROR, "MfcMemorySetup", "Data buffer Memory mapping fail!\r\n");
        return FALSE;
    }

    return TRUE;
}


volatile MFC_SFR *GetSfrVirAddr()
{
    return (volatile MFC_SFR *)virMFCSfr;    
}

volatile unsigned char *GetFWCodeBufVirAddr()
{
    return (volatile unsigned char *)virFWBuf;      
}

volatile unsigned char * GetFWCtxBufVirAddr(int instanceNo)
{
#ifdef POWER_CNTRL
    return (volatile unsigned char *)(GetFWCodeBufVirAddr() + MFC_FIRMWARE_CODE_SIZE\
                          + (instanceNo-1)*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE));   
#else
    return (volatile unsigned char *)(GetFWCodeBufVirAddr() + MFC_FIRMWARE_CODE_SIZE\
                          + instanceNo*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE));

#endif
}
volatile unsigned char * GetSharedMemVirAddr(int instanceNo)
{
#ifdef POWER_CNTRL
    return (volatile unsigned char *)(GetFWCodeBufVirAddr() + MFC_FIRMWARE_CODE_SIZE\
                          + (instanceNo-1)*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE))
                          + MFC_FW_DEC_BUFF_SIZE
                          - MFC_DEC_SHARED_MEMORY_SIZE;   
#else
    return (volatile unsigned char *)(GetFWCodeBufVirAddr() + MFC_FIRMWARE_CODE_SIZE\
                          + instanceNo*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE))
                          + MFC_FW_DEC_BUFF_SIZE
                          - MFC_DEC_SHARED_MEMORY_SIZE; 
#endif
}
unsigned int GetSfrPhyAddr()
{
    return (unsigned int)BASE_REG_PA_MFC;
}

unsigned int GetFWCodeBufPhyAddr()
{
    return (unsigned int)phyFWAddr;      
}

unsigned int GetFWDataBufPhyAddr(int instanceNo)
{
#ifdef POWER_CNTRL
    return (unsigned int)(phyFWAddr + MFC_FIRMWARE_CODE_SIZE\
                          + (instanceNo-1)*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE))
                          + MFC_FIRMWARE_INSTANCE_BUFF_SIZE;   
#else
    return (unsigned int)(phyFWAddr + MFC_FIRMWARE_CODE_SIZE\
                          + instanceNo*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE))
                          + MFC_FIRMWARE_INSTANCE_BUFF_SIZE;

#endif
}
unsigned int GetFWCtxBufPhyAddr(int instanceNo)
{
#ifdef POWER_CNTRL
    return (unsigned int)(phyFWAddr + MFC_FIRMWARE_CODE_SIZE\
                          + (instanceNo-1)*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE));   
#else
    return (unsigned int)(phyFWAddr + MFC_FIRMWARE_CODE_SIZE\
                          + instanceNo*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE));

#endif
}

unsigned int GetSharedMemPhyAddr(int instanceNo)
{
#ifdef POWER_CNTRL
    return (unsigned int)(phyFWAddr + MFC_FIRMWARE_CODE_SIZE\
                          + (instanceNo-1)*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE))
                          + MFC_FW_DEC_BUFF_SIZE
                          - MFC_DEC_SHARED_MEMORY_SIZE;   
#else
    return (unsigned int)(phyFWAddr + MFC_FIRMWARE_CODE_SIZE\
                          + instanceNo*(MFC_FIRMWARE_INSTANCE_BUFF_SIZE + MFC_FW_DEC_BUFF_SIZE + MFC_FW_ENC_BUFF_SIZE))
                          + MFC_FW_DEC_BUFF_SIZE
                          - MFC_DEC_SHARED_MEMORY_SIZE; 
#endif
}
unsigned int GetDramAPhyBaseAddr()
{
    return (unsigned int)GetFWCodeBufPhyAddr();
}

unsigned int GetDramBPhyBaseAddr()
{
    return (unsigned int)DRAM_BASE_PA_START;;
}





