BOOL MFC_MemorySetup(void) { //MfcMemMapping(); BOOL ret_sfr, ret_bit, ret_dat; unsigned char *pDataBuf; // MFC SFR(Special Function Registers), Bitprocessor buffer, Data buffer의 // physical address 를 virtual address로 mapping 한다 ret_sfr = MfcSfrMemMapping(); if (ret_sfr == FALSE) { LOG_MSG(LOG_ERROR, "MfcMemorySetup", "MFC SFR Memory mapping fail!\r\n"); return FALSE; } ret_bit = MfcBitProcBufMemMapping(); if (ret_bit == FALSE) { LOG_MSG(LOG_ERROR, "MfcMemorySetup", "Bitprocessor buffer Memory mapping fail!\r\n"); return FALSE; } ret_dat = MfcDataBufMemMapping(); if (ret_dat == FALSE) { LOG_MSG(LOG_ERROR, "MfcMemorySetup", "Data buffer Memory mapping fail!\r\n"); return FALSE; } // FramBufMgr Module Initialization pDataBuf = (unsigned char *)GetDataBufVirAddr(); FramBufMgrInit(pDataBuf + MFC_STRM_BUF_SIZE, MFC_FRAM_BUF_SIZE); return TRUE; }
static int s3c_mfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; MFCInstCtx *pMfcInst; MFC_HANDLE *handle; unsigned char *OutBuf = NULL; MFC_CODECMODE codec_mode = 0; int buf_size; unsigned int tmp; MFC_ARGS args; enc_info_t enc_info; // modified by RainAde for header type of mpeg4 (+ VOS/VO) #if 1 // Hdr0 : SPS or VOL // Hdr1 : PPS or VOS // Hdr2 : VO (VIS) int nStrmLen, nHdrLen, nHdr0Len, nHdr1Len, nHdr2Len; #else // modified by RainAde for composer interface int nStrmLen, nHdrLen, nSps, nPps; #endif void *temp; unsigned int vir_mv_addr; unsigned int vir_mb_type_addr; ////////////////////// // Parameter Check // ////////////////////// handle = (MFC_HANDLE *)file->private_data; if (handle->mfc_inst == NULL) { return -EFAULT; } pMfcInst = handle->mfc_inst; switch(cmd) { case IOCTL_MFC_MPEG4_ENC_INIT: case IOCTL_MFC_H264_ENC_INIT: case IOCTL_MFC_H263_ENC_INIT: MFC_Mutex_Lock(); LOG_MSG(LOG_TRACE, "mfc_ioctl", "cmd = %d\r\n", cmd); Copy_From_User(&args.enc_init, (MFC_ENC_INIT_ARG *)arg, sizeof(MFC_ENC_INIT_ARG)); if ( cmd == IOCTL_MFC_MPEG4_ENC_INIT ) codec_mode = MP4_ENC; else if ( cmd == IOCTL_MFC_H264_ENC_INIT ) codec_mode = AVC_ENC; else if ( cmd == IOCTL_MFC_H263_ENC_INIT ) codec_mode = H263_ENC; ////////////////////////////// // Initialize MFC Instance // ////////////////////////////// enc_info.width = args.enc_init.in_width; enc_info.height = args.enc_init.in_height; enc_info.bitrate = args.enc_init.in_bitrate; enc_info.gopNum = args.enc_init.in_gopNum; enc_info.frameRateRes = args.enc_init.in_frameRateRes; enc_info.frameRateDiv = args.enc_init.in_frameRateDiv; ret = MFCInst_Enc_Init(pMfcInst, codec_mode, &enc_info); args.enc_init.ret_code = ret; Copy_To_User((MFC_ENC_INIT_ARG *)arg, &args.enc_init, sizeof(MFC_ENC_INIT_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_ENC_EXE: case IOCTL_MFC_H264_ENC_EXE: case IOCTL_MFC_H263_ENC_EXE: MFC_Mutex_Lock(); Copy_From_User(&args.enc_exe, (MFC_ENC_EXE_ARG *)arg, sizeof(MFC_ENC_EXE_ARG)); tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; // from 2.8.5 //dmac_clean_range(pMfcInst->pFramBuf, pMfcInst->pFramBuf + tmp); //outer_clean_range(__pa(pMfcInst->pFramBuf), __pa(pMfcInst->pFramBuf + tmp)); // from 2.8.5 : cache flush cpu_cache.flush_kern_all(); ////////////////////////// // Decode MFC Instance // ////////////////////////// // modified by RainAde for composer interface //ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen, &nHdr0Len, &nHdr1Len); // modified by RainAde for header type of mpeg4 (+ VOS/VO) ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen, &nHdr0Len, &nHdr1Len, &nHdr2Len); // from 2.8.5 //dmac_clean_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); //outer_clean_range(__pa(pMfcInst->pStrmBuf), __pa(pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE)); args.enc_exe.ret_code = ret; if (ret == MFCINST_RET_OK) { args.enc_exe.out_encoded_size = nStrmLen; args.enc_exe.out_header_size = nHdrLen; // modified by RainAde for composer interface args.enc_exe.out_header0_size = nHdr0Len; args.enc_exe.out_header1_size = nHdr1Len; // modified by RainAde for header type of mpeg4 (+ VOS/VO) args.enc_exe.out_header2_size = nHdr2Len; } Copy_To_User((MFC_ENC_EXE_ARG *)arg, &args.enc_exe, sizeof(MFC_ENC_EXE_ARG)); // added by RainAde for cache coherency cpu_cache.dma_inv_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_DEC_INIT: case IOCTL_MFC_H264_DEC_INIT: case IOCTL_MFC_H263_DEC_INIT: case IOCTL_MFC_VC1_DEC_INIT: MFC_Mutex_Lock(); #ifdef CONFIG_MACH_SATURN lcd_gamma_change(LCD_VIDEO); // when decoder init to start playing video, AMOLED gamma set to video mode #endif Copy_From_User(&args.dec_init, (MFC_DEC_INIT_ARG *)arg, sizeof(MFC_DEC_INIT_ARG)); // yj: fix the PiP problem cpu_cache.flush_kern_all(); if ( cmd == IOCTL_MFC_MPEG4_DEC_INIT ) codec_mode = MP4_DEC; else if ( cmd == IOCTL_MFC_H264_DEC_INIT ) codec_mode = AVC_DEC; else if ( cmd == IOCTL_MFC_H263_DEC_INIT) codec_mode = H263_DEC; else { codec_mode = VC1_DEC; } ////////////////////////////// // Initialize MFC Instance // ////////////////////////////// ret = MFCInst_Init(pMfcInst, codec_mode, args.dec_init.in_strmSize); args.dec_init.ret_code = ret; if (ret == MFCINST_RET_OK) { args.dec_init.out_width = pMfcInst->width; args.dec_init.out_height = pMfcInst->height; args.dec_init.out_buf_width = pMfcInst->buf_width; args.dec_init.out_buf_height = pMfcInst->buf_height; } Copy_To_User((MFC_DEC_INIT_ARG *)arg, &args.dec_init, sizeof(MFC_DEC_INIT_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_DEC_EXE: case IOCTL_MFC_H264_DEC_EXE: case IOCTL_MFC_H263_DEC_EXE: case IOCTL_MFC_VC1_DEC_EXE: MFC_Mutex_Lock(); Copy_From_User(&args.dec_exe, (MFC_DEC_EXE_ARG *)arg, sizeof(MFC_DEC_EXE_ARG)); // from 2.8.5 //dmac_clean_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); //outer_clean_range(__pa(pMfcInst->pStrmBuf), __pa(pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE)); // from 2.8.5 : cache flush cpu_cache.flush_kern_all(); if (pMfcInst->inbuf_type == DEC_INBUF_LINE_BUF) { ret = MFCInst_Decode(pMfcInst, args.dec_exe.in_strmSize); } else if (pMfcInst->inbuf_type == DEC_INBUF_RING_BUF) { ret = MFCInst_Decode_Stream(pMfcInst, args.dec_exe.in_strmSize); } else { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "Buffer type is not defined.\n"); MFC_Mutex_Release(); args.dec_exe.ret_code = -1; return -EINVAL; } args.dec_exe.ret_code = ret; Copy_To_User((MFC_DEC_EXE_ARG *)arg, &args.dec_exe, sizeof(MFC_DEC_EXE_ARG)); // added by RainAde for cache coherency tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; cpu_cache.dma_inv_range(pMfcInst->pFramBuf, pMfcInst->pFramBuf + tmp); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_RING_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); ret = MFCInst_GetRingBuf(pMfcInst, &OutBuf, &buf_size); args.get_buf_addr.out_buf_size = buf_size; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + ((int)(OutBuf - GetDataBufVirAddr())); args.get_buf_addr.ret_code = ret; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_LINE_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); ret = MFCInst_GetLineBuf(pMfcInst, &OutBuf, &buf_size); args.get_buf_addr.out_buf_size = buf_size; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + (OutBuf - GetDataBufVirAddr()); args.get_buf_addr.ret_code = ret; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_DBK_BUF_ADDR: // newly added by yj: returns to DBK_BUF' virtual address and its size. MFC_Mutex_Lock(); Copy_From_User(&args.get_dbkbuf_addr, (MFC_GET_DBK_BUF_ARG *)arg, sizeof(MFC_GET_DBK_BUF_ARG)); if (pMfcInst->isMp4DbkOn != 1) { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "MFC DBK_BUF is not internally allocated yet.\n"); MFC_Mutex_Release(); return -EFAULT; } args.get_dbkbuf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; args.get_dbkbuf_addr.out_buf_addr = args.get_dbkbuf_addr.in_usr_mapped_addr + ((unsigned int)GetDbkBufVirAddr() - (unsigned int)GetDataBufVirAddr()); args.get_dbkbuf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_DBK_BUF_ARG *)arg, &args.get_dbkbuf_addr, sizeof(MFC_GET_DBK_BUF_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_FRAM_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); if (pMfcInst->pFramBuf == NULL) { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "MFC Frame buffer is not internally allocated yet.\n"); MFC_Mutex_Release(); return -EFAULT; } // FRAM_BUF address is calculated differently for Encoder and Decoder. switch (pMfcInst->codec_mode) { case MP4_DEC: case AVC_DEC: case VC1_DEC: case H263_DEC: // Decoder case args.get_buf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; tmp = (unsigned int)args.get_buf_addr.in_usr_data + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->idx) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); #if (MFC_ROTATE_ENABLE == 1) if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { tmp = (unsigned int)args.get_buf_addr.in_usr_data + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->frambufCnt) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); } #endif args.get_buf_addr.out_buf_addr = tmp; break; case MP4_ENC: case AVC_ENC: case H263_ENC: // Encoder case tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + (pMfcInst->idx * tmp) + (int)(pMfcInst->pFramBuf - GetDataBufVirAddr()); break; } args.get_buf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); args.get_buf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; // args.get_buf_addr.out_buf_size = ((pMfcInst->width+2*DIVX_PADDING) * (pMfcInst->height+2*DIVX_PADDING) * 3) >> 1; tmp = (unsigned int)S3C6400_BASEADDR_MFC_DATA_BUF + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->idx) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); //.[ i: sichoi 081103 (ROTATE) #if (MFC_ROTATE_ENABLE == 1) if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { tmp = (unsigned int)S3C6400_BASEADDR_MFC_DATA_BUF + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->frambufCnt) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); } #endif //.] sichoi 081103 args.get_buf_addr.out_buf_addr = tmp; args.get_buf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_MPEG4_ASP_PARAM: #if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1)) Copy_From_User(&args.mpeg4_asp_param, (MFC_GET_MPEG4ASP_ARG *)arg, sizeof(MFC_GET_MPEG4ASP_ARG)); ret = MFCINST_RET_OK; args.mpeg4_asp_param.ret_code = MFCINST_RET_OK; args.mpeg4_asp_param.mp4asp_vop_time_res = pMfcInst->RET_DEC_SEQ_INIT_BAK_MP4ASP_VOP_TIME_RES; args.mpeg4_asp_param.byte_consumed = pMfcInst->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED; args.mpeg4_asp_param.mp4asp_fcode = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE; args.mpeg4_asp_param.mp4asp_time_base_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST; args.mpeg4_asp_param.mp4asp_nonb_time_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST; args.mpeg4_asp_param.mp4asp_trd = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD; args.mpeg4_asp_param.mv_addr = (args.mpeg4_asp_param.in_usr_mapped_addr + MFC_STRM_BUF_SIZE) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf); args.mpeg4_asp_param.mb_type_addr = args.mpeg4_asp_param.mv_addr + 25920; args.mpeg4_asp_param.mv_size = 25920; args.mpeg4_asp_param.mb_type_size = 1620; vir_mv_addr = (unsigned int)((pMfcInst->pStrmBuf + MFC_STRM_BUF_SIZE) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf)); vir_mb_type_addr = vir_mv_addr + 25920; Copy_To_User((MFC_GET_MPEG4ASP_ARG *)arg, &args.mpeg4_asp_param, sizeof(MFC_GET_MPEG4ASP_ARG)); // from 2.8.5 //dmac_clean_range(vir_mv_addr, vir_mv_addr + args.mpeg4_asp_param.mv_size); //outer_clean_range(__pa(vir_mv_addr), __pa(vir_mv_addr + args.mpeg4_asp_param.mv_size)); //dmac_clean_range(vir_mb_type_addr, vir_mb_type_addr + args.mpeg4_asp_param.mb_type_size); //outer_clean_range(__pa(vir_mb_type_addr), __pa(vir_mb_type_addr + args.mpeg4_asp_param.mb_type_size)); #endif break; case IOCTL_MFC_GET_CONFIG: MFC_Mutex_Lock(); Copy_From_User(&args, (MFC_ARGS *)arg, sizeof(MFC_ARGS)); ret = MFC_GetConfigParams(pMfcInst, &args); Copy_To_User((MFC_ARGS *)arg, &args, sizeof(MFC_ARGS)); MFC_Mutex_Release(); break; case IOCTL_MFC_SET_CONFIG: MFC_Mutex_Lock(); Copy_From_User(&args, (MFC_ARGS *)arg, sizeof(MFC_ARGS)); ret = MFC_SetConfigParams(pMfcInst, &args); Copy_To_User((MFC_ARGS *)arg, &args, sizeof(MFC_ARGS)); MFC_Mutex_Release(); break; case IOCTL_MFC_SET_H263_MULTIPLE_SLICE: MFC_Mutex_Lock(); pMfcInst->multiple_slice = 1; MFC_Mutex_Release(); break; case IOCTL_VIRT_TO_PHYS: //MFC_Mutex_Lock(); temp = __virt_to_phys((void *)arg); return (int)temp; //MFC_Mutex_Release(); break; default: MFC_Mutex_Lock(); LOG_MSG(LOG_TRACE, "s3c_mfc_ioctl", "Requested ioctl command is not defined. (ioctl cmd=0x%X)\n", cmd); MFC_Mutex_Release(); return -EINVAL; } switch(ret) { case MFCINST_RET_OK: return TRUE; default: return -1; } return -1; }