2242 lines
54 KiB
C++
2242 lines
54 KiB
C++
/********************************************************************
|
|
* Copyright(c) 2006-2009 Broadcom Corporation.
|
|
*
|
|
* Name: libcrystalhd_int_if.cpp
|
|
*
|
|
* Description: Driver Internal Interfaces
|
|
*
|
|
* AU
|
|
*
|
|
* HISTORY:
|
|
*
|
|
********************************************************************
|
|
*
|
|
* This file is part of libcrystalhd.
|
|
*
|
|
* This library is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published
|
|
* by the Free Software Foundation, either version 2.1 of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*******************************************************************/
|
|
|
|
#include "7411d.h"
|
|
#include "bc_defines.h"
|
|
#include "bc_decoder_regs.h"
|
|
#include "libcrystalhd_priv.h"
|
|
#include "libcrystalhd_int_if.h"
|
|
#include "libcrystalhd_fwcmds.h"
|
|
|
|
#include <emmintrin.h>
|
|
|
|
#define SV_MAX_LINE_SZ 128
|
|
#define PCI_GLOBAL_CONTROL MISC2_GLOBAL_CTRL
|
|
#define PCI_INT_STS_REG MISC2_INTERNAL_STATUS
|
|
|
|
// FLEA
|
|
#define BCHP_MISC2_GLOBAL_CTRL 0x00502100 /* Global Control Register */
|
|
#define BCHP_CLK_TEMP_MON_CTRL 0x00070040 /* Temperature monitor control. */
|
|
#define BCHP_CLK_TEMP_MON_STATUS 0x00070044 /* Temperature monitor status. */
|
|
|
|
|
|
//===================================Externs ===========================================
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsGetHwType(
|
|
HANDLE hDevice,
|
|
uint32_t *DeviceID,
|
|
uint32_t *VendorID,
|
|
uint32_t *HWRev
|
|
)
|
|
{
|
|
BC_HW_TYPE *pHWInfo;
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
pHWInfo = &pIocData->u.hwType;
|
|
|
|
pHWInfo->PciDevId = 0xffff;
|
|
pHWInfo->PciVenId = 0xffff;
|
|
pHWInfo->HwRev = 0xff;
|
|
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_GET_HWTYPE,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsGetHwType: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
*DeviceID = pHWInfo->PciDevId;
|
|
*VendorID = pHWInfo->PciVenId;
|
|
*HWRev = pHWInfo->HwRev;
|
|
|
|
// Set these early
|
|
Ctx->DevId = pHWInfo->PciDevId;
|
|
Ctx->hwRevId = pHWInfo->HwRev;
|
|
Ctx->VendorId = pHWInfo->PciVenId;
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API VOID
|
|
DtsHwReset(
|
|
HANDLE hDevice
|
|
)
|
|
{
|
|
|
|
return;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSoftReset(
|
|
HANDLE hDevice
|
|
)
|
|
{
|
|
|
|
uint32_t Val = 0;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(Ctx->DevId == BC_PCI_DEVID_LINK || Ctx->DevId == BC_PCI_DEVID_DOZER)
|
|
{
|
|
DtsDevRegisterWr( hDevice, DecHt_HostSwReset, 0x00000001); // Assert c011 soft reset
|
|
bc_sleep_ms(50);
|
|
DtsDevRegisterWr( hDevice, DecHt_HostSwReset, 0x00000000 ); // Release c011 soft reset
|
|
|
|
/* Disable Stuffing.. */
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&Val);
|
|
Val |= BC_BIT(8);
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,Val);
|
|
|
|
//DtsSetCoreClock(hDevice, 0);
|
|
}
|
|
else if(Ctx->DevId == BC_PCI_DEVID_FLEA)
|
|
{
|
|
// For Link, this is used to bring up 7412 and running.
|
|
// Since the 70012 was running in low power mode, but the 7412 was not.
|
|
// In flea there is no need for this. In general most of the chip will be in idle mode,
|
|
// and should not be needed to reset in order to start up.
|
|
// In Flea, we can never do full chip reset, because that will reset PCIe as well and
|
|
// probably cause a BSOD. Individual blocks will have to be reset, either by asserting true resets
|
|
// (but not from the host) or by re-initializing -like the ARM for example.
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetLinkIn422Mode(HANDLE hDevice)
|
|
{
|
|
uint32_t Val = 0;
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
uint32_t ModeSelect;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
ModeSelect = Ctx->b422Mode;
|
|
|
|
DebugLog_Trace(LDIL_DBG,"Setting Color Mode to %u\n", Ctx->b422Mode);
|
|
/*
|
|
* EN_WRITE_ALL BIT -Bit 20
|
|
* This bit dictates that weather the data will be xferred in
|
|
* 1 - UYVY Mode.
|
|
* 0 - YUY2 Mode.
|
|
*/
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&Val);
|
|
|
|
if (ModeSelect == OUTPUT_MODE420) {
|
|
Val &= 0xffeeffff;
|
|
} else {
|
|
Val |= BC_BIT(16);
|
|
if(ModeSelect == OUTPUT_MODE422_UYVY) {
|
|
Val |= BC_BIT(20);
|
|
} else {
|
|
Val &= ~BC_BIT(20);
|
|
}
|
|
}
|
|
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,Val);
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetFleaIn422Mode(HANDLE hDevice)
|
|
{
|
|
uint32_t Val = 0;
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
uint32_t ModeSelect;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
ModeSelect = Ctx->b422Mode;
|
|
|
|
// Flea HW only support UYVY/YUY2
|
|
if( ModeSelect != OUTPUT_MODE422_UYVY && ModeSelect != OUTPUT_MODE422_YUY2 )
|
|
return BC_STS_INV_ARG;
|
|
|
|
DtsDevRegisterRead(hDevice,BCHP_MISC2_GLOBAL_CTRL,&Val);
|
|
|
|
Val &= 0x0000007c;
|
|
if( ModeSelect == OUTPUT_MODE422_YUY2 )
|
|
{
|
|
Val |= BC_BIT(1); // bit_1 0-> UYVY, 1-> YUY2
|
|
}
|
|
|
|
DtsDevRegisterWr(hDevice,BCHP_MISC2_GLOBAL_CTRL,Val);
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsGetConfig(
|
|
HANDLE hDevice,
|
|
BC_DTS_CFG *cfg
|
|
)
|
|
{
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!cfg){
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
*cfg = Ctx->CfgFlags;
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetConfig(
|
|
HANDLE hDevice,
|
|
BC_DTS_CFG *cfg
|
|
)
|
|
{
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!cfg){
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
Ctx->CfgFlags = *cfg;
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
BC_STATUS
|
|
DtsSetCoreClock(
|
|
HANDLE hDevice,
|
|
uint32_t freq
|
|
)
|
|
{
|
|
// uint32_t Val=0,clkRate=0, cnt;
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
// uint32_t DevID,VendorID,Revision;
|
|
|
|
uint32_t reg;
|
|
uint32_t n, i;
|
|
uint32_t vco_mg;
|
|
uint32_t refresh_reg;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
if(Ctx->DevId != BC_PCI_DEVID_LINK)
|
|
{
|
|
//DebugLog_Trace(LDIL_DBG,"DtsSetCoreClock is not supported in this device\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
#if 0
|
|
if(BC_STS_SUCCESS != DtsGetHwType(hDevice,&DevID,&VendorID,&Revision)) {
|
|
DebugLog_Trace(LDIL_DBG,"Get Hardware Type Failed\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if(DevID == BC_PCI_DEVID_LINK) {
|
|
// Don't set the core clock
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
if(freq){
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetCoreClock: Custom pll settings not implemented yet.\n");
|
|
return BC_STS_NOT_IMPL;
|
|
}
|
|
if(Ctx->CfgFlags & BC_DEC_VCLK_74MHZ){
|
|
clkRate = 0x000230f0;
|
|
}else if(Ctx->CfgFlags & BC_DEC_VCLK_77MHZ){
|
|
clkRate = 0x000230f2;
|
|
}else{
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
#endif
|
|
if(freq == 0)
|
|
return BC_STS_SUCCESS;
|
|
|
|
n = freq/5;
|
|
|
|
//if (n == Ctx->prev_n)
|
|
// return BC_STS_CLK_NOCHG;
|
|
|
|
if ((n * 27) < 560)
|
|
vco_mg = 0;
|
|
else if ((n * 27) < 900)
|
|
vco_mg = 1;
|
|
else if ((n * 27) < 1030)
|
|
vco_mg = 2;
|
|
else
|
|
vco_mg = 3;
|
|
|
|
DtsDevRegisterRead(hDevice,DecHt_PllACtl, ®);
|
|
|
|
reg &= 0xFFFFCFC0;
|
|
reg |= n;
|
|
reg |= vco_mg << 12;
|
|
|
|
refresh_reg = (7 * freq / 16);
|
|
DtsDevRegisterWr(hDevice,SDRAM_REF_PARAM,((1 << 12) | refresh_reg));
|
|
|
|
DtsDevRegisterWr(hDevice, DecHt_PllACtl, reg);
|
|
DebugLog_Trace(LDIL_DBG,"Clock set to %d\n", freq);
|
|
i = 0;
|
|
|
|
while (i < 10) {
|
|
DtsDevRegisterRead(hDevice,DecHt_PllACtl, ®);
|
|
|
|
if (reg & 0x00020000) {
|
|
//Ctx->prev_n = n;
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
else {
|
|
bc_sleep_ms(10);
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetTSMode(
|
|
HANDLE hDevice,
|
|
uint32_t resv1
|
|
)
|
|
{
|
|
uint32_t RegVal = 0;
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
BOOL TsMode = TRUE;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(Ctx->DevId != BC_PCI_DEVID_LINK && Ctx->DevId != BC_PCI_DEVID_DOZER)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetTSMode is not supported in this device\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
if(Ctx->FixFlags & DTS_LOAD_FILE_PLAY_FW)
|
|
TsMode = FALSE;
|
|
|
|
if(TsMode){
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&RegVal);
|
|
RegVal &= 0xFFFFFFFE; //Reset Bit 0
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,RegVal);
|
|
}else{
|
|
// Set the FPGA up in non TS mode
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&RegVal);
|
|
RegVal |= 0x01; //Set Bit 0
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,RegVal);
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetProgressive(
|
|
HANDLE hDevice,
|
|
uint32_t resv1
|
|
)
|
|
{
|
|
uint32_t RegVal;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
if(Ctx->DevId != BC_PCI_DEVID_LINK && Ctx->DevId != BC_PCI_DEVID_DOZER)
|
|
{
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
// Set the FPGA up in Progressive mode - i.e. 1 vsync/frame
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&RegVal);
|
|
RegVal |= 0x10; //Set Bit 4
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,RegVal);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
BC_STATUS
|
|
DtsRstVidClkDLL(
|
|
HANDLE hDevice)
|
|
{
|
|
uint32_t RegVal,Cnt=100;
|
|
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&RegVal);
|
|
RegVal |= 0x08; //Set Bit 3 the Reset Bit
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,RegVal);
|
|
|
|
//
|
|
// Wait for the bit to go low [Unlock]
|
|
//
|
|
while(Cnt)
|
|
{
|
|
DtsFPGARegisterRead(hDevice,PCI_INT_STS_REG,&RegVal);
|
|
if(!(RegVal | 0x04) )
|
|
{
|
|
break;
|
|
|
|
}else{
|
|
bc_sleep_ms(100);
|
|
Cnt--;
|
|
}
|
|
}
|
|
bc_sleep_ms(100);
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&RegVal);
|
|
RegVal &= 0xfffffff7; //reset bit 3
|
|
DtsFPGARegisterWr(hDevice,PCI_GLOBAL_CONTROL,RegVal);
|
|
RegVal=0;
|
|
Cnt =100;
|
|
while(Cnt)
|
|
{
|
|
DtsFPGARegisterRead(hDevice,PCI_INT_STS_REG,&RegVal);
|
|
if(RegVal & 0x04)
|
|
{
|
|
//
|
|
// This means that the video clock is locked.
|
|
//
|
|
return BC_STS_SUCCESS;
|
|
}else{
|
|
bc_sleep_ms(100);
|
|
Cnt--;
|
|
}
|
|
}
|
|
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetVideoClock: DLL did not lock.\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetVideoClock(
|
|
HANDLE hDevice,
|
|
uint32_t freq
|
|
)
|
|
{
|
|
uint32_t Val=0;
|
|
uint32_t clkRate = 0;
|
|
DTS_LIB_CONTEXT *Ctx;
|
|
uint32_t DevID,VendorID,Revision;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(freq){
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetVideoClock: Custom pll settings not implemented yet.\n");
|
|
return BC_STS_NOT_IMPL;
|
|
}
|
|
|
|
if(BC_STS_SUCCESS != DtsGetHwType(hDevice,&DevID,&VendorID,&Revision)) {
|
|
DebugLog_Trace(LDIL_DBG,"Get Hardware Type Failed\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
if(DevID == BC_PCI_DEVID_LINK || DevID == BC_PCI_DEVID_FLEA) {
|
|
// Don't set the video clock
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
if(Ctx->CfgFlags & BC_DEC_VCLK_74MHZ){
|
|
// Program PLL-E to 75 MHZ (n = 44, m = 10, vco_rng = 1)
|
|
clkRate = 0x000012AC;
|
|
}else if(Ctx->CfgFlags & BC_DEC_VCLK_77MHZ){
|
|
// Program PLL-E to 77 MHZ (n = ??, m = ??, vco_rng = ??)
|
|
clkRate = 0x000012B0;
|
|
}else{
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
|
|
DtsDevRegisterWr( hDevice, DecHt_PllDCtl, 0x00010000); // Bypass PLL-D
|
|
|
|
bc_sleep_ms(50);
|
|
|
|
DtsDevRegisterRead( hDevice, DecHt_PllDCtl, &Val);
|
|
|
|
if(Val != 0x00030000){
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetVideoClock: Failed to change PLL_D_CTL\n");
|
|
//FIX_ME
|
|
//return BC_STS_NO_ACCESS;
|
|
}
|
|
|
|
DtsDevRegisterWr( hDevice, DecHt_PllECtl, clkRate);
|
|
|
|
bc_sleep_ms(50);
|
|
|
|
DtsDevRegisterRead( hDevice, DecHt_PllECtl, &Val);
|
|
|
|
if(Val != (clkRate | 0x00020000) ){
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetVideoClock: Failed to change PLL_E_CTL\n");
|
|
//FIX_ME
|
|
//return BC_STS_NO_ACCESS;
|
|
}
|
|
|
|
//if(BC_STS_SUCCESS != DtsRstVidClkDLL(hDevice))
|
|
//{
|
|
// DebugLog_Trace(LDIL_DBG,"DtsSetVideoClock: Vid Clk DLL Failed to Lock\n");
|
|
// return BC_STS_ERROR;
|
|
//}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
DRVIFLIB_INT_API BOOL
|
|
DtsIsVideoClockSet(HANDLE hDevice)
|
|
{
|
|
uint32_t RegVal=0;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
uint32_t DevID,VendorID,Revision;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(BC_STS_SUCCESS != DtsGetHwType(hDevice,&DevID,&VendorID,&Revision)) {
|
|
DebugLog_Trace(LDIL_DBG,"Get Hardware Type Failed\n");
|
|
return FALSE;
|
|
}
|
|
if(DevID == BC_PCI_DEVID_LINK || DevID == BC_PCI_DEVID_FLEA) {
|
|
// Don't set the video clock
|
|
return FALSE;
|
|
}
|
|
|
|
if((Ctx->RegCfg.DbgOptions & BC_BIT(1)) && (Ctx->OpMode == DTS_PLAYBACK_MODE))
|
|
return FALSE;
|
|
|
|
DtsFPGARegisterRead(hDevice,PCI_GLOBAL_CONTROL,&RegVal);
|
|
|
|
if(RegVal & BC_BIT(0))
|
|
return TRUE;
|
|
|
|
DtsFPGARegisterRead(hDevice,PCI_INT_STS_REG,&RegVal);
|
|
|
|
return (RegVal & BC_BIT(2));
|
|
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsGetPciConfigSpace(
|
|
HANDLE hDevice,
|
|
uint8_t *info
|
|
)
|
|
{
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
BC_PCI_CFG *pciInfo;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!info)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsGetPciConfigSpace: Invlid Arguments\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
pciInfo = (BC_PCI_CFG *)&pIocData->u.pciCfg;
|
|
|
|
pciInfo->Size = PCI_CFG_SIZE;
|
|
pciInfo->Offset = 0;
|
|
memset(info,0, PCI_CFG_SIZE);
|
|
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_RD_PCI_CFG,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsGetPciConfigSpace: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
memcpy(info,pciInfo->pci_cfg_space,PCI_CFG_SIZE);
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsDevRegisterRead(
|
|
HANDLE hDevice,
|
|
uint32_t offset,
|
|
uint32_t *Value
|
|
)
|
|
{
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
BC_CMD_REG_ACC *reg_acc_read;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
|
|
reg_acc_read = (BC_CMD_REG_ACC *) &pIocData->u.regAcc;
|
|
|
|
//
|
|
// Prepare the command here.
|
|
//
|
|
reg_acc_read->Offset = offset;
|
|
reg_acc_read->Value = 0;
|
|
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_REG_RD,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevRegisterRead: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
*Value = reg_acc_read->Value;
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsDevRegisterWr(
|
|
HANDLE hDevice,
|
|
uint32_t offset,
|
|
uint32_t Value
|
|
)
|
|
{
|
|
BC_CMD_REG_ACC *reg_acc_wr;
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
|
|
DTS_GET_CTX(hDevice, Ctx);
|
|
|
|
if (!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
reg_acc_wr = (BC_CMD_REG_ACC *) &pIocData->u.regAcc;
|
|
|
|
// Prepare the command here.
|
|
reg_acc_wr->Offset = offset;
|
|
reg_acc_wr->Value = Value;
|
|
|
|
sts = DtsDrvCmd(Ctx, BCM_IOC_REG_WR, 0, pIocData, FALSE);
|
|
|
|
if (sts != BC_STS_SUCCESS)
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevRegisterWr: Ioctl failed: %d\n", sts);
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return sts;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsFPGARegisterRead(
|
|
HANDLE hDevice,
|
|
uint32_t offset,
|
|
uint32_t *Value
|
|
)
|
|
{
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
BC_CMD_REG_ACC *reg_acc_read;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
|
|
reg_acc_read = (BC_CMD_REG_ACC *) &pIocData->u.regAcc;
|
|
|
|
//
|
|
// Prepare the command here.
|
|
//
|
|
reg_acc_read->Offset = offset;
|
|
reg_acc_read->Value = 0;
|
|
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_FPGA_RD,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsFPGARegisterRead: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
*Value = reg_acc_read->Value;
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsFPGARegisterWr(
|
|
HANDLE hDevice,
|
|
uint32_t offset,
|
|
uint32_t Value
|
|
)
|
|
{
|
|
BC_CMD_REG_ACC *reg_acc_wr;
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
reg_acc_wr = (BC_CMD_REG_ACC *) &pIocData->u.regAcc;
|
|
|
|
//
|
|
// Prepare the command here.
|
|
//
|
|
reg_acc_wr->Offset = offset;
|
|
reg_acc_wr->Value = Value;
|
|
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_FPGA_WR,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsFPGARegisterWr: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsDevMemRd(
|
|
HANDLE hDevice,
|
|
uint32_t *Buffer,
|
|
uint32_t BuffSz,
|
|
uint32_t Offset
|
|
)
|
|
{
|
|
uint8_t *pXferBuff;
|
|
uint32_t IOcCode,size_in_dword;
|
|
BC_IOCTL_DATA *pIoctlData;
|
|
BC_CMD_DEV_MEM *pMemAccessRd;
|
|
uint32_t BytesReturned,AllocSz;
|
|
|
|
if(!hDevice)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemRd: Invalid Handle\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if(!Buffer)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemRd: Null Buffer\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if(BuffSz % 4)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemRd: Buff Size is not a multiple of DWORD\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
|
|
AllocSz = sizeof(BC_IOCTL_DATA) + (BuffSz);
|
|
|
|
pIoctlData = (BC_IOCTL_DATA *) malloc(AllocSz);
|
|
|
|
if(!pIoctlData)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemRd: Memory Allocation Failed\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
pXferBuff = ( ((PUCHAR)pIoctlData) + sizeof(BC_IOCTL_DATA));
|
|
|
|
pMemAccessRd = &pIoctlData->u.devMem;
|
|
size_in_dword = BuffSz / 4;
|
|
pIoctlData->RetSts = BC_STS_ERROR;
|
|
pIoctlData->IoctlDataSz = sizeof(BC_IOCTL_DATA);
|
|
pMemAccessRd->StartOff = Offset;
|
|
memset(pXferBuff,'a',BuffSz);
|
|
/* The size is passed in Bytes*/
|
|
pMemAccessRd->NumDwords = size_in_dword;
|
|
IOcCode = BCM_IOC_MEM_RD;
|
|
if(!DtsDrvIoctl(hDevice,
|
|
BCM_IOC_MEM_RD,
|
|
pIoctlData,
|
|
AllocSz,
|
|
pIoctlData,
|
|
AllocSz,
|
|
(LPDWORD)&BytesReturned,
|
|
0))
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemRd: DeviceIoControl Failed\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
if(BC_STS_ERROR == pIoctlData->RetSts)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemRd: IOCTL Cmd Failed By Driver\n");
|
|
return pIoctlData->RetSts;
|
|
}
|
|
|
|
memcpy(Buffer,pXferBuff,BuffSz);
|
|
|
|
if(pIoctlData)
|
|
free(pIoctlData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsDevMemWr(
|
|
HANDLE hDevice,
|
|
uint32_t *Buffer,
|
|
uint32_t BuffSz,
|
|
uint32_t Offset
|
|
)
|
|
{
|
|
uint8_t *pXferBuff;
|
|
uint32_t IOcCode,size_in_dword;
|
|
BC_IOCTL_DATA *pIoctlData;
|
|
BC_CMD_DEV_MEM *pMemAccessRd;
|
|
uint32_t BytesReturned,AllocSz;
|
|
|
|
//pIoctlData = (BC_IOCTL_DATA *)malloc(sizeof(BC_IOCTL_DATA));
|
|
|
|
|
|
if(!hDevice)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemWr: Invalid Handle\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if(!Buffer)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemWr: Null Buffer\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if(BuffSz % 4)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemWr: Buff Size is not a multiple of DWORD\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
|
|
AllocSz = sizeof(BC_IOCTL_DATA) + (BuffSz);
|
|
|
|
pIoctlData = (BC_IOCTL_DATA *) malloc(AllocSz);
|
|
|
|
if(!pIoctlData)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemWr: Memory Allocation Failed\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
pXferBuff = ( ((PUCHAR)pIoctlData) + sizeof(BC_IOCTL_DATA));
|
|
|
|
pMemAccessRd = &pIoctlData->u.devMem;
|
|
size_in_dword = BuffSz / 4;
|
|
pIoctlData->RetSts = BC_STS_ERROR;
|
|
pIoctlData->IoctlDataSz = sizeof(BC_IOCTL_DATA);
|
|
pMemAccessRd->StartOff = Offset;
|
|
memcpy(pXferBuff,Buffer,BuffSz);
|
|
/* The size is passed in Bytes*/
|
|
pMemAccessRd->NumDwords = size_in_dword;
|
|
IOcCode = BCM_IOC_MEM_WR;
|
|
if(!DtsDrvIoctl(hDevice,
|
|
BCM_IOC_MEM_WR,
|
|
pIoctlData,
|
|
AllocSz,
|
|
pIoctlData,
|
|
AllocSz,
|
|
(LPDWORD)&BytesReturned,
|
|
NULL))
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemWr: DeviceIoControl Failed\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
if(BC_STS_ERROR == pIoctlData->RetSts)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDevMemWr: IOCTL Cmd Failed By Driver\n");
|
|
return pIoctlData->RetSts;
|
|
}
|
|
|
|
if(pIoctlData)
|
|
free(pIoctlData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsTxDmaText( HANDLE hDevice ,
|
|
uint8_t *pUserData,
|
|
uint32_t ulSizeInBytes,
|
|
uint32_t *dramOff,
|
|
uint8_t Encrypted)
|
|
{
|
|
BC_STATUS status = BC_STS_SUCCESS;
|
|
uint32_t ulDmaSz;
|
|
uint8_t *pDmaBuff;
|
|
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if( (!pUserData) || (!ulSizeInBytes) || !dramOff)
|
|
{
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
pDmaBuff = pUserData;
|
|
ulDmaSz = ulSizeInBytes;
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
pIocData->RetSts = BC_STS_ERROR;
|
|
pIocData->IoctlDataSz = sizeof(BC_IOCTL_DATA);
|
|
pIocData->u.ProcInput.DramOffset =0;
|
|
pIocData->u.ProcInput.pDmaBuff = pDmaBuff;
|
|
pIocData->u.ProcInput.BuffSz = ulDmaSz;
|
|
pIocData->u.ProcInput.Mapped = FALSE;
|
|
pIocData->u.ProcInput.Encrypted = Encrypted;
|
|
if(Ctx->VidParams.VideoAlgo == BC_VID_ALGO_VC1MP)
|
|
pIocData->u.ProcInput.Encrypted|=0x2;
|
|
|
|
|
|
status = DtsDrvCmd(Ctx,BCM_IOC_PROC_INPUT,1,pIocData,FALSE);
|
|
|
|
*dramOff = pIocData->u.ProcInput.DramOffset;
|
|
|
|
if( BC_STS_SUCCESS != status && BC_STS_IO_USER_ABORT != status)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsTxDmaText: DeviceIoControl Failed with Sts %d\n", status);
|
|
}
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
DumpInputSampleToFile(pUserData,ulSizeInBytes);
|
|
|
|
return status;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsCancelProcOutput(
|
|
HANDLE hDevice,
|
|
PVOID Context)
|
|
{
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
return DtsCancelFetchOutInt(Ctx);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
// Name: DtsChkYUVSizes
|
|
// Description: Check Src/Dst buffer sizes with configured resolution.
|
|
//
|
|
// Vin: Strtucture received from HW
|
|
// Vout: Structure got from App (Where data need to be copied)
|
|
//
|
|
//------------------------------------------------------------------------
|
|
DRVIFLIB_INT_API BC_STATUS DtsChkYUVSizes(
|
|
DTS_LIB_CONTEXT *Ctx,
|
|
BC_DTS_PROC_OUT *Vout,
|
|
BC_DTS_PROC_OUT *Vin)
|
|
{
|
|
if (!Vout || !Vout->Ybuff || !Vin || !Vin->Ybuff){
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
if((!Ctx->b422Mode) && (!Vout->UVbuff || !Vin->UVbuff)){
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
/* Pass on size info irrespective of the status (for debug) */
|
|
Vout->YBuffDoneSz = Vin->YBuffDoneSz;
|
|
Vout->UVBuffDoneSz = Vin->UVBuffDoneSz;
|
|
|
|
/* Does Driver qualifies this condition before setting _PIB_VALID flag??..*/
|
|
if( !( Vin->YBuffDoneSz) || ((!Ctx->b422Mode) && (!Vin->UVBuffDoneSz)) ){
|
|
DebugLog_Trace(LDIL_DBG,"DtsChkYUVSizes: Incomplete Transfer\n");
|
|
return BC_STS_IO_XFR_ERROR;
|
|
}
|
|
/*
|
|
Let the upper layer take care of this
|
|
if(!(Vin->PoutFlags & BC_POUT_FLAGS_PIB_VALID)){
|
|
DebugLog_Trace(LDIL_DBG,"DtsChkYUVSizes: PIB not Valid\n");
|
|
return BC_STS_IO_XFR_ERROR;
|
|
}*/
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
/***/
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsGetDrvStat(
|
|
HANDLE hDevice,
|
|
BC_DTS_STATS *pDrvStat
|
|
)
|
|
{
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
BC_DTS_STATS *pIntDrvStat;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
// float fTemperature = 0;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
if(!pDrvStat)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsGetDrvStat: Invlid Arguments\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
if(Ctx->SingleThreadedAppMode)
|
|
pIocData->u.drvStat.DrvNextMDataPLD = pDrvStat->DrvNextMDataPLD;
|
|
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_GET_DRV_STAT,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsGetDriveStats: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
/* DIL counters */
|
|
pIntDrvStat = DtsGetgStats ( );
|
|
//memcpy_s(pDrvStat, 128, pIntDrvStat, 128);
|
|
memcpy(pDrvStat, pIntDrvStat, 128);
|
|
|
|
/* Driver counters */
|
|
pIntDrvStat = (BC_DTS_STATS *)&pIocData->u.drvStat;
|
|
pDrvStat->drvRLL = pIntDrvStat->drvRLL;
|
|
pDrvStat->drvFLL = pIntDrvStat->drvFLL;
|
|
pDrvStat->intCount = pIntDrvStat->intCount;
|
|
pDrvStat->pauseCount = pIntDrvStat->pauseCount;
|
|
pDrvStat->DrvIgnIntrCnt = pIntDrvStat->DrvIgnIntrCnt;
|
|
pDrvStat->DrvTotalFrmDropped = pIntDrvStat->DrvTotalFrmDropped;
|
|
pDrvStat->DrvTotalHWErrs = pIntDrvStat->DrvTotalHWErrs;
|
|
pDrvStat->DrvTotalPIBFlushCnt = pIntDrvStat->DrvTotalPIBFlushCnt;
|
|
pDrvStat->DrvTotalFrmCaptured = pIntDrvStat->DrvTotalFrmCaptured;
|
|
pDrvStat->DrvPIBMisses = pIntDrvStat->DrvPIBMisses;
|
|
pDrvStat->DrvPauseTime = pIntDrvStat->DrvPauseTime;
|
|
pDrvStat->DrvRepeatedFrms = pIntDrvStat->DrvRepeatedFrms;
|
|
pDrvStat->TxFifoBsyCnt = pIntDrvStat->TxFifoBsyCnt;
|
|
pDrvStat->pwr_state_change = pIntDrvStat->pwr_state_change;
|
|
pDrvStat->DrvNextMDataPLD = pIntDrvStat->DrvNextMDataPLD;
|
|
pDrvStat->DrvcpbEmptySize = pIntDrvStat->DrvcpbEmptySize;
|
|
pDrvStat->eosDetected = pIntDrvStat->eosDetected;
|
|
pDrvStat->picNumFlags = pIntDrvStat->picNumFlags;
|
|
|
|
|
|
//
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsSetTemperatureMeasure(
|
|
HANDLE hDevice,
|
|
BOOL bTurnOn
|
|
)
|
|
{
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
uint32_t Val = 0;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
if( Ctx->DevId != BC_PCI_DEVID_FLEA )
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetTemperatureMeasure Only support for Flea.\n");
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
if( bTurnOn )
|
|
{
|
|
Val = 0x3; //
|
|
sts = DtsDevRegisterWr(hDevice,BCHP_CLK_TEMP_MON_CTRL,Val);
|
|
bc_sleep_ms(10);
|
|
|
|
Val = 0x203; //
|
|
sts = DtsDevRegisterWr(hDevice,BCHP_CLK_TEMP_MON_CTRL,Val);
|
|
bc_sleep_ms(10);
|
|
}
|
|
else
|
|
{
|
|
Val = 0x103; //
|
|
sts = DtsDevRegisterWr(hDevice,BCHP_CLK_TEMP_MON_CTRL,Val);
|
|
bc_sleep_ms(10);
|
|
}
|
|
return sts;
|
|
}
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsGetCoreTemperature(
|
|
HANDLE hDevice,
|
|
float *pTemperature
|
|
)
|
|
{
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_ERROR;
|
|
uint32_t Val = 0;
|
|
*pTemperature = 0;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
if( Ctx->DevId != BC_PCI_DEVID_FLEA )
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsSetTemperatureMeasure Only support for Flea.\n");
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
sts = DtsDevRegisterRead(hDevice,BCHP_CLK_TEMP_MON_STATUS,&Val);
|
|
if( sts != BC_STS_SUCCESS )
|
|
return sts;
|
|
Val = Val & 0x0000ffff;
|
|
|
|
*pTemperature = 267.2 - 0.7 * (float)Val;
|
|
|
|
return sts;
|
|
}
|
|
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsRstDrvStat(
|
|
HANDLE hDevice
|
|
)
|
|
{
|
|
BC_IOCTL_DATA *pIocData = NULL;
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
/* CHECK WHETHER NULL pIocData CAN BE PASSED */
|
|
if(!(pIocData = DtsAllocIoctlData(Ctx)))
|
|
return BC_STS_INSUFF_RES;
|
|
|
|
/* Driver related counters */
|
|
if( (sts=DtsDrvCmd(Ctx,BCM_IOC_RST_DRV_STAT,0,pIocData,FALSE)) != BC_STS_SUCCESS){
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
DebugLog_Trace(LDIL_DBG,"DtsRstDrvStats: Ioctl failed: %d\n",sts);
|
|
return sts;
|
|
}
|
|
|
|
/* DIL related counters */
|
|
DtsRstStats( );
|
|
|
|
DtsRelIoctlData(Ctx,pIocData);
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
/**/
|
|
/* Get firmware files */
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsGetFWFiles(
|
|
HANDLE hDevice,
|
|
char *StreamFName,
|
|
char *VDecOuter,
|
|
char *VDecInner
|
|
)
|
|
{
|
|
DTS_LIB_CONTEXT *Ctx = NULL;
|
|
BC_STATUS sts = BC_STS_SUCCESS;
|
|
|
|
DTS_GET_CTX(hDevice,Ctx);
|
|
|
|
sts = DtsGetFirmwareFiles(Ctx);
|
|
if(sts == BC_STS_SUCCESS){
|
|
strncpy(StreamFName, Ctx->StreamFile, MAX_PATH);
|
|
strncpy(VDecOuter, Ctx->VidOuter, MAX_PATH);
|
|
strncpy(VDecInner, Ctx->VidInner, MAX_PATH );
|
|
}else{
|
|
return sts;
|
|
}
|
|
|
|
return sts;
|
|
}
|
|
/**/
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsDownloadFWBin(HANDLE hDevice, uint8_t *binBuff, uint32_t buffsize, uint32_t dramOffset)
|
|
{
|
|
BC_STATUS rstatus = BC_STS_SUCCESS;
|
|
|
|
/* Write bootloader vector table section */
|
|
rstatus = DtsDevMemWr(hDevice,(uint32_t *)binBuff,buffsize,dramOffset);
|
|
if (BC_STS_SUCCESS != rstatus)
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsDownloadFWBin: Fw Download Failed\n");
|
|
}
|
|
|
|
return rstatus;
|
|
}
|
|
|
|
BC_STATUS
|
|
DtsCopyRawDataToOutBuff(DTS_LIB_CONTEXT *Ctx,
|
|
BC_DTS_PROC_OUT *Vout,
|
|
BC_DTS_PROC_OUT *Vin)
|
|
{
|
|
uint32_t y,lDestStride=0;
|
|
uint8_t *pSrc = NULL, *pDest=NULL;
|
|
uint32_t dstWidthInPixels, dstHeightInPixels;
|
|
uint32_t srcWidthInPixels = 0, srcHeightInPixels;
|
|
BC_STATUS Sts = BC_STS_SUCCESS;
|
|
|
|
if ( (Sts = DtsChkYUVSizes(Ctx,Vout,Vin)) != BC_STS_SUCCESS)
|
|
return Sts;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE)
|
|
lDestStride = Vout->StrideSz;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_SIZE) {
|
|
// Use DShow provided size for now
|
|
dstWidthInPixels = Vout->PicInfo.width;
|
|
if(!Ctx->VidParams.Progressive)
|
|
dstHeightInPixels = Vout->PicInfo.height/2;
|
|
else
|
|
dstHeightInPixels = Vout->PicInfo.height;
|
|
/* Check for Valid data based on the filter information */
|
|
/* interlaced frames currently don't get delivered from the library if this check is in place */
|
|
#if 0
|
|
if(Vout->YBuffDoneSz < (dstWidthInPixels * dstHeightInPixels / 2)) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsCopy422: XFER ERROR dnsz %u, w %u, h %u\n", Vout->YBuffDoneSz, dstWidthInPixels, dstHeightInPixels);
|
|
return BC_STS_IO_XFR_ERROR;
|
|
}
|
|
#endif
|
|
srcWidthInPixels = Ctx->HWOutPicWidth;
|
|
srcHeightInPixels = dstHeightInPixels;
|
|
} else {
|
|
dstWidthInPixels = Vin->PicInfo.width;
|
|
dstHeightInPixels = Vin->PicInfo.height;
|
|
}
|
|
|
|
lDestStride = lDestStride*2;
|
|
dstWidthInPixels = dstWidthInPixels*2;
|
|
srcWidthInPixels = srcWidthInPixels*2;
|
|
// Do a strided copy only if the stride is non-zero
|
|
if( (lDestStride != 0)|| (srcWidthInPixels != dstWidthInPixels) ) {
|
|
// Y plane
|
|
pDest = Vout->Ybuff;
|
|
pSrc = Vin->Ybuff;
|
|
for (y = 0; y < dstHeightInPixels; y++){
|
|
memcpy(pDest,pSrc,dstWidthInPixels);
|
|
//memcpy_fast(pDest,pSrc,dstWidthInPixels*2);
|
|
pDest += dstWidthInPixels + lDestStride;
|
|
pSrc += (srcWidthInPixels);
|
|
}
|
|
} else {
|
|
// Y Plane
|
|
memcpy(Vout->Ybuff, Vin->Ybuff, dstHeightInPixels * dstWidthInPixels);
|
|
//memcpy_fast(Vout->Ybuff, Vin->Ybuff, dstHeightInPixels * dstWidthInPixels * 2);
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
/***/
|
|
//FIX_ME:: This routine assumes, Y & UV buffs are contiguous..
|
|
BC_STATUS DtsCopyNV12ToYV12(DTS_LIB_CONTEXT *Ctx, BC_DTS_PROC_OUT *Vout, BC_DTS_PROC_OUT *Vin)
|
|
{
|
|
|
|
uint8_t *buff=NULL;
|
|
uint8_t *yv12buff = NULL;
|
|
uint32_t uvbase=0;
|
|
BC_STATUS Sts = BC_STS_SUCCESS;
|
|
uint32_t x,y,lDestStrideY=0, lDestStrideUV=0;
|
|
uint8_t *pSrc = NULL, *pDest=NULL;
|
|
uint32_t dstWidthInPixels, dstHeightInPixels;
|
|
uint32_t srcWidthInPixels, srcHeightInPixels;
|
|
|
|
|
|
if ( (Sts = DtsChkYUVSizes(Ctx,Vout,Vin)) != BC_STS_SUCCESS)
|
|
return Sts;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_SIZE)// needs to be optimized.
|
|
{
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE)
|
|
lDestStrideUV = (lDestStrideY = Vout->StrideSz)/2;
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE_UV)
|
|
lDestStrideUV = Vout->StrideSzUV;
|
|
|
|
// Use DShow provided size for now
|
|
dstWidthInPixels = Vout->PicInfo.width;
|
|
if(!Ctx->VidParams.Progressive)
|
|
dstHeightInPixels = Vout->PicInfo.height/2;
|
|
else
|
|
dstHeightInPixels = Vout->PicInfo.height;
|
|
|
|
/* Check for Valid data based on the filter information */
|
|
if((Vout->YBuffDoneSz < (dstWidthInPixels * dstHeightInPixels / 4)) ||
|
|
(Vout->UVBuffDoneSz < (dstWidthInPixels * dstHeightInPixels/2 / 4)))
|
|
{
|
|
DebugLog_Trace(LDIL_DBG,"DtsCopyYV12: XFER ERROR\n");
|
|
return BC_STS_IO_XFR_ERROR;
|
|
}
|
|
srcWidthInPixels = Ctx->HWOutPicWidth;
|
|
srcHeightInPixels = dstHeightInPixels;
|
|
|
|
//copy luma
|
|
pDest = Vout->Ybuff;
|
|
pSrc = Vin->Ybuff;
|
|
for (y = 0; y < dstHeightInPixels; y++)
|
|
{
|
|
memcpy(pDest,pSrc,dstWidthInPixels);
|
|
pDest += dstWidthInPixels + lDestStrideY;
|
|
pSrc += srcWidthInPixels;
|
|
}
|
|
//copy chroma
|
|
pDest = Vout->UVbuff;
|
|
pSrc = Vin->UVbuff;
|
|
uvbase = (dstWidthInPixels + lDestStrideY) * dstHeightInPixels/4 ;//(Vin->UVBuffDoneSz * 4/2);
|
|
for (y = 0; y < dstHeightInPixels/2; y++)
|
|
{
|
|
for(x = 0; x < dstWidthInPixels; x += 2)
|
|
{
|
|
pDest[x/2] = pSrc[x+1];
|
|
pDest[uvbase + x/2] = pSrc[x];
|
|
}
|
|
pDest += dstWidthInPixels / 2 + lDestStrideUV;
|
|
pSrc += srcWidthInPixels;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Y-Buff loop */
|
|
buff = Vin->Ybuff;
|
|
yv12buff = Vout->Ybuff;
|
|
for(uint32_t i = 0; i < Vin->YBuffDoneSz*4; i += 2) {
|
|
yv12buff[i] = buff[i];
|
|
yv12buff[i+1] = buff[i+1];
|
|
}
|
|
|
|
/* UV-Buff loop */
|
|
buff = Vin->UVbuff;
|
|
yv12buff = Vout->UVbuff;
|
|
uvbase = (Vin->UVBuffDoneSz * 4/2);
|
|
for(uint32_t i = 0; i < Vin->UVBuffDoneSz*4; i += 2) {
|
|
yv12buff[i/2] = buff[i+1];
|
|
yv12buff[uvbase + (i/2)] = buff[i];
|
|
}
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
|
|
BC_STATUS DtsCopyNV12(DTS_LIB_CONTEXT *Ctx, BC_DTS_PROC_OUT *Vout, BC_DTS_PROC_OUT *Vin)
|
|
{
|
|
uint32_t y,lDestStrideY=0,lDestStrideUV=0;
|
|
uint8_t *pSrc = NULL, *pDest=NULL;
|
|
uint32_t dstWidthInPixels, dstHeightInPixels;
|
|
uint32_t srcWidthInPixels=0, srcHeightInPixels;
|
|
|
|
BC_STATUS Sts = BC_STS_SUCCESS;
|
|
|
|
if ( (Sts = DtsChkYUVSizes(Ctx,Vout,Vin)) != BC_STS_SUCCESS)
|
|
return Sts;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE)
|
|
lDestStrideUV = lDestStrideY = Vout->StrideSz;
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE_UV)
|
|
lDestStrideUV = Vout->StrideSzUV;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_SIZE) {
|
|
// Use DShow provided size for now
|
|
dstWidthInPixels = Vout->PicInfo.width;
|
|
if(!Ctx->VidParams.Progressive)
|
|
dstHeightInPixels = Vout->PicInfo.height/2;
|
|
else
|
|
dstHeightInPixels = Vout->PicInfo.height;
|
|
/* Check for Valid data based on the filter information */
|
|
if((Vout->YBuffDoneSz < (dstWidthInPixels * dstHeightInPixels / 4)) ||
|
|
(Vout->UVBuffDoneSz < (dstWidthInPixels * dstHeightInPixels/2 / 4)))
|
|
return BC_STS_IO_XFR_ERROR;
|
|
srcWidthInPixels = Ctx->HWOutPicWidth;
|
|
srcHeightInPixels = dstHeightInPixels;
|
|
} else {
|
|
dstWidthInPixels = Vin->PicInfo.width;
|
|
dstHeightInPixels = Vin->PicInfo.height;
|
|
}
|
|
|
|
// NV12 is planar: Y plane, followed by packed U-V plane.
|
|
|
|
// Do a strided copy only if the stride is non-zero
|
|
if((lDestStrideY != 0) || (lDestStrideUV != 0) || (srcWidthInPixels != dstWidthInPixels)) {
|
|
// Y plane
|
|
pDest = Vout->Ybuff;
|
|
pSrc = Vin->Ybuff;
|
|
for (y = 0; y < dstHeightInPixels; y++){
|
|
memcpy(pDest,pSrc,dstWidthInPixels);
|
|
pDest += dstWidthInPixels + lDestStrideY;
|
|
pSrc += srcWidthInPixels;
|
|
}
|
|
// U-V plane
|
|
pDest = Vout->UVbuff;
|
|
pSrc = Vin->UVbuff;
|
|
for (y = 0; y < dstHeightInPixels/2; y++){
|
|
memcpy(pDest,pSrc,dstWidthInPixels);
|
|
pDest += dstWidthInPixels + lDestStrideUV;
|
|
pSrc += srcWidthInPixels;
|
|
}
|
|
} else {
|
|
// Y Plane
|
|
memcpy(Vout->Ybuff, Vin->Ybuff, dstHeightInPixels * dstWidthInPixels);
|
|
// UV Plane
|
|
memcpy(Vout->UVbuff, Vin->UVbuff, dstHeightInPixels/2 * dstWidthInPixels);
|
|
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
// TODO: add sse2 detection
|
|
static bool gSSE2 = true; // most of the platforms will have it anyway:
|
|
// 64 bits: no test necessary
|
|
// mac: no test necessary
|
|
// linux/windows: we might have to do the test.
|
|
|
|
static void fast_memcpy(uint8_t *dst, const uint8_t *src, uint32_t count)
|
|
{
|
|
// tested
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dst) & 0xf) == 0) && ((((uintptr_t) src) & 0xf) == 0))
|
|
{
|
|
while (count >= (16*4))
|
|
{
|
|
_mm_stream_si128((__m128i *) (dst+ 0*16), _mm_load_si128((__m128i *) (src+ 0*16)));
|
|
_mm_stream_si128((__m128i *) (dst+ 1*16), _mm_load_si128((__m128i *) (src+ 1*16)));
|
|
_mm_stream_si128((__m128i *) (dst+ 2*16), _mm_load_si128((__m128i *) (src+ 2*16)));
|
|
_mm_stream_si128((__m128i *) (dst+ 3*16), _mm_load_si128((__m128i *) (src+ 3*16)));
|
|
count -= 16*4;
|
|
src += 16*4;
|
|
dst += 16*4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (count >= (16*4))
|
|
{
|
|
_mm_storeu_si128((__m128i *) (dst+ 0*16), _mm_loadu_si128((__m128i *) (src+ 0*16)));
|
|
_mm_storeu_si128((__m128i *) (dst+ 1*16), _mm_loadu_si128((__m128i *) (src+ 1*16)));
|
|
_mm_storeu_si128((__m128i *) (dst+ 2*16), _mm_loadu_si128((__m128i *) (src+ 2*16)));
|
|
_mm_storeu_si128((__m128i *) (dst+ 3*16), _mm_loadu_si128((__m128i *) (src+ 3*16)));
|
|
count -= 16*4;
|
|
src += 16*4;
|
|
dst += 16*4;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (count --)
|
|
*dst++ = *src++;
|
|
}
|
|
|
|
// this is not good.
|
|
// if we have 3 buffers, we cannot assume V is after U
|
|
static BC_STATUS DtsCopy422ToYV12(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{ // copy YUY2 to YV12
|
|
// TODO
|
|
// NOTE: if we want to support this porperly, we will need to add a Vbuffer pointer
|
|
// if we have 3 destination buffers, there's no guarantee that V buffer is derivable from UV pointer.
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
// this is just a memcpy
|
|
static BC_STATUS DtsCopy422ToYUY2(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{ // copy YUY2 to YUY2
|
|
uint32_t y;
|
|
|
|
// TODO: test this
|
|
strideY += dstWidth*2;
|
|
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
fast_memcpy(dstY, srcY, srcWidth*2);
|
|
srcY += srcWidth*2;
|
|
dstY += strideY;
|
|
}
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
// almost a memcpy, we just need to shuffle YUV's around
|
|
static BC_STATUS DtsCopy422ToUYVY(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{
|
|
// TODO, test this
|
|
uint32_t x = 0, __y;
|
|
|
|
strideY += dstWidth*2;
|
|
|
|
for (__y = 0; __y < height; __y++)
|
|
{
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-7)
|
|
{
|
|
__m128i v = _mm_load_si128((__m128i *)(srcY+x*2));
|
|
__m128i v1 = _mm_srli_epi16(v, 8);
|
|
__m128i v2 = _mm_slli_epi16(v, 8);
|
|
_mm_stream_si128((__m128i *)(dstY+x*2), _mm_or_si128(v1, v2));
|
|
x += 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-7)
|
|
{
|
|
__m128i v = _mm_loadu_si128((__m128i *)(srcY+x*2));
|
|
__m128i v1 = _mm_srli_epi16(v, 8);
|
|
__m128i v2 = _mm_slli_epi16(v, 8);
|
|
_mm_storeu_si128((__m128i *)(dstY+x*2), _mm_or_si128(v1, v2));
|
|
x += 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+0] = srcY[x+1];
|
|
dstY[x*2+1] = srcY[x+0];
|
|
dstY[x*2+2] = srcY[x+3];
|
|
dstY[x*2+3] = srcY[x+2];
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth*2;
|
|
dstY += strideY;
|
|
}
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
// convert to NV12
|
|
static BC_STATUS DtsCopy422ToNV12(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{
|
|
// tested
|
|
uint32_t x, __y;
|
|
|
|
strideY += dstWidth;
|
|
strideUV += dstWidth;
|
|
|
|
static __m128i mask = _mm_set_epi16(0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff);
|
|
|
|
for (__y = 0; __y < height; __y += 2)
|
|
{
|
|
x = 0;
|
|
|
|
// first line: Y and UV extraction
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0) && ((((uintptr_t) dstUV) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i s1 = _mm_load_si128((__m128i *) (srcY+x*2+ 0)); // load 8 pixels
|
|
__m128i s2 = _mm_load_si128((__m128i *) (srcY+x*2+16)); // load 8 more
|
|
|
|
__m128i y1 = _mm_and_si128(s1, mask); // mask out uvs
|
|
__m128i y2 = _mm_and_si128(s2, mask); // mask out uvs
|
|
__m128i y = _mm_packus_epi16 (y1, y2); // get the y together
|
|
_mm_stream_si128((__m128i *) (dstY+x), y); // store 16 Y
|
|
|
|
s1 = _mm_srli_epi16(s1, 8); // get rid of Y
|
|
s2 = _mm_srli_epi16(s2, 8); // get rid of Y
|
|
__m128i uv = _mm_packus_epi16 (s1, s2); // get the uv together
|
|
_mm_stream_si128((__m128i *) (dstUV+x), uv); // store 8 UV pairs
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i s1 = _mm_loadu_si128((__m128i *) (srcY+x*2+ 0)); // load 8 pixels
|
|
__m128i s2 = _mm_loadu_si128((__m128i *) (srcY+x*2+16)); // load 8 more
|
|
|
|
__m128i y1 = _mm_and_si128(s1, mask); // mask out uvs
|
|
__m128i y2 = _mm_and_si128(s2, mask); // mask out uvs
|
|
__m128i y = _mm_packus_epi16 (y1, y2); // get the y together
|
|
_mm_storeu_si128((__m128i *) (dstY+x), y); // store 16 Y
|
|
|
|
s1 = _mm_srli_epi16(s1, 8); // get rid of Y
|
|
s2 = _mm_srli_epi16(s2, 8); // get rid of Y
|
|
__m128i uv = _mm_packus_epi16 (s1, s2); // get the uv together
|
|
_mm_storeu_si128((__m128i *) (dstUV+x), uv); // store 8 UV pairs
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY [x+0] = srcY[x*2+0]; // Y
|
|
dstUV[x+0] = srcY[x*2+1]; // U
|
|
dstY [x+1] = srcY[x*2+2]; // Y
|
|
dstUV[x+1] = srcY[x*2+3]; // V
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth*2;
|
|
dstY += strideY;
|
|
dstUV += strideUV;
|
|
|
|
// second line: just Y
|
|
x = 0;
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i s1 = _mm_load_si128((__m128i *) (srcY+x*2+ 0)); // load 8 pixels
|
|
__m128i s2 = _mm_load_si128((__m128i *) (srcY+x*2+16)); // load 8 more
|
|
|
|
__m128i y1 = _mm_and_si128(s1, mask); // mask out uvs
|
|
__m128i y2 = _mm_and_si128(s2, mask); // mask out uvs
|
|
__m128i y = _mm_packus_epi16 (y1, y2); // get the y
|
|
_mm_stream_si128((__m128i *) (dstY+x), y); // store 16 Y
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i s1 = _mm_loadu_si128((__m128i *) (srcY+x*2+ 0)); // load 8 pixels
|
|
__m128i s2 = _mm_loadu_si128((__m128i *) (srcY+x*2+16)); // load 8 more
|
|
|
|
__m128i y1 = _mm_and_si128(s1, mask); // mask out uvs
|
|
__m128i y2 = _mm_and_si128(s2, mask); // mask out uvs
|
|
__m128i y = _mm_packus_epi16 (y1, y2); // get the y
|
|
_mm_storeu_si128((__m128i *) (dstY+x), y); // store 16 Y
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY [x+0] = srcY[x*2+0]; // Y
|
|
dstY [x+1] = srcY[x*2+2]; // Y
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth*2;
|
|
dstY += strideY;
|
|
}
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
|
|
// this is not good.
|
|
// if we have 3 textures, we cannot assume V is after U
|
|
static BC_STATUS DtsCopy420ToYV12(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{
|
|
// TODO
|
|
// NOTE: if we want to support this porperly, we will need to add a Vbuffer pointer
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
static BC_STATUS DtsCopy420ToYUY2(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{
|
|
// TODO, test this
|
|
uint32_t x, __y;
|
|
|
|
strideY += dstWidth*2;
|
|
|
|
__y = 0;
|
|
while (__y < height-2)
|
|
{
|
|
// first line
|
|
x = 0;
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_load_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_load_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(y, uv)); // store 8 pixels
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(y, uv)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_loadu_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_loadu_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(y, uv)); // store 8 pixels
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(y, uv)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+0] = srcY [x+0];
|
|
dstY[x*2+1] = srcUV[x+0];
|
|
dstY[x*2+2] = srcY [x+1];
|
|
dstY[x*2+3] = srcUV[x+1];
|
|
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth;
|
|
dstY += strideY;
|
|
|
|
// second line
|
|
|
|
x = 0;
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_load_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv1 = _mm_load_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
__m128i uv2 = _mm_load_si128((__m128i *) (srcUV+x+srcWidth)); // load 8 UV
|
|
__m128i uv = _mm_avg_epu8(uv1, uv2);
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(y, uv)); // store 8 pixels
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(y, uv)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_loadu_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv1 = _mm_loadu_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
__m128i uv2 = _mm_loadu_si128((__m128i *) (srcUV+x+srcWidth)); // load 8 UV
|
|
__m128i uv = _mm_avg_epu8(uv1, uv2);
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(y, uv)); // store 8 pixels
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(y, uv)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+0] = srcY [x+0];
|
|
dstY[x*2+1] = (srcUV[x+0] + srcUV[x+0+srcWidth])/2;
|
|
dstY[x*2+2] = srcY [x+1];
|
|
dstY[x*2+3] = (srcUV[x+1] + srcUV[x+1+srcWidth])/2;
|
|
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth;
|
|
srcUV += srcWidth;
|
|
dstY += strideY;
|
|
|
|
__y += 2;
|
|
}
|
|
|
|
// last 2 lines
|
|
while (__y < height)
|
|
{
|
|
x = 0;
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_load_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_load_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(y, uv)); // store 8 pixels
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(y, uv)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_loadu_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_loadu_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(y, uv)); // store 8 pixels
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(y, uv)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+0] = srcY [x+0];
|
|
dstY[x*2+1] = srcUV[x+0];
|
|
dstY[x*2+2] = srcY [x+1];
|
|
dstY[x*2+3] = srcUV[x+1];
|
|
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth;
|
|
dstY += strideY;
|
|
|
|
__y++;
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
static BC_STATUS DtsCopy420ToUYVY(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{
|
|
// TODO, test this
|
|
uint32_t x, __y;
|
|
|
|
strideY += dstWidth*2;
|
|
|
|
__y = 0;
|
|
while (__y < height-2)
|
|
{
|
|
// first line
|
|
x = 0;
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_load_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_load_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(uv, y)); // store 8 pixels
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(uv, y)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_loadu_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_loadu_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(uv, y)); // store 8 pixels
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(uv, y)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+1] = srcY [x+0];
|
|
dstY[x*2+0] = srcUV[x+0];
|
|
dstY[x*2+3] = srcY [x+1];
|
|
dstY[x*2+2] = srcUV[x+1];
|
|
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth;
|
|
dstY += strideY;
|
|
|
|
// second line
|
|
|
|
x = 0;
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_load_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv1 = _mm_load_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
__m128i uv2 = _mm_load_si128((__m128i *) (srcUV+x+srcWidth)); // load 8 UV
|
|
__m128i uv = _mm_avg_epu8(uv1, uv2);
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(uv, y)); // store 8 pixels
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(uv, y)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_loadu_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv1 = _mm_loadu_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
__m128i uv2 = _mm_loadu_si128((__m128i *) (srcUV+x+srcWidth)); // load 8 UV
|
|
__m128i uv = _mm_avg_epu8(uv1, uv2);
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(uv, y)); // store 8 pixels
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(uv, y)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+1] = srcY [x+0];
|
|
dstY[x*2+0] = (srcUV[x+0] + srcUV[x+0+srcWidth])/2;
|
|
dstY[x*2+3] = srcY [x+1];
|
|
dstY[x*2+2] = (srcUV[x+1] + srcUV[x+1+srcWidth])/2;
|
|
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth;
|
|
srcUV += srcWidth;
|
|
dstY += strideY;
|
|
}
|
|
|
|
// last 2 lines
|
|
while (__y < height)
|
|
{
|
|
x = 0;
|
|
|
|
if (gSSE2)
|
|
{
|
|
if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0))
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_load_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_load_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(uv, y)); // store 8 pixels
|
|
_mm_stream_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(uv, y)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (x < srcWidth-15)
|
|
{
|
|
__m128i y = _mm_loadu_si128((__m128i *) (srcY+x)); // load 16 Y pixels
|
|
__m128i uv = _mm_loadu_si128((__m128i *) (srcUV+x)); // load 8 UV
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+ 0), _mm_unpacklo_epi8(uv, y)); // store 8 pixels
|
|
_mm_storeu_si128((__m128i *) (dstY+x*2+16), _mm_unpackhi_epi8(uv, y)); // store 8 pixels
|
|
|
|
x += 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (x < srcWidth-1)
|
|
{
|
|
dstY[x*2+1] = srcY [x+0];
|
|
dstY[x*2+0] = srcUV[x+0];
|
|
dstY[x*2+3] = srcY [x+1];
|
|
dstY[x*2+2] = srcUV[x+1];
|
|
|
|
x += 2;
|
|
}
|
|
|
|
srcY += srcWidth;
|
|
dstY += strideY;
|
|
|
|
__y++;
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
static BC_STATUS DtsCopy420ToNV12(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV)
|
|
{ // tested
|
|
uint32_t __y;
|
|
|
|
strideY += dstWidth;
|
|
strideUV += dstWidth;
|
|
|
|
// first copy Y
|
|
for (__y = 0; __y < height; __y++)
|
|
{
|
|
fast_memcpy(dstY, srcY, srcWidth);
|
|
dstY += strideY;
|
|
srcY += srcWidth;
|
|
}
|
|
|
|
// now copy uvs
|
|
height /= 2;
|
|
for (__y = 0; __y < height; __y++)
|
|
{
|
|
fast_memcpy(dstUV, srcUV, srcWidth);
|
|
srcUV += srcWidth;
|
|
dstUV += strideUV;
|
|
|
|
}
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
|
|
// copy 422/420 ( device format to format specified in Vout)
|
|
BC_STATUS DtsCopyFormat(DTS_LIB_CONTEXT *Ctx, BC_DTS_PROC_OUT *Vout, BC_DTS_PROC_OUT *Vin)
|
|
{
|
|
uint32_t lDestStrideY=0, lDestStrideUV=0;
|
|
uint32_t dstHeightInPixels;
|
|
|
|
BC_STATUS Sts = BC_STS_SUCCESS;
|
|
|
|
if ( (Sts = DtsChkYUVSizes(Ctx,Vout,Vin)) != BC_STS_SUCCESS)
|
|
return Sts;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE)
|
|
lDestStrideUV = lDestStrideY = Vout->StrideSz;
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_STRIDE_UV)
|
|
lDestStrideUV = Vout->StrideSzUV;
|
|
|
|
if(Vout->PoutFlags & BC_POUT_FLAGS_SIZE) {
|
|
// Use application provided size for now
|
|
if(!Ctx->VidParams.Progressive)
|
|
dstHeightInPixels = Vout->PicInfo.height/2;
|
|
else
|
|
dstHeightInPixels = Vout->PicInfo.height;
|
|
/* Check for Valid data based on the application information */
|
|
// we cannot do that any more.size may vary, we have to suppose them
|
|
// ok
|
|
// if((Vout->YBuffDoneSz < (dstWidthInPixels * dstHeightInPixels / 4)) ||
|
|
// (Vout->UVBuffDoneSz < (dstWidthInPixels * dstHeightInPixels/2 / 4)))
|
|
// return BC_STS_IO_XFR_ERROR;
|
|
} else {
|
|
dstHeightInPixels = Vin->PicInfo.height;
|
|
}
|
|
|
|
// check that we can do the copy properly
|
|
if (Ctx->HWOutPicWidth > Vin->PicInfo.width)
|
|
return BC_STS_IO_XFR_ERROR;
|
|
|
|
//DebugLog_Trace(LDIL_DBG,"Copying from %d to %d\n", Ctx->b422Mode, Vout->b422Mode);
|
|
|
|
if (Ctx->b422Mode) {
|
|
// input is 422 (YUY2)
|
|
switch (Vout->b422Mode) {
|
|
case OUTPUT_MODE422_YUY2:
|
|
Sts = DtsCopy422ToYUY2(
|
|
Vout->Ybuff, Vout->UVbuff, Vin->Ybuff,
|
|
Ctx->HWOutPicWidth, Vin->PicInfo.width, dstHeightInPixels, lDestStrideY, lDestStrideUV
|
|
);
|
|
break;
|
|
case OUTPUT_MODE422_UYVY:
|
|
Sts = DtsCopy422ToUYVY(
|
|
Vout->Ybuff, Vout->UVbuff, Vin->Ybuff,
|
|
Ctx->HWOutPicWidth, Vin->PicInfo.width, dstHeightInPixels, lDestStrideY, lDestStrideUV
|
|
);
|
|
break;
|
|
case OUTPUT_MODE420_NV12:
|
|
Sts = DtsCopy422ToNV12(
|
|
Vout->Ybuff, Vout->UVbuff, Vin->Ybuff,
|
|
Ctx->HWOutPicWidth, Vin->PicInfo.width, dstHeightInPixels, lDestStrideY, lDestStrideUV
|
|
);
|
|
break;
|
|
default:
|
|
Sts = BC_STS_INV_ARG;
|
|
break;
|
|
}
|
|
}else{
|
|
// input is 420 (NV12)
|
|
switch (Vout->b422Mode) {
|
|
case OUTPUT_MODE422_YUY2:
|
|
Sts = DtsCopy420ToYUY2(
|
|
Vout->Ybuff, Vout->UVbuff, Vin->Ybuff, Vin->UVbuff,
|
|
Ctx->HWOutPicWidth, Vin->PicInfo.width, dstHeightInPixels, lDestStrideY, lDestStrideUV
|
|
);
|
|
break;
|
|
case OUTPUT_MODE422_UYVY:
|
|
Sts = DtsCopy420ToUYVY(
|
|
Vout->Ybuff, Vout->UVbuff, Vin->Ybuff, Vin->UVbuff,
|
|
Ctx->HWOutPicWidth, Vin->PicInfo.width, dstHeightInPixels, lDestStrideY, lDestStrideUV
|
|
);
|
|
break;
|
|
case OUTPUT_MODE420_NV12:
|
|
Sts = DtsCopy420ToNV12(
|
|
Vout->Ybuff, Vout->UVbuff, Vin->Ybuff, Vin->UVbuff,
|
|
Ctx->HWOutPicWidth, Vin->PicInfo.width, dstHeightInPixels, lDestStrideY, lDestStrideUV
|
|
);
|
|
break;
|
|
default:
|
|
Sts = BC_STS_INV_ARG;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return Sts;
|
|
}
|
|
|
|
|
|
|
|
|
|
DRVIFLIB_INT_API BC_STATUS
|
|
DtsPushFwBinToLink(
|
|
HANDLE hDevice,
|
|
uint32_t *Buffer,
|
|
uint32_t BuffSz)
|
|
{
|
|
uint8_t *pXferBuff;
|
|
BC_IOCTL_DATA *pIoctlData;
|
|
BC_CMD_DEV_MEM *pMemAccess;
|
|
uint32_t BytesReturned, AllocSz;
|
|
|
|
if (!hDevice) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsPushFwBinToLink: Invalid Handle\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if (!Buffer) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsPushFwBinToLink: Null Buffer\n");
|
|
return BC_STS_INV_ARG;
|
|
}
|
|
|
|
if (BuffSz % 4) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsPushFwBinToLink: Buff Size is not a multiple of DWORD\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
AllocSz = sizeof(BC_IOCTL_DATA) + (BuffSz);
|
|
pIoctlData = (BC_IOCTL_DATA *) malloc(AllocSz);
|
|
if(!pIoctlData) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsPushFwBinToLink: Memory Allocation Failed\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
memset(pIoctlData, 0, AllocSz);
|
|
pXferBuff = ((PUCHAR)pIoctlData) + sizeof(BC_IOCTL_DATA);
|
|
pMemAccess = &pIoctlData->u.devMem;
|
|
pIoctlData->RetSts = BC_STS_ERROR;
|
|
pIoctlData->IoctlDataSz = sizeof(BC_IOCTL_DATA);
|
|
pMemAccess->StartOff = 0;
|
|
pMemAccess->NumDwords = BuffSz/4;
|
|
memcpy(pXferBuff, Buffer, BuffSz);
|
|
|
|
if (!DtsDrvIoctl(hDevice, BCM_IOC_FW_DOWNLOAD, pIoctlData, AllocSz, pIoctlData, AllocSz, (LPDWORD)&BytesReturned, 0)) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsPushFwBinToLink: DeviceIoControl Failed\n");
|
|
return BC_STS_ERROR;
|
|
}
|
|
|
|
if (BC_STS_ERROR == pIoctlData->RetSts) {
|
|
DebugLog_Trace(LDIL_DBG,"DtsPushFwBinToLink: IOCTL Cmd Failed By Driver\n");
|
|
return pIoctlData->RetSts;
|
|
}
|
|
|
|
if(pIoctlData) {
|
|
free(pIoctlData);
|
|
}
|
|
|
|
return BC_STS_SUCCESS;
|
|
}
|
|
|
|
/*====================== Debug Routines ========================================*/
|
|
void DumpDataToFile(FILE *fp, char *header, uint32_t off, uint8_t *buff, uint32_t dwcount)
|
|
{
|
|
uint32_t i, k=1;
|
|
|
|
#ifndef _LIB_EN_FWDUMP_
|
|
// Skip FW Download dumping..
|
|
return ;
|
|
#endif
|
|
|
|
if(!fp)
|
|
return;
|
|
|
|
if(header){
|
|
fprintf(fp,"%s\n",header);
|
|
}
|
|
|
|
for(i = 0; i < dwcount; i++){
|
|
if (k == 1)
|
|
fprintf(fp, "0x%08X : ", off);
|
|
|
|
fprintf(fp," 0x%08X ", *((uint32_t *)buff));
|
|
|
|
buff += sizeof(uint32_t);
|
|
off += sizeof(uint32_t);
|
|
k++;
|
|
if ((i == dwcount - 1) || (k > 4)){
|
|
fprintf(fp,"\n");
|
|
k = 1;
|
|
}
|
|
}
|
|
//fprintf(fp,"\n");
|
|
|
|
fflush(fp);
|
|
}
|
|
|
|
void DumpInputSampleToFile(uint8_t *buff, uint32_t buffsize)
|
|
{
|
|
#ifndef _LIB_EN_INDUMP_
|
|
return ;
|
|
#endif
|
|
|
|
static FILE *pOutputFile=NULL;
|
|
|
|
if(!buff || !buffsize){
|
|
if(pOutputFile){
|
|
fclose(pOutputFile);
|
|
pOutputFile = NULL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(!pOutputFile){
|
|
if(!(pOutputFile = fopen("hdfile_dump.ts","wb")) )
|
|
return;
|
|
}
|
|
|
|
fwrite(buff, sizeof(uint8_t), buffsize, pOutputFile);
|
|
|
|
fflush(pOutputFile);
|
|
}
|
|
|