⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfcsfr.c

📁 Samsung公司S3C6400芯片的BSP源码包
💻 C
字号:
/*
 * Project Name MFC DRIVER 
 * Copyright  2007 Samsung Electronics Co, Ltd. All Rights Reserved. 
 *
 * This software is the confidential and proprietary information
 * of Samsung Electronics  ("Confidential Information").   
 * you shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Samsung Electronics 
 *
 * This source file is for setting the MFC's registers.
 *
 * @name MFC DRIVER MODULE Module (MfcSfr.c)
 * @author name(email address)
 * @date 03-28-07
 */

#include "MfcSfr.h"
#include "MfcMemory.h"
#include "LogMsg.h"
#include "MfcConfig.h"
#include "Prism_S.h"
#include "MfcMutex.h"
#include "MfcIntrNotification.h"


static volatile S3C6400_MFC_SFR   *vir_pMFC_SFR		= NULL;
static volatile unsigned int      *vir_pSW_RESET	= NULL;

static unsigned int                phyMFC_SFR		= 0;
static unsigned int                phySW_RESET		= 0;


static char *GetCmdString(MFC_COMMAND mfc_cmd)
{
	switch (mfc_cmd) {
	case SEQ_INIT:
		return "SEQ_INIT";

	case SEQ_END:
		return "SEQ_END";

	case PIC_RUN:
		return "PIC_RUN";

	case SET_FRAME_BUF:
		return "SET_FRAME_BUF";

	case ENCODE_HEADER:
		return "ENCODE_HEADER";

	case ENC_PARA_SET:
		return "ENC_PARA_SET";

	case DEC_PARA_SET:
		return "DEC_PARA_SET";

	case GET_FW_VER:
		return "GET_FW_VER";

	}

	return "UNDEF CMD";
}

static int WaitForReady(void)
{
	int   i;

#ifdef _WIN32_WCE
	for (i=0; i<15; i++) {
		if (vir_pMFC_SFR->BUSY_FLAG == 0) {
			return TRUE;
		}
		Sleep(2);
	}
#else
	for (i=0; i<1000; i++) {
		if (vir_pMFC_SFR->BUSY_FLAG == 0) {
			return TRUE;
		}
		Sleep(100);	// 1/1000 second
	}
#endif

	LOG_MSG(LOG_TRACE, "WaitForReady", "Timeout in waiting for the Bit Processor available.\r\n");


	return FALSE;
}


int GetFirmwareVersion(void)
{
	unsigned int prd_no, ver_no;

	WaitForReady();

	vir_pMFC_SFR->RUN_CMD     = GET_FW_VER;

	LOG_MSG(LOG_TRACE, "GetFirmwareVersion ", "GET_FW_VER command was issued.\r\n");

	WaitForReady();

	prd_no = vir_pMFC_SFR->param.dec_seq_init.RET_SEQ_SUCCESS >> 16;
	ver_no = (vir_pMFC_SFR->param.dec_seq_init.RET_SEQ_SUCCESS & 0x00FFFF);

	LOG_MSG(LOG_TRACE, "GetFirmwareVersion", "GET_FW_VER => 0x%X, 0x%X\n", prd_no, ver_no);
	LOG_MSG(LOG_TRACE, "BUSY_FLAG", "BUSY_FLAG => %d\n", vir_pMFC_SFR->BUSY_FLAG);

	return vir_pMFC_SFR->param.dec_seq_init.RET_SEQ_SUCCESS;
}


BOOL MfcIssueCmd(int inst_no, MFC_CODECMODE codec_mode, MFC_COMMAND mfc_cmd)
{
	unsigned int intr_reason;

	vir_pMFC_SFR->RUN_INDEX     = inst_no;

	if (codec_mode == H263_DEC) {
		vir_pMFC_SFR->RUN_COD_STD	= MP4_DEC;
	} else if (codec_mode == H263_ENC) {
		vir_pMFC_SFR->RUN_COD_STD	= MP4_ENC;
	} else {
		vir_pMFC_SFR->RUN_COD_STD   = codec_mode;
	}
		
	switch (mfc_cmd) 
	{
	case PIC_RUN:

		vir_pMFC_SFR->RUN_CMD       = mfc_cmd;

		intr_reason = WaitInterruptNotification();
		if (intr_reason == WAIT_INT_NOTI_TIMEOUT) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, WaitInterruptNotification returns TIMEOUT.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}
		if (intr_reason & 0xC000) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, BUFFER EMPTY interrupt was raised.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}
		break;

	case SEQ_INIT:
		vir_pMFC_SFR->RUN_CMD       = mfc_cmd;

		intr_reason = WaitInterruptNotification();
		if (intr_reason == WAIT_INT_NOTI_TIMEOUT) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, WaitInterruptNotification returns TIMEOUT.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}
		if (intr_reason & 0xC000) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, BUFFER EMPTY interrupt was raised.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}
		break;

	
	case SEQ_END:
		vir_pMFC_SFR->RUN_CMD       = mfc_cmd;
		
		intr_reason = WaitInterruptNotification();
		if (intr_reason == WAIT_INT_NOTI_TIMEOUT) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, WaitInterruptNotification returns TIMEOUT.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}
		if (intr_reason & 0xC000) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, BUFFER EMPTY interrupt was raised.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}
		break;
		
	default:
		if (WaitForReady() == FALSE) {
			LOG_MSG(LOG_ERROR, "LOG_ERROR", "MfcIssueCmd CMD = %s, BitProcessor is busy before issuing the command.\n", GetCmdString(mfc_cmd));
			return FALSE;
		}

		vir_pMFC_SFR->RUN_CMD       = mfc_cmd;
	
		WaitForReady();
			
	} 

	return TRUE;
}


BOOL MfcSfrMemMapping(void)
{
	BOOL	ret = FALSE;

	// virtual address mapping
	vir_pMFC_SFR = (volatile S3C6400_MFC_SFR *)Phy2Vir_AddrMapping(S3C6400_BASEADDR_MFC_SFR, S3C6400_MFC_SFR_SW_RESET_ADDR);
	
	if (vir_pMFC_SFR == NULL)
	{
		LOG_MSG(LOG_ERROR, "MfcSfrMapping", "For MFC_SFR: VirtualAlloc failed!\r\n");
		return ret;
	}

	
	vir_pSW_RESET = (unsigned int *) ((int)vir_pMFC_SFR  +  S3C6400_MFC_SFR_SW_RESET_ADDR);

	// Physical address mapping
	phyMFC_SFR	= S3C6400_BASEADDR_MFC_SFR;
	phySW_RESET	= S3C6400_BASEADDR_MFC_SFR + S3C6400_MFC_SFR_SW_RESET_ADDR;


	ret = TRUE;

	return ret;
}

volatile S3C6400_MFC_SFR *GetMfcSfrVirAddr(void)
{
	volatile S3C6400_MFC_SFR	*mfc_sfr;

	mfc_sfr = vir_pMFC_SFR;

	return mfc_sfr;
}

void *MfcGetCmdParamRegion(void)
{
	return (void *) &(vir_pMFC_SFR->param);
}

// Perform the SW_RESET
void MfcReset(void)
{
	*vir_pSW_RESET = 0x00;
	*vir_pSW_RESET = 0x01;
//	vir_pMFC_SFR->INT_ENABLE = 0xC0FF;	// enable all interrupt
	vir_pMFC_SFR->INT_ENABLE = 0xC00E;	// Interrupt is enabled for PIC_RUN command and empty/full STRM_BUF status.
	vir_pMFC_SFR->INT_REASON = 0x0;
	vir_pMFC_SFR->BITS_INT_CLEAR = 0x1;
}

// Clear the MFC Interrupt
// After catching the MFC Interrupt,
// it is required to call this functions for clearing the interrupt-related register.
void MfcClearIntr(void)
{
	vir_pMFC_SFR->BITS_INT_CLEAR = 0x1;
	vir_pMFC_SFR->INT_REASON     = 0x0;
}

// Check INT_REASON register of MFC (the interrupt reason register)
unsigned int MfcIntrReason(void)
{
	return vir_pMFC_SFR->INT_REASON;
}

// Set the MFC's SFR of DEC_FUNC_CTRL to 1.
// It means that the data will not be added more to the STRM_BUF.
// It is required in RING_BUF mode (VC-1 DEC).
void MfcSetEos()
{
	vir_pMFC_SFR->DEC_FUNC_CTRL = 1;	// 1: Whole stream is in buffer.
}


void MfcFirmwareIntoCodeDownReg(void)
{
	unsigned int  i;
	unsigned int  data;


	///////////////////////////////////////////////////////
	// Download the Boot code into MFC's internal memory //
	///////////////////////////////////////////////////////
	for (i=0; i<512; i++)
	{
		data = bit_code[i];

		vir_pMFC_SFR->CODE_DN_LOAD = ((i<<16) | data); // i: 13bit addr
	}

}

void MfcStartBitProcessor(void)
{
	vir_pMFC_SFR->CODE_RUN = 0x01;
}


void MfcStopBitProcessor(void)
{
	vir_pMFC_SFR->CODE_RUN = 0x00;
}

void MfcConfigSFR_BITPROC_BUF(void)
{
	// CODE BUFFER ADDRESS (BASE + 0x100)
	//   : Located from the Base address of the BIT PROCESSOR'S Firmware code segment
	vir_pMFC_SFR->CODE_BUF_ADDR = S3C6400_BASEADDR_MFC_BITPROC_BUF;


	// WORKING BUFFER ADDRESS (BASE + 0x104)
	//   : Located from the next to the BIT PROCESSOR'S Firmware code segment
	vir_pMFC_SFR->WORK_BUF_ADDR = vir_pMFC_SFR->CODE_BUF_ADDR + MFC_CODE_BUF_SIZE;


	// PARAMETER BUFFER ADDRESS (BASE + 0x108)
	//   : Located from the next to the WORKING BUFFER
	vir_pMFC_SFR->PARA_BUF_ADDR = vir_pMFC_SFR->WORK_BUF_ADDR + MFC_WORK_BUF_SIZE;
}

void MfcConfigSFR_CTRL_OPTS(void)
{
	unsigned int  uRegData;

	// BIT STREAM BUFFER CONTROL (BASE + 0x10C)
	uRegData = vir_pMFC_SFR->STRM_BUF_CTRL;
	vir_pMFC_SFR->STRM_BUF_CTRL = (uRegData & ~(0x03)) | BUF_STATUS_FULL_EMPTY_CHECK_BIT | STREAM_ENDIAN_LITTLE;


	// FRAME MEMORY CONTROL  (BASE + 0x110)
	vir_pMFC_SFR->FRME_BUF_CTRL = FRAME_MEM_ENDIAN_LITTLE;


	// DECODER FUNCTION CONTROL (BASE + 0x114)
	vir_pMFC_SFR->DEC_FUNC_CTRL = 0;	// 0: Whole stream is not in buffer.

	// WORK BUFFER CONTROL (BASE + 0x11C)
	vir_pMFC_SFR->WORK_BUF_CTRL = 0;	// 0: Work buffer control is disabled.
}


⌨️ 快捷键说明

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