| /******************************************************************************** |
| * 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 |