static int  __ccif_v1_reset(ccif_t* ccif)
{
    ccci_write32(CCIF_CON(ccif->m_reg_base), 1);
    ccif->m_rx_idx = 0;
    ccif->m_tx_idx = 0;
    // ACK MD all channel
    ccci_write32(CCIF_ACK(ccif->m_reg_base), 0xFF);
    __ccif_v1_clear_sram(ccif);

    return 0;
}
static int __ccif_v1_init(ccif_t* ccif)
{
    //*CCIF_CON(ccif->m_reg_base) = 1;
    ccci_write32(CCIF_CON(ccif->m_reg_base), CCIF_CON_ARB);
    ccif->m_rx_idx = 0;
    ccif->m_tx_idx = 0;
    // ACK MD all channel
    //*CCIF_ACK(ccif->m_reg_base) = 0xFF;
    ccci_write32(CCIF_ACK(ccif->m_reg_base), 0xFF);
    __ccif_v1_clear_sram(ccif);

    return 0;
}
static int  __ccif_v1_get_rx_ch(ccif_t* ccif)
{
    while (CCIF_CON_ARB != ccci_read32(CCIF_CON(ccif->m_reg_base))){
        ccci_write32(CCIF_CON(ccif->m_reg_base), CCIF_CON_ARB);
    }
    return ccci_read32(CCIF_RCHNUM(ccif->m_reg_base));
}
static int  __ccif_v1_ack(ccif_t* ccif, int ch)
{
    //*CCIF_ACK(ccif->m_reg_base) = (1 << ch);
    ccci_write32(CCIF_ACK(ccif->m_reg_base), (1<<ch));

    return 0;
}
void md_cd_dump_debug_register(struct ccci_modem *md)
{
	struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
	
        md_cd_lock_cldma_clock_src(1);
	CCCI_INF_MSG(md->index, TAG, "Dump MD Bus status %x\n", MD_BUS_STATUS_BASE);
	ccci_mem_dump(md->index,md_ctrl->md_bus_status, MD_BUS_STATUS_LENGTH);
	CCCI_INF_MSG(md->index, TAG, "Dump MD PC monitor %x\n", MD_PC_MONITOR_BASE);
	ccci_write32(md_ctrl->md_pc_monitor, 0, 0x80000000); // stop MD PCMon
	ccci_mem_dump(md->index, md_ctrl->md_pc_monitor, MD_PC_MONITOR_LENGTH);
	ccci_write32(md_ctrl->md_pc_monitor, 0, 0x1); // restart MD PCMon
	CCCI_INF_MSG(md->index, TAG, "Dump MD TOPSM status %x\n", MD_TOPSM_STATUS_BASE);
	ccci_mem_dump(md->index, md_ctrl->md_topsm_status, MD_TOPSM_STATUS_LENGTH);
	CCCI_INF_MSG(md->index, TAG, "Dump MD OST status %x\n", MD_OST_STATUS_BASE);
	ccci_mem_dump(md->index, md_ctrl->md_ost_status, MD_OST_STATUS_LENGTH);
        md_cd_lock_cldma_clock_src(0);
}
void md_cldma_hw_reset(struct ccci_modem *md)
{
    unsigned int reg_value;
    struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
    CCCI_INF_MSG(md->index, TAG, "md_cldma_hw_reset:rst cldma\n");
    //reset cldma hw
    reg_value = ccci_read32(infra_ao_base,INFRA_RST0_REG);
    reg_value &=~(CLDMA_AO_RST_MASK|CLDMA_PD_RST_MASK);
    reg_value |=(CLDMA_AO_RST_MASK|CLDMA_PD_RST_MASK);
    ccci_write32(infra_ao_base,INFRA_RST0_REG,reg_value);
    CCCI_INF_MSG(md->index, TAG, "md_cldma_hw_reset:clear reset\n");
    //reset cldma clr
    reg_value = ccci_read32(infra_ao_base,INFRA_RST1_REG);
    reg_value &=~(CLDMA_AO_RST_MASK|CLDMA_PD_RST_MASK);
    reg_value |=(CLDMA_AO_RST_MASK|CLDMA_PD_RST_MASK);
    ccci_write32(infra_ao_base,INFRA_RST1_REG,reg_value);
    CCCI_INF_MSG(md->index, TAG, "md_cldma_hw_reset:done\n");
}
static int  __ccif_v1_clear_sram(ccif_t* ccif)
{
    int i;
    volatile unsigned int *ccif_tx_addr = (volatile unsigned int *) CCIF_TXCHDATA(ccif->m_reg_base);

    for(i=0; i<4*16; i++){
        ccci_write32(&ccif_tx_addr[i], 0);
    }
    return 0;
}
static int  __ccif_v1_write_runtime_data(ccif_t* ccif, unsigned int buf[], int len)
{
    int i;
    volatile unsigned int *curr_ccif_smem_addr = (unsigned int*)(ccif->m_reg_base+CCIF_STD_V1_RUN_TIME_DATA_OFFSET);
    if ( len > CCIF_STD_V1_RUM_TIME_MEM_MAX_LEN ) {
        return -CCCI_ERR_CCIF_INVALID_RUNTIME_LEN;
    }
    for(i=0; i<len; i++){
        ccci_write32(&curr_ccif_smem_addr[i], buf[i]);
    }
    //__ccif_v1_dump_reg(ccif, NULL, 0);
    return 0;
}
void md_cd_dump_debug_register(struct ccci_modem *md)
{
	struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
	unsigned int reg_value;
    md_cd_lock_modem_clock_src(1);
	CCCI_INF_MSG(md->index, TAG, "Dump MD Bus status %x\n", MD_BUS_STATUS_BASE);
	ccci_mem_dump(md->index,md_ctrl->md_bus_status, MD_BUS_STATUS_LENGTH);
	CCCI_INF_MSG(md->index, TAG, "Dump MD PC monitor %x\n", MD_PC_MONITOR_BASE);
	// stop MD PCMon
	reg_value = ccci_read32(md_ctrl->md_pc_monitor,0); 
	reg_value &= ~(0x1<<21);
	ccci_write32(md_ctrl->md_pc_monitor, 0, reg_value); // clear bit[21]
	ccci_write32((md_ctrl->md_pc_monitor+4), 0, 0x80000000); // stop MD PCMon
	ccci_mem_dump(md->index, md_ctrl->md_pc_monitor, MD_PC_MONITOR_LENGTH);
	ccci_write32(md_ctrl->md_pc_monitor+4, 0, 0x1); // restart MD PCMon
	CCCI_INF_MSG(md->index, TAG, "Dump MD TOPSM status %x\n", MD_TOPSM_STATUS_BASE);
	ccci_mem_dump(md->index, md_ctrl->md_topsm_status, MD_TOPSM_STATUS_LENGTH);
	CCCI_INF_MSG(md->index, TAG, "Dump MD OST status %x\n", MD_OST_STATUS_BASE);
	ccci_mem_dump(md->index, md_ctrl->md_ost_status, MD_OST_STATUS_LENGTH);
	CCCI_INF_MSG(md->index, TAG, "Dump MD PLL %x\n", MD_PLL_BASE);
	ccci_mem_dump(md->index, md_ctrl->md_pll, MD_PLL_LENGTH);
    md_cd_lock_modem_clock_src(0);
}
static int  __ccif_v1_write_phy_ch_data(ccif_t* ccif, unsigned int buf[], int retry_en)
{
    int             ret = 0;
    unsigned int    busy;
    unsigned long    flag;
    unsigned int    retry_count = 200;
    unsigned int    ch;
    ccif_msg_t        *tx_msg;
    int md_id = ccif->m_md_id;

    CCCI_FUNC_ENTRY(md_id);
    if(retry_en == 0)
        retry_count = 1;

    do{
        spin_lock_irqsave(&ccif->m_lock, flag);
        busy=ccci_read32(CCIF_BUSY(ccif->m_reg_base));

        ch = ccif->m_tx_idx;
        if (busy&(1<<ch)) {                
            ret = -CCCI_ERR_CCIF_NO_PHYSICAL_CHANNEL;
            if (busy != 0xff) {
                CCCI_DBG_MSG(md_id, "cci", "Wrong Busy value: 0x%X\n", busy);
            }
            spin_unlock_irqrestore(&ccif->m_lock,flag);
            
            udelay(1);
            retry_count--;
        } else {
            ccci_write32(CCIF_BUSY(ccif->m_reg_base), 1<<ch);
            ccif->m_tx_idx++;
            ccif->m_tx_idx &= (CCIF_STD_V1_MAX_CH_NUM-1);
            //spin_unlock_irqrestore(&ccif->m_lock,flag);
            
            //mb(); // Note here, make sure data has write to memory be really send
            tx_msg = (ccif_msg_t*)(CCIF_TXCHDATA(ccif->m_reg_base));
            ccci_write32(&(tx_msg[ch].data[0]), buf[0]);
            ccci_write32(&(tx_msg[ch].data[1]), buf[1]);
            ccci_write32(&(tx_msg[ch].channel), buf[2]);
            ccci_write32(&(tx_msg[ch].reserved), buf[3]);
            //mb();

            ccci_write32(CCIF_TCHNUM(ccif->m_reg_base), ch);
            
            spin_unlock_irqrestore(&ccif->m_lock,flag);

            ret = sizeof(ccif_msg_t);
            break;
        }
    }while(retry_count>0);

    if(lg_ch_tx_debug_enable[md_id] & (1<< buf[2])) 
        CCCI_MSG_INF(md_id, "cci", "[TX]: %08X, %08X, %02d, %08X (%02d)\n",
             buf[0], buf[1], buf[2], buf[3], ch);

    return ret;
}
static int __ccif_v1_intr_handler(ccif_t *ccif)
{
    ccif_msg_t        phy_ch_data;
    int                re_enter_cnt = 0;
    int                r_ch_val;
    int                i;
    int                rx_ch;
    int                md_id = ccif->m_md_id;
    bool             reg_err = FALSE;
    unsigned int    msg[4];

    CCCI_FUNC_ENTRY(md_id);
    set_bit(CCIF_TOP_HALF_RUNNING,&ccif->m_status);
                            
    //CCCI_DBG_MSG(md_id, "cci", "ISR\n");
                            
    if(ccif->isr_notify)
        ccif->isr_notify(md_id);

    rx_ch = ccif->m_rx_idx;

    while( (r_ch_val = ccif->ccif_get_rx_ch(ccif)) && (re_enter_cnt<CCIF_INTR_MAX_RE_ENTER_CNT) )
    {
        for(i=0; i<CCIF_STD_V1_MAX_CH_NUM; i++)
        {
            if (r_ch_val&(1<<rx_ch)) {
                // We suppose always read success
                ccif->ccif_read_phy_ch_data(ccif, rx_ch, (unsigned int*)&phy_ch_data);
                #ifdef CCIF_DEBUG
                if (phy_ch_data.channel >= CCCI_MAX_CH_NUM) {
                    if (!reg_err) {
                        reg_err = TRUE;
                        __ccif_v1_dump_reg(ccif, NULL, 0);
                        CCCI_MSG_INF(md_id, "cci", "[CCIF Register Error]RX: %08X, %08X, %02d, %08X (%02d)\n", phy_ch_data.data[0], \
                            phy_ch_data.data[1], phy_ch_data.channel, phy_ch_data.reserved, rx_ch);
                    }
                }
                #endif

                if((lg_ch_rx_debug_enable[md_id] & ENABLE_ALL_RX_LOG) || 
                    (lg_ch_rx_debug_enable[md_id] & (1<< phy_ch_data.channel))) {
                    CCCI_DBG_MSG(md_id, "cci", "[RX]: %08X, %08X, %02d, %08X (%02d)\n", phy_ch_data.data[0], \
                        phy_ch_data.data[1], phy_ch_data.channel, phy_ch_data.reserved, rx_ch);
                }

                // push ccif message to up layer
                if (unlikely(ccif->push_msg == NULL)) {
                    CCCI_DBG_MSG(md_id, "cci", "push_msg func not registered:0x%08x, 0x%08x, %02d, 0x%08x\n", \
                            phy_ch_data.data[0], phy_ch_data.data[1], phy_ch_data.channel, phy_ch_data.reserved);
                } else {
                    if ( ccif->push_msg(&phy_ch_data, ccif->m_logic_ctl_block) != sizeof(ccif_msg_t) ) {
                        //CCCI_DBG_MSG(md_id, "cci", "push data fail(ch%d)\n", phy_ch_data.channel);
                    }
                }

                // Ack modem side ccif
                ccci_write32(CCIF_ACK(ccif->m_reg_base), (1<<rx_ch));

                r_ch_val &=~(1<<rx_ch);
            } else  {
                if (r_ch_val != 0) {
                    // We suppose rx channel usage should be fifo mode
                    CCCI_DBG_MSG(md_id, "cci", "rx channel error(rx>%02x : %d<curr)\n", r_ch_val, rx_ch);
                    __ccif_v1_dump_reg(ccif, NULL, 0);
                } else {
                    break;
                }
            }
            ++rx_ch;
            rx_ch = rx_ch&(CCIF_STD_V1_MAX_CH_NUM-1);
        }
        re_enter_cnt++;
    }
    
    if( (re_enter_cnt>=CCIF_INTR_MAX_RE_ENTER_CNT) && (r_ch_val!=0) ) {
        CCCI_DBG_MSG(md_id, "cci", "too much message to process\n");
        __ccif_v1_dump_reg(ccif, NULL, 0);
    }

    // Store latest rx channel index
    ccif->m_rx_idx = rx_ch;

    // Notify uplayer begin to process data
    if (unlikely(ccif->notify_push_done == NULL)) {
        //CCCI_DBG_MSG(md_id, "cci", "notify_push_done not registered!\n");
    } else {
        ccif->notify_push_done(ccif->m_logic_ctl_block);
    }

    clear_bit(CCIF_TOP_HALF_RUNNING,&ccif->m_status);

    
    #ifdef CCIF_DEBUG
    if (reg_err) {        
        reg_err = FALSE;
        msg[0]    = 0xFFFFFFFF;
        msg[1]    = 0x5B5B5B5B;
        msg[2]    = CCCI_FORCE_ASSERT_CH;
        msg[3]  = 0xB5B5B5B5;
        __ccif_v1_write_phy_ch_data(ccif, msg, 0);
    }
    #endif

    return 0;
}
static void __ccif_v1_set_busy_state(ccif_t* ccif, unsigned int val)
{
    //*CCIF_BUSY(ccif->m_reg_base) = val;
    ccci_write32(CCIF_BUSY(ccif->m_reg_base), val);
}