blob: 7861d545e5774718be889d56124f59f2bdbbc9d1 [file] [log] [blame]
/***************************************************
Copyright (c) 2015 Amphion Semiconductor Ltd
All rights reserved.
***************************************************
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
****************************************************
Author : Media IP FW team ( Belfast and Shanghai )
File name : DecLibHWControl.c
Notes : Processes commands from decoder lib scheduler
Establishes context for and makes calls to
the base decoders
This file provides the hardware facing aspect to
the interface. It is part of a group with
DecLibStreamControl.c which provides the
HW funtionality
******************************************************/
/////////////////////////////////////////////////////////////////////////////////
// Header Files
/////////////////////////////////////////////////////////////////////////////////
#include "basetype.h"
#include "mediaip_fw_types.h"
#include "pal.h"
#include "mvd_types.h"
#include "mvd_reg_map.h"
#include "mvd_sif_control.h"
#include "DecKernelLibPrivate.h"
#include "DecKernelLibHWControl.h"
/////////////////////////////////////////////////////////////////////////////////
// Extern Function Prototypes
/////////////////////////////////////////////////////////////////////////////////
extern MEDIAIP_IRQ_RETCODE mvd_kernel_hw_primary_isr ( u_int32 irq_val );
extern MEDIAIP_IRQ_RETCODE mvd_kernel_hw_secondary_isr ( u_int32 irq_val );
/////////////////////////////////////////////////////////////////////////////////
// Private Function Prototypes
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////////;
extern DEC_KERNEL_LIB gDecKernelLib;
MALONE_KERNEL_HW_SESSION gMvdKernelHw[(DECODERLIB_MAX_MALONES + 1)];
pMALONE_KERNEL_HW_SESSION pgMVDKernelHw;
u_int32 gMaloneList[(DECODERLIB_MAX_MALONES + 1)] = { MALONE_HW_1,
#if DECODERLIB_MAX_MALONES > 1
MALONE_HW_2,
#endif
MALONE_SW };
static u_int32 uSWMaloneRegSpace[2048]; /* Until we are sure we have eliminated register access */
/* for functions using the 'SW Malone', point them here */
extern u_int32 uDecLibIrqPin[DECODERLIB_MAX_MALONES][0x2];
/////////////////////////////////////////////////////////////////////////////////
// Code
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: mvd_kernel_hw_control_init //
// //
// DESCRIPTION: Perform all HW initialisation and shared structure setup //
// //
// INPUTS: uMaloneID - The ID of the Malone for which the info is to //
// be restored //
// pCtxArea - Pointer to area of memory from which data is to be //
// read //
// //
// OUTPUTS: None. //
// //
// RETURNS: None. //
// //
// NOTES: None. //
// //
// CONTEXT: This function must be called from non-interrupt context //
// //
////////////////////////////////////////////////////////////////////////////////////
void mvd_kernel_hw_control_init ( DECODERLIB_KERNEL_CFG * pCfg )
{
/* Init the handles */
/* This sets up the reg pointers so do it first */
mvd_kernel_hw_init_handles ( pCfg,
TRUE );
/* Default global pointers to a 1st Malone focus */
mvd_kernel_hw_set_focus ( MALONE_HW_1, &pgMVDKernelHw );
}
////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: mvd_kernel_hw_set_malone_instance //
// //
// DESCRIPTION: Look for the most appropriate Malone instance to service //
// the command for a specified stream //
// //
// INPUTS: uStrId - The Stream ID //
// bSWCmd - is the command to be carried out for this stream //
// capable of being handled without using the HW engine? //
// uHWIndex - HW Index suggested by scheduler //
// bUseSch - Set to guarantee scheduler suggested unit is used //
// //
// OUTPUTS: None. //
// //
// RETURNS: The most suitable Malone ID to be used //
// //
// NOTES: This function must return a value. //
// //
// CONTEXT: This function must be called from non-interrupt context //
// //
////////////////////////////////////////////////////////////////////////////////////
u_int32 mvd_kernel_hw_set_malone_instance ( u_int32 uStrId,
bool bSWCmd,
u_int32 uHWIndex,
bool bUseSch
)
{
u_int32 uIdx = 0;
if ( bUseSch )
{
return uHWIndex;
}
for ( uIdx = 0; uIdx < gDecKernelLib.uNumMalones; uIdx++ )
{
/* Even if there is no command active, this is a valid check as */
/* it avoids need for a context change if it matches */
if ( gMvdKernelHw[uIdx].uStrID == uStrId )
{
return uIdx;
}
}
if ( bSWCmd ) return MALONE_SW;
/* Look for free Malone - this function should not be called */
/* unless this is a SW command or there is a free Malone */
for ( uIdx = 0; uIdx < gDecKernelLib.uNumMalones; uIdx++ )
{
/* Even if there is no command active, this is a valid check as */
/* it avoids need for a context change if it matches */
if ( gMvdKernelHw[uIdx].eState == MALONE_INACTIVE )
{
break;
}
}
/* Do not assign this stream and do NOT make it active yet */
/* Only make this malone active when the command is issued */
/* This is necessary so we we can trigger context switches */
/* We should set the global pointer though so calls to sif */
/* etc can get correct functions!! */
mvd_kernel_hw_set_focus ( uIdx, &pgMVDKernelHw );
return uIdx;
}
////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: mvd_kernel_hw_set_focus //
// //
// DESCRIPTION: Changes focus to the selected Malone HW unit //
// //
// INPUTS: uMaloneID - The ID of the Malone //
// //
// OUTPUTS: ppMVDHw - Pointer to a HW session structure for the specified //
// Malone //
// //
// RETURNS: None. //
// //
// NOTES: Only makes sense in multi-malone configs //
// //
// CONTEXT: This function may be called from any context //
// //
////////////////////////////////////////////////////////////////////////////////////
void mvd_kernel_hw_set_focus ( u_int32 uMaloneID, pMALONE_KERNEL_HW_SESSION * ppMVDHw )
{
*ppMVDHw = ( MALONE_KERNEL_HW_SESSION * )&gMvdKernelHw[uMaloneID];
}
////////////////////////////////////////////////////////////////////////////////////
// FUNCTION: mvd_kernel_hw_init_handles //
// //
// DESCRIPTION: Initialise the HW session handles //
// //
// INPUTS: pCfg - A pointer to the DecLib Config structure //
// bSoftInit - If set, the FW pointers get established - leave //
// FALSE when restarting from a snapshot //
// //
// OUTPUTS: None. //
// //
// RETURNS: None. //
// //
// NOTES: None. //
// //
// CONTEXT: This function must be called from non-interrupt context //
// //
////////////////////////////////////////////////////////////////////////////////////
void mvd_kernel_hw_init_handles ( DECODERLIB_KERNEL_CFG * pCfg,
bool bSoftInit
)
{
u_int32 uIdx;
pMALONE_KERNEL_HW_SESSION pMVDHw;
MvdHwRegMap *pMvdReg;
for ( uIdx = 0; uIdx < (gDecKernelLib.uNumMalones + 1); uIdx++ )
{
/* If we have set up all the HW handles then move to the SW */
/* handle and set it up */
if ( uIdx == gDecKernelLib.uNumMalones ) uIdx = DECODERLIB_MAX_MALONES;
pMVDHw = &gMvdKernelHw[uIdx];
if ( bSoftInit )
{
pMVDHw->eState = MALONE_INACTIVE;
pMVDHw->uStrID = 0;
pMVDHw->uForceFIQ = 0;
pMVDHw->uForceDFEFIQ = 0;
/* Malone ID that the instance uses, normally fixed... */
pMVDHw->uMaloneID = gMaloneList[uIdx];
}
if ( pMVDHw->uMaloneID == DECODERLIB_MAX_MALONES )
{
pMvdReg = ( MvdHwRegMap * )uSWMaloneRegSpace;
}
else if ( pMVDHw->uMaloneID == MALONE_HW_2 )
{
pMvdReg = ( MvdHwRegMap * ) ( pCfg->uMaloneBaseAddr[0x1] + pCfg->uMaloneHifOffset[0x1] );
}
else
{
pMvdReg = ( MvdHwRegMap * ) ( pCfg->uMaloneBaseAddr[0x0] + pCfg->uMaloneHifOffset[0x0] );
}
if ( pMVDHw->uMaloneID == MALONE_SW )
{
pMVDHw->msd_regp = ( MvdHwRegMap * )pMvdReg;
pMVDHw->hif_regp = ( MvdHwRegHifMap * )pMvdReg;
pMVDHw->sif_regp = ( MvdHwRegSifMap * )pMvdReg;
pMVDHw->ctx_regp = ( MvdHwRegCtxMap * )pMvdReg;
pMVDHw->rsb_regp = ( MvdHwReg * )pMvdReg;
pMVDHw->rpr_regp = ( MvdHwRegRprMap * )pMvdReg;
pMVDHw->spp_regp = ( MvdHwRegSppMap * )pMvdReg;
pMVDHw->avc_regp = ( MvdHwRegH264Map * )pMvdReg;
pMVDHw->mp2d_regp = ( MvdHwRegMp2dMap * )pMvdReg;
pMVDHw->avsd_regp = ( MvdHwRegAvsdMap * )pMvdReg;
pMVDHw->aspd_regp = ( MvdHwRegAspdMap * )pMvdReg;
pMVDHw->vc1d_regp = ( MvdHwRegVc1dMap * )pMvdReg;
pMVDHw->jpgd_regp = ( MvdHwRegAspdMap * )pMvdReg;
pMVDHw->rvid_regp = ( MvdHwRegRvidMap * )pMvdReg;
pMVDHw->hevc_regp = ( MvdHwRegHevcMap * )pMvdReg;
pMVDHw->on2d_regp = ( MvdHwRegOn2dMap * )pMvdReg;
pMVDHw->cq_regp = ( MvdHwRegCqMap * )pMvdReg;
pMVDHw->rc4_regp = ( MvdHwRegRC4Map * )pMvdReg;
pMVDHw->dfe_regp = ( MvdHwRegDfeMap * )pMvdReg;
pMVDHw->dbe_regp[0x0] = ( MvdHwRegDbeMap * )pMvdReg;
pMVDHw->dbe_regp[0x1] = ( MvdHwRegDbeMap * )pMvdReg;
}
else
{
pMVDHw->msd_regp = pMvdReg;
pMVDHw->hif_regp = &( pMvdReg->HifMap.hif_map );
pMVDHw->sif_regp = &( pMvdReg->SifMap.sif_map );
pMVDHw->ctx_regp = &( pMvdReg->CtxMap.ctx_map );
pMVDHw->rpr_regp = &( pMvdReg->RprMap.rpr_map );
pMVDHw->spp_regp = &( pMvdReg->SppMap.spp_map );
pMVDHw->avc_regp = &( pMvdReg->DecMap.h264_map );
pMVDHw->mp2d_regp = &( pMvdReg->DecMap.mp2d_map );
pMVDHw->aspd_regp = &( pMvdReg->DecMap.aspd_map );
pMVDHw->avsd_regp = &( pMvdReg->DecMap.avsd_map );
pMVDHw->vc1d_regp = &( pMvdReg->DecMap.vc1d_map );
pMVDHw->jpgd_regp = &( pMvdReg->DecMap.aspd_map );
pMVDHw->on2d_regp = &( pMvdReg->DecMap.on2d_map );
pMVDHw->rvid_regp = &( pMvdReg->DecMap.rvid_map );
pMVDHw->hevc_regp = &( pMvdReg->DecMap.hevc_map );
pMVDHw->bbd_regp = &( pMvdReg->BbdMap.bbd_map );
pMVDHw->cq_regp = &( pMvdReg->CqMap.cq_map );
pMVDHw->rc4_regp = &( pMvdReg->RC4Map.RC4_map );
pMVDHw->dfe_regp = &( pMvdReg->DcpMap.dfe_map );
pMVDHw->dbe_regp[0x0] = &( pMvdReg->DcpMap.dbe_map[0x0] );
pMVDHw->dbe_regp[0x1] = &( pMvdReg->DcpMap.dbe_map[0x1] );
if ( pMVDHw->uMaloneID == MALONE_HW_2 )
{
pMVDHw->rsb_regp = ( MvdHwReg * ) pCfg->uMaloneBaseAddr[0x1] ;
}
else
{
pMVDHw->rsb_regp = ( MvdHwReg * ) pCfg->uMaloneBaseAddr[0x0] ;
}
}
}
}
/* End of File */