mfcdriver.cpp

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 847 行 · 第 1/2 页

CPP
847
字号
#include <windows.h>
#include <nkintr.h>
#include <oal_intr.h>
#include <pm.h>
#include <pmplatform.h>


#include "MfcDriver.h"
#include "MfcPwrMgmt.h"
#include "MfcSetClk.h"
#include "MfcDrvParams.h"

#include "MfcConfig.h"

#include "MFC_HW_Init.h"
#include "MFC_Instance.h"
#include "MFC_Inst_Pool.h"
#include "MfcSfr.h"
#include "DataBuf.h"

#include "LogMsg.h"

#include "MfcMutex.h"
#include "MfcIntrNotification.h"

static BOOL InitializeIST();
static LONG _openhandle_count = 0;

extern int MFC_GetConfigParams(MFCInstCtx  *pMfcInst, MFC_ARGS   *args);
extern int MFC_SetConfigParams(MFCInstCtx  *pMfcInst, MFC_ARGS   *args);


typedef struct _MFC_HANDLE
{
	MFCInstCtx  *mfc_inst;

#if (_WIN32_WCE >= 600)
	HANDLE          hUsrProc;	// Used for virtual address conversion (WCE600 or higher)
	unsigned char  *pStrmBuf;	// STRM_BUF pointer (virtual address of Application)
	unsigned char  *pFramBuf;	// FRAM_BUF pointer (virtual address of Application)
#endif
} MFC_HANDLE;



BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
	switch ( dwReason )
	{
	case DLL_PROCESS_ATTACH:

		DisableThreadLibraryCalls((HMODULE) hInstDll);
		break;

	}

	return (TRUE);
}


//  1. Mutex Creation
//  2. MFC Hardware Initialization
DWORD
MFC_Init(
    DWORD dwContext
    )
{
	/////////////////////////
	//  1. Mutex Creation  //
	/////////////////////////
	if (MFC_Mutex_Create() == FALSE)
		return FALSE;

	///////////////////////////
	//  2. MFC Memory Setup  //
	///////////////////////////
	if (MFC_MemorySetup() == FALSE)
		return FALSE;


	/////////////////////////////////////////
	//  3. MFC Clock divider configuration //
	/////////////////////////////////////////
	if (Mfc_Set_ClkDiv(2) == FALSE)
		return FALSE;


	// Turn on MFC Power & Clock
	Mfc_Pwr_On();
	Mfc_Clk_On();

	//////////////////////////////////////
	//  4. MFC Hardware Initialization  //
	//////////////////////////////////////
	if (MFC_HW_Init() == FALSE)
		return FALSE;

	// Turn off MFC Power & Clock
	Mfc_Clk_Off();
	Mfc_Pwr_Off();

	///////////////////////////////////////////////////////
	//  5. IST(Interrupt Service Thread) Initialization  //
	///////////////////////////////////////////////////////
	if (InitializeIST() == FALSE)
		return FALSE;


	// Number of open handle
	_openhandle_count = 0;

	return 0x9224033;
}


//  1. Mutex Deletion
BOOL
MFC_Deinit(
    DWORD InitHandle
    )
{
	MFC_Mutex_Delete();

	return TRUE;
}


#define  MFC_POWER_HANDLE_VALUE		(0x05080273)

DWORD
MFC_Open(
	DWORD InitHandle,
	DWORD dwAccess,
	DWORD dwShareMode
    )
{
	MFC_HANDLE   *handle;
	static BOOL   is_first_call = TRUE;


	// The first call of this function is not by the MFC application
	// but by the Power Manager in the booting process.
	// Therefore, the MFC instance is not created
	// and the specific value (MFC_POWER_HANDLE_VALUE) is returned.
	if (is_first_call) {
		is_first_call = FALSE;
		return MFC_POWER_HANDLE_VALUE;
	}

	// Mutex Lock
	MFC_Mutex_Lock();


	////////////////
	// MFC Handle //
	////////////////
	handle = (MFC_HANDLE *) malloc(sizeof(MFC_HANDLE));
	if (!handle) {
		RETAILMSG(1, (L"\n[MFC_Open Error] ERROR\n"));
		MFC_Mutex_Release();
		return 0;
	}
	memset(handle, 0, sizeof(MFC_HANDLE));

	// MFCInst
	handle->mfc_inst = MFCInst_Create();
	if (!handle->mfc_inst) {
		free(handle);
		MFC_Mutex_Release();
		RETAILMSG(1, (L"\n[MFC_Open Error] ERROR\n"));
	}


	// MFC Power is on and MFC HW is initialized
	// only if the Open handle count is 1.
	// (If number of open handles are more than 1,
	//  then MFC should not be initialized.)
	if (InterlockedIncrement(&_openhandle_count) == 1) {
		// MFC Power On
		Mfc_Pwr_On();
		Mfc_Clk_On();
		// MFC HW Init
		if (MFC_HW_Init() == FALSE) {
			Mfc_Clk_Off();
			Mfc_Pwr_Off();
			return 0;
		}
		Mfc_Clk_Off();
	}

	// Mutex Release
	MFC_Mutex_Release();

	return (DWORD) handle;
}



BOOL
MFC_Close(
    DWORD OpenHandle
    )
{
	MFC_HANDLE *handle;
	BOOL        r;

	MFCINST_DEC_INBUF_TYPE  inbuf_type;

	// If the OpenHandle is power handle, do nothing.
	// The function returns immediately.
	if (OpenHandle == MFC_POWER_HANDLE_VALUE)
		return TRUE;


	handle = (MFC_HANDLE *) OpenHandle;
	if (handle == NULL)
		return FALSE;


#if (_WIN32_WCE >= 600)
	r = VirtualFreeEx(handle->hUsrProc,	// HANDLE hProcess
	                  handle->pStrmBuf,
	                  handle->mfc_inst->nStrmBufSize,
	                  MEM_DECOMMIT);
	if (r == FALSE)
		RETAILMSG(1, (L"\n[MFC_Close] VirtualFreeEx(STRM_BUF) returns FALSE.\n"));
	r = VirtualFreeEx(handle->hUsrProc,	// HANDLE hProcess
	                  handle->pFramBuf,
	                  handle->mfc_inst->nFramBufSize,
	                  MEM_DECOMMIT);
	if (r == FALSE)
		RETAILMSG(1, (L"\n[MFC_Close] VirtualFreeEx(FRAM_BUF) returns FALSE.\n"));
#endif


	if (handle->mfc_inst) {
		inbuf_type = handle->mfc_inst->inbuf_type;
		MFCInst_Delete(handle->mfc_inst);
	}
	free(handle);


#if (MFC_LINE_RING_SHARE == 1)
	// In case of (MFC_LINE_RING_SHARE == 1), all the instances were reserved.
	// Therefore the instances need to be released.
	if (inbuf_type == DEC_INBUF_RING_BUF) {
		MfcInstPool_ReleaseAll();
	}
#endif


	if (InterlockedDecrement(&_openhandle_count) == 0) {
		// MFC Power Off
		Mfc_Pwr_Off();
	}

	return TRUE;
}


//  1. MFC instance Initialization
//  2. MFC Dec/Enc
BOOL
MFC_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
	int             ret;
	int             nStrmLen, nHdrLen;
	MFC_HANDLE     *handle;
	MFCInstCtx     *pMfcInst;

	MFC_CODECMODE   codec_mode;

	unsigned char  *p_buf;
	int             n_bufsize;


	MFC_ARGS       *args;
	enc_info_t      enc_info;

	static CEDEVICE_POWER_STATE   mfc_pwr_state;
	static BOOL                   is_mfc_on = FALSE;



	// If the OpenHandle is power handle,
	// handle the requests of IOCTL_POWER_xxxx.
	if (OpenHandle == MFC_POWER_HANDLE_VALUE) {
		PPOWER_CAPABILITIES ppc;

		MFC_Mutex_Lock();


		switch ( dwIoControlCode ) {
		case IOCTL_POWER_CAPABILITIES:

			RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES]\n"));

			if ( !pBytesReturned || !pOutBuf || (nOutBufSize < sizeof(POWER_CAPABILITIES)) ) {
       			SetLastError (ERROR_INVALID_PARAMETER);
				MFC_Mutex_Release();
				return FALSE;
			}

			ppc = (PPOWER_CAPABILITIES)pOutBuf;

			memset(ppc, 0, sizeof(POWER_CAPABILITIES));

			// support D0, D4
			ppc->DeviceDx = 0x11;

			// no wake
			// no inrush

			// Report our nominal power consumption in uAmps rather than mWatts.
			ppc->Flags = POWER_CAP_PREFIX_MICRO | POWER_CAP_UNIT_AMPS;

			//ppc->Power[D0] = 56000;

			*pBytesReturned = sizeof(POWER_CAPABILITIES);

			ret = MFCINST_RET_OK;
			RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] leaving...\n"));
			break;

		case IOCTL_POWER_QUERY:
			break;

		case IOCTL_POWER_SET:
			CEDEVICE_POWER_STATE NewDx;
			NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf;

			RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] newdx = %d\n", NewDx));

			switch ( NewDx ) {
			case D0:	// Power Up
				if ( mfc_pwr_state == D4) {

					if (is_mfc_on) {
						Mfc_Pwr_On();
						Mfc_Clk_On();
						MFC_Wakeup();
						Mfc_Clk_Off();
						RETAILMSG(0, (L"[MFC IOCTL_POWER_SET] POWER UP, handle = 0x%X\n", (DWORD) OpenHandle));

						// Recover the MFC instance state to PowerOn
						for (int inst_no = 0; inst_no < MFC_NUM_INSTANCES_MAX; inst_no++) {
							MFCInstCtx *mfcinst_ctx = MFCInst_GetCtx(inst_no);
							if (mfcinst_ctx) {

								// On Power Up, the state of the MFC instance is recovered.
								MFCInst_PowerOnState(mfcinst_ctx);
							}
						}
					}
				}
				mfc_pwr_state = D0;	// MFC power state is now changed to D0(Power On) state.
				break;

			case D4:	// Power Down
				if ( mfc_pwr_state == D0) {

					is_mfc_on = FALSE;

					// Check if MFC is being used
					// and change the MFC instance state to PowerOff
					for (int inst_no = 0; inst_no < MFC_NUM_INSTANCES_MAX; inst_no++) {
						MFCInstCtx *mfcinst_ctx = MFCInst_GetCtx(inst_no);
						if (mfcinst_ctx) {
							is_mfc_on = TRUE;

							// On Power Down, the MFC instance is invalidated.
							// Then the MFC operations (DEC_EXE, ENC_EXE, etc.) will not be performed
							// until it is validated by entering Power Up state transition.
							MFCInst_PowerOffState(mfcinst_ctx);
//							break;
						}
					}

					if (is_mfc_on) {

						Mfc_Clk_On();
						MFC_Sleep();
						// Clock & Power off the MFC block if they are on.
						Mfc_Clk_Off();
						Mfc_Pwr_Off();
						RETAILMSG(0, (L"[MFC IOCTL_POWER_SET] POWER DOWN, handle = 0x%X\n", (DWORD) OpenHandle));
					}
				}

				mfc_pwr_state = D4;	// MFC power state is now changed to D4(Sleep) state.
				break;

			default:
				MFC_Mutex_Release();
				return FALSE;
			}

			// return our state
			*(PCEDEVICE_POWER_STATE)pOutBuf = mfc_pwr_state;

			*pBytesReturned = sizeof(CEDEVICE_POWER_STATE);

			break;
		}

		MFC_Mutex_Release();

		return TRUE;
	}


	/////////////////////
	// Parameter Check //
	/////////////////////
	if (OpenHandle == NULL){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?