| /* |
| * Copyright (C) 2018 Synaptics Incorporated. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND |
| * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, |
| * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY |
| * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR |
| * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE |
| * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND |
| * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF |
| * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT |
| * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY |
| * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS. |
| */ |
| |
| /****************************************************************************** |
| * 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. |
| * |
| ******************************************************************************/ |
| #include "io.h" |
| #include "dHub.h" |
| #include "avio.h" |
| #include "api_dhub.h" |
| #include "avio_memmap.h" |
| #include "api_avio_dhub.h" |
| #ifdef __LINUX_KERNEL__ |
| #include <linux/version.h> |
| #include <linux/init.h> |
| #include <linux/module.h> |
| #include <linux/fs.h> |
| #include <linux/mm.h> |
| #include <linux/sched.h> |
| #include <linux/signal.h> |
| #include <linux/pagemap.h> |
| #include <linux/mman.h> |
| #include <linux/atomic.h> |
| #include <linux/dma-mapping.h> |
| #include <linux/slab.h> |
| #include <linux/fs.h> |
| #include <linux/uaccess.h> |
| #endif |
| |
| #define MEMMAP_AVIO_REG_BASE 0xF7400000 |
| #define MEMMAP_AVIO_BCM_REG_BASE (MEMMAP_AVIO_REG_BASE + AVIO_MEMMAP_AVIO_BCM_REG_BASE) |
| #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) GA_REG_WORD32_READ(a, &d); |
| #define IO32WR(d, a) GA_REG_WORD32_WRITE(a, d); |
| |
| #undef IO32CFG |
| #define IO32CFG(cfgQ, i, a, d) \ |
| do { if (cfgQ) { \ |
| (cfgQ)[i][0] = (d); \ |
| (cfgQ)[i][1] = (a); \ |
| } \ |
| else \ |
| IO32WR(d, a); \ |
| (i)++; \ |
| } while (0) |
| |
| #define PRINT |
| |
| /** SECTION - handle of local contexts |
| */ |
| |
| #pragma pack(4) |
| UINT32 sizeof_hdl_semaphore = sizeof(HDL_semaphore); |
| UINT32 sizeof_hdl_hbo = sizeof(HDL_hbo); |
| UINT32 sizeof_hdl_dhub = sizeof(HDL_dhub); |
| UINT32 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(UINT32 ra, void *hdl) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| |
| sem->ra = ra; |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_cfg |
| * Description: Configurate a semaphore's depth & reset pointers. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ |
| *******************************************************************************/ |
| UINT32 semaphore_cfg(void *hdl, INT32 id, INT32 depth, T64b cfgQ[]) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| T32Semaphore_CFG cfg; |
| UINT32 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; |
| |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_intr_enable |
| * Description: Configurate interrupt enable bits of a semaphore. |
| ******************************************************************************/ |
| void semaphore_intr_enable(void *hdl, INT32 id, INT32 empty, |
| INT32 full, INT32 almostEmpty, |
| INT32 almostFull, INT32 cpu) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| T32SemaINTR_mask mask; |
| UINT32 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)); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_query |
| * Description: Query current status (counter & pointer) of a semaphore. |
| * Return: UINT32 -Current available unit level |
| ******************************************************************************/ |
| UINT32 semaphore_query(void *hdl, INT32 id, INT32 master, UINT32 *ptr) |
| { |
| 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; |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_push |
| * Description: Producer semaphore push. |
| ******************************************************************************/ |
| void semaphore_push(void *hdl, INT32 id, INT32 delta) |
| { |
| 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); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_push |
| * Description: Consumer semaphore pop. |
| ******************************************************************************/ |
| void semaphore_pop(void *hdl, INT32 id, INT32 delta) |
| { |
| 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); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_chk_empty |
| * Description: Check 'empty' status of a semaphore (or all semaphores). |
| * Return: UINT32 -status bit of given semaphore, or |
| * status bits of all semaphores if id==-1 |
| ******************************************************************************/ |
| UINT32 semaphore_chk_empty(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, sem->ra + RA_SemaHub_empty); |
| return (id < 0) ? d : bTST(d, id); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_chk_full |
| * Description: Check 'full' status of a semaphore (or all semaphores). |
| * Return: UINT32 -status bit of given semaphore, or |
| * status bits of all semaphores if id==-1 |
| ******************************************************************************/ |
| UINT32 semaphore_chk_full(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, sem->ra + RA_SemaHub_full); |
| return (id < 0) ? d : bTST(d, id); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_chk_almostEmpty |
| * Description: Check 'almostEmpty' status of a semaphore (or all semaphores). |
| * Return: UINT32 -status bit of given semaphore, or |
| * status bits of all semaphores if id==-1 |
| ******************************************************************************/ |
| UINT32 semaphore_chk_almostEmpty(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, sem->ra + RA_SemaHub_almostEmpty); |
| return (id < 0) ? d : bTST(d, id); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_chk_almostFull |
| * Description: Check 'almostFull' status of a semaphore (or all semaphores). |
| * Return: UINT32 -status bit of given semaphore, or |
| * status bits of all semaphores if id==-1 |
| ******************************************************************************/ |
| UINT32 semaphore_chk_almostFull(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, sem->ra + RA_SemaHub_almostFull); |
| return (id < 0) ? d : bTST(d, id); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_clr_empty |
| * Description: Clear 'empty' status of a semaphore. |
| ******************************************************************************/ |
| void semaphore_clr_empty(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| |
| IO32WR(1<<id, sem->ra + RA_SemaHub_empty); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_clr_full |
| * Description: Clear 'full' status of a semaphore. |
| ******************************************************************************/ |
| void semaphore_clr_full(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| |
| IO32WR(1<<id, sem->ra + RA_SemaHub_full); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_clr_almostEmpty |
| * Description: Clear 'almostEmpty' status of a semaphore. |
| ******************************************************************************/ |
| void semaphore_clr_almostEmpty(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| |
| IO32WR(1<<id, sem->ra + RA_SemaHub_almostEmpty); |
| } |
| |
| /****************************************************************************** |
| * Function: semaphore_clr_almostFull |
| * Description: Clear 'almostFull' status of a semaphore. |
| ******************************************************************************/ |
| void semaphore_clr_almostFull(void *hdl, INT32 id) |
| { |
| HDL_semaphore *sem = (HDL_semaphore *)hdl; |
| |
| IO32WR(1<<id, sem->ra + RA_SemaHub_almostFull); |
| } |
| |
| /** ENDOFSECTION |
| */ |
| |
| /** SECTION - API definitions for $HBO |
| */ |
| /****************************************************************************** |
| * Function: hbo_hdl |
| * Description: Initialize HDL_hbo with a $HBO BIU instance. |
| ******************************************************************************/ |
| void hbo_hdl(UINT32 mem, INT32 ra, void *hdl) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| HDL_semaphore *fifoCtl = &(hbo->fifoCtl); |
| |
| hbo->mem = mem; hbo->ra = ra; |
| semaphore_hdl(ra + RA_HBO_FiFoCtl, fifoCtl); |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_fifoCtl |
| * Description: Get HDL_semaphore pointer from a HBO instance. |
| * Return: void* -Handle for HBO.FiFoCtl |
| *******************************************************************************/ |
| void *hbo_fifoCtl(void *hdl) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| HDL_semaphore *fifoCtl = &(hbo->fifoCtl); |
| |
| return fifoCtl; |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_cfg |
| * Description: Configurate a FIFO's base, depth & reset pointers. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ |
| ******************************************************************************/ |
| UINT32 hbo_queue_cfg(void *hdl, INT32 id, UINT32 base, INT32 depth, |
| INT32 enable, T64b cfgQ[]) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| HDL_semaphore *fifoCtl = &(hbo->fifoCtl); |
| T32FiFo_CFG cfg; |
| UINT32 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; |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_enable |
| * Description: HBO FIFO enable/disable. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ |
| *******************************************************************************/ |
| UINT32 hbo_queue_enable(void *hdl, INT32 id, INT32 enable, T64b cfgQ[]) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| UINT32 i = 0, a; |
| |
| a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo); |
| IO32CFG(cfgQ, i, a + RA_FiFo_START, enable); |
| return i; |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_clear |
| * Description: Issue HBO FIFO clear (will NOT wait for finish). |
| ******************************************************************************/ |
| void hbo_queue_clear(void *hdl, INT32 id) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| UINT32 a; |
| |
| a = hbo->ra + RA_HBO_ARR + id*sizeof(SIE_FiFo); |
| IO32WR(1, a + RA_FiFo_CLEAR); |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_busy |
| * Description: Read HBO 'BUSY' status for all channel FIFOs. |
| * Return: UINT32 -'BUSY' status bits of all channels |
| ******************************************************************************/ |
| UINT32 hbo_queue_busy(void *hdl) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, hbo->ra + RA_HBO_BUSY); |
| return d; |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_clear_done |
| * Description: Wait for a given channel or all channels to be cleared. |
| ******************************************************************************/ |
| void hbo_queue_clear_done(void *hdl, INT32 id) |
| { |
| UINT32 d; |
| |
| do { |
| d = hbo_queue_busy(hdl); |
| if (id >= 0) |
| d = bTST(d, id); |
| } while (d); |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_read |
| * Description: Read a number of 64b data & pop FIFO from HBO SRAM. |
| * Return: UINT32 - Number of 64b data being read (=n), or (when cfgQ==NULL) |
| * 0 if there're not sufficient data in FIFO |
| ******************************************************************************/ |
| UINT32 hbo_queue_read(void *hdl, INT32 id, INT32 n, T64b data[], UINT32 *ptr) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| INT32 i; |
| UINT32 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; |
| } |
| |
| /****************************************************************************** |
| * Function: hbo_queue_write |
| * Description: Write a number of 64b data & push FIFO to HBO SRAM. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ, or (when cfgQ==NULL) |
| * 0 if there're not sufficient space in FIFO |
| ******************************************************************************/ |
| UINT32 hbo_queue_write(void *hdl, INT32 id, INT32 n, T64b data[], |
| T64b cfgQ[], UINT32 *ptr) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| INT32 i, depth; |
| UINT32 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, (UINT32)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; |
| } |
| |
| /** ENDOFSECTION |
| */ |
| |
| /** SECTION - API definitions for $dHubReg |
| */ |
| /****************************************************************************** |
| * Function: dhub_hdl |
| * Description: Initialize HDL_dhub with a $dHub BIU instance. |
| ******************************************************************************/ |
| void dhub_hdl(UINT32 mem, UINT32 ra, void *hdl) |
| { |
| 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); |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_semaphore |
| * Description: Get HDL_semaphore pointer from a dHub instance. |
| * Return: void* -Handle for dHub.SemaHub |
| ******************************************************************************/ |
| void *dhub_semaphore(void *hdl) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| HDL_semaphore *semaHub = &(dhub->semaHub); |
| |
| return semaHub; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_hbo |
| * Description: Get HDL_hbo pointer from a dHub instance. |
| * Return: void* -Handle for dHub.HBO |
| ******************************************************************************/ |
| void *dhub_hbo(void *hdl) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| HDL_hbo *hbo = &(dhub->hbo); |
| |
| return hbo; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_cfg |
| * Description: Configurate a dHub channel. |
| * Return: UINT32 - Number of (adr,pair) added to cfgQ, or (when cfgQ==NULL) |
| * 0 if either cmdQ or dataQ in HBO is still busy |
| ******************************************************************************/ |
| UINT32 dhub_channel_cfg(void *hdl, INT32 id, UINT32 baseCmd, |
| UINT32 baseData, INT32 depthCmd, INT32 depthData, |
| INT32 MTU, INT32 QoS, INT32 selfLoop, |
| INT32 enable, T64b cfgQ[]) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| HDL_hbo *hbo = &(dhub->hbo); |
| T32dHubChannel_CFG cfg; |
| UINT32 i = 0, a; |
| UINT32 cmdID = dhub_id2hbo_cmdQ(id), dataID = dhub_id2hbo_data(id); |
| |
| 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); |
| } |
| a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel); |
| 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_4096byte: |
| dhub->MTUb[id] = 10; |
| break; |
| } |
| |
| 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); |
| IO32CFG(cfgQ, i, a + RA_dHubChannel_START, enable); |
| |
| return i; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_enable |
| * Description: dHub channel enable/disable. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ |
| ******************************************************************************/ |
| UINT32 dhub_channel_enable(void *hdl, INT32 id, INT32 enable, T64b cfgQ[]) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| UINT32 i = 0, a; |
| |
| a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel); |
| IO32CFG(cfgQ, i, a + RA_dHubChannel_START, enable); |
| return i; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_clear |
| * Description: Issue dHub channel clear (will NOT wait for finish). |
| ******************************************************************************/ |
| void dhub_channel_clear(void *hdl, INT32 id) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| UINT32 a; |
| |
| a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel); |
| IO32WR(1, a + RA_dHubChannel_CLEAR); |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_flush |
| * Description: Issue dHub channel(H2M only) flush(will NOT wait for finish). |
| ******************************************************************************/ |
| void dhub_channel_flush(void *hdl, INT32 id) |
| { |
| UINT32 a; |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| |
| a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel); |
| IO32WR(1, a + RA_dHubChannel_FLUSH); |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_busy |
| * Description: Read dHub 'BUSY' status for all channel FIFOs. |
| * Return: UINT32 -'BUSY' status bits of all channels |
| *******************************************************************************/ |
| UINT32 dhub_channel_busy(void *hdl) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, dhub->ra + RA_dHubReg_BUSY); |
| return d; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_pending |
| * Description: Read dHub 'PENDING' status for all channel FIFOs. |
| * Return: UINT32 -'PENDING' status bits of all channels |
| ******************************************************************************/ |
| UINT32 dhub_channel_pending(void *hdl) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, dhub->ra + RA_dHubReg_PENDING); |
| return d; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_clear_done |
| * Description: Wait for a given channel or all channels to be cleared. |
| ******************************************************************************/ |
| void dhub_channel_clear_done(void *hdl, INT32 id) |
| { |
| UINT32 d; |
| |
| do { |
| d = dhub_channel_busy(hdl); |
| d |= dhub_channel_pending(hdl); |
| if (id >= 0) |
| d = bTST(d, id); |
| } while (d); |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_write_cmd |
| * Description: Write a 64b command for a dHub channel. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ if success, or |
| * 0 if there're not sufficient space in FIFO |
| ******************************************************************************/ |
| UINT32 dhub_channel_write_cmd(void *hdl, INT32 id, UINT32 addr, |
| INT32 size, INT32 semOnMTU, INT32 chkSemId, |
| INT32 updSemId, INT32 interrupt, T64b cfgQ[], |
| UINT32 *ptr) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| HDL_hbo *hbo = &(dhub->hbo); |
| SIE_dHubCmd cmd; |
| INT32 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); |
| } |
| |
| void dhub_channel_generate_cmd(void *hdl, INT32 id, UINT32 *addr, |
| INT32 size, INT32 semOnMTU, INT32 chkSemId, |
| INT32 updSemId, INT32 interrupt, INT32 *pData) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| SIE_dHubCmd cmd; |
| INT32 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; |
| #pragma GCC diagnostic push |
| #pragma GCC diagnostic ignored "-Wpointer-to-int-cast" |
| cmd.uMEM_addr = (UINT32)addr; |
| #pragma GCC diagnostic pop |
| pcmd = (INT32 *)(&cmd); |
| pData[0] = pcmd[0]; |
| pData[1] = pcmd[1]; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub_channel_big_write_cmd |
| * Description: Write a sequence of 64b command for a dHub channel. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ if success, or |
| * 0 if there're not sufficient space in FIFO |
| *******************************************************************************/ |
| UINT32 dhub_channel_big_write_cmd(void *hdl, INT32 id, UINT32 addr, |
| INT32 size, INT32 semOnMTU, INT32 chkSemId, |
| INT32 updSemId, INT32 interrupt, T64b cfgQ[], UINT32 *ptr) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| INT32 i; |
| INT32 j, jj; |
| |
| i = size >> dhub->MTUb[id]; |
| if (size < (1<<16)) { |
| j = dhub_channel_write_cmd(hdl, id, addr, size, |
| semOnMTU, chkSemId, updSemId, |
| interrupt, cfgQ, ptr); |
| } else { |
| INT32 size0, size1; |
| |
| size0 = 0xffff << dhub->MTUb[id]; |
| j = 0; |
| 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; |
| } |
| |
| /** ENDOFSECTION |
| */ |
| |
| /** SECTION - API definitions for $dHubReg2D |
| */ |
| /****************************************************************************** |
| * Function: dhub2d_hdl |
| * Description: Initialize HDL_dhub2d with a $dHub2D BIU instance. |
| ******************************************************************************/ |
| void dhub2d_hdl(UINT32 mem, UINT32 ra, void *hdl) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d *)hdl; |
| HDL_dhub *dhub = &(dhub2d->dhub); |
| |
| dhub2d->ra = ra; |
| dhub_hdl(mem, ra + RA_dHubReg2D_dHub, dhub); |
| } |
| |
| /****************************************************************************************************************** |
| * Function: dhub2nd_channel_cfg |
| * Description: Configurate a dHub2ND channel. |
| * Return: UNSG32 - Number of (adr,pair) added to cfgQ |
| ******************************************************************************************************************/ |
| UNSG32 dhub2nd_channel_cfg( |
| void *hdl, /*! Handle to HDL_dhub2d !*/ |
| SIGN32 id, /*! Channel ID in $dHubReg2D !*/ |
| UNSG32 addr, /*! CMD: 2ND-buffer address !*/ |
| SIGN32 burst, /*! CMD: line stride size in bytes !*/ |
| SIGN32 step1, /*! CMD: buffer width in bytes !*/ |
| SIGN32 size1, /*! CMD: buffer height in lines !*/ |
| SIGN32 step2, /*! CMD: loop size (1~4) of semaphore operations !*/ |
| SIGN32 size2, /*! 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 dHub2ND, or |
| Pass non-zero to receive programming sequence |
| in (adr,data) pairs |
| !*/ |
| ) |
| |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl; |
| SIE_dHubCmd2ND cmd; |
| |
| UNSG32 a, j = 0; |
| a = dhub2d->ra + RA_dHubReg2D_ARR_2ND + id*sizeof(SIE_dHubCmd2ND); |
| IO32CFG(cfgQ, j, a + RA_dHubCmd2ND_START, 0); |
| |
| cmd.uMEM_addr = addr; |
| IO32CFG(cfgQ, j, a + RA_dHubCmd2ND_MEM, cmd.u32dHubCmd2ND_MEM); |
| |
| cmd.uDESC_burst = burst; |
| cmd.uDESC_interrupt = interrupt; |
| cmd.uDESC_chkSemId = chkSemId; |
| cmd.uDESC_updSemId = updSemId; |
| IO32CFG(cfgQ, j, a + RA_dHubCmd2ND_DESC, cmd.u32dHubCmd2ND_DESC); |
| |
| cmd.uDESC_1D_step = step1; |
| cmd.uDESC_1D_size = size1; |
| IO32CFG(cfgQ, j, a + RA_dHubCmd2ND_DESC_1D, cmd.u32dHubCmd2ND_DESC_1D); |
| |
| cmd.uDESC_2D_step = step2; |
| cmd.uDESC_2D_size = size2; |
| IO32CFG(cfgQ, j, a + RA_dHubCmd2ND_DESC_2D, cmd.u32dHubCmd2ND_DESC_2D); |
| |
| IO32CFG(cfgQ, j, a + RA_dHubCmd2ND_START, enable); |
| |
| return j; |
| /** ENDOFFUNCTION: dhub2nd_channel_cfg **/ |
| } |
| |
| /****************************************************************************************************************** |
| * Function: dhub2nd_channel_enable |
| * Description: dHub2ND channel enable/disable. |
| * Return: UNSG32 - Number of (adr,pair) added to cfgQ |
| ******************************************************************************************************************/ |
| UNSG32 dhub2nd_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_2ND + id*sizeof(SIE_dHubCmd2ND); |
| |
| IO32CFG(cfgQ, i, a + RA_dHubCmd2ND_START, enable); |
| return i; |
| /** ENDOFFUNCTION: dhub2nd_channel_enable **/ |
| } |
| |
| /****************************************************************************************************************** |
| * Function: dhub2nd_channel_clear |
| * Description: Issue dHub2ND channel clear (will NOT wait for finish). |
| ******************************************************************************************************************/ |
| void dhub2nd_channel_clear( |
| void *hdl, /*! Handle to HDL_dhub2d !*/ |
| SIGN32 id /*! Channel ID in $dHubReg2D !*/ |
| ) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d*)hdl; |
| UNSG32 a = 0; |
| a = dhub2d->ra + RA_dHubReg2D_ARR_2ND + id*sizeof(SIE_dHubCmd2ND); |
| |
| IO32WR( 1, a + RA_dHubCmd2ND_CLEAR); |
| /** ENDOFFUNCTION: dhub2nd_channel_clear **/ |
| } |
| |
| /****************************************************************************** |
| * Function: dhub2d_channel_cfg |
| * Description: Configurate a dHub2D channel. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ |
| ******************************************************************************/ |
| UINT32 dhub2d_channel_cfg(void *hdl, INT32 id, UINT32 addr, |
| INT32 stride, INT32 width, INT32 height, |
| INT32 semLoop, INT32 semOnMTU, INT32 chkSemId[], |
| INT32 updSemId[], INT32 interrupt, INT32 enable, |
| T64b cfgQ[]) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d *)hdl; |
| HDL_dhub *dhub = &(dhub2d->dhub); |
| SIE_dHubCmd2D cmd; |
| SIE_dHubCmdHDR hdr; |
| INT32 i, size = width; |
| UINT32 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; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub2d_channel_enable |
| * Description: dHub2D channel enable/disable. |
| * Return: UINT32 -Number of (adr,pair) added to cfgQ |
| *******************************************************************************/ |
| UINT32 dhub2d_channel_enable(void *hdl, INT32 id, |
| INT32 enable, T64b cfgQ[]) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d *)hdl; |
| UINT32 i = 0, a; |
| |
| a = dhub2d->ra + RA_dHubReg2D_ARR + |
| id*sizeof(SIE_dHubCmd2D); |
| IO32CFG(cfgQ, i, a + RA_dHubCmd2D_START, enable); |
| return i; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub2d_channel_clear |
| * Description: Issue dHub2D channel clear (will NOT wait for finish). |
| ******************************************************************************/ |
| void dhub2d_channel_clear(void *hdl, INT32 id) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d *)hdl; |
| UINT32 a; |
| |
| a = dhub2d->ra + RA_dHubReg2D_ARR + |
| id*sizeof(SIE_dHubCmd2D); |
| IO32WR(1, a + RA_dHubCmd2D_CLEAR); |
| return; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub2d_channel_busy |
| * Description: Read dHub2D 'BUSY' status for all channel FIFOs. |
| * Return: UINT32 -'BUSY' status bits of all channels |
| ******************************************************************************/ |
| UINT32 dhub2d_channel_busy(void *hdl) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d *)hdl; |
| UINT32 d; |
| |
| IO32RD(d, dhub2d->ra + RA_dHubReg2D_BUSY); |
| return d; |
| } |
| |
| /****************************************************************************** |
| * Function: dhub2d_channel_clear_done |
| * Description: Wait for a given channel or all channels to be cleared. |
| ******************************************************************************/ |
| void dhub2d_channel_clear_done(void *hdl, INT32 id) |
| { |
| UINT32 d; |
| |
| do { |
| d = dhub2d_channel_busy(hdl); |
| if (id >= 0) |
| d = bTST(d, id); |
| } while (d); |
| } |
| |
| |
| #if (BERLIN_CHIP_VERSION >= BERLIN_BG2) |
| void BCM_SCHED_SetMux(UINT32 QID, UINT32 TrigEvent) |
| { |
| UINT32 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(UINT32 QID, UINT32 *pCmd, UINT32 *cfgQ) |
| { |
| UINT32 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(UINT32 QID, UINT32 *EmptySts) |
| { |
| UINT32 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; |
| |
| } |
| |
| int BCM_SCHED_AutoPushCmd(UNSG32 QID, UNSG8 uchEnable) |
| { |
| volatile UNSG32 uiBcmQ_AutoPushSts = 0; |
| |
| /* parameter error */ |
| if ((QID > BCM_SCHED_Q18) || (uchEnable >1)) |
| return -1; |
| |
| //Read the BCM Auto Push register |
| GA_REG_WORD32_READ(MEMMAP_AVIO_BCM_REG_BASE + RA_AVIO_BCM_AUTOPUSH, &uiBcmQ_AutoPushSts); |
| |
| //Enable AutoPush for requested Queue. |
| if(uchEnable) |
| uiBcmQ_AutoPushSts |= (1 << QID); |
| else |
| uiBcmQ_AutoPushSts &= ~(1 << QID); |
| |
| //Write to Register |
| GA_REG_WORD32_WRITE(MEMMAP_AVIO_BCM_REG_BASE + RA_AVIO_BCM_AUTOPUSH, uiBcmQ_AutoPushSts); |
| |
| return 0; |
| } |
| |
| /****************************************************************************************************************** |
| * Function: dhub_channel_enable_InverseScan |
| * Description: Inverse scan for dHub channel enable/disable. |
| * Return: UNSG32 - Number of (adr,pair) added to cfgQ |
| ******************************************************************************************************************/ |
| |
| UNSG32 dhub_channel_enable_InverseScan(void *hdl, //Dhub Handle |
| SIGN32 id, //Channel Number |
| SIGN32 iMode, //Mode of scanninf |
| T64b cfgQ[]) //Prepared command is update dto cfgQ, |
| //Pass NULL to write directly to Dhub. |
| { |
| HDL_dhub *dhub = (HDL_dhub*)hdl; |
| T32dHubChannel_CFG cfg; |
| UNSG32 i = 0, a; |
| a = dhub->ra + RA_dHubReg_ARR + id*sizeof(SIE_dHubChannel); |
| |
| //Get the configuration of channel |
| getDhubChannelInfo(hdl, id, &cfg); |
| |
| switch(iMode) |
| { |
| //Normal Scanning |
| case 0: |
| cfg.uCFG_hScan = 0; cfg.uCFG_vScan = 0; |
| break; |
| //Only H inverse scan |
| case 1: |
| cfg.uCFG_hScan = 1; |
| break; |
| //Only V inverse Scan |
| case 2: |
| cfg.uCFG_vScan = 1; |
| break; |
| case 3: |
| //Both HV inverse |
| cfg.uCFG_hScan = 1; cfg.uCFG_vScan = 1; |
| break; |
| } |
| |
| IO32CFG(cfgQ, i, a + RA_dHubChannel_CFG, cfg.u32); |
| return i; |
| } |
| |
| /**************************************************** |
| * dhub2d_channel_clear_seq() |
| * |
| * dHub2D channel clear sequence |
| ****************************************************/ |
| void dhub2d_channel_clear_seq(void *hdl, INT32 id) |
| { |
| UINT32 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, INT32 id) |
| { |
| UINT32 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); |
| } |
| |
| void dhub_channel_clear_bcmbuf(void *hdl, INT32 id, |
| VIP_BCMBUF *pbcmbuf) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| UINT32 a; |
| |
| a = dhub->ra + RA_dHubReg_ARR + |
| id*sizeof(SIE_dHubChannel); |
| |
| if (pbcmbuf == NULL) |
| return; |
| if (pbcmbuf->writer == pbcmbuf->tail) |
| return; |
| |
| /*save the data to the buffer*/ |
| *pbcmbuf->writer = 1; |
| pbcmbuf->writer++; |
| *pbcmbuf->writer = a + RA_dHubChannel_CLEAR; |
| pbcmbuf->writer++; |
| } |
| |
| UINT32 dhub_channel_enable_bcmbuf(void *hdl, INT32 id, |
| INT32 enable, VIP_BCMBUF *pbcmbuf) |
| { |
| HDL_dhub *dhub = (HDL_dhub *)hdl; |
| UINT32 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++; |
| |
| return i; |
| } |
| |
| void hbo_queue_clear_bcmbuf(void *hdl, INT32 id, VIP_BCMBUF *pbcmbuf) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| UINT32 a; |
| |
| a = hbo->ra + RA_HBO_ARR + |
| id*sizeof(SIE_FiFo); |
| |
| if (pbcmbuf == NULL) |
| return; |
| if (pbcmbuf->writer == pbcmbuf->tail) |
| return; |
| /*save the data to the buffer*/ |
| *pbcmbuf->writer = 1; |
| pbcmbuf->writer++; |
| *pbcmbuf->writer = a + RA_FiFo_CLEAR; |
| pbcmbuf->writer++; |
| } |
| |
| UINT32 hbo_queue_enable_bcmbuf(void *hdl, INT32 id, |
| INT32 enable, VIP_BCMBUF *pbcmbuf) |
| { |
| HDL_hbo *hbo = (HDL_hbo *)hdl; |
| UINT32 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++; |
| return i; |
| } |
| |
| void dhub2d_channel_clear_bcmbuf(void *hdl, INT32 id, |
| VIP_BCMBUF *pbcmbuf) |
| { |
| HDL_dhub2d *dhub2d = (HDL_dhub2d *)hdl; |
| UINT32 a; |
| |
| a = dhub2d->ra + RA_dHubReg2D_ARR + |
| id*sizeof(SIE_dHubCmd2D); |
| *pbcmbuf->writer = 1; |
| pbcmbuf->writer++; |
| *pbcmbuf->writer = a + RA_dHubCmd2D_CLEAR; |
| pbcmbuf->writer++; |
| return; |
| } |
| |
| |
| /**************************************************** |
| * dhub2d_channel_clear_seq() |
| * |
| * dHub 2D channel clear sequence |
| * No wait, return immediately. Use BCM buffer. |
| ****************************************************/ |
| void dhub2d_channel_clear_seq_bcm(void *hdl, INT32 id, void *pbcmbuf) |
| { |
| UINT32 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); |
| 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, INT32 id, VIP_BCMBUF *pbcmbuf) |
| { |
| UINT32 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); |
| |
| 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 |
| /** ENDOFSECTION |
| */ |