blob: 539d3bbcbbf46d2cfd997721c2948bd01a83f487 [file] [log] [blame]
/********************************************************************************
* Marvell GPL License Option
*
* If you received this File from Marvell, you may opt to use, redistribute and/or
* modify this File in accordance with the terms and conditions of the General
* Public License Version 2, June 1991 (the "GPL License"), a copy of which is
* available along with the File in the license.txt file or by writing to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
* on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
*
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
* WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
* DISCLAIMED. The GPL License provides additional details about this warranty
* disclaimer.
******************************************************************************/
/**********************************************************************************************************************
* $Log: vsys#comm#cmodel#hal#drv#hal_dhub.c,v $
* Revision 1.7 2007-11-26 09:12:33-08 kbhatt
* merge changes with version of ctsai
*
* Revision 1.6 2007-11-18 00:11:43-08 ctsai
* disabled redundant io32wr & io32rd
*
* Revision 1.5 2007-11-12 14:15:57-08 bofeng
* removed #define __CUSTOMIZED_IO__ as default
* restore the modification for io32rd and io32wr
*
* Revision 1.4 2007-10-30 11:08:35-07 ctsai
* changed printf to xdbg
*
* Revision 1.3 2007-10-24 21:41:16-07 kbhatt
* add structures to api_dhub.h
*
* Revision 1.2 2007-10-12 21:36:55-07 oussama
* adapted the env to use Alpha's Cmodel driver
*
* Revision 1.1 2007-08-29 20:27:00-07 lsha
* Initial revision.
*
*
* DESCRIPTION:
* OS independent layer for dHub/HBO/SemaHub APIs.
*
**********************************************************************************************************************/
//#define __CUSTOMIZED_IO__
#ifdef __VDEC_HAL__
#include "cmacros.h"
#define IO32WR(d, a) DRV_IO_WR32((a),(d))
#define IO32RD(d, a) do { (d) = DRV_IO_RD32((a)); } while(0)
/* Directly write a 32b register or append to 'T64b cfgQ[]', in (adr,data) pairs */
#define IO32CFG(cfgQ, i, a, d) do{ if(cfgQ) { (cfgQ)[i][0] = (a); (cfgQ)[i][1] = (d); } \
else IO32WR(d, a); \
(i) ++; \
}while(0)
#else
//#include "cinclude.h"
#define bTST(x, b) (((x) >> (b)) & 1)
#define ModInc(x, i, mod) do{ (x) += (i); while((x) >= (mod)) (x) -= (mod); }while(0)
#define IO32RD(d, a) do{ (d) = *(UNSG32*)(a); }while(0)
#define IO32WR(d, a) do{ *(UNSG32*)(a) = (d); }while(0)
#define IO32CFG(cfgQ, i, a, d) do{ if(cfgQ) { (cfgQ)[i][0] = (d); (cfgQ)[i][1] = (a); } \
else IO32WR(d, a); \
(i) ++; \
}while(0)
#endif
#include "api_dhub.h"
#include "dHub.h"
#if (BERLIN_CHIP_VERSION >= BERLIN_BG2)
#include "galois_io.h"
#include "Galois_memmap.h"
#include "avio.h"
#endif
//#include "drv_io.h"
// comment out the following line to disable debugging output
//#define DHUB_DBG
#ifdef DHUB_DBG
#define xdbg printf
#else
#define xdbg(...)
#endif
/** SECTION - handle of local contexts
*/
#pragma pack(4)
UNSG32 sizeof_hdl_semaphore = sizeof( HDL_semaphore );
UNSG32 sizeof_hdl_hbo = sizeof( HDL_hbo );
UNSG32 sizeof_hdl_dhub = sizeof( HDL_dhub );
UNSG32 sizeof_hdl_dhub2d = sizeof( HDL_dhub2d );
#pragma pack()
/** ENDOFSECTION
*/
/** SECTION - API definitions for $SemaHub
*/
/******************************************************************************************************************
* Function: semaphore_hdl
* Description: Initialize HDL_semaphore with a $SemaHub BIU instance.
******************************************************************************************************************/
void semaphore_hdl(
UNSG32 ra, /*! Base address of a BIU instance of $SemaHub !*/
void *hdl /*! Handle to HDL_semaphore !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
sem->ra = ra;
/** ENDOFFUNCTION: semaphore_hdl **/
}
/******************************************************************************************************************
* Function: semaphore_cfg
* Description: Configurate a semaphore's depth & reset pointers.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ
******************************************************************************************************************/
UNSG32 semaphore_cfg(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id, /*! Semaphore ID in $SemaHub !*/
SIGN32 depth, /*! Semaphore (virtual FIFO) depth !*/
T64b cfgQ[] /*! Pass NULL to directly init SemaHub, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
T32Semaphore_CFG cfg;
UNSG32 i = 0, a;
a = sem->ra + RA_SemaHub_ARR + id*sizeof(SIE_Semaphore);
cfg.u32 = 0; cfg.uCFG_DEPTH = sem->depth[id] = depth;
IO32CFG(cfgQ, i, a + RA_Semaphore_CFG, cfg.u32);
return i;
/** ENDOFFUNCTION: semaphore_cfg **/
}
/******************************************************************************************************************
* Function: semaphore_intr_enable
* Description: Configurate interrupt enable bits of a semaphore.
******************************************************************************************************************/
void semaphore_intr_enable(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id, /*! Semaphore ID in $SemaHub !*/
SIGN32 empty, /*! Interrupt enable for CPU at condition 'empty' !*/
SIGN32 full, /*! Interrupt enable for CPU at condition 'full' !*/
SIGN32 almostEmpty, /*! Interrupt enable for CPU at condition 'almostEmpty' !*/
SIGN32 almostFull, /*! Interrupt enable for CPU at condition 'almostFull' !*/
SIGN32 cpu /*! CPU ID (0/1/2) !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
T32SemaINTR_mask mask;
UNSG32 a;
a = sem->ra + RA_SemaHub_ARR + id*sizeof(SIE_Semaphore);
mask.u32 = 0;
mask.umask_empty = empty;
mask.umask_full = full;
mask.umask_almostEmpty = almostEmpty;
mask.umask_almostFull = almostFull;
IO32WR(mask.u32, a + RA_Semaphore_INTR + cpu*sizeof(SIE_SemaINTR));
/** ENDOFFUNCTION: semaphore_intr_enable **/
}
/******************************************************************************************************************
* Function: semaphore_query
* Description: Query current status (counter & pointer) of a semaphore.
* Return: UNSG32 - Current available unit level
******************************************************************************************************************/
UNSG32 semaphore_query(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id, /*! Semaphore ID in $SemaHub !*/
SIGN32 master, /*! 0/1 as procuder/consumer query !*/
UNSG32 *ptr /*! Non-zero to receive semaphore r/w pointer !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
T32SemaQuery_RESP resp;
T32SemaQueryMap_ADDR map;
map.u32 = 0; map.uADDR_ID = id; map.uADDR_master = master;
IO32RD(resp.u32, sem->ra + RA_SemaHub_Query + map.u32);
if(ptr) *ptr = resp.uRESP_PTR;
return resp.uRESP_CNT;
/** ENDOFFUNCTION: semaphore_query **/
}
/******************************************************************************************************************
* Function: semaphore_push
* Description: Producer semaphore push.
******************************************************************************************************************/
void semaphore_push(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id, /*! Semaphore ID in $SemaHub !*/
SIGN32 delta /*! Delta to push as a producer !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
T32SemaHub_PUSH push;
push.u32 = 0; push.uPUSH_ID = id; push.uPUSH_delta = delta;
IO32WR(push.u32, sem->ra + RA_SemaHub_PUSH);
/** ENDOFFUNCTION: semaphore_push **/
}
/******************************************************************************************************************
* Function: semaphore_push
* Description: Consumer semaphore pop.
******************************************************************************************************************/
void semaphore_pop(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id, /*! Semaphore ID in $SemaHub !*/
SIGN32 delta /*! Delta to pop as a consumer !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
T32SemaHub_POP pop;
pop.u32 = 0; pop.uPOP_ID = id; pop.uPOP_delta = delta;
IO32WR(pop.u32, sem->ra + RA_SemaHub_POP);
/** ENDOFFUNCTION: semaphore_pop **/
}
/******************************************************************************************************************
* Function: semaphore_chk_empty
* Description: Check 'empty' status of a semaphore (or all semaphores).
* Return: UNSG32 - status bit of given semaphore, or
* status bits of all semaphores if id==-1
******************************************************************************************************************/
UNSG32 semaphore_chk_empty(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub
-1 to return all 32b of the interrupt status
!*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
UNSG32 d;
IO32RD(d, sem->ra + RA_SemaHub_empty);
return (id < 0) ? d : bTST(d, id);
/** ENDOFFUNCTION: semaphore_chk_empty **/
}
/******************************************************************************************************************
* Function: semaphore_chk_full
* Description: Check 'full' status of a semaphore (or all semaphores).
* Return: UNSG32 - status bit of given semaphore, or
* status bits of all semaphores if id==-1
******************************************************************************************************************/
UNSG32 semaphore_chk_full(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub
-1 to return all 32b of the interrupt status
!*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
UNSG32 d;
IO32RD(d, sem->ra + RA_SemaHub_full);
return (id < 0) ? d : bTST(d, id);
/** ENDOFFUNCTION: semaphore_chk_full **/
}
/******************************************************************************************************************
* Function: semaphore_chk_almostEmpty
* Description: Check 'almostEmpty' status of a semaphore (or all semaphores).
* Return: UNSG32 - status bit of given semaphore, or
* status bits of all semaphores if id==-1
******************************************************************************************************************/
UNSG32 semaphore_chk_almostEmpty(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub
-1 to return all 32b of the interrupt status
!*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
UNSG32 d;
IO32RD(d, sem->ra + RA_SemaHub_almostEmpty);
return (id < 0) ? d : bTST(d, id);
/** ENDOFFUNCTION: semaphore_chk_almostEmpty **/
}
/******************************************************************************************************************
* Function: semaphore_chk_almostFull
* Description: Check 'almostFull' status of a semaphore (or all semaphores).
* Return: UNSG32 - status bit of given semaphore, or
* status bits of all semaphores if id==-1
******************************************************************************************************************/
UNSG32 semaphore_chk_almostFull(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub
-1 to return all 32b of the interrupt status
!*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
UNSG32 d;
IO32RD(d, sem->ra + RA_SemaHub_almostFull);
return (id < 0) ? d : bTST(d, id);
/** ENDOFFUNCTION: semaphore_chk_almostFull **/
}
/******************************************************************************************************************
* Function: semaphore_clr_empty
* Description: Clear 'empty' status of a semaphore.
******************************************************************************************************************/
void semaphore_clr_empty(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
IO32WR(1<<id, sem->ra + RA_SemaHub_empty);
/** ENDOFFUNCTION: semaphore_clr_empty **/
}
/******************************************************************************************************************
* Function: semaphore_clr_full
* Description: Clear 'full' status of a semaphore.
******************************************************************************************************************/
void semaphore_clr_full(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
IO32WR(1<<id, sem->ra + RA_SemaHub_full);
/** ENDOFFUNCTION: semaphore_clr_full **/
}
/******************************************************************************************************************
* Function: semaphore_clr_almostEmpty
* Description: Clear 'almostEmpty' status of a semaphore.
******************************************************************************************************************/
void semaphore_clr_almostEmpty(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
IO32WR(1<<id, sem->ra + RA_SemaHub_almostEmpty);
/** ENDOFFUNCTION: semaphore_clr_almostEmpty **/
}
/******************************************************************************************************************
* Function: semaphore_clr_almostFull
* Description: Clear 'almostFull' status of a semaphore.
******************************************************************************************************************/
void semaphore_clr_almostFull(
void *hdl, /*! Handle to HDL_semaphore !*/
SIGN32 id /*! Semaphore ID in $SemaHub !*/
)
{
HDL_semaphore *sem = (HDL_semaphore*)hdl;
IO32WR(1<<id, sem->ra + RA_SemaHub_almostFull);
/** ENDOFFUNCTION: semaphore_clr_almostFull **/
}
/** ENDOFSECTION
*/
/** SECTION - API definitions for $HBO
*/
/******************************************************************************************************************
* Function: hbo_hdl
* Description: Initialize HDL_hbo with a $HBO BIU instance.
******************************************************************************************************************/
void hbo_hdl( UNSG32 mem, /*! Base address of HBO SRAM !*/
UNSG32 ra, /*! Base address of a BIU instance of $HBO !*/
void *hdl /*! Handle to HDL_hbo !*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
HDL_semaphore *fifoCtl = &(hbo->fifoCtl);
hbo->mem = mem; hbo->ra = ra;
semaphore_hdl(ra + RA_HBO_FiFoCtl, fifoCtl);
/** ENDOFFUNCTION: hbo_hdl **/
}
/******************************************************************************************************************
* Function: hbo_fifoCtl
* Description: Get HDL_semaphore pointer from a HBO instance.
* Return: void* - Handle for HBO.FiFoCtl
******************************************************************************************************************/
void* hbo_fifoCtl(void *hdl /*! Handle to HDL_hbo !*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
HDL_semaphore *fifoCtl = &(hbo->fifoCtl);
return fifoCtl;
/** ENDOFFUNCTION: hbo_fifoCtl **/
}
/******************************************************************************************************************
* Function: hbo_queue_cfg
* Description: Configurate a FIFO's base, depth & reset pointers.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ
******************************************************************************************************************/
UNSG32 hbo_queue_cfg(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id, /*! Queue ID in $HBO !*/
UNSG32 base, /*! Channel FIFO base address (byte address) !*/
SIGN32 depth, /*! Channel FIFO depth, in 64b word !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
T64b cfgQ[] /*! Pass NULL to directly init HBO, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
HDL_semaphore *fifoCtl = &(hbo->fifoCtl);
T32FiFo_CFG cfg;
UNSG32 i = 0, a;
a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo);
IO32CFG(cfgQ, i, a + RA_FiFo_START, 0);
cfg.u32 = 0; cfg.uCFG_BASE = hbo->base[id] = base;
IO32CFG(cfgQ, i, a + RA_FiFo_CFG, cfg.u32);
i += semaphore_cfg(fifoCtl, id, depth, cfgQ ? (cfgQ + i) : NULL);
IO32CFG(cfgQ, i, a + RA_FiFo_START, enable);
return i;
/** ENDOFFUNCTION: hbo_queue_cfg **/
}
/******************************************************************************************************************
* Function: hbo_queue_enable
* Description: HBO FIFO enable/disable.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ
******************************************************************************************************************/
UNSG32 hbo_queue_enable(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id, /*! Queue ID in $HBO !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
T64b cfgQ[] /*! Pass NULL to directly init HBO, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
UNSG32 i = 0, a;
a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo);
IO32CFG(cfgQ, i, a + RA_FiFo_START, enable);
return i;
/** ENDOFFUNCTION: hbo_queue_enable **/
}
/******************************************************************************************************************
* Function: hbo_queue_clear
* Description: Issue HBO FIFO clear (will NOT wait for finish).
******************************************************************************************************************/
void hbo_queue_clear(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id /*! Queue ID in $HBO !*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
UNSG32 a;
a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo);
IO32WR(1, a + RA_FiFo_CLEAR);
/** ENDOFFUNCTION: hbo_queue_enable **/
}
/******************************************************************************************************************
* Function: hbo_queue_busy
* Description: Read HBO 'BUSY' status for all channel FIFOs.
* Return: UNSG32 - 'BUSY' status bits of all channels
******************************************************************************************************************/
UNSG32 hbo_queue_busy(
void *hdl /*! Handle to HDL_hbo !*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
UNSG32 d;
IO32RD(d, hbo->ra + RA_HBO_BUSY);
return d;
/** ENDOFFUNCTION: hbo_queue_busy **/
}
/******************************************************************************************************************
* Function: hbo_queue_clear_done
* Description: Wait for a given channel or all channels to be cleared.
******************************************************************************************************************/
void hbo_queue_clear_done(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id /*! Queue ID in $HBO
-1 to wait for all channel clear done
!*/
)
{
UNSG32 d;
do{
d = hbo_queue_busy(hdl);
if(id >= 0) d = bTST(d, id);
} while(d);
/** ENDOFFUNCTION: hbo_queue_clear_done **/
}
/******************************************************************************************************************
* Function: hbo_queue_read
* Description: Read a number of 64b data & pop FIFO from HBO SRAM.
* Return: UNSG32 - Number of 64b data being read (=n), or (when cfgQ==NULL)
* 0 if there're not sufficient data in FIFO
******************************************************************************************************************/
UNSG32 hbo_queue_read(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id, /*! Queue ID in $HBO !*/
SIGN32 n, /*! Number 64b entries to read !*/
T64b data[], /*! To receive read data !*/
UNSG32 *ptr /*! Pass in current FIFO pointer (in 64b word),
& receive updated new pointer,
Pass NULL to read from HW
!*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
SIGN32 i;
UNSG32 p, base, depth;
base = hbo->mem + hbo->base[id]; depth = hbo->fifoCtl.depth[id];
i = hbo_queue_query(hdl, id, SemaQueryMap_ADDR_master_consumer, &p);
if(i < n)
return 0;
if(ptr) p = *ptr;
for(i = 0; i < n; i ++) {
IO32RD(data[i][0], base + p*8);
IO32RD(data[i][1], base + p*8 + 4);
ModInc(p, 1, depth);
}
hbo_queue_pop(hdl, id, n);
if(ptr) *ptr = p;
return n;
/** ENDOFFUNCTION: hbo_queue_read **/
}
/******************************************************************************************************************
* Function: hbo_queue_write
* Description: Write a number of 64b data & push FIFO to HBO SRAM.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ, or (when cfgQ==NULL)
* 0 if there're not sufficient space in FIFO
******************************************************************************************************************/
UNSG32 hbo_queue_write(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id, /*! Queue ID in $HBO !*/
SIGN32 n, /*! Number 64b entries to write !*/
T64b data[], /*! Write data !*/
T64b cfgQ[], /*! Pass NULL to directly update HBO, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
UNSG32 *ptr /*! Pass in current FIFO pointer (in 64b word),
& receive updated new pointer,
Pass NULL to read from HW
!*/
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
SIGN32 i, depth;
UNSG32 base, j = 0,p;
base = hbo->mem + hbo->base[id]; depth = hbo->fifoCtl.depth[id];
if(!ptr) {
i = hbo_queue_query(hdl, id, SemaQueryMap_ADDR_master_producer, &p);
if(i > depth - n)
return 0;
} else {
p = *ptr;
}
for(i = 0; i < n; i ++) {
IO32CFG(cfgQ, j, base + p*8, data[i][0]);
IO32CFG(cfgQ, j, base + p*8 + 4, data[i][1]);
ModInc(p, 1, (unsigned int)depth);
}
if(!cfgQ)
hbo_queue_push(hdl, id, n);
else {
T32SemaHub_PUSH push;
push.u32 = 0; push.uPUSH_ID = id; push.uPUSH_delta = n;
IO32CFG(cfgQ, j, hbo->fifoCtl.ra + RA_SemaHub_PUSH, push.u32);
}
if(ptr) *ptr = p;
return j;
/** ENDOFFUNCTION: hbo_queue_write **/
}
/** ENDOFSECTION
*/
/** SECTION - API definitions for $dHubReg
*/
/******************************************************************************************************************
* Function: dhub_hdl
* Description: Initialize HDL_dhub with a $dHub BIU instance.
******************************************************************************************************************/
void dhub_hdl( UNSG32 mem, /*! Base address of dHub.HBO SRAM !*/
UNSG32 ra, /*! Base address of a BIU instance of $dHub !*/
void *hdl /*! Handle to HDL_dhub !*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
HDL_hbo *hbo = &(dhub->hbo);
HDL_semaphore *semaHub = &(dhub->semaHub);
dhub->ra = ra;
semaphore_hdl(ra + RA_dHubReg_SemaHub, semaHub);
hbo_hdl(mem, ra + RA_dHubReg_HBO, hbo );
/** ENDOFFUNCTION: dhub_hdl **/
}
/******************************************************************************************************************
* Function: dhub_semaphore
* Description: Get HDL_semaphore pointer from a dHub instance.
* Return: void* - Handle for dHub.SemaHub
******************************************************************************************************************/
void* dhub_semaphore(
void *hdl /*! Handle to HDL_dhub !*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
HDL_semaphore *semaHub = &(dhub->semaHub);
return semaHub;
/** ENDOFFUNCTION: dhub_semaphore **/
}
/******************************************************************************************************************
* Function: dhub_hbo
* Description: Get HDL_hbo pointer from a dHub instance.
* Return: void* - Handle for dHub.HBO
******************************************************************************************************************/
void* dhub_hbo( void *hdl /*! Handle to HDL_dhub !*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
HDL_hbo *hbo = &(dhub->hbo);
return hbo;
/** ENDOFFUNCTION: dhub_hbo **/
}
/******************************************************************************************************************
* Function: dhub_channel_cfg
* Description: Configurate a dHub channel.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ, or (when cfgQ==NULL)
* 0 if either cmdQ or dataQ in HBO is still busy
******************************************************************************************************************/
UNSG32 dhub_channel_cfg(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
UNSG32 baseCmd, /*! Channel FIFO base address (byte address) for cmdQ !*/
UNSG32 baseData, /*! Channel FIFO base address (byte address) for dataQ !*/
SIGN32 depthCmd, /*! Channel FIFO depth for cmdQ, in 64b word !*/
SIGN32 depthData, /*! Channel FIFO depth for dataQ, in 64b word !*/
SIGN32 MTU, /*! See 'dHubChannel.CFG.MTU' !*/
SIGN32 QoS, /*! See 'dHubChannel.CFG.QoS' !*/
SIGN32 selfLoop, /*! See 'dHubChannel.CFG.selfLoop' !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
T64b cfgQ[] /*! Pass NULL to directly init dHub, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
HDL_hbo *hbo = &(dhub->hbo);
T32dHubChannel_CFG cfg;
UNSG32 i = 0, a, cmdID = dhub_id2hbo_cmdQ(id), dataID = dhub_id2hbo_data(id);
xdbg ("hal_dhub:: value of id is %0d \n" , id ) ;
xdbg ("hal_dhub:: value of baseCmd is %0d \n" , baseCmd ) ;
xdbg ("hal_dhub:: value of baseData is %0d \n" , baseData ) ;
xdbg ("hal_dhub:: value of depthCmd is %0d \n" , depthCmd ) ;
xdbg ("hal_dhub:: value of depthData is %0d \n" , depthData ) ;
xdbg ("hal_dhub:: value of MTU is %0d \n" , MTU ) ;
xdbg ("hal_dhub:: value of QOS is %0d \n" , QoS ) ;
xdbg ("hal_dhub:: value of SelfLoop is %0d \n" , selfLoop ) ;
xdbg ("hal_dhub:: value of Enable is %0d \n" , enable ) ;
if(!cfgQ) {
hbo_queue_enable(hbo, cmdID, 0, NULL);
hbo_queue_clear(hbo, cmdID);
hbo_queue_enable(hbo, dataID, 0, NULL);
hbo_queue_clear(hbo, dataID);
//if(bTST(busyStatus, cmdID) || bTST(busyStatus, dataID))
// return 0;
}
a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel);
xdbg ("hal_dhub:: value of Channel Addr is %0x \n" , a ) ;
IO32CFG(cfgQ, i, a + RA_dHubChannel_START, 0);
cfg.u32 = 0; cfg.uCFG_MTU = MTU; cfg.uCFG_QoS = QoS; cfg.uCFG_selfLoop = selfLoop;
switch(MTU) {
case dHubChannel_CFG_MTU_8byte : dhub->MTUb[id] = 3; break;
case dHubChannel_CFG_MTU_32byte : dhub->MTUb[id] = 5; break;
case dHubChannel_CFG_MTU_128byte: dhub->MTUb[id] = 7; break;
case dHubChannel_CFG_MTU_1024byte : dhub->MTUb[id] = 10; break;
}
xdbg ("hal_dhub:: addr of ChannelCFG is %0x data is %0x \n" , a + RA_dHubChannel_CFG , cfg.u32 ) ;
IO32CFG(cfgQ, i, a + RA_dHubChannel_CFG, cfg.u32);
i += hbo_queue_cfg(hbo, cmdID, baseCmd , depthCmd , enable, cfgQ ? (cfgQ + i) : NULL);
i += hbo_queue_cfg(hbo, dataID, baseData, depthData, enable, cfgQ ? (cfgQ + i) : NULL);
xdbg ("hal_dhub:: addr of ChannelEN is %0x data is %0x \n" , a + RA_dHubChannel_START , enable ) ;
IO32CFG(cfgQ, i, a + RA_dHubChannel_START, enable);
return i;
/** ENDOFFUNCTION: dhub_channel_cfg **/
}
/******************************************************************************************************************
* Function: dhub_channel_enable
* Description: dHub channel enable/disable.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ
******************************************************************************************************************/
UNSG32 dhub_channel_enable(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
T64b cfgQ[] /*! Pass NULL to directly init dHub, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
UNSG32 i = 0, a;
a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel);
IO32CFG(cfgQ, i, a + RA_dHubChannel_START, enable);
return i;
/** ENDOFFUNCTION: dhub_channel_enable **/
}
/******************************************************************************************************************
* Function: dhub_channel_clear
* Description: Issue dHub channel clear (will NOT wait for finish).
******************************************************************************************************************/
void dhub_channel_clear(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id /*! Channel ID in $dHubReg !*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
UNSG32 a;
a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel);
IO32WR(1, a + RA_dHubChannel_CLEAR);
/** ENDOFFUNCTION: dhub_channel_clear **/
}
/******************************************************************************************************************
* Function: dhub_channel_flush
* Description: Issue dHub channel (H2M only) flush (will NOT wait for finish).
******************************************************************************************************************/
void dhub_channel_flush(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id /*! Channel ID in $dHubReg !*/
)
{
UNSG32 a;
HDL_dhub *dhub = (HDL_dhub*)hdl;
a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel);
IO32WR(1, a + RA_dHubChannel_FLUSH);
/** ENDOFFUNCTION: dhub_channel_flush **/
}
/******************************************************************************************************************
* Function: dhub_channel_busy
* Description: Read dHub 'BUSY' status for all channel FIFOs.
* Return: UNSG32 - 'BUSY' status bits of all channels
******************************************************************************************************************/
UNSG32 dhub_channel_busy(
void *hdl /*! Handle to HDL_dhub !*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
UNSG32 d;
IO32RD(d, dhub->ra + RA_dHubReg_BUSY);
return d;
/** ENDOFFUNCTION: dhub_channel_busy **/
}
/******************************************************************************************************************
* Function: dhub_channel_pending
* Description: Read dHub 'PENDING' status for all channel FIFOs.
* Return: UNSG32 - 'PENDING' status bits of all channels
******************************************************************************************************************/
UNSG32 dhub_channel_pending(
void *hdl /*! Handle to HDL_dhub !*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
UNSG32 d;
IO32RD(d, dhub->ra + RA_dHubReg_PENDING);
return d;
/** ENDOFFUNCTION: dhub_channel_pending **/
}
/******************************************************************************************************************
* Function: dhub_channel_clear_done
* Description: Wait for a given channel or all channels to be cleared.
******************************************************************************************************************/
void dhub_channel_clear_done(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id /*! Channel ID in $dHubReg
-1 to wait for all channel clear done
!*/
)
{
UNSG32 d;
do{
d = dhub_channel_busy(hdl);
d |= dhub_channel_pending(hdl);
if(id >= 0) d = bTST(d, id);
} while(d);
/** ENDOFFUNCTION: dhub_channel_clear_done **/
}
/******************************************************************************************************************
* Function: dhub_channel_write_cmd
* Description: Write a 64b command for a dHub channel.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ if success, or
* 0 if there're not sufficient space in FIFO
******************************************************************************************************************/
UNSG32 dhub_channel_write_cmd(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
UNSG32 addr, /*! CMD: buffer address !*/
SIGN32 size, /*! CMD: number of bytes to transfer !*/
SIGN32 semOnMTU, /*! CMD: semaphore operation at CMD/MTU (0/1) !*/
SIGN32 chkSemId, /*! CMD: non-zero to check semaphore !*/
SIGN32 updSemId, /*! CMD: non-zero to update semaphore !*/
SIGN32 interrupt, /*! CMD: raise interrupt at CMD finish !*/
T64b cfgQ[], /*! Pass NULL to directly update dHub, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
UNSG32 *ptr /*! Pass in current cmdQ pointer (in 64b word),
& receive updated new pointer,
Pass NULL to read from HW
!*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
HDL_hbo *hbo = &(dhub->hbo);
SIE_dHubCmd cmd;
SIGN32 i;
cmd.ie_HDR.u32dHubCmdHDR_DESC = 0;
i = size >> dhub->MTUb[id];
if((i << dhub->MTUb[id]) < size)
cmd.ie_HDR.uDESC_size = size;
else {
cmd.ie_HDR.uDESC_sizeMTU = 1;
cmd.ie_HDR.uDESC_size = i;
}
cmd.ie_HDR.uDESC_chkSemId = chkSemId; cmd.ie_HDR.uDESC_updSemId = updSemId;
cmd.ie_HDR.uDESC_semOpMTU = semOnMTU; cmd.ie_HDR.uDESC_interrupt = interrupt;
cmd.uMEM_addr = addr;
return hbo_queue_write(hbo, dhub_id2hbo_cmdQ(id), 1, (T64b*)&cmd, cfgQ, ptr);
/** ENDOFFUNCTION: dhub_channel_write_cmd **/
}
void dhub_channel_generate_cmd(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
UNSG32 addr, /*! CMD: buffer address !*/
SIGN32 size, /*! CMD: number of bytes to transfer !*/
SIGN32 semOnMTU, /*! CMD: semaphore operation at CMD/MTU (0/1) !*/
SIGN32 chkSemId, /*! CMD: non-zero to check semaphore !*/
SIGN32 updSemId, /*! CMD: non-zero to update semaphore !*/
SIGN32 interrupt, /*! CMD: raise interrupt at CMD finish !*/
SIGN32 *pData
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
SIE_dHubCmd cmd;
SIGN32 i, *pcmd;
cmd.ie_HDR.u32dHubCmdHDR_DESC = 0;
i = size >> dhub->MTUb[id];
if((i << dhub->MTUb[id]) < size)
cmd.ie_HDR.uDESC_size = size;
else {
cmd.ie_HDR.uDESC_sizeMTU = 1;
cmd.ie_HDR.uDESC_size = i;
}
cmd.ie_HDR.uDESC_chkSemId = chkSemId; cmd.ie_HDR.uDESC_updSemId = updSemId;
cmd.ie_HDR.uDESC_semOpMTU = semOnMTU; cmd.ie_HDR.uDESC_interrupt = interrupt;
cmd.uMEM_addr = addr;
pcmd = (SIGN32 *)(&cmd);
pData[0] = pcmd[0];
pData[1] = pcmd[1];
/** ENDOFFUNCTION: dhub_channel_write_cmd **/
}
/******************************************************************************************************************
* Function: dhub_channel_big_write_cmd
* Description: Write a sequence of 64b command for a dHub channel.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ if success, or
* 0 if there're not sufficient space in FIFO
******************************************************************************************************************/
UNSG32 dhub_channel_big_write_cmd(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
UNSG32 addr, /*! CMD: buffer address !*/
SIGN32 size, /*! CMD: number of bytes to transfer !*/
SIGN32 semOnMTU, /*! CMD: semaphore operation at CMD/MTU (0/1) !*/
SIGN32 chkSemId, /*! CMD: non-zero to check semaphore !*/
SIGN32 updSemId, /*! CMD: non-zero to update semaphore !*/
SIGN32 interrupt, /*! CMD: raise interrupt at CMD finish !*/
T64b cfgQ[], /*! Pass NULL to directly update dHub, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
UNSG32 *ptr /*! Pass in current cmdQ pointer (in 64b word),
& receive updated new pointer,
Pass NULL to read from HW
!*/
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
SIGN32 i;
SIGN32 j, jj;
i = size >> dhub->MTUb[id];
//size < 64K
if( size<(1<<16) )
{
j = dhub_channel_write_cmd(hdl, id, addr, size, semOnMTU, chkSemId, updSemId, interrupt, cfgQ, ptr);
}
else {
SIGN32 size0, size1;
size0 = 0xffff << dhub->MTUb[id];
j = 0;
//size > 128x64k
while( i > 0xffff )
{
jj = dhub_channel_write_cmd(hdl, id, addr, size0, semOnMTU, chkSemId, updSemId, 0, cfgQ, ptr);
if (cfgQ) cfgQ += jj;
j += jj;
i -= 0xffff;
size -= size0;
addr += size0;
}
if( (i << dhub->MTUb[id]) == size )
{
j += dhub_channel_write_cmd(hdl, id, addr, size, semOnMTU, chkSemId, updSemId, interrupt, cfgQ, ptr);
}
else
{
size0 = i << dhub->MTUb[id];
j += dhub_channel_write_cmd(hdl, id, addr, size0, semOnMTU, chkSemId, updSemId, 0, cfgQ, ptr);
if (cfgQ) cfgQ += j;
addr += size0;
size1 = size - size0;
j += dhub_channel_write_cmd(hdl, id, addr, size1, semOnMTU, chkSemId, updSemId, interrupt, cfgQ, ptr);
}
}
return (j);
#if 0
if ((size < (1<<16)) || ((i << dhub->MTUb[id]) == size)) {
j = dhub_channel_write_cmd(hdl, id, addr, size, semOnMTU, chkSemId, updSemId, interrupt, cfgQ, ptr);
} else {
SIGN32 i_q, p, depth;
UNSG32 hbo_id;
SIGN32 size1, size0;
hbo_id = dhub_id2hbo_cmdQ(id);
depth = hbo->fifoCtl.depth[hbo_id];
if(!cfgQ) { // to make sure that there are enough space in Queue.
i_q = hbo_queue_query(hbo, hbo_id, SemaQueryMap_ADDR_master_producer, &p);
if(i_q > depth - 2)
return 0;
}
size1 = (i << dhub->MTUb[id]);
size0 = size - size1;
j = dhub_channel_write_cmd(hdl, id, addr, size1, semOnMTU, chkSemId, updSemId, 0, cfgQ, ptr);
addr += size1;
if (cfgQ) cfgQ += j;
j += dhub_channel_write_cmd(hdl, id, addr, size0, semOnMTU, chkSemId, updSemId, interrupt, cfgQ, ptr);
/** ENDOFFUNCTION: dhub_channel_big_write_cmd **/
}
return (j);
#endif
}
/** ENDOFSECTION
*/
/** SECTION - API definitions for $dHubReg2D
*/
/******************************************************************************************************************
* Function: dhub2d_hdl
* Description: Initialize HDL_dhub2d with a $dHub2D BIU instance.
******************************************************************************************************************/
void dhub2d_hdl( UNSG32 mem, /*! Base address of dHub2D.dHub.HBO SRAM !*/
UNSG32 ra, /*! Base address of a BIU instance of $dHub2D !*/
void *hdl /*! Handle to HDL_dhub2d !*/
)
{
HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl;
HDL_dhub *dhub = &(dhub2d->dhub);
dhub2d->ra = ra;
dhub_hdl(mem, ra + RA_dHubReg2D_dHub, dhub);
/** ENDOFFUNCTION: dhub2d_hdl **/
}
/******************************************************************************************************************
* Function: dhub2d_channel_cfg
* Description: Configurate a dHub2D channel.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ
******************************************************************************************************************/
UNSG32 dhub2d_channel_cfg(
void *hdl, /*! Handle to HDL_dhub2d !*/
SIGN32 id, /*! Channel ID in $dHubReg2D !*/
UNSG32 addr, /*! CMD: 2D-buffer address !*/
SIGN32 stride, /*! CMD: line stride size in bytes !*/
SIGN32 width, /*! CMD: buffer width in bytes !*/
SIGN32 height, /*! CMD: buffer height in lines !*/
SIGN32 semLoop, /*! CMD: loop size (1~4) of semaphore operations !*/
SIGN32 semOnMTU, /*! CMD: semaphore operation at CMD/MTU (0/1) !*/
SIGN32 chkSemId[], /*! CMD: semaphore loop pattern - non-zero to check !*/
SIGN32 updSemId[], /*! CMD: semaphore loop pattern - non-zero to update !*/
SIGN32 interrupt, /*! CMD: raise interrupt at CMD finish !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
T64b cfgQ[] /*! Pass NULL to directly init dHub2D, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl;
HDL_dhub *dhub = &(dhub2d->dhub);
SIE_dHubCmd2D cmd;
SIE_dHubCmdHDR hdr;
SIGN32 i, size = width;
UNSG32 a, j = 0;
a = dhub2d->ra + RA_dHubReg2D_ARR + id*sizeof(SIE_dHubCmd2D);
IO32CFG(cfgQ, j, a + RA_dHubCmd2D_START, 0);
cmd.uMEM_addr = addr;
cmd.uDESC_stride = stride; cmd.uDESC_numLine = height;
cmd.uDESC_hdrLoop = semLoop; cmd.uDESC_interrupt = interrupt;
IO32CFG(cfgQ, j, a + RA_dHubCmd2D_MEM, cmd.u32dHubCmd2D_MEM);
IO32CFG(cfgQ, j, a + RA_dHubCmd2D_DESC, cmd.u32dHubCmd2D_DESC);
hdr.u32dHubCmdHDR_DESC = 0;
i = size >> dhub->MTUb[id];
if((i << dhub->MTUb[id]) < size)
hdr.uDESC_size = size;
else {
hdr.uDESC_sizeMTU = 1;
hdr.uDESC_size = i;
}
hdr.uDESC_semOpMTU = semOnMTU;
for(i = 0; i < semLoop; i ++) {
if (chkSemId) {
hdr.uDESC_chkSemId = chkSemId[i];
}
if (updSemId) {
hdr.uDESC_updSemId = updSemId[i];
}
IO32CFG(cfgQ, j, a + RA_dHubCmd2D_HDR + i*sizeof(SIE_dHubCmdHDR), hdr.u32dHubCmdHDR_DESC);
}
IO32CFG(cfgQ, j, a + RA_dHubCmd2D_START, enable);
return j;
/** ENDOFFUNCTION: dhub2d_channel_cfg **/
}
/******************************************************************************************************************
* Function: dhub2d_channel_enable
* Description: dHub2D channel enable/disable.
* Return: UNSG32 - Number of (adr,pair) added to cfgQ
******************************************************************************************************************/
UNSG32 dhub2d_channel_enable(
void *hdl, /*! Handle to HDL_dhub2d !*/
SIGN32 id, /*! Channel ID in $dHubReg2D !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
T64b cfgQ[] /*! Pass NULL to directly init dHub2D, or
Pass non-zero to receive programming sequence
in (adr,data) pairs
!*/
)
{
HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl;
UNSG32 i = 0, a;
a = dhub2d->ra + RA_dHubReg2D_ARR + id*sizeof(SIE_dHubCmd2D);
IO32CFG(cfgQ, i, a + RA_dHubCmd2D_START, enable);
return i;
/** ENDOFFUNCTION: dhub2d_channel_enable **/
}
/******************************************************************************************************************
* Function: dhub2d_channel_clear
* Description: Issue dHub2D channel clear (will NOT wait for finish).
******************************************************************************************************************/
void dhub2d_channel_clear(
void *hdl, /*! Handle to HDL_dhub2d !*/
SIGN32 id /*! Channel ID in $dHubReg2D !*/
)
{
HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl;
UNSG32 a = dhub2d->ra + RA_dHubReg2D_ARR + id*sizeof(SIE_dHubCmd2D);
IO32WR( 1, a + RA_dHubCmd2D_CLEAR);
return ;
/** ENDOFFUNCTION: dhub2d_channel_clear **/
}
/******************************************************************************************************************
* Function: dhub2d_channel_busy
* Description: Read dHub2D 'BUSY' status for all channel FIFOs.
* Return: UNSG32 - 'BUSY' status bits of all channels
******************************************************************************************************************/
UNSG32 dhub2d_channel_busy(
void *hdl /*! Handle to HDL_dhub2d !*/
)
{
HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl;
UNSG32 d;
IO32RD(d, dhub2d->ra + RA_dHubReg2D_BUSY);
return d;
/** ENDOFFUNCTION: dhub2d_channel_busy **/
}
/******************************************************************************************************************
* Function: dhub2d_channel_clear_done
* Description: Wait for a given channel or all channels to be cleared.
******************************************************************************************************************/
void dhub2d_channel_clear_done(
void *hdl, /*! Handle to HDL_dhub2d !*/
SIGN32 id /*! Channel ID in $dHubReg2D
!*/
)
{
UNSG32 d;
do{
d = dhub2d_channel_busy(hdl);
if(id >= 0) d = bTST(d, id);
} while(d);
/** ENDOFFUNCTION: dhub2d_channel_clear_done **/
}
#if (BERLIN_CHIP_VERSION >= BERLIN_BG2)
void BCM_SCHED_Open(void)
{
}
void BCM_SCHED_Close(void)
{
}
void BCM_SCHED_SetMux(UNSG32 QID, UNSG32 TrigEvent)
{
UNSG32 addr;
if (TrigEvent > BCM_SCHED_TRIG_NONE)
return;
if (QID <= BCM_SCHED_Q11) {
addr = RA_AVIO_BCM_Q0 + QID * 4;
GA_REG_WORD32_WRITE(MEMMAP_AVIO_BCM_REG_BASE + addr, TrigEvent);
} else if ((QID >= BCM_SCHED_Q14) && (QID <= BCM_SCHED_Q18)) {
addr = RA_AVIO_BCM_Q14 + (QID-BCM_SCHED_Q14) * 4;
GA_REG_WORD32_WRITE(MEMMAP_AVIO_BCM_REG_BASE + addr, TrigEvent);
}
return;
}
int BCM_SCHED_PushCmd(UNSG32 QID, UNSG32 *pCmd, UNSG32 *cfgQ)
{
UNSG32 value, addr, j;
if ((QID > BCM_SCHED_Q18) || !pCmd)
return -1; /* parameter error */
if (!cfgQ) {
GA_REG_WORD32_READ(MEMMAP_AVIO_BCM_REG_BASE + RA_AVIO_BCM_FULL_STS, &value);
if (value & (1 << QID)) {
return 0; /* Q FIFO is full */
}
}
if (pCmd) {
j = 0;
addr = QID * 4 * 2;
if (cfgQ) {
cfgQ[0] = pCmd[0];
cfgQ[1] = MEMMAP_AVIO_BCM_REG_BASE + addr;
cfgQ[2] = pCmd[1];
cfgQ[3] = MEMMAP_AVIO_BCM_REG_BASE + addr + 4;
} else {
GA_REG_WORD32_WRITE(MEMMAP_AVIO_BCM_REG_BASE + addr, pCmd[0]);
GA_REG_WORD32_WRITE(MEMMAP_AVIO_BCM_REG_BASE + addr + 4, pCmd[1]);
}
j = 2;
}
return j;
}
void BCM_SCHED_GetEmptySts(UNSG32 QID, UNSG32 *EmptySts)
{
UNSG32 bcmQ_sts;
GA_REG_WORD32_READ(MEMMAP_AVIO_BCM_REG_BASE + RA_AVIO_BCM_EMP_STS, &bcmQ_sts);
if (bcmQ_sts & (1 << QID)) {
*EmptySts = 1;
} else {
*EmptySts = 0;
}
}
/****************************************************
* dhub2d_channel_clear_seq()
*
* dHub2D channel clear sequence
****************************************************/
void dhub2d_channel_clear_seq(void *hdl, SIGN32 id)
{
UNSG32 cmdID = dhub_id2hbo_cmdQ(id), dataID = dhub_id2hbo_data(id);
dhub2d_channel_clear((HDL_dhub2d *)hdl, id);
hbo_queue_enable(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), cmdID, 0, NULL);
dhub_channel_enable(&((HDL_dhub2d *)hdl)->dhub, id, 0, NULL);
dhub_channel_clear(&((HDL_dhub2d *)hdl)->dhub, id);
dhub_channel_clear_done(&((HDL_dhub2d *)hdl)->dhub, id);
hbo_queue_clear(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), cmdID);
hbo_queue_enable(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), dataID, 0, NULL);
hbo_queue_clear(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), dataID);
}
/****************************************************
* dhub2d_channel_start_seq()
*
* dHub2D channel start sequence
****************************************************/
void dhub2d_channel_start_seq(void *hdl, SIGN32 id)
{
UNSG32 cmdID = dhub_id2hbo_cmdQ(id), dataID = dhub_id2hbo_data(id);
hbo_queue_enable(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), cmdID, 1, NULL);
hbo_queue_enable(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), dataID, 1, NULL);
dhub_channel_enable(&((HDL_dhub2d *)hdl)->dhub, id, 1, NULL);
}
/******************************************************************************************************************
* DHub/HBO clear/disable/enable functions
* Same as original ones, but use BCM buffer for VIP VBI clear sequence.
******************************************************************************************************************/
typedef struct VIP_BCMBUF_T {
unsigned int *head; // head of total BCM buffer
unsigned int *tail; // tail of the buffer, used for checking wrap around
unsigned int *writer; // write pointer of queue
int size; // size of total BCM buffer
} VIP_BCMBUF;
void dhub_channel_clear_bcmbuf(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
VIP_BCMBUF *pbcmbuf
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
UNSG32 a;
a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel);
if (pbcmbuf == NULL)
return;
if(pbcmbuf->writer == pbcmbuf->tail){
/*the buffer is full, no space for wrap around*/
return;
}
/*save the data to the buffer*/
*pbcmbuf->writer = 1;
pbcmbuf->writer ++;
*pbcmbuf->writer = a + RA_dHubChannel_CLEAR;
pbcmbuf->writer ++;
//IO32WR(1, a + RA_dHubChannel_CLEAR);
}
UNSG32 dhub_channel_enable_bcmbuf(
void *hdl, /*! Handle to HDL_dhub !*/
SIGN32 id, /*! Channel ID in $dHubReg !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
VIP_BCMBUF *pbcmbuf
)
{
HDL_dhub *dhub = (HDL_dhub*)hdl;
UNSG32 i = 0, a;
a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel);
*pbcmbuf->writer = enable;
pbcmbuf->writer ++;
*pbcmbuf->writer = a + RA_dHubChannel_START;
pbcmbuf->writer ++;
//IO32CFG(cfgQ, i, a + RA_dHubChannel_START, enable);
return i;
}
void hbo_queue_clear_bcmbuf(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id, /*! Queue ID in $HBO !*/
VIP_BCMBUF *pbcmbuf
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
UNSG32 a;
a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo);
if (pbcmbuf == NULL)
return;
if(pbcmbuf->writer == pbcmbuf->tail){
/*the buffer is full, no space for wrap around*/
return;
}
/*save the data to the buffer*/
*pbcmbuf->writer = 1;
pbcmbuf->writer ++;
*pbcmbuf->writer = a + RA_FiFo_CLEAR;
pbcmbuf->writer ++;
//IO32WR(1, a + RA_FiFo_CLEAR);
/** ENDOFFUNCTION: hbo_queue_enable **/
}
UNSG32 hbo_queue_enable_bcmbuf(
void *hdl, /*! Handle to HDL_hbo !*/
SIGN32 id, /*! Queue ID in $HBO !*/
SIGN32 enable, /*! 0 to disable, 1 to enable !*/
VIP_BCMBUF *pbcmbuf
)
{
HDL_hbo *hbo = (HDL_hbo*)hdl;
UNSG32 i = 0, a;
a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo);
*pbcmbuf->writer = enable;
pbcmbuf->writer ++;
*pbcmbuf->writer = a + RA_FiFo_START;
pbcmbuf->writer ++;
//IO32CFG(cfgQ, i, a + RA_FiFo_START, enable);
return i;
}
void dhub2d_channel_clear_bcmbuf(
void *hdl, /*! Handle to HDL_dhub2d !*/
SIGN32 id, /*! Channel ID in $dHubReg2D !*/
VIP_BCMBUF *pbcmbuf
)
{
HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl;
UNSG32 a;
a = dhub2d->ra + RA_dHubReg2D_ARR + id*sizeof(SIE_dHubCmd2D);
/*save the data to the buffer*/
*pbcmbuf->writer = 1;
pbcmbuf->writer ++;
*pbcmbuf->writer = a + RA_dHubCmd2D_CLEAR;
pbcmbuf->writer ++;
//IO32WR( 1, a + RA_dHubCmd2D_CLEAR);
return ;
/** ENDOFFUNCTION: dhub2d_channel_clear **/
}
/****************************************************
* dhub2d_channel_clear_seq()
*
* dHub 2D channel clear sequence
* No wait, return immediately. Use BCM buffer.
****************************************************/
void dhub2d_channel_clear_seq_bcm(void *hdl, SIGN32 id, VIP_BCMBUF *pbcmbuf)
{
UNSG32 cmdID = dhub_id2hbo_cmdQ(id), dataID = dhub_id2hbo_data(id);
dhub2d_channel_clear_bcmbuf((HDL_dhub2d *)hdl, id, pbcmbuf);
hbo_queue_enable_bcmbuf(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), cmdID, 0, pbcmbuf);
dhub_channel_enable_bcmbuf(&((HDL_dhub2d *)hdl)->dhub, id, 0, pbcmbuf);
dhub_channel_clear_bcmbuf(&((HDL_dhub2d *)hdl)->dhub, id, pbcmbuf);
hbo_queue_clear_bcmbuf(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), cmdID, pbcmbuf);
hbo_queue_enable_bcmbuf(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), dataID, 0, pbcmbuf);
hbo_queue_clear_bcmbuf(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), dataID, pbcmbuf);
//restart!
hbo_queue_enable_bcmbuf(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), cmdID, 1, pbcmbuf);
hbo_queue_enable_bcmbuf(dhub_hbo(&((HDL_dhub2d *)hdl)->dhub), dataID, 1, pbcmbuf);
dhub_channel_enable_bcmbuf(&((HDL_dhub2d *)hdl)->dhub, id, 1, pbcmbuf);
}
/****************************************************
* dhub_channel_clear_seq()
*
* dHub channel clear sequence
* No wait, return immediately. Use BCM buffer.
****************************************************/
void dhub_channel_clear_seq(void *hdl, SIGN32 id, VIP_BCMBUF *pbcmbuf)
{
UNSG32 cmdID = dhub_id2hbo_cmdQ(id), dataID = dhub_id2hbo_data(id);
hbo_queue_enable_bcmbuf(dhub_hbo(hdl), cmdID, 0, pbcmbuf);
dhub_channel_enable_bcmbuf(hdl, id, 0, pbcmbuf);
dhub_channel_clear_bcmbuf(hdl, id, pbcmbuf);
hbo_queue_clear_bcmbuf(dhub_hbo(hdl), cmdID, pbcmbuf);
hbo_queue_enable_bcmbuf(dhub_hbo(hdl), dataID, 0, pbcmbuf);
hbo_queue_clear_bcmbuf(dhub_hbo(hdl), dataID, pbcmbuf);
//restart!
hbo_queue_enable_bcmbuf(dhub_hbo(hdl), cmdID, 1, pbcmbuf);
hbo_queue_enable_bcmbuf(dhub_hbo(hdl), dataID, 1, pbcmbuf);
dhub_channel_enable_bcmbuf(hdl, id, 1, pbcmbuf);
}
#endif
///******************************************************************************************************************
//* Function: io32wr
//* Parameters : 32 bit addr and data
//* Description: This write is only for SYSTEM VERILOG TB AHB Write
//******************************************************************************************************************/
//void io32wr(UNSG32 d, UNSG32 a)
//{
// xdbg ( " The data is %0d" , d ) ;
// xdbg ( " The addr is %0d" , a ) ;
// DRV_IO_WR32 ( a, d );
//}
///******************************************************************************************************************
//* Function: io32wr
//* Parameters : 32 bit addr and read data
//* Description: This write is only for SYSTEM VERILOG TB AHB Write
//******************************************************************************************************************/
//void io32rd(UNSG32 *d, UNSG32 a)
//{
// xdbg ( " The data is %0d" , d ) ;
// xdbg ( " The addr is %0d" , a ) ;
// DRV_IO_RD32 (a, d);
//}
/** ENDOFSECTION
*/
/** ENDOFFILE: hal_dhub.c *********************************************************************************************
*/
#ifdef __LINUX_KERNEL__
#include <linux/module.h>
EXPORT_SYMBOL(dhub2d_channel_cfg);
EXPORT_SYMBOL(dhub_channel_big_write_cmd);
EXPORT_SYMBOL(dhub_channel_write_cmd);
EXPORT_SYMBOL(semaphore_intr_enable);
EXPORT_SYMBOL(semaphore_cfg);
EXPORT_SYMBOL(dhub_semaphore);
EXPORT_SYMBOL(dhub_channel_cfg);
EXPORT_SYMBOL(dhub_channel_generate_cmd);
EXPORT_SYMBOL(dhub_channel_clear_done);
EXPORT_SYMBOL(dhub_channel_enable);
EXPORT_SYMBOL(dhub_channel_clear);
EXPORT_SYMBOL(dhub_hdl);
EXPORT_SYMBOL(semaphore_chk_full);
EXPORT_SYMBOL(semaphore_clr_full);
EXPORT_SYMBOL(semaphore_pop);
EXPORT_SYMBOL(BCM_SCHED_PushCmd);
EXPORT_SYMBOL(BCM_SCHED_GetEmptySts);
EXPORT_SYMBOL(hbo_queue_clear);
EXPORT_SYMBOL(hbo_queue_enable);
EXPORT_SYMBOL(hbo_queue_clear_done);
EXPORT_SYMBOL(dhub2d_hdl);
#endif