// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : phy_init.c
// Author        : xianfeng.du
// Created On    : 2022-12-27
// Last Modified :
// -----------------------------------------------------------------
// Description:
// ecs_rfm_spu1 phy_init
//
// -FHDR------------------------------------------------------------

#include "phy_para.h"
#include "mtimer_cell.h"
#include "ucp_utility.h"
#include "app_interface.h"
#include "phy_para.h"
#include "rfm1_drv.h"
#include "jesd_orx_timer.h"
#include "ecs_rfm_dm_mgt.h"

#define CELL_SETUP_TYPE_SIMULATION (0x5a6b7c8d)
#define ORX_MSG_TYPE_SIMULATION (0xaabb7788)

#define ECS_RFM1_TEST_MSG_SIZE   (8)
#define ECS_RFM1_MSG_TYPE        (0)

uint8_t gu8_send_create_task_cnt = 0;
uint8_t gu8_send_del_task_cnt = 0;

int32_t phy_fh_drv_init()
{
    stFrontHaulDrvPara fhDrvPara;
    memset_ucp(&fhDrvPara, 0, sizeof(stFrontHaulDrvPara));

#ifdef DISTRIBUTED_BS
    fhDrvPara.protocolSel = PROTOCOL_CPRI;
    fhDrvPara.rateOption = CPRI_OPTION_8;
    fhDrvPara.mapOption = OTIC_MAP_FIGURE12;
#endif

#ifdef ECPRI_DISTRIBUTED_BS
    fhDrvPara.protocolSel = PROTOCOL_ECPRI;
    fhDrvPara.rateOption = ECPRI_OPTION_10G;
#endif

#ifdef INTEGRATED_BS
    fhDrvPara.protocolSel = PROTOCOL_JESD;
    fhDrvPara.rateOption = JESD_OPTION_204B;
#endif
#ifdef INTEGRATED_204C_BS
	fhDrvPara.protocolSel = PROTOCOL_JESD;
	fhDrvPara.rateOption = JESD_OPTION_204C;
#endif

    fronthaul_drv_cfg(&fhDrvPara);

    return 0;
}

void ecs_rfm1_send_create_task_info(uint8_t dst_core_id)
{
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char* addr = NULL;
    addr = osp_alloc_msg(ECS_RFM1_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 58), 0xa1);
        debug_write(DBG_DDR_COMMON_IDX(core_id, 59), dst_core_id);
        return ;
    }
    debug_write(DBG_DDR_COMMON_IDX(core_id, 4), (uint32_t)addr);
    do_write(addr, 0xa1a2a3a4);
    do_write((addr+4), 0xb1b2b3b4);
    ret = osp_send_msg((uint32_t)(addr),
                        ECS_RFM1_TEST_MSG_SIZE,
                        ECS_RFM1_MSG_TYPE,
                        11,     // src que id
                        dst_core_id,      // dst que id
                        50,     // src task id
                        50);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 58), 0xa2);
        debug_write(DBG_DDR_COMMON_IDX(core_id, 59), dst_core_id);
        return ;
    }
    debug_write(DBG_DDR_COMMON_IDX(core_id, 60), ++gu8_send_create_task_cnt);
    return ;
}

void ecs_rfm1_send_del_task_info(uint8_t dst_core_id)
{
    uint32_t core_id = get_core_id();
    int32_t  ret = 0;
    char* addr = NULL;
    addr = osp_alloc_msg(ECS_RFM1_TEST_MSG_SIZE);
    if (NULL == addr)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 61), 0xa1);
        debug_write(DBG_DDR_COMMON_IDX(core_id, 62), dst_core_id);
        return ;
    }
    debug_write(DBG_DDR_COMMON_IDX(core_id, 4), (uint32_t)addr);
    do_write(addr, 0xa1a2a3a4);
    do_write((addr+4), 0xb1b2b3b4);
    ret = osp_send_msg((uint32_t)(addr),
                        ECS_RFM1_TEST_MSG_SIZE,
                        ECS_RFM1_MSG_TYPE,
                        11,     // src que id
                        dst_core_id,      // dst que id
                        51,     // src task id
                        51);    // dst task id

    if (0 != ret)
    {
        debug_write(DBG_DDR_COMMON_IDX(core_id, 61), 0xa2);
        debug_write(DBG_DDR_COMMON_IDX(core_id, 62), dst_core_id);
        return ;
    }
    debug_write(DBG_DDR_COMMON_IDX(core_id, 63), ++gu8_send_del_task_cnt);
    return ;
}

void ecs_rfm1_build_cell(uint32_t scsId, uint32_t cellId, uint32_t coreId, uint32_t frame_type)
{
    phy_timer_config_ind_t my_cpritmr;

    my_cpritmr.scsId = scsId;
    if ((0 <= cellId) || ((3 >= cellId)))
    {
        my_cpritmr.runCoreId = coreId;
    }
    else 
    {
        my_cpritmr.runCoreId = 0;
    }

	my_cpritmr.frameType = frame_type;
    if (TDD_2500US_DOUBLE == frame_type)
    {
        my_cpritmr.t_period = 5000;
        my_cpritmr.t_us = 500;
        my_cpritmr.num_tti = 10;
        my_cpritmr.num_tti_per_sfn = 20;

        my_cpritmr.num_t_dl[0] = 3; 	    // dl slot num
        my_cpritmr.num_t_dl_symb[0] = 6;	// dl symbol num
        my_cpritmr.num_t_ul_symb[0] = 4;	// ul symbol num
        my_cpritmr.num_ants[0] = 4;

        my_cpritmr.num_t_dl[1] = 2; 	    // dl slot num
        my_cpritmr.num_t_dl_symb[1] = 6;	// dl symbol num
        my_cpritmr.num_t_ul_symb[1] = 4;	// ul symbol num
        my_cpritmr.num_ants[1] = 4;
    }
    else 
    {
        if (NR_SCS_30K == scsId)
        {
            //my_cpritmr.frameType = TDD_MODE;
            //my_cpritmr.frameType = FDD_MODE;
            my_cpritmr.t_period = 5000;
            my_cpritmr.t_us = 500;
            my_cpritmr.num_tti = 10;
            my_cpritmr.num_tti_per_sfn = 20;

            my_cpritmr.num_t_dl[0] = 7;		// dl slot num
            my_cpritmr.num_t_dl_symb[0] = 6;	// dl symbol num
            my_cpritmr.num_t_ul_symb[0] = 4;	// ul symbol num
            my_cpritmr.num_ants[0] = 4;
        }
        else if (LTE_SCS_ID == scsId)
        {
            //my_cpritmr.frameType = TDD_MODE;
            //my_cpritmr.frameType = FDD_MODE;
            my_cpritmr.t_period = 10000;
            my_cpritmr.t_us = 1000;
            my_cpritmr.num_tti = 10;
            my_cpritmr.num_tti_per_sfn = 10;

            my_cpritmr.num_t_dl[0] =10;// 7;		// dl slot num
            my_cpritmr.num_t_dl_symb[0] = 14;//6;	// dl symbol num
            my_cpritmr.num_t_ul_symb[0] = 14;//4;	// ul symbol num
            my_cpritmr.num_ants[0] = 2;
        }
        else
        {
            return;
        }
    }

    int32_t ret = mtimer_init4phy(&my_cpritmr);
    if (0 != ret)
    {
        return;
    }

    uint32_t apeId = 0;
    uint32_t runCore = my_cpritmr.runCoreId;
    volatile uint32_t h1Pos = __builtin_clz(runCore); // 从高bit开始，第一个1前面的0的个数
    while (h1Pos != 32)
    {
        apeId = 31 - h1Pos;
        if (8 <= apeId)
        {
            return;
        }

        ecs_rfm1_send_create_task_info(apeId);

        runCore &= (~(1 << apeId));
        h1Pos = __builtin_clz(runCore);
    }
}

void ecs_rfm1_delete_cell(uint32_t scsId, uint32_t cellId, uint32_t coreId)
{
    int32_t ret = 0;
#ifdef PALLADIUM_TEST
    int32_t flag = 1;
    debug_write((DBG_DDR_IDX_DRV_BASE+52), flag);		// 0xb7e060d0
#endif

    stPhyDelCell myDelCell;
    myDelCell.scsId = scsId;
    if ((0 <= cellId) || (3 >= cellId))
    {
        myDelCell.delCoreId = coreId;
    }
    else 
    {
        myDelCell.delCoreId = 0;
    }

    uint32_t apeId = 0;
    uint32_t runCore = myDelCell.delCoreId;
    volatile uint32_t h1Pos = __builtin_clz(runCore); // 从高bit开始，第一个1前面的0的个数
    while (h1Pos != 32)
    {
        apeId = 31 - h1Pos;
        if (8 <= apeId)
        {
            return;
        }

        ecs_rfm1_send_del_task_info(apeId);

        runCore &= (~(1 << apeId));
        h1Pos = __builtin_clz(runCore);
    }
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+52), flag);		// 0xb7e060d0
#endif

    ret = mtimer_del_cell_cfg(&myDelCell);
#ifdef PALLADIUM_TEST
    flag++;
    debug_write((DBG_DDR_IDX_DRV_BASE+52), flag);		// 0xb7e060d0
#endif
}

volatile uint32_t gCellFlag = 0;
void phy_init(void)
{
    gCellFlag = 0;
    return;
}

void phy_oam_msg_proc(uint32_t u32msg_addr, uint32_t u32msg_size)
{
    return ;
}

void phy_msg_proc(uint32_t u32msg_addr, uint32_t u32msg_size)
{
    uint32_t msg_buf = do_read(u32msg_addr);
    uint32_t msg_type = do_read(msg_buf);
//    EcsRfmDmLocalMgt_t* pEcsDmLocalMgt = get_ecs_rfm_dm_local_mgt();
//    JesdOrxPara_t* orx_para_ptr = pEcsDmLocalMgt->jesd_orx_para_ptr;

    //memcpy_ucp(0x60000000, msg_buf, 32); // temp code
    if (CELL_SETUP_TYPE_SIMULATION == msg_type)
    {
        uint32_t msg_new_del = do_read(msg_buf+12); // 0; // 
        uint32_t scs_id = do_read(msg_buf+16);      // 1; // 
        uint32_t cell_id = do_read(msg_buf+20);     // 0; // 
        uint32_t run_core = do_read(msg_buf+24);
        uint32_t frame_type = do_read(msg_buf+28);

        if (1 < msg_new_del)
        {
            return;
        }
        if (NR_SCS_120K < scs_id)
        {
            return;
        }

        if (0 == msg_new_del)
        {
            ecs_rfm1_build_cell(scs_id, cell_id, run_core, frame_type);
        }
        else
        {
            ecs_rfm1_delete_cell(scs_id, cell_id, run_core);
        }
        debug_write(DBG_DDR_COMMON_IDX(get_core_id(),1), 0x12345678);
    }
    else if (ORX_MSG_TYPE_SIMULATION == msg_type)
    {
        //if (1 > orx_para_ptr->orx_calldrv_cnt)
        {
            phy_sniffer_start(10000);
            debug_write(DBG_DDR_COMMON_IDX(get_core_id(),2), ORX_MSG_TYPE_SIMULATION);
        }
    }

    return;
}

uint32_t gDdrCallCnt = 0;
void ddr_wr_callback()
{
    gDdrCallCnt++;
    debug_write((DBG_DDR_IDX_DRV_BASE+127), gDdrCallCnt); // 0x1fc
}

uint32_t gFapiCallCnt = 0;
void rfm1_fapi_callback()
    {
    gFapiCallCnt++;
    debug_write((DBG_DDR_IDX_DRV_BASE+123), gFapiCallCnt); // 0x1ec
}

uint32_t gOrxCallCnt = 0;
void phy_sniffer_data_proc()
{
    gOrxCallCnt++;
    debug_write((DBG_DDR_IDX_DRV_BASE+123), gOrxCallCnt); // 0x1ec
}

void Mem_Init(void)
{
    return ;
}

uint32_t get_core_mask_by_phy(void)
{
    return APE_CORE_MASK & 0xff;
}


