cs_status ssp_oper_trigger_done(void) { AHB_SSP_CTRL_t ctrl; cs_uint32 cnt = SSP_POLL_TIME; /* start the control to receive the data. * poll until it finishes */ CS_REG_READ(IROS_AHB_SSP_CTRL, ctrl.wrd); ctrl.bf.sspstart = 1; CS_REG_WRITE(IROS_AHB_SSP_CTRL, ctrl.wrd); do { CS_REG_READ(IROS_AHB_SSP_CTRL, ctrl.wrd); if (ctrl.bf.sspdone) { break; } } while (cnt--); if (cnt <= 0) { /* unable to receive completely before count runs out */ cs_printf("couldn't complete receiving data\n"); return CS_E_TIMEOUT; } /* write sspdone back to register to clear off */ CS_REG_READ(IROS_AHB_SSP_CTRL, ctrl.wrd); ctrl.bf.sspdone = 1; CS_REG_WRITE(IROS_AHB_SSP_CTRL, ctrl.wrd); return CS_E_OK; }
cs_status ssp_config_init(ssp_intf_cfg_t *in_cfg) { AHB_SSP_CFG_t cfg; AHB_SSP_CLK_t clk; if (in_cfg == NULL) return CS_E_PARAM; if (0 == in_cfg->speed_kHz) return CS_E_PARAM; CS_REG_READ(IROS_AHB_SSP_CLK, clk.wrd); clk.bf.counter_load = LYNXD_ASIC_HCLK_KHZ/(2*in_cfg->speed_kHz) -1; CS_REG_WRITE(IROS_AHB_SSP_CLK, clk.wrd); SSP_DBG("SSP_CLK: 0x%08x\n", clk.wrd); CS_REG_READ(IROS_AHB_SSP_CFG, cfg.wrd); cfg.bf.sel_ssp_cs = 0xF & (1 << in_cfg->ssp_select); cfg.bf.micro_wire_cs_sel = 0xF & (in_cfg->mwr_ssp_select << in_cfg->ssp_select); cfg.bf.tdat_cpha = 0x1 & in_cfg->tdat_cpha; cfg.bf.idat_mode = 0x1 & in_cfg->idat_mode; cfg.bf.datin_cmds = 0x1 & in_cfg->datin_cmds; cfg.bf.edge_align = 0x1 & in_cfg->edge_align; cfg.bf.pre_ssp_dat_cnt = 0x1F & in_cfg->data_len; cfg.bf.ssp_cmd_cnt = 0x7F & in_cfg->command_len; cfg.bf.command_cyc = 0x1 & in_cfg->command_only; CS_REG_WRITE(IROS_AHB_SSP_CFG, cfg.wrd); SSP_DBG("SSP_CFG: 0x%08x\n", cfg.wrd); return CS_E_OK; }
cs_status ssp_cmd_set(cs_uint32 cmd_addr_0,cs_uint32 cmd_addr_1,cs_uint32 cmd_addr_2) { /* write the _data to cmd0 register */ CS_REG_WRITE(IROS_AHB_SSP_CA0, cmd_addr_0); CS_REG_WRITE(IROS_AHB_SSP_CA1, cmd_addr_1); CS_REG_WRITE(IROS_AHB_SSP_CA2, cmd_addr_2); return CS_E_OK; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_drop_cells(cs_uint16 port_id, cs_ctl_t ctl, cs_dir_t dir) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* o CS_RX or CS_TX or CS_TX_AND_RX */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Configures the ATM Cell processor to drop all received cells.*/ /* When CS_ENABLE is set for RX direction, no cells are passed */ /* to the datacom interface. And likewise when DROP is enabled */ /* for the TX direction, no cells are accepted from the datacon */ /* interface. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; cs_boolean rx_dir , tx_dir ; volatile cs_reg * regaddr ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_FR_PARSE_DIR_CTL(rx_dir, tx_dir, dir) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; if ( rx_dir ) { ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.DropCells = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; } if ( tx_dir ) { ARN5_FR_STREAMTX_CellControl_t tx_cellCtrl ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamTx_CellControl.wrd ; tx_cellCtrl.wrd = CS_REG_READ(regaddr) ; tx_cellCtrl.bf.Drop = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, tx_cellCtrl.wrd) ; } ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_sel_tx_clkout(cs_uint16 port_id, arn5_lif_tx_clkout_sel_t sel) /* INPUTS : o Port Id */ /* o Selection, see table below */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Select one of the possible clock frequency outputting to TX_CLKOUT */ /* Use with care, no validation. */ /* Use API arn5_lif_ctl_tx_clkout() to enable or disable the selected */ /* output */ /* */ /* [sel] description */ /* ------------------------------------------------------------------ */ /* ARN5_LIF_TX_CLKOUT_STX_CLK stx_clk */ /* ARN5_LIF_TX_CLKOUT_STX_PILOT stx_pilot */ /* ARN5_LIF_TX_CLKOUT_155_MHz (*) 155.52 MHz(SONET)/156.25 MHz(ETH) */ /* ARN5_LIF_TX_CLKOUT_High_Speed high speed clock */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.STX_CLKOUT_SEL = sel & 0x3; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_sel_rx_clkout_common(cs_uint16 port_id, arn5_lif_rx_clkout_sel_t sel) /* INPUTS : o Port Id */ /* o Selection, ARN5_LIF_RX_CLKOUT_15X_MHz or */ /* ARN5_LIF_RX_CLKOUT_7X_MHz */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Select commonly used clock frequency outputting to RX_CLKOUT */ /* Use API arn5_lif_sel_rx_clkout_raw() for all other selections */ /* Use API arn5_lif_ctl_rx_clkout() to enable or disable the selected */ /* output */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.SRX_CLKOUT_SEL = (sel == ARN5_LIF_RX_CLKOUT_15X_MHz) ? 0x13 : 0x1b; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_line_loopback(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o Loopback control(CS_ENABLE or CS_DISABLE) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable or disable line loopback at the Line Interface. The */ /* Rx data is looped back to Tx. */ /* User should enable the loop time mode by calling */ /* arn5_lif_ctl_loop_timing API(). */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_GP_CTRL_t gpctrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); gpctrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.GP_CTRL.wrd) ; gpctrl.bf.LINE_LOOP_BK = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.GP_CTRL.wrd, gpctrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return(CS_OK) ; }
cs_status ssp_data_write(cs_int32 data) { AHB_SSP_CFG_t cfg; cs_status ret = CS_E_OK; /* prepare cfg value */ CS_REG_READ(IROS_AHB_SSP_CFG, cfg.wrd); cfg.bf.read_write = 0; /* set it as write */ CS_REG_WRITE(IROS_AHB_SSP_CFG, cfg.wrd); CS_REG_WRITE(IROS_AHB_SSP_WDAT, data); ret = ssp_oper_trigger_done(); return ret; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_set_sreset(cs_uint16 port_id) /* INPUTS : o Port Id */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Put Line Interface(LIF) block in Soft/Logic Reset. */ /* The CPU access registers are unaffected. */ /* */ /* The reset bit in LIF register is self-clearing and will be */ /* cleared after all the LIF logic reset has been done. */ /* */ /* The caller is responsible to ensure that soft reset is */ /* complete by calling arn5_lif_is_sreset_done() and checking */ /* for a TRUE return value before proceeding further in */ /* configuring LIF registers. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_RESET_t reset ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); reset.wrd = 0 ; if (!CS_IN_TEST_ENV()) { reset.bf.TX_RST = 1 ; reset.bf.RX_RST = 1 ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.RESET.wrd, reset.wrd) ; return(CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_drop_idle(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable / Disable the filtering of IDLE/unassigned cells . */ /* When Enabled no idle/unassigned cells are passed onto system */ /* interface. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.DropIdle = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_ctl_err_correction(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enables/Disables the single bit HEC error correction. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.CorrHec = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_tx_clkout(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o TX_CLKOUT control(CS_ENABLE or CS_DISABLE) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable/Disable the TX clock output */ /* */ /* Use API arn5_lif_sel_tx_clkout() to select frequency before enable */ /* the output. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.STX_CLKOUT_E = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
/* Chip select 3 is used for SSP RXD mux, deselect is requred after use*/ void cs3_deselect(void) { AHB_SSP_CFG_t ssp_cfg; /* deselect chip select 3 */ CS_REG_READ(IROS_AHB_SSP_CFG, ssp_cfg.wrd); ssp_cfg.bf.sel_ssp_cs &= 0x7; CS_REG_WRITE(IROS_AHB_SSP_CFG, ssp_cfg.wrd); }
cs_status cs_gpio_intr_disable(cs_uint8 gpio_id) { cs_uint32 val32; CS_REG_READ(CS_GPIO_IE, val32); val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_IE,val32); return CS_OK; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_set_thr_val(cs_uint16 port_id, arn5_framer_atm_thr_t thr, cs_uint8 value) /* INPUTS : o Port Id */ /* o Threshold type */ /* o Threshold value */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Sets the variousthresolds for ATM Cell FSM. */ /* */ /* The [thr] parameter is specified as following: */ /* ARN5_FR_ATM_OOS_THR or ARN5_FR_ATM_IS_THR or */ /* ARN5_FR_ATM_ERR_CORR_THR */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_Cellfsm_t cellFsm ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; if ((thr != ARN5_FR_ATM_ERR_CORR_THR) && (value <= 1)) { CS_HNDL_ERROR( port_id, EARN5_PORT_ID_OUT_OF_RANGE, NULL) ; return (CS_ERROR) ; } ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.Cellfsm.wrd ; cellFsm.wrd = CS_REG_READ(regaddr) ; switch (thr) { case ARN5_FR_ATM_OOS_THR : cellFsm.bf.ALPHA = value ; break ; case ARN5_FR_ATM_IS_THR : cellFsm.bf.DELTA = value ; break ; case ARN5_FR_ATM_ERR_CORR_THR : cellFsm.bf.GAMMA = value ; break ; } CS_REG_WRITE(regaddr, cellFsm.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_ctl_hec(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enables/Disables the HEC processing by the ATM Cell processor*/ /* When the HEC check is disabled, cells coming from the datacom*/ /* interface no HEC is inserted. HEC thats coming is passed */ /* along. On RX side, when the check is disabled no HEC checking*/ /* is done and the cells with HEC errors is also passed to */ /* datacom interface. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_STREAMTX_CellControl_t tx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.PassHEC = (ctl == CS_DISABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamTx_CellControl.wrd ; tx_cellCtrl.wrd = CS_REG_READ(regaddr) ; tx_cellCtrl.bf.HECDis = (ctl == CS_DISABLE) ? 1 : 0 ; CS_REG_WRITE(regaddr, tx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_framer_atm_ctl_scrambling(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o CS_DISABLE(0) or CS_ENABLE(1) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enables/Disables the scrambling of the ATM cell payload. */ /* $rtn_hdr_end. */ /****************************************************************/ { cs_uint16 sl_num ; ARN5_t * pDev ; volatile cs_reg * regaddr ; ARN5_FR_STREAMTX_CellControl_t tx_cellCtrl ; ARN5_FR_STREAMRX_CellControl_t rx_cellCtrl ; ARN5_FR_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR) ; ARN5_PORT_LOCK(port_id, ARN5_ID_FRAMER) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamRx_CellControl.wrd ; rx_cellCtrl.wrd = CS_REG_READ(regaddr) ; rx_cellCtrl.bf.DisDScr = (ctl == CS_ENABLE) ? 0 : 1 ; CS_REG_WRITE(regaddr, rx_cellCtrl.wrd) ; regaddr = (cs_reg *) &pDev->slice[sl_num].Framer.streamTx_CellControl.wrd ; tx_cellCtrl.wrd = CS_REG_READ(regaddr) ; tx_cellCtrl.bf.DisScr = (ctl == CS_ENABLE) ? 0 : 1 ; CS_REG_WRITE(regaddr, tx_cellCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_FRAMER) ; return (CS_OK) ; }
cs_status cs_gpio_write(cs_uint8 gpio_id, cs_uint8 data) { cs_uint32 val32; if(g_gpio_mode[gpio_id] == GPIO_OUTPUT) { CS_REG_READ(CS_GPIO_OUT, val32); if(data) val32 |= 0x1<<gpio_id; else val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_OUT,val32); } return CS_OK; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_prbs(cs_uint16 port_id, cs_ctl_t tx_ctl, cs_ctl_t rx_ctl, cs_boolean tx_invert, cs_boolean rx_invert, arn5_lif_prbs_t tx_ptrn, arn5_lif_prbs_t rx_ptrn) /* INPUTS : o Port Id */ /* o CS_DISABLE (default) or CS_ENABLE */ /* o CS_DISABLE (default) or CS_ENABLE */ /* o FALSE or TRUE */ /* o FALSE or TRUE */ /* o TX PRBS pattern */ /* o RX PRBS pattern */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable/Disable the PRBS on LIF interfaces. */ /* */ /* [tx_invert]/[rx_invert] indicates whether to invert the transmit or*/ /* receive PRBS pattern. */ /* */ /* The [tx_ptrn]/[rx_ptrn] parameter is one of the following: */ /* ARN5_LIF_PRBS_PATTERN_31 or ARN5_LIF_PRBS_PATTERN_23 or */ /* ARN5_LIF_PRBS_PATTERN_15 or ARN5_LIF_PRBS_PATTERN_7 */ /* */ /* NOTE : UNFRAMERD PRBS feature can be used for internal/external */ /* loopback diagnostics and SONET compliance test as well. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_PRBS_PROV_t prbs_prvsn ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); prbs_prvsn.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.PRBS_PROV.wrd) ; prbs_prvsn.bf.PRBS_TX_SEL = tx_ptrn ; prbs_prvsn.bf.PRBS_RX_SEL = rx_ptrn ; prbs_prvsn.bf.PRBS_TX_INVERT = ( tx_invert ) ? 1 : 0 ; prbs_prvsn.bf.PRBS_RX_INVERT = ( rx_invert ) ? 1 : 0 ; prbs_prvsn.bf.PRBS_TX_ENABLE = ( tx_ctl == CS_ENABLE ) ? 1 : 0 ; prbs_prvsn.bf.PRBS_RX_ENABLE = ( rx_ctl == CS_ENABLE ) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.PRBS_PROV.wrd, prbs_prvsn.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
cs_status cs_gpio_mode_set(cs_uint8 gpio_id, gpio_mode_t mode) { cs_uint32 val32; g_gpio_mode[gpio_id] = mode; switch(mode) { case GPIO_OUTPUT: CS_REG_READ(CS_GPIO_CFG, val32); val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_CFG,val32); break; case GPIO_INPUT: CS_REG_READ(CS_GPIO_CFG, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_CFG,val32); break; case GPIO_INPUT_FALLING: CS_REG_READ(CS_GPIO_CFG, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_CFG,val32); CS_REG_READ(CS_GPIO_LVL, val32); val32 &= ~(0x1<<gpio_id); CS_REG_WRITE(CS_GPIO_LVL,val32); if(!intr_flag) { intr_flag = 0xf; cs_intr_reg(GPIO_INT_NUM, "gpio_irq",cs_gpio_isr, (void*)GPIO_INT_NUM, INTR_DSR_CB); } break; case GPIO_INPUT_RISING: CS_REG_READ(CS_GPIO_CFG, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_CFG,val32); CS_REG_READ(CS_GPIO_LVL, val32); val32 |= 0x1<<gpio_id; CS_REG_WRITE(CS_GPIO_LVL,val32); if(!intr_flag) { intr_flag = 0xf; cs_intr_reg(GPIO_INT_NUM, "gpio_irq",cs_gpio_isr, (void*)GPIO_INT_NUM, INTR_DSR_CB); } break; } return CS_OK; }
cs_status ssp_data_read(cs_int32 *rdata) { AHB_SSP_CFG_t cfg; cs_status ret = CS_E_OK; cs_int32 read_data; /* prepare cfg value */ CS_REG_READ(IROS_AHB_SSP_CFG, cfg.wrd); cfg.bf.read_write = 1; /* set it as read */ CS_REG_WRITE(IROS_AHB_SSP_CFG, cfg.wrd); ret = ssp_oper_trigger_done(); if(CS_E_OK == ret){ /* read the data */ CS_REG_READ(IROS_AHB_SSP_RDAT, read_data); *rdata = read_data; } return ret; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_sel_rx_clkout_raw(cs_uint16 port_id, cs_uint16 sel) /* INPUTS : o Port Id */ /* o Selection, see table below */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Select one of all possible clock frequency outputting to RX_CLKOUT */ /* Use with care, no validation. */ /* Use API arn5_lif_ctl_rx_clkout() to enable or disable the selected */ /* output. */ /* */ /* [sel], the value is mode dependent as listed below. */ /* sel value OC48 mode OC12 mode OC3 mode 1GE mode */ /* -------------------------------------------------------------------*/ /* 0x03 622.08 MHz 622.08 MHz 622.08 MHz 625 MHz */ /* 0x0b 311.04 MHz 311.04 MHz 311.04 MHz 312.5 MHz */ /* 0x13 (*) 155.52 MHz 155.52 MHz 155.52 MHz 156.25 MHz */ /* 0x1b 77.76 MHz 77.76 MHz 77.76 MHz 78.125 MHz */ /* 0x33 38.88 MHz 38.88 MHz 38.88 MHZ 39.0625 MHz */ /* 0x3b SRX_CLK(77.76 MHz) (19.44 MHz) (4.86 MHz) (125 MHz)*/ /* 0x3d 2.488 GHz 2.488 GHz 2.488 GHz 2.5 GHz */ /* 0x3e 2.5 Gb/s 622 Mb/s 155 Mb/s 1.25 Gb/s*/ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_CLKOUT_CTRL_t clkoutCtrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); clkoutCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd) ; clkoutCtrl.bf.SRX_CLKOUT_SEL = sel; CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLKOUT_CTRL.wrd, clkoutCtrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
static cs_status arn5_lif_ctl_clk(ARN5_t * pDev, cs_uint16 sl_num, cs_uint8 clk, cs_ctl_t ctl) { ARN5_LIF_CLOCK_ENABLE_t clkCtrl ; clkCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.CLOCK_ENABLE.wrd) ; if (clk & ARN5_LIF_RX_CLK) { clkCtrl.bf.RX_CLK_E = ( ctl == CS_DISABLE ) ? 0 : 1 ; } if (clk & ARN5_LIF_TX_CLK) { clkCtrl.bf.TX_CLK_E = ( ctl == CS_DISABLE ) ? 0 : 1 ; } if (clk & ARN5_LIF_LD_CLK) { clkCtrl.bf.LD_CLK_E = ( ctl == CS_DISABLE ) ? 0 : 1 ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.CLOCK_ENABLE.wrd, clkCtrl.wrd) ; return (CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_analog_loopback(cs_uint16 port_id, cs_ctl_t ctl) /* INPUTS : o Port Id */ /* o Loopback control(CS_ENABLE or CS_DISABLE) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Enable or disable analog terminal loopback at the Line Interface. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_LIF_GP_CTRL_t gpctrl ; ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); gpctrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.GP_CTRL.wrd) ; gpctrl.bf.FE_TERM_LP_BK = (ctl == CS_ENABLE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.GP_CTRL.wrd, gpctrl.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }
static cs_int32 cs_gpio_isr(int irq, void *dev_id) { cs_uint32 stat; cs_int32 i; if(irq != GPIO_INT_NUM) { cs_printf("lynxd gpio: wrong irq number: %d\n", irq); return CS_ERROR; } CS_REG_READ(CS_GPIO_INT, stat); CS_REG_WRITE(CS_GPIO_INT, stat); for(i=0; i<GPIO_MAX_NUM;i++) { if((stat&(0x1<<i))&& g_gpio_handler[i]!=NULL) g_gpio_handler[i]((void*)g_gpio_handler_data[i]); } return CS_OK; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_ctl_loop_timing(cs_uint16 port_id, arn5_lif_tx_clk_mode_t tx_clk_mode) /* INPUTS : o Port Id */ /* o TX Clock Mode */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Configures the TX clock timing. */ /* */ /* The [tx_clk_mode] parameter is one of the following: */ /* ARN5_LIF_TX_CLK_LOCAL or ARN5_LIF_TX_CLK_LOOP_INTERNAL or */ /* ARN5_LIF_TX_CLK_LOOP_EXTERNAL */ /* */ /* While selecting ARN5_LIF_TX_CLK_LOOP_EXTERNAL, user might need to */ /* select and enable RX_CLKOUT first. */ /* See also arn5_lif_ctl_rx_clkout, arn5_lif_sel_rx_clkout_commmon */ /* arn5_lif_sel_rx_clkout_raw */ /* */ /* LIF Soft-reset will be hit in this API. */ /* It is also required to hit Framer logic reset whenever loop_timing */ /* mode is changed. */ /* For Framer reset, use API arn5_framer_ctl_domain_sreset(), and */ /* select all domains, ARN5_FR_ALL_DOMAINS. Toggle the reset control */ /* with minimum of 10us in between. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; arn5_lif_ref_clk_t refClk ; cs_uint16 sl_num ; cs_uint8 tx_clk_div1, tx_clk_div2, clk_mask = 0; ARN5_LIF_TIMING_CTRL_t tmCtrl ; ARN5_LIF_GP_CTRL_t gpCtrl ; cs_uint16 rxVcoTune2, rxLoopFilter ; cs_uint16 rxChargePump, testCtrl ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); if (arn5_mpif_is_in_gige_mode(port_id) && (tx_clk_mode != ARN5_LIF_TX_CLK_LOCAL)) { CS_HNDL_ERROR(port_id, EARN5_PORT_INVALID_USER_ARG, ": GIGE only works with local timing mode.\n") ; return (CS_ERROR) ; } ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); /* * Get the current configured value of the reference clock. */ refClk = ARN5_LIF_GET_REF_CLK_VAL(port_id) ; rxVcoTune2 = 0x735 ; testCtrl = 0 ; rxLoopFilter = 0xa3 ; rxChargePump = 0xf2f ; if (arn5_mpif_is_in_oc12_mode(port_id)) { if (tx_clk_mode == ARN5_LIF_TX_CLK_LOOP_INTERNAL) { rxVcoTune2 = 0xf35 ; testCtrl = 1 ; rxLoopFilter = 0x93 ; rxChargePump = 0xfbf ; } } else if (arn5_mpif_is_in_oc48_mode(port_id)) { if (tx_clk_mode == ARN5_LIF_TX_CLK_LOOP_INTERNAL) { rxVcoTune2 = 0xf34 ; testCtrl = 1 ; rxLoopFilter = 0x13 ; rxChargePump = 0xfbf ; } } else if (arn5_mpif_is_in_oc3_mode(port_id)) { rxLoopFilter = 0xd3 ; rxChargePump = 0xfbf ; if (tx_clk_mode == ARN5_LIF_TX_CLK_LOOP_INTERNAL) { rxVcoTune2 = 0xf35 ; testCtrl = 1 ; } } else { /* GigeE */ } CS_REG_WRITE(&pDev->slice[sl_num].LIF.RX_VCO_TUNE2.wrd, rxVcoTune2) ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.TEST_CTRL.wrd, testCtrl) ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.RX_LOOP_FILTER.wrd, rxLoopFilter) ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.RX_CHARGE_PUMP.wrd, rxChargePump) ; /* * Check if div1 or div2 needs to be changed. If so, modify them. */ tx_clk_div1 = arn5_lif_get_STX_CKREF_DIV1(refClk) ; tx_clk_div2 = arn5_lif_get_STX_CKREF_DIV2(refClk, tx_clk_mode) ; tmCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.TIMING_CTRL.wrd) ; if (tmCtrl.bf.STX_CKREF_DIV1 != tx_clk_div1) { clk_mask = (ARN5_LIF_TX_CLK | ARN5_LIF_LD_CLK) ; } else if (tmCtrl.bf.STX_CKREF_DIV2 != tx_clk_div2) { clk_mask = (ARN5_LIF_TX_CLK) ; } if ( clk_mask ) { arn5_lif_ctl_clk(pDev, sl_num, clk_mask, CS_DISABLE ) ; tmCtrl.bf.STX_CKREF_DIV1 = tx_clk_div1 ; tmCtrl.bf.STX_CKREF_DIV2 = tx_clk_div2 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.TIMING_CTRL.wrd, tmCtrl.wrd) ; arn5_lif_ctl_clk(pDev, sl_num, clk_mask, CS_ENABLE ) ; } gpCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.GP_CTRL.wrd) ; gpCtrl.bf.STX_CKREF_SEL = (tx_clk_mode == ARN5_LIF_TX_CLK_LOOP_EXTERNAL) ? 1 : 0 ; gpCtrl.bf.STX_LPTIME_E = 0 ; /* always */ CS_REG_WRITE(&pDev->slice[sl_num].LIF.GP_CTRL.wrd, gpCtrl.wrd) ; /* set this value to TX_OUTPUT_CTRL regardless mode selection */ CS_REG_WRITE(&pDev->slice[sl_num].LIF.TX_OUTPUT_CTRL.wrd, 0x43) ; /* hit soft reset to let LIF start a new life */ arn5_lif_set_sreset(port_id) ; CS_UDELAY(10) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return(CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_init_cfg(cs_uint16 port_id, arn5_port_cfg_t * pPortCfg) /* INPUTS : o Chip Id */ /* o Pointer to port configuration struct */ /* */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* This initializes the port level of the LIF block */ /* with the given summary. */ /* */ /* The [pPortCfg] parameter is a pointer to the configuration */ /* data-structure, which has all the configuration parameters */ /* set. */ /* The API expects the data-structure to be already allocated */ /* and populated with the configuration settings. */ /* $_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; ARN5_LIF_SERDES_CONFIGURATION_t serdes ; cs_uint8 sl_num ; cs_uint32 usec_delay = 100, usec_timeout = 1000 ; cs_uint32 usec_elapsed = 0; arn5_lif_cfg_t * pCfg = &pPortCfg->lif ; //CS_PRINT("\t Initializing LIF... \n") ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); ARN5_PORT_LOCK(port_id, ARN5_ID_LIF) ; serdes.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.SERDES_CONFIGURATION.wrd) ; serdes.bf.STX_E_CKREF_SEL = (pPortCfg->summ.line_rate == ARN5_PORT_RATE_GIGE) ? 1 : 0 ; CS_REG_WRITE(&pDev->slice[sl_num].LIF.SERDES_CONFIGURATION.wrd, serdes.wrd) ; ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF) ; if (arn5_lif_ctl_rx_clkout(port_id, pCfg->rx_clkout_ctl) != CS_OK) { return CS_ERROR ; } if (arn5_lif_sel_rx_clkout_raw(port_id, pCfg->rx_clkout_sel) != CS_OK) { return CS_ERROR ; } if (arn5_lif_ctl_tx_clkout(port_id, pCfg->tx_clkout_ctl) != CS_OK) { return CS_ERROR ; } if (arn5_lif_sel_tx_clkout(port_id, pCfg->tx_clkout_sel) != CS_OK) { return CS_ERROR ; } if (arn5_lif_ctl_loop_timing(port_id, pCfg->tx_clk_mode) != CS_OK) { return CS_ERROR ; } if (pCfg->terminal_loopback) { if (pCfg->analog_term_lb) { arn5_lif_ctl_analog_loopback(port_id, CS_ENABLE); } else { arn5_lif_ctl_terminal_loopback(port_id, CS_ENABLE); } } else if (pCfg->line_loopback) { arn5_lif_ctl_line_loopback(port_id, CS_ENABLE) ; } /* Soft-reset LIF before starting traffic */ if (arn5_lif_set_sreset(port_id) != CS_OK) { return CS_ERROR ; } while ( !(arn5_lif_is_sreset_done(port_id)) ) { if (usec_elapsed >= usec_timeout) break ; CS_UDELAY(usec_delay) ; usec_elapsed += usec_delay ; } /* Init IRQ Tables and enable default IRQs */ if (arn5_lif_init_irq_cfg(port_id, pCfg) != CS_OK ) { return (CS_ERROR) ; } return(CS_OK) ; }
/* CHIP : Arsenal5 */ cs_status arn5_lif_inj_error(cs_uint16 port_id, arn5_lif_prbs_err_t err, cs_boolean once, cs_uint16 duration) /* INPUTS : o Port Id */ /* o ERROR TYPE ( 1 BIT ) OR BLOCK ERROR */ /* o Once ( TRUE ) or continuously ( FALSE ) */ /* o Durtaion of error injection(if doing continously) */ /* OUTPUTS : ---- */ /* RETURNS : CS_OK or CS_ERROR */ /* DESCRIPTION: */ /* Injects error in the PRBS stream. */ /* The [err] parameter is one of the following: */ /* ARN5_LIF_PRBS_1_BIT_ERR or ARN5_LIF_PRBS_BLOCK_ERR */ /* Note : This function might block for "duration" if continuous */ /* errors need to be generated. */ /* $rtn_hdr_end */ /**********************************************************************/ { ARN5_t * pDev ; cs_uint16 sl_num ; ARN5_LIF_PRBS_CTRL_t prbsCtrl ; ARN5_LIF_GET_DEVICE_ADDR(port_id, pDev, sl_num, CS_ERROR); prbsCtrl.wrd = CS_REG_READ(&pDev->slice[sl_num].LIF.PRBS_CTRL.wrd) ; ARN5_PORT_LOCK(port_id, ARN5_ID_LIF); switch ( err ) { case ARN5_LIF_PRBS_BLOCK_ERR: if(once) { prbsCtrl.bf.PRBS_WORD_ERR_INJ_ONCE = 1 ; } else { prbsCtrl.bf.PRBS_WORD_ERR_INJ = 1 ; } break ; case ARN5_LIF_PRBS_1_BIT_ERR: if(once) { prbsCtrl.bf.PRBS_BIT_ERR_INJ_ONCE = 1 ; } else { prbsCtrl.bf.PRBS_BIT_ERR_INJ = 1 ; } break ; default : ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); CS_HNDL_ERROR(port_id, EARN5_LIF_INVALID_ERROR_OP, "\n" ) ; return (CS_ERROR) ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.PRBS_CTRL.wrd, prbsCtrl.wrd) ; if(!once) { CS_UDELAY(duration) ; if ( err == ARN5_LIF_PRBS_BLOCK_ERR ) { prbsCtrl.bf.PRBS_WORD_ERR_INJ = 0 ; } else { prbsCtrl.bf.PRBS_BIT_ERR_INJ = 0 ; } CS_REG_WRITE(&pDev->slice[sl_num].LIF.PRBS_CTRL.wrd, prbsCtrl.wrd) ; } ARN5_PORT_UNLOCK(port_id, ARN5_ID_LIF); return (CS_OK) ; }