#include "lisoc_test.h"
#include "ddr.h"


volatile uint32_t ddr_ctrl_base;
volatile uint32_t ddr_phy_base;


void phy_apb_wr_cmd( uint32_t addr, uint8_t stop, uint8_t start, uint32_t wdata ){
    unsigned int tmp0 =0 ;
    unsigned int tmp1 =0 ;
        tmp0 =(*(volatile uint32_t *)((addr)  | ddr_phy_base));
        tmp1 =(((0xffffffff <<(31-stop))>>(31-stop+start))<<start);
        tmp0 = tmp0 &(~tmp1);
        tmp0 =((wdata <<start) & tmp1)|tmp0;
       (*(volatile uint32_t *)((addr)  | ddr_phy_base)) = tmp0;   
       //printf("[PHY_WR]addr[%d:%d] = 0x%08x;   wdata = 0x%08x\n",stop,start,addr,wdata);
}

uint32_t phy_apb_rd_cmd( uint32_t addr, uint8_t stop, uint8_t start){
        unsigned int tmp =0  ;
        tmp =(*(volatile uint32_t *)((addr)| ddr_phy_base));
        tmp =((tmp <<(31-stop))>>(31-stop+start));
        // printf("[PHY_WR]addr[%d:%d] = 0x%08x;   rdata = 0x%08x\n",stop,start,addr,tmp);        
        return tmp;
}
#if 0
void apb_ctrl_wr_cmd( uint32_t addr, uint8_t stop, uint8_t start, uint32_t wdata ){
    unsigned int tmp0 =0 ;
    unsigned int tmp1 =0 ;
        tmp0 =(*(volatile uint32_t *)((addr)  | ddr_ctrl_base));
        tmp1 =(((0xffffffff <<(31-stop))>>(31-stop+start))<<start);
        tmp0 = tmp0 &(~tmp1);
        tmp0 =((wdata <<start) & tmp1)|tmp0;
       (*(volatile uint32_t *)((addr)  | ddr_ctrl_base)) = tmp0;   
       //printf("[PHY_WR]addr[%d:%d] = 0x%08x;   wdata = 0x%08x\n",stop,start,addr,wdata);
}
#endif

uint32_t apb_ctrl_rd_cmd1( uint32_t addr, uint8_t stop, uint8_t start){
        unsigned int tmp =0  ;
        tmp =(*(volatile uint32_t *)((addr)| ddr_ctrl_base));
        tmp =((tmp <<(31-stop))>>(31-stop+start));
        //printf("[PHY_WR]addr[%d:%d] = 0x%08x;   rdata = 0x%08x\n",stop,start,addr,tmp);        
        return tmp;
}

void ddrn_phy_wr_training(struct train_result *tresult,int	cs_sel,int freq_sel ){
int	readreg_data0;
int	readreg_data1;
//the register address offset of the training result.
int rank_num;
int i;


    if(cs_sel == 0xe){  
        rank_num = 0;
    }else if(cs_sel == 0xd){
        rank_num = 1;
    }else if(cs_sel == 0xb){
        rank_num = 2;
    }else{
        rank_num = 3;
    }
        readreg_data0=0x0;
        readreg_data0 = phy_apb_rd_cmd(reg_wr_train_error_byte);//byte error
        if((readreg_data0 & 0xf) !=0){
	        printf("[INNO_INFO] ERROR: when normal wr train, expect valid byte no error, but byte error=%04x  ...\n",readreg_data0 & 0xf);

        }
  printf("[INNO_INFO] Get the write train result.\n");
   
    if(1){
      printf("[INNO_INFO] reg_a_l_train_min_for_dq0 =0x%x; reg_a_l_train_max_for_dq0 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq0),phy_apb_rd_cmd(reg_a_l_train_max_for_dq0));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq1 =0x%x; reg_a_l_train_max_for_dq1 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq1),phy_apb_rd_cmd(reg_a_l_train_max_for_dq1));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq2 =0x%x; reg_a_l_train_max_for_dq2 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq2),phy_apb_rd_cmd(reg_a_l_train_max_for_dq2));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq3 =0x%x; reg_a_l_train_max_for_dq3 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq3),phy_apb_rd_cmd(reg_a_l_train_max_for_dq3));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq4 =0x%x; reg_a_l_train_max_for_dq4 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq4),phy_apb_rd_cmd(reg_a_l_train_max_for_dq4));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq5 =0x%x; reg_a_l_train_max_for_dq5 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq5),phy_apb_rd_cmd(reg_a_l_train_max_for_dq5));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq6 =0x%x; reg_a_l_train_max_for_dq6 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq6),phy_apb_rd_cmd(reg_a_l_train_max_for_dq6));
      printf("[INNO_INFO] reg_a_l_train_min_for_dq7 =0x%x; reg_a_l_train_max_for_dq7 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dq7),phy_apb_rd_cmd(reg_a_l_train_max_for_dq7));
      //printf("[INNO_INFO] reg_a_l_train_min_for_dm  =0x%x; reg_a_l_train_max_for_dm  =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_dm ),phy_apb_rd_cmd(reg_a_l_train_max_for_dm ));

    }
    #if 1
    if(1){
      printf("[INNO_INFO] reg_a_h_train_min_for_dq0 =0x%x; reg_a_h_train_max_for_dq0 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq0),phy_apb_rd_cmd(reg_a_h_train_max_for_dq0));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq1 =0x%x; reg_a_h_train_max_for_dq1 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq1),phy_apb_rd_cmd(reg_a_h_train_max_for_dq1));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq2 =0x%x; reg_a_h_train_max_for_dq2 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq2),phy_apb_rd_cmd(reg_a_h_train_max_for_dq2));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq3 =0x%x; reg_a_h_train_max_for_dq3 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq3),phy_apb_rd_cmd(reg_a_h_train_max_for_dq3));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq4 =0x%x; reg_a_h_train_max_for_dq4 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq4),phy_apb_rd_cmd(reg_a_h_train_max_for_dq4));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq5 =0x%x; reg_a_h_train_max_for_dq5 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq5),phy_apb_rd_cmd(reg_a_h_train_max_for_dq5));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq6 =0x%x; reg_a_h_train_max_for_dq6 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq6),phy_apb_rd_cmd(reg_a_h_train_max_for_dq6));
      printf("[INNO_INFO] reg_a_h_train_min_for_dq7 =0x%x; reg_a_h_train_max_for_dq7 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dq7),phy_apb_rd_cmd(reg_a_h_train_max_for_dq7));
      //printf("[INNO_INFO] reg_a_h_train_min_for_dm  =0x%x; reg_a_h_train_max_for_dm  =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_dm ),phy_apb_rd_cmd(reg_a_h_train_max_for_dm ));
    }
    if(1){
      printf("[INNO_INFO] reg_b_l_train_min_for_dq0 =0x%x; reg_b_l_train_max_for_dq0 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq0),phy_apb_rd_cmd(reg_b_l_train_max_for_dq0));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq1 =0x%x; reg_b_l_train_max_for_dq1 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq1),phy_apb_rd_cmd(reg_b_l_train_max_for_dq1));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq2 =0x%x; reg_b_l_train_max_for_dq2 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq2),phy_apb_rd_cmd(reg_b_l_train_max_for_dq2));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq3 =0x%x; reg_b_l_train_max_for_dq3 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq3),phy_apb_rd_cmd(reg_b_l_train_max_for_dq3));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq4 =0x%x; reg_b_l_train_max_for_dq4 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq4),phy_apb_rd_cmd(reg_b_l_train_max_for_dq4));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq5 =0x%x; reg_b_l_train_max_for_dq5 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq5),phy_apb_rd_cmd(reg_b_l_train_max_for_dq5));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq6 =0x%x; reg_b_l_train_max_for_dq6 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq6),phy_apb_rd_cmd(reg_b_l_train_max_for_dq6));
      printf("[INNO_INFO] reg_b_l_train_min_for_dq7 =0x%x; reg_b_l_train_max_for_dq7 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dq7),phy_apb_rd_cmd(reg_b_l_train_max_for_dq7));
      //printf("[INNO_INFO] reg_b_l_train_min_for_dm  =0x%x; reg_b_l_train_max_for_dm  =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_dm ),phy_apb_rd_cmd(reg_b_l_train_max_for_dm ));
    }
    if(1){
      printf("[INNO_INFO] reg_b_h_train_min_for_dq0 =0x%x; reg_b_h_train_max_for_dq0 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq0),phy_apb_rd_cmd(reg_b_h_train_max_for_dq0));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq1 =0x%x; reg_b_h_train_max_for_dq1 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq1),phy_apb_rd_cmd(reg_b_h_train_max_for_dq1));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq2 =0x%x; reg_b_h_train_max_for_dq2 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq2),phy_apb_rd_cmd(reg_b_h_train_max_for_dq2));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq3 =0x%x; reg_b_h_train_max_for_dq3 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq3),phy_apb_rd_cmd(reg_b_h_train_max_for_dq3));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq4 =0x%x; reg_b_h_train_max_for_dq4 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq4),phy_apb_rd_cmd(reg_b_h_train_max_for_dq4));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq5 =0x%x; reg_b_h_train_max_for_dq5 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq5),phy_apb_rd_cmd(reg_b_h_train_max_for_dq5));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq6 =0x%x; reg_b_h_train_max_for_dq6 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq6),phy_apb_rd_cmd(reg_b_h_train_max_for_dq6));
      printf("[INNO_INFO] reg_b_h_train_min_for_dq7 =0x%x; reg_b_h_train_max_for_dq7 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dq7),phy_apb_rd_cmd(reg_b_h_train_max_for_dq7));
      //printf("[INNO_INFO] reg_b_h_train_min_for_dm  =0x%x; reg_b_h_train_max_for_dm  =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_dm ),phy_apb_rd_cmd(reg_b_h_train_max_for_dm ));
    }
    #endif

}//endtask

void ddrn_phy_dqs_calib(struct train_result *tresult,int	cs_sel,int freq_sel ){

int	read_data,read_data1;
int rank_num;

    if(cs_sel == 0xe){  
        rank_num = 0;
    }else if(cs_sel == 0xd){
        rank_num = 1;
    }else if(cs_sel == 0xb){
        rank_num = 2;
    }else{
        rank_num = 3;
    }
    

        
    tresult->dqs_calib_cycsel[rank_num][freq_sel][0] =phy_apb_rd_cmd(reg_a_l_cycsel);
    tresult->dqs_calib_ophsel[rank_num][freq_sel][0] =phy_apb_rd_cmd(reg_a_l_ophsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][0] =phy_apb_rd_cmd(reg_a_l_dllsel);

    #if 0
    tresult->dqs_calib_cycsel[rank_num][freq_sel][1] =phy_apb_rd_cmd(reg_a_h_cycsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][1] =phy_apb_rd_cmd(reg_a_h_ophsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][1] =phy_apb_rd_cmd(reg_a_h_dllsel);
                                  
    tresult->dqs_calib_cycsel[rank_num][freq_sel][2] =phy_apb_rd_cmd(reg_b_l_cycsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][2] =phy_apb_rd_cmd(reg_b_l_ophsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][2] =phy_apb_rd_cmd(reg_b_l_dllsel);
                                  
    tresult->dqs_calib_cycsel[rank_num][freq_sel][3] =phy_apb_rd_cmd(reg_b_h_cycsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][3] =phy_apb_rd_cmd(reg_b_h_ophsel);
    tresult->dqs_calib_dllsel[rank_num][freq_sel][3] =phy_apb_rd_cmd(reg_b_h_dllsel);
    #endif
    printf("[INNO_INFO] Rember the calibration value\n");
    if(1){
        printf("[INNO_INFO] calib_cycsel[%d][%d][0]=%x\n", rank_num,freq_sel,tresult->dqs_calib_cycsel[rank_num][freq_sel][0]);
        printf("[INNO_INFO] calib_ophsel[%d][%d][0]=%x\n", rank_num,freq_sel,tresult->dqs_calib_ophsel[rank_num][freq_sel][0]);
        printf("[INNO_INFO] calib_dllsel[%d][%d][0]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][0]);
    }
    #if 0 
    if(def->DQ_LANE2){                                                 
        printf("[INNO_INFO] calib_cycsel[%d][%d][1]=%x\n", rank_num,freq_sel,tresult->dqs_calib_cycsel[rank_num][freq_sel][1]);
        printf("[INNO_INFO] calib_ophsel[%d][%d][1]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][1]);
        printf("[INNO_INFO] calib_dllsel[%d][%d][1]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][1]);
    }
    if(def->DQ_LANE3){                                                
        printf("[INNO_INFO] calib_cycsel[%d][%d][2]=%x\n", rank_num,freq_sel,tresult->dqs_calib_cycsel[rank_num][freq_sel][2]);
        printf("[INNO_INFO] calib_ophsel[%d][%d][2]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][2]);
        printf("[INNO_INFO] calib_dllsel[%d][%d][2]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][2]);
    }
    if(def->DQ_LANE4){                                                   
        printf("[INNO_INFO] calib_cycsel[%d][%d][3]=%x\n", rank_num,freq_sel,tresult->dqs_calib_cycsel[rank_num][freq_sel][3]);
        printf("[INNO_INFO] calib_ophsel[%d][%d][3]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][3]);
        printf("[INNO_INFO] calib_dllsel[%d][%d][3]=%x\n", rank_num,freq_sel,tresult->dqs_calib_dllsel[rank_num][freq_sel][3]);
    }
    #endif

}//endtask

void ddrn_phy_rd_training(struct train_result *tresult,int	cs_sel,int freq_sel ){


int	readreg_data;
int	readreg_data0;
int	readreg_data1;
int rank_num;

	        readreg_data0  = phy_apb_rd_cmd( reg_train_error_for_rd_byte);      //reg_read_train_done

	        if((readreg_data0) != 0 ) {
	            printf("[INNO_INFO]  DQ32 rd_l and rd_r AUTO TRAIN error  ...\n");
	            printf("[INNO_INFO]  reg_train_error_for_rd_byte = 0x%x",readreg_data0);
                
            } else {
	            printf("[INNO_INFO]  rd AUTO TRAIN pass  ...\n");
            }

    printf("[INNO_INFO] Get the read train result.\n");
        if(1){
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq0 =0x%x; reg_a_l_train_max_for_rd_dq0 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq0),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq0));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq1 =0x%x; reg_a_l_train_max_for_rd_dq1 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq1),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq1));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq2 =0x%x; reg_a_l_train_max_for_rd_dq2 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq2),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq2));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq3 =0x%x; reg_a_l_train_max_for_rd_dq3 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq3),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq3));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq4 =0x%x; reg_a_l_train_max_for_rd_dq4 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq4),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq4));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq5 =0x%x; reg_a_l_train_max_for_rd_dq5 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq5),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq5));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq6 =0x%x; reg_a_l_train_max_for_rd_dq6 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq6),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq6));
          printf("[INNO_INFO] reg_a_l_train_min_for_rd_dq7 =0x%x; reg_a_l_train_max_for_rd_dq7 =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dq7),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dq7));
          //printf("[INNO_INFO] reg_a_l_train_min_for_rd_dm  =0x%x; reg_a_l_train_max_for_rd_dm  =0x%x\n",phy_apb_rd_cmd(reg_a_l_train_min_for_rd_dm ),phy_apb_rd_cmd(reg_a_l_train_max_for_rd_dm ));

        }

        if(1){
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq0 =0x%x; reg_a_h_train_max_for_rd_dq0 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq0),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq0));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq1 =0x%x; reg_a_h_train_max_for_rd_dq1 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq1),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq1));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq2 =0x%x; reg_a_h_train_max_for_rd_dq2 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq2),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq2));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq3 =0x%x; reg_a_h_train_max_for_rd_dq3 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq3),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq3));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq4 =0x%x; reg_a_h_train_max_for_rd_dq4 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq4),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq4));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq5 =0x%x; reg_a_h_train_max_for_rd_dq5 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq5),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq5));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq6 =0x%x; reg_a_h_train_max_for_rd_dq6 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq6),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq6));
          printf("[INNO_INFO] reg_a_h_train_min_for_rd_dq7 =0x%x; reg_a_h_train_max_for_rd_dq7 =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dq7),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dq7));
          //printf("[INNO_INFO] reg_a_h_train_min_for_rd_dm  =0x%x; reg_a_h_train_max_for_rd_dm  =0x%x\n",phy_apb_rd_cmd(reg_a_h_train_min_for_rd_dm ),phy_apb_rd_cmd(reg_a_h_train_max_for_rd_dm ));
        }
        if(1){
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq0 =0x%x; reg_b_l_train_max_for_rd_dq0 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq0),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq0));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq1 =0x%x; reg_b_l_train_max_for_rd_dq1 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq1),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq1));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq2 =0x%x; reg_b_l_train_max_for_rd_dq2 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq2),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq2));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq3 =0x%x; reg_b_l_train_max_for_rd_dq3 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq3),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq3));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq4 =0x%x; reg_b_l_train_max_for_rd_dq4 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq4),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq4));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq5 =0x%x; reg_b_l_train_max_for_rd_dq5 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq5),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq5));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq6 =0x%x; reg_b_l_train_max_for_rd_dq6 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq6),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq6));
          printf("[INNO_INFO] reg_b_l_train_min_for_rd_dq7 =0x%x; reg_b_l_train_max_for_rd_dq7 =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dq7),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dq7));
          //printf("[INNO_INFO] reg_b_l_train_min_for_rd_dm  =0x%x; reg_b_l_train_max_for_rd_dm  =0x%x\n",phy_apb_rd_cmd(reg_b_l_train_min_for_rd_dm ),phy_apb_rd_cmd(reg_b_l_train_max_for_rd_dm ));
        }
        if(1){
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq0 =0x%x; reg_b_h_train_max_for_rd_dq0 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq0),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq0));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq1 =0x%x; reg_b_h_train_max_for_rd_dq1 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq1),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq1));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq2 =0x%x; reg_b_h_train_max_for_rd_dq2 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq2),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq2));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq3 =0x%x; reg_b_h_train_max_for_rd_dq3 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq3),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq3));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq4 =0x%x; reg_b_h_train_max_for_rd_dq4 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq4),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq4));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq5 =0x%x; reg_b_h_train_max_for_rd_dq5 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq5),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq5));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq6 =0x%x; reg_b_h_train_max_for_rd_dq6 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq6),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq6));
          printf("[INNO_INFO] reg_b_h_train_min_for_rd_dq7 =0x%x; reg_b_h_train_max_for_rd_dq7 =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dq7),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dq7));
          //printf("[INNO_INFO] reg_b_h_train_min_for_rd_dm  =0x%x; reg_b_h_train_max_for_rd_dm  =0x%x\n",phy_apb_rd_cmd(reg_b_h_train_min_for_rd_dm ),phy_apb_rd_cmd(reg_b_h_train_max_for_rd_dm ));
        }

//add by tancc
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x10);
printf("byte0_dq0 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x11);
printf("byte0_dq1 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x12);
printf("byte0_dq2 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x13);
printf("byte0_dq3 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x14);
printf("byte0_dq4 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x15);
printf("byte0_dq5 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x16);
printf("byte0_dq6 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x17);
printf("byte0_dq7 = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_l_cs0_loop_invdelaysel,0x18);
printf("byte0_dm = 0x%x\n",phy_apb_rd_cmd(reg_a_l_cs0_value_dqx_invdelaysel) );


phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x10);
printf("byte1_dq0 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x11);
printf("byte1_dq1 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x12);
printf("byte1_dq2 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x13);
printf("byte1_dq3 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x14);
printf("byte1_dq4 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x15);
printf("byte1_dq5 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x16);
printf("byte1_dq6 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x17);
printf("byte1_dq7 = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
phy_apb_wr_cmd( reg_a_h_cs0_loop_invdelaysel,0x18);
printf("byte1_dm = 0x%x\n",phy_apb_rd_cmd(reg_a_h_cs0_value_dqx_invdelaysel) );
}//endtask

void ddrn_phy_write_leveling(struct train_result *tresult,int	cs_sel,int freq_sel ){

int	read_data;
int rank_num;


//    phy_apb_wr_cmd( reg_wl_loadmode, (0x41<<8) +( 0 <<3)+1 );

    if(cs_sel == 0xe){  
        rank_num = 0;
    }else if(cs_sel == 0xd){
        rank_num = 1;
    }else if (cs_sel == 0xb){
        rank_num = 2;
    }else{
        rank_num = 3;
    }



    if(cs_sel =0xe){
     printf("[INNO_INFO] reg_a_l_tdqs_invdelaysel0 =0x%x\n", phy_apb_rd_cmd( reg_a_l_tdqs_invdelaysel0));
     printf("[INNO_INFO] reg_a_h_tdqs_invdelaysel0 =0x%x\n", phy_apb_rd_cmd( reg_a_h_tdqs_invdelaysel0));
     printf("[INNO_INFO] reg_b_l_tdqs_invdelaysel0 =0x%x\n", phy_apb_rd_cmd( reg_b_l_tdqs_invdelaysel0));
     printf("[INNO_INFO] reg_b_h_tdqs_invdelaysel0 =0x%x\n", phy_apb_rd_cmd( reg_b_h_tdqs_invdelaysel0));
  
    }else if(cs_sel =0xd){
     printf("[INNO_INFO] reg_a_l_tdqs_invdelaysel1 =0x%x\n", phy_apb_rd_cmd( reg_a_l_tdqs_invdelaysel1));
     printf("[INNO_INFO] reg_a_h_tdqs_invdelaysel1 =0x%x\n", phy_apb_rd_cmd( reg_a_h_tdqs_invdelaysel1));
     printf("[INNO_INFO] reg_b_l_tdqs_invdelaysel1 =0x%x\n", phy_apb_rd_cmd( reg_b_l_tdqs_invdelaysel1));
     printf("[INNO_INFO] reg_b_h_tdqs_invdelaysel1 =0x%x\n", phy_apb_rd_cmd( reg_b_h_tdqs_invdelaysel1));
    }else if(cs_sel =0xb){
    //printf("[INNO_INFO] reg_a_l_tdqs_invdelaysel2 =0x%x\n", phy_apb_rd_cmd( reg_a_l_tdqs_invdelaysel2));
    //printf("[INNO_INFO] reg_a_h_tdqs_invdelaysel2 =0x%x\n", phy_apb_rd_cmd( reg_a_h_tdqs_invdelaysel2));
    //printf("[INNO_INFO] reg_b_l_tdqs_invdelaysel2 =0x%x\n", phy_apb_rd_cmd( reg_b_l_tdqs_invdelaysel2));
    //printf("[INNO_INFO] reg_b_h_tdqs_invdelaysel2 =0x%x\n", phy_apb_rd_cmd( reg_b_h_tdqs_invdelaysel2));
    }else if(cs_sel =0x7){
    //printf("[INNO_INFO] reg_a_l_tdqs_invdelaysel3 =0x%x\n", phy_apb_rd_cmd( reg_a_l_tdqs_invdelaysel3));
    //printf("[INNO_INFO] reg_a_h_tdqs_invdelaysel3 =0x%x\n", phy_apb_rd_cmd( reg_a_h_tdqs_invdelaysel3));
    //printf("[INNO_INFO] reg_b_l_tdqs_invdelaysel3 =0x%x\n", phy_apb_rd_cmd( reg_b_l_tdqs_invdelaysel3));
    //printf("[INNO_INFO] reg_b_h_tdqs_invdelaysel3 =0x%x\n", phy_apb_rd_cmd( reg_b_h_tdqs_invdelaysel3));
    }

}//endtask
void bist_op(uint32_t bist_mode, uint32_t bist_start_addr, uint32_t bist_end_addr)
{

	uint32_t err_cnt;
	uint32_t readreg_data;
	uint32_t readreg_data0;
	uint32_t readreg_data1;
	uint32_t bist_error_addr, act_bist_data, exp_bist_data;
	if (bist_mode == 3)
	{
		printf("\r\nBIST_MODE IS [ WR_RD ]\r\n");
	}
	else if (bist_mode == 0)
	{
		printf("\r\nBIST_MODE IS [ WR_ONLY ]\r\n");
	}
	else if (bist_mode == 1)
	{
		printf("\r\nBIST_MODE IS [ RD_ONLY ]\r\n");
	}

	apb_ctrl_wr_cmd(reg_mem_bist_channel_en, 0xf);
	apb_ctrl_wr_cmd(reg_bist_en, 1);
	printf("\r\nBIST EN\r\n");
	printf("\r\n[ bist_start_addr = 0x%x]  [ bist_end_addr = 0x%x ]\r\n", bist_start_addr, bist_end_addr);
	apb_ctrl_wr_cmd(reg_bist_soft_rstn, 0);
	apb_ctrl_wr_cmd(reg_bist_soft_rstn, 1);
	apb_ctrl_wr_cmd(reg_bist_serial_wr_stop, 0);
	printf("\r\nBIST SOFT RESET\r\n");
	apb_ctrl_wr_cmd(reg_bist_addr_pattern_sel, 0);
	apb_ctrl_wr_cmd(reg_bist_data, 0x5a5a5a5a);
	apb_ctrl_wr_cmd(reg_bist_start_addr, bist_start_addr);
	apb_ctrl_wr_cmd(reg_bist_end_addr, bist_end_addr);
	apb_ctrl_wr_cmd(reg_bist_data_pattern_sel, 2);
	// 2'b00: solid data(0x55aa);
	// 2'b01: datas from register that will configure in step 7.
	// 2'b10: random data that generate by itself;
	// Default : bist data = 128'h0;
	// Choose one of the patterns then configure the register

	apb_ctrl_wr_cmd(reg_bist_mode_sel, bist_mode);
	// 3'b000: write;
	// 3'b001: read;
	// 3'b010: read modify_write;
	// 3'b011: write read;
	// 3'b100: write read modify_write read ;
	// 3'b101: write read write read .;
	// Choose one of the modes then configure the register.
	apb_ctrl_wr_cmd(reg_bist_start, 1);
	readreg_data = 0;
	while (readreg_data != 1)
	{ // Wait the bist done.
		readreg_data = apb_ctrl_rd_cmd1(reg_bist_done);
		//printf("Wait the bist done\n\r");
	}
	readreg_data = 0;
	readreg_data0 = 0;
	readreg_data1 = 0;

	readreg_data0 = apb_ctrl_rd_cmd1(reg_bist_done);
	readreg_data1 = apb_ctrl_rd_cmd1(reg_bist_pass);
	if (readreg_data1 && readreg_data0)
	{
		printf(" $$$$$$$$$$$$$$$$$$$$$$$$$$$BIST-W-RMW-R RMW Operation is PASS $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\r");
	}
	else
	{
		printf(" $$$$$$$$$$$$$$$$$$$$$$$$$$$BIST-W-RMW-R RMW Operation is ERROR $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\r");
		err_cnt = err_cnt + 1;
	}
	printf("\t Complete the RMW Operation.\n\r");

	printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$---[INNO_INFO] Get the bist result---$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.\n\r");

	bist_error_addr = apb_ctrl_rd_cmd1(reg_bist_error_addr_obs_31_0);
	printf("BIST ERROR ADDR = 0x%08x\t\n\n", bist_error_addr);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_0_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_0_31_0);
	printf("act_bist_data0 = 0x%08x;\t exp_bist_data0 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_1_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_1_31_0);
	printf("act_bist_data1 = 0x%08x;\t exp_bist_data1 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_2_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_2_31_0);
	printf("act_bist_data2 = 0x%08x;\t exp_bist_data2 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_3_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_3_31_0);
	printf("act_bist_data3 = 0x%08x;\t exp_bist_data3 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

#if 0
	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_4_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_4_31_0);
	printf("act_bist_data4 = 0x%08x;\t exp_bist_data4 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_5_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_5_31_0);
	printf("act_bist_data5 = 0x%08x;\t exp_bist_data5 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_6_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_6_31_0);
	printf("act_bist_data6 = 0x%08x;\t exp_bist_data6 = 0x%08x;\t\n", act_bist_data, exp_bist_data);

	act_bist_data = apb_ctrl_rd_cmd1(reg_bist_act_data_obs_sel_7_31_0);
	exp_bist_data = apb_ctrl_rd_cmd1(reg_bist_exp_data_obs_sel_7_31_0);
	printf("act_bist_data7 = 0x%08x;\t exp_bist_data7 = 0x%08x;\t\n", act_bist_data, exp_bist_data);
#endif
	readreg_data = 0;
	apb_ctrl_wr_cmd(reg_bist_start, 0);
	apb_ctrl_wr_cmd(reg_bist_en, 0);
}

void tr_test(uint32_t ctrl_base,uint32_t phy_base)
{
  struct train_result *tresult;
  struct train_result train_result1;
  tresult = &train_result1;

  ddr_ctrl_base = ctrl_base;
  ddr_phy_base = phy_base;
  //while(1){
    //bist_op(3,0,0x3ffff0);//WR_RD
  bist_op(4,0,0x3ffff0);//WR_RD
  //bist_op(3,0,0x1ffffff0);//WR_RD
  //}
  #if 0
  ddrn_phy_write_leveling(tresult,0xe,0);
  ddrn_phy_dqs_calib(tresult,0xe,0);
  ddrn_phy_rd_training(tresult,0xe,0);
  ddrn_phy_wr_training(tresult,0xe,0);
  #endif
}




void phy_analog_config(uint32_t phy_base)
{
    struct predefine *def;    
    struct predefine predefine1; 
    def = &predefine1;

    ddr_phy_base = phy_base;

    ////////phy drver/odt/vref configeration/////////
    def->cmd_drv_nr     = 0x0e;
    def->cmd_drv_pr     = 0x0e;
    def->dq_dqs_drv_nr  = 0x0e;
    def->dq_dqs_drv_pr  = 0x0e;
    def->ck_drv_nr      = 0x0e;
    def->ck_drv_pr      = 0x0e;
    def->dq_odt_pu      = 0x30;
    def->dq_odt_pd      = 0x30;
    def->dq_vref        = 0x80;

    // cmd drv
    phy_apb_wr_cmd(0x0f4, 28, 24, def->cmd_drv_nr); // reg_cmd_abutnrcomp4_reg - reg_cmd_abutnrcomp0_reg
    phy_apb_wr_cmd(0x0f4, 20, 16, def->cmd_drv_pr); // reg_cmd_abutprcomp4_reg - reg_cmd_abutprcomp0_reg

    // ck drv
    phy_apb_wr_cmd(0x0f4, 12, 8, def->ck_drv_nr); // reg_cmd_abutnrcomp4_ck0_reg - reg_cmd_abutnrcomp0_ck0_reg
    phy_apb_wr_cmd(0x0f4, 4, 0, def->ck_drv_pr); // reg_cmd_abutprcomp4_ck0_reg - reg_cmd_abutprcomp0_ck0_reg
    phy_apb_wr_cmd(0x0f8, 12, 8, def->ck_drv_nr); // reg_cmd_abutnrcomp4_special_reg - reg_cmd_abutnrcomp0_special_reg
    phy_apb_wr_cmd(0x0f8, 4, 0, def->ck_drv_pr); // reg_cmd_abutprcomp4_special_reg - reg_cmd_abutprcomp0_special_reg

    // tx drv
    phy_apb_wr_cmd(0x304, 0x1c, 0x18, def->dq_dqs_drv_nr); // reg_a_l_abutnrcompdq4_reg - reg_a_l_abutnrcompdq0_reg
    phy_apb_wr_cmd(0x304, 0x14, 0x10, def->dq_dqs_drv_pr); // reg_a_l_abutprcompdq4_reg - reg_a_l_abutprcompdq0_reg

    phy_apb_wr_cmd(0x484, 0x1c, 0x18, def->dq_dqs_drv_nr); // reg_a_h_abutnrcompdq4_reg - reg_a_h_abutnrcompdq0_reg
    phy_apb_wr_cmd(0x484, 0x14, 0x10, def->dq_dqs_drv_pr); // reg_a_h_abutprcompdq4_reg - reg_a_h_abutprcompdq0_reg
    phy_apb_wr_cmd(0x604, 0x1c, 0x18, def->dq_dqs_drv_nr); // reg_b_l_abutnrcompdq4_reg - reg_b_l_abutnrcompdq0_reg
    phy_apb_wr_cmd(0x604, 0x14, 0x10, def->dq_dqs_drv_pr); // reg_b_l_abutprcompdq4_reg - reg_b_l_abutprcompdq0_reg
    phy_apb_wr_cmd(0x784, 0x1c, 0x18, def->dq_dqs_drv_nr); // reg_b_h_abutnrcompdq4_reg - reg_b_h_abutnrcompdq0_reg
    phy_apb_wr_cmd(0x784, 0x14, 0x10, def->dq_dqs_drv_pr); // reg_b_h_abutprcompdq4_reg - reg_b_h_abutprcompdq0_reg
#if 1
    // rx odt
    phy_apb_wr_cmd(0x304, 0xc, 0x8, def->dq_odt_pd); // reg_a_l_abutodtpddq4_reg - reg_a_l_abutodtpddq0_reg
    phy_apb_wr_cmd(0x304, 0x4, 0x0, def->dq_odt_pu); // reg_a_l_abutodtpudq4_reg - reg_a_l_abutodtpudq0_reg

    phy_apb_wr_cmd(0x484, 0xc, 0x8, def->dq_odt_pd); // reg_a_h_abutodtpddq4_reg - reg_a_h_abutodtpddq0_reg
    phy_apb_wr_cmd(0x484, 0x4, 0x0, def->dq_odt_pu); // reg_a_h_abutodtpudq4_reg - reg_a_h_abutodtpudq0_reg
    phy_apb_wr_cmd(0x604, 0xc, 0x8, def->dq_odt_pd); // reg_b_l_abutodtpddq4_reg - reg_b_l_abutodtpddq0_reg
    phy_apb_wr_cmd(0x604, 0x4, 0x0, def->dq_odt_pu); // reg_b_l_abutodtpudq4_reg - reg_b_l_abutodtpudq0_reg
    phy_apb_wr_cmd(0x784, 0xc, 0x8, def->dq_odt_pd); // reg_b_h_abutodtpddq4_reg - reg_b_h_abutodtpddq0_reg
    phy_apb_wr_cmd(0x784, 0x4, 0x0, def->dq_odt_pu); // reg_b_h_abutodtpudq4_reg - reg_b_h_abutodtpudq0_reg
#endif

    // rx vref
    phy_apb_wr_cmd(reg_a_h_vref1_margsel_reg, def->dq_vref); // reg_a_h_vref1_margsel_reg
    phy_apb_wr_cmd(reg_a_l_vref1_margsel_reg, def->dq_vref); // reg_a_l_vref1_margsel_reg
    phy_apb_wr_cmd(reg_b_h_vref1_margsel_reg, def->dq_vref); // reg_b_h_vref1_margsel_reg
    phy_apb_wr_cmd(reg_b_l_vref1_margsel_reg, def->dq_vref); // reg_b_l_vref1_margsel_reg

    phy_apb_wr_cmd(reg_train_reg_update_en, 1); 
    phy_apb_wr_cmd(reg_rx_vref_value_update, 1); 
    phy_apb_wr_cmd(reg_rx_vref_value_update, 0); 
    phy_apb_wr_cmd(reg_train_reg_update_en, 0); 

    /////////for deskew pll pfd /////////////
    phy_apb_wr_cmd(reg_pllfbdiv_dqcmd, 2);
    phy_apb_wr_cmd(reg_pllprediv_dqcmd, 2);

    /*
    4xclk(MHz)	reg_pllprediv<5:0>	reg_pllfbdiv<5:0>	reg_pllpostdiven	reg_pllpostdiv<2:0>
    2133-4266	1					1					0					000
    1066-2132	1					1					1					001
    533-1065	1					1					1					010
    266-532 	1					1					1					011
    133-265 	1					1					1					110
    66-132		1					1					1					111
    */
    #if 0

    if (def->SPEED_4266 == 1)
    {
        phy_apb_wr_cmd(reg_pllpostdiv_fsp0, 0);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp0, 0);
        phy_apb_wr_cmd(reg_pllpostdiv_fsp1, 0);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp1, 0);
    }
    else if (def->SPEED_3200 == 1)
    {
        phy_apb_wr_cmd(reg_pllpostdiv_fsp0, 0);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp0, 0);
        phy_apb_wr_cmd(reg_pllpostdiv_fsp1, 0);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp1, 0);
    }
    else if (def->SPEED_2133 == 1)
    {
        phy_apb_wr_cmd(reg_pllpostdiv_fsp0, 0);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp0, 0);
        phy_apb_wr_cmd(reg_pllpostdiv_fsp1, 0);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp1, 0);
    }
    else if (def->SPEED_1600 == 1)
    {
        phy_apb_wr_cmd(reg_pllpostdiv_fsp0, 1);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp0, 1);
        phy_apb_wr_cmd(reg_pllpostdiv_fsp1, 1);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp1, 1);
    }
    else if (def->SPEED_800 == 1)
    {
        phy_apb_wr_cmd(reg_pllpostdiv_fsp0, 2);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp0, 1);
        phy_apb_wr_cmd(reg_pllpostdiv_fsp1, 2);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp1, 1);
    }
    else
    {
        phy_apb_wr_cmd(reg_pllpostdiv_fsp0, 3);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp0, 1);
        phy_apb_wr_cmd(reg_pllpostdiv_fsp1, 3);
        phy_apb_wr_cmd(reg_pllpostdiven_fsp1, 1);
    }
#endif
    ////////for lpddr4 ca training//////////
    phy_apb_wr_cmd(reg_wait_cnt, 0x3000);
    phy_apb_wr_cmd(reg_pll_lock_bypass, 1);

    //phy_apb_wr_cmd(reg_pllpostdiv_ls, 1);
    //phy_apb_wr_cmd(reg_pllpostdiven_ls, 1);
    phy_apb_wr_cmd(reg_clk_div_cnt, 8);

    ////////for read odt//////////////
    phy_apb_wr_cmd(reg_rxodt_start_point, 3);
    phy_apb_wr_cmd(reg_rxodt_length, 2);

    ////////for write leveling//////////////
    phy_apb_wr_cmd(reg_wl_dqs_start_point, 0x46);





    ////////for ddr4/lpddr4 dq map ,rd train pattern need to set/////////
//////dq0 dq1 dq2 dq3 dq4 dq5 dq6 dq7 dq8 dq9 dq10 dq11 dq12 dq13 dq14 dq15 
//wrap  0  1   2   3   0   1   2   3    0   1  2    3     0    1   2     3
    // phy_apb_wr_cmd(reg_a_l_rdtrain_check_wrap0,0x7d);// 0b0111 1101) ;//dq5 dq7 dq3 dq1
    // phy_apb_wr_cmd(reg_a_l_rdtrain_check_wrap1,0x22);// 0b0010 0010) ;// 2 0 6 4 
    // phy_apb_wr_cmd(reg_a_h_rdtrain_check_wrap0,0xd7);// 0b1101 0111) ;// 7 1 5 3
    // phy_apb_wr_cmd(reg_a_h_rdtrain_check_wrap1,0x22);// 0b0010 0010) ;// 6 0 2 4
    // phy_apb_wr_cmd(reg_b_l_rdtrain_check_wrap0,0x7d);// 0b01111101) ;//5 7 3 1
    // phy_apb_wr_cmd(reg_b_l_rdtrain_check_wrap1,0x22);// 0b00100010) ;//2 0 6 4
    // phy_apb_wr_cmd(reg_b_h_rdtrain_check_wrap0,0xd7);// 0b11010111) ;//7 1 5 3
    // phy_apb_wr_cmd(reg_b_h_rdtrain_check_wrap1,0x22);// 0b00100010) ;//6 0 2 4
    
    // phy_apb_wr_cmd(reg_rd_train_check_value_en,0x01) ;

    // ////////////tx interface timing///////////////
     phy_apb_wr_cmd(reg_fb1xclk_invdelaysel_dqcmd, 0x0);
}

#if 0
void zqcalib_train(struct predefine *def,struct train_result *tresult){
int read_data;
        if(def->LPDDR4X){
            phy_apb_wr_cmd(reg_lpddr4x_zqcal, 0x1);
            if(def->ZQCALIB_TYPE_SEL){
                phy_apb_wr_cmd(reg_zqcali_type_sel, 0x1);
            }
        }else if(def->LPDDR4){
            if(def->ZQCALIB_TYPE_SEL){
                phy_apb_wr_cmd(reg_zqcali_type_sel, 0x1);
            }
        }else{
            phy_apb_wr_cmd(reg_lpddr4x_zqcal, 0x0);
        }
        phy_apb_wr_cmd(reg_zqcali_bypass, 0x0);
        phy_apb_wr_cmd(reg_pd_zqcali,0x0);
        phy_apb_wr_cmd(reg_drvlegpu_zqcali,0x0);
        phy_apb_wr_cmd(reg_drvlegpd_zqcali,0x0);
        phy_apb_wr_cmd(reg_odtlegpu_zqcali,0x0);
        phy_apb_wr_cmd(reg_odtlegpd_zqcali,0x0);
        phy_apb_wr_cmd(reg_zqcali_en,0x0);
        phy_apb_wr_cmd(reg_hclk_zqcalib_sel,0x1);
        phy_apb_wr_cmd(reg_zqcali_clear,0x1);
        phy_apb_wr_cmd(reg_zqcali_clear,0x0);
        phy_apb_wr_cmd(reg_hclk_zqcalib_sel,0x0);
        phy_apb_wr_cmd(reg_zq_chg_interval,0x1ff);
        phy_apb_wr_cmd(reg_pu_interval,0x3f);
        if(def->LPDDR4X){
        phy_apb_wr_cmd(reg_drvpu_zqcali_vref_sel,0xb7);
        phy_apb_wr_cmd(reg_drvpd_zqcali_vref_sel,0x80);
        phy_apb_wr_cmd(reg_odtpu_zqcali_vref_sel,0xa0);
        phy_apb_wr_cmd(reg_odtpd_zqcali_vref_sel,0x80);

        }else if(def->DDR3){
        phy_apb_wr_cmd(reg_drvpu_zqcali_vref_sel,0xb7);
        phy_apb_wr_cmd(reg_drvpd_zqcali_vref_sel,0x80);
        phy_apb_wr_cmd(reg_odtpu_zqcali_vref_sel,0xa0);
        phy_apb_wr_cmd(reg_odtpd_zqcali_vref_sel,0x80);

        }else if(def->DDR4){
        phy_apb_wr_cmd(reg_drvpu_zqcali_vref_sel,0xc0); // DDR4 Drv-pu cali: 34ohm--=1 +199(0xc7), 40ohm-->192(0xc0),48ohm-->183(0xb7)
        phy_apb_wr_cmd(reg_drvpd_zqcali_vref_sel,0x80); // DDR4 Drv-pd cali:fix to 128
        phy_apb_wr_cmd(reg_odtpu_zqcali_vref_sel,0x8c); // DDR4 odt-pu cali: 120ohm--=1 +128(0x80), 100ohm-->140(0x8c),80ohm-->154(0x9a),60ohm-->171(0xab)
        phy_apb_wr_cmd(reg_odtpd_zqcali_vref_sel,0x80); // DDR4 odt-pd cali:fix to 128

        }else if(def->LPDDR3){
        phy_apb_wr_cmd(reg_drvpu_zqcali_vref_sel,0xb7);
        phy_apb_wr_cmd(reg_drvpd_zqcali_vref_sel,0x80);
        phy_apb_wr_cmd(reg_odtpu_zqcali_vref_sel,0xa0);
        phy_apb_wr_cmd(reg_odtpd_zqcali_vref_sel,0x80);

        }else if(def->LPDDR4){
        phy_apb_wr_cmd(reg_drvpu_zqcali_vref_sel,0x80); // LPDDR4 Drv-pu cali:fix to 128
        phy_apb_wr_cmd(reg_drvpd_zqcali_vref_sel,0x40);  // LPDDR4 Drv-pd cali:34ohm--=1 +57(0x39), 40ohm-->64(0x40), 48ohm-->73(0x49)
        phy_apb_wr_cmd(reg_odtpu_zqcali_vref_sel,0x80); // LPDDR4 odt-pu cali:fix to 128
        phy_apb_wr_cmd(reg_odtpd_zqcali_vref_sel,0x74); // LPDDR4 odt-pd cali:120ohm--=1 +128(0x80), 100ohm-->116(0x74),80ohm-->102(0x66),60ohm-->85(0x55)

        }else{
        phy_apb_wr_cmd(reg_drvpu_zqcali_vref_sel,0xb7);
        phy_apb_wr_cmd(reg_drvpd_zqcali_vref_sel,0x80);
        phy_apb_wr_cmd(reg_odtpu_zqcali_vref_sel,0xa0);
        phy_apb_wr_cmd(reg_odtpd_zqcali_vref_sel,0x80);

        }

        //#15;
        phy_apb_wr_cmd(reg_zqcali_en,0x1);

        //phy_apb_wr_cmd(reg_zqcali_en, 0x1);




        read_data = 0;
        while(read_data != 0x1) {
                  read_data = phy_apb_rd_cmd(reg_zqcali_done);
            printf("[INNO_INFO] Wait ZQCALI end\n");
            //usleep( 10 );
        }
            printf("[INNO_INFO] ZQCALI DONE\n");
        read_data = 0;
        if(def->ZQCALIB_CLEAR){
            //zqcalib_clear;
            //inject_error = 0;
        }
        phy_apb_wr_cmd(reg_zqcali_en, 0x0);
        if(def->DQ_LANE1){
                phy_apb_wr_cmd(reg_a_l_dq_drv_zqcali_en, 0x1);
                phy_apb_wr_cmd(reg_a_l_dq_odt_zqcali_en, 0x1);
        }
        if(def->DQ_LANE2){
                phy_apb_wr_cmd(reg_a_h_dq_drv_zqcali_en, 0x1);
                phy_apb_wr_cmd(reg_a_h_dq_odt_zqcali_en, 0x1);
        }
        if(def->DQ_LANE3){
                phy_apb_wr_cmd(reg_b_l_dq_drv_zqcali_en, 0x1);
                phy_apb_wr_cmd(reg_b_h_dq_odt_zqcali_en, 0x1);
        }
        if(def->DQ_LANE4){
                phy_apb_wr_cmd(reg_b_h_dq_drv_zqcali_en, 0x1);
                phy_apb_wr_cmd(reg_b_h_dq_odt_zqcali_en, 0x1);
        }

        phy_apb_wr_cmd(reg_cmd_drv_zqcalib_en  , 0x1);

}//endtask

void command_auto_bus_train(struct predefine *def,struct train_result *tresult){

int	cat_read_data;
int	read_data_1;
int	read_data_2;
int     i = 0;
int rank_num=1;

if(def->RANK2){
    rank_num=2;
}else if(def->RANK4){
    rank_num=4;
}
	//-=1 + cat_event;
    //wdqs_ctrl_mode  = 0;

    #ifdef MIX_SIM
        phy_apb_wr_cmd( reg_cat_cs_left_scan_steps, 0xf );
        phy_apb_wr_cmd( reg_cat_cs_right_scan_steps, 0xf );
    #else
        phy_apb_wr_cmd( reg_cat_cs_left_scan_steps, 0x30 );//zhangzj cstrain范围太小了 0x30->0xff
        phy_apb_wr_cmd( reg_cat_cs_right_scan_steps, 0x30 );
    #endif
    #ifdef VIP
        phy_apb_wr_cmd( reg_cs_pwc_disable, 0x1 ); //disable the cs width %75
      //phy_apb_wr_cmd( reg_cat_skip_cs_train,      0x1 );
    #endif

        phy_apb_wr_cmd( reg_cs_pwc_disable, 0x1 ); //disable the cs width %75
        phy_apb_wr_cmd( reg_cat_skip_cs_train,      0x0 );

        phy_apb_wr_cmd( reg_cat_vref_scan_max, 0x32 );

    #ifdef ONLY_CHOOSE_RANK0
        phy_apb_wr_cmd( reg_cat_rank_num,      0x2 );
        phy_apb_wr_cmd( reg_cat_bp_rank_sel,   0x2 );
        phy_apb_wr_cmd( reg_lpddr4_ca_odt,     0x1 );
    #elif defined ONLY_CHOOSE_RANK1
        phy_apb_wr_cmd( reg_cat_rank_num,      0x1 );
        phy_apb_wr_cmd( reg_cat_bp_rank_sel,   0x1 );
        phy_apb_wr_cmd( reg_lpddr4_ca_odt,     0x2 );
    #else
    	if(def->RANK4){
        	phy_apb_wr_cmd( reg_cat_rank_num,      0x0 );
        	phy_apb_wr_cmd( reg_cat_bp_rank_sel,   0x0 );
        	phy_apb_wr_cmd( reg_lpddr4_ca_odt,     0xf );
        }else if(def->RANK2){
        	phy_apb_wr_cmd( reg_cat_rank_num,      0xc );
        	phy_apb_wr_cmd( reg_cat_bp_rank_sel,   0xc );
        	phy_apb_wr_cmd( reg_lpddr4_ca_odt,     0xf );
        }else{
    		phy_apb_wr_cmd( reg_cat_rank_num,      0x2 );
        	phy_apb_wr_cmd( reg_cat_bp_rank_sel,   0x2 );
        	phy_apb_wr_cmd( reg_lpddr4_ca_odt,     0x1 );
        }
    #endif


   //phy_apb_wr_cmd( `reg_mr1,{1'b0,tr.lpddr4_wr[2:0],1'b0,1'b1,tr.lpddr4_bl[1:0]} );
   //phy_apb_wr_cmd( `reg_mr2,{1'b0,1'b0,tr.lpddr4_wl[2:0],tr.lpddr4_rl_rtp[2:0]} );

    printf("[INNO_INFO] Enter Command Bus Training[FSP1].\n");
   
    //phy_apb_wr_cmd( 0x25, 0x6, 0x6, 0x1 );
    //phy_apb_wr_cmd( 0x20, 0x7, 0x7, 0x1 );
    //phy_apb_wr_cmd( reg_cat_skip_cs_train , 0x1 );
    phy_apb_wr_cmd( reg_cat_vref_scan_disable, 0x1 );


    phy_apb_wr_cmd( reg_cat_enable, 0x1 );
  //all_cmd_perbit_skew_update( 0x1f );
    phy_apb_wr_cmd( reg_cat_start, 0x1 );
    cat_read_data = 0;
    while( cat_read_data != 0x1 )    {
              cat_read_data  = phy_apb_rd_cmd( cha_cat_done);
        //usleep( 10 );
    }
    cat_read_data = 0;
    while( cat_read_data != 0x1 )    {
              cat_read_data  = phy_apb_rd_cmd( chb_cat_done);
        //usleep( 10 );
    }
    phy_apb_wr_cmd( reg_cat_start, 0x0 );
    #ifdef COMMAND_TRAIN_DEBUG
    #else
    phy_apb_wr_cmd( reg_phy_sdram_initial, 0x0);
    #endif
    phy_apb_wr_cmd( reg_cat_enable, 0x0 );
    printf("[INNO_INFO] Exit Command Bus Training.\n");
          read_data_1  = phy_apb_rd_cmd( cha_rank0_min_cs_perbit_skew_pass   );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_max_cs_perbit_skew_pass   );
    tresult->cha_perbit_skew_train_result_max[0][0] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][0] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_ca0_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_ca0_max_perbit_skew_pass  );
    tresult->cha_perbit_skew_train_result_max[0][1] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][1] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_ca1_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_ca1_max_perbit_skew_pass  );
    tresult->cha_perbit_skew_train_result_max[0][2] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][2] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_ca2_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_ca2_max_perbit_skew_pass  );
    tresult->cha_perbit_skew_train_result_max[0][3] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][3] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_ca3_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_ca3_max_perbit_skew_pass  );
    tresult->cha_perbit_skew_train_result_max[0][4] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][4] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_ca4_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_ca4_max_perbit_skew_pass  );
    tresult->cha_perbit_skew_train_result_max[0][5] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][5] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_ca5_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_ca5_max_perbit_skew_pass  );
    tresult->cha_perbit_skew_train_result_max[0][6] = read_data_2;
    tresult->cha_perbit_skew_train_result_min[0][6] = read_data_1;
    printf("[INNO_INFO] RANK0 CHA_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( cha_rank0_min_cs_vref_pass          );
          read_data_2  = phy_apb_rd_cmd( cha_rank0_max_cs_vref_pass          );
    printf("[INNO_INFO] RANK0 CHA_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);

          read_data_1  = phy_apb_rd_cmd( chb_rank0_min_cs_perbit_skew_pass   );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_max_cs_perbit_skew_pass   );
    tresult->chb_perbit_skew_train_result_max[0][0] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][0] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_ca0_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_ca0_max_perbit_skew_pass  );
    tresult->chb_perbit_skew_train_result_max[0][1] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][1] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_ca1_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_ca1_max_perbit_skew_pass  );
    tresult->chb_perbit_skew_train_result_max[0][2] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][2] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_ca2_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_ca2_max_perbit_skew_pass  );
    tresult->chb_perbit_skew_train_result_max[0][3] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][3] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_ca3_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_ca3_max_perbit_skew_pass  );
    tresult->chb_perbit_skew_train_result_max[0][4] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][4] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_ca4_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_ca4_max_perbit_skew_pass  );
    tresult->chb_perbit_skew_train_result_max[0][5] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][5] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_ca5_min_perbit_skew_pass  );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_ca5_max_perbit_skew_pass  );
    tresult->chb_perbit_skew_train_result_max[0][6] = read_data_2;
    tresult->chb_perbit_skew_train_result_min[0][6] = read_data_1;
    printf("[INNO_INFO] RANK0 CHB_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
          read_data_1  = phy_apb_rd_cmd( chb_rank0_min_cs_vref_pass          );
          read_data_2  = phy_apb_rd_cmd( chb_rank0_max_cs_vref_pass          );
    printf("[INNO_INFO] RANK0 CHB_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);

    if(def->RANK2_OR_RANK4){
              read_data_1  = phy_apb_rd_cmd( cha_rank1_min_cs_perbit_skew_pass   );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_max_cs_perbit_skew_pass   );
        tresult->cha_perbit_skew_train_result_max[1][0] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][0] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_ca0_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_ca0_max_perbit_skew_pass  );
        tresult->cha_perbit_skew_train_result_max[1][1] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][1] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_ca1_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_ca1_max_perbit_skew_pass  );
        tresult->cha_perbit_skew_train_result_max[1][2] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][2] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_ca2_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_ca2_max_perbit_skew_pass  );
        tresult->cha_perbit_skew_train_result_max[1][3] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][3] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_ca3_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_ca3_max_perbit_skew_pass  );
        tresult->cha_perbit_skew_train_result_max[1][4] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][4] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_ca4_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_ca4_max_perbit_skew_pass  );
        tresult->cha_perbit_skew_train_result_max[1][5] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][5] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_ca5_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_ca5_max_perbit_skew_pass  );
        tresult->cha_perbit_skew_train_result_max[1][6] = read_data_2;
        tresult->cha_perbit_skew_train_result_min[1][6] = read_data_1;
        printf("[INNO_INFO] RANK1 CHA_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( cha_rank1_min_cs_vref_pass          );
              read_data_2  = phy_apb_rd_cmd( cha_rank1_max_cs_vref_pass          );
        printf("[INNO_INFO] RANK1 CHA_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);

              read_data_1  = phy_apb_rd_cmd( chb_rank1_min_cs_perbit_skew_pass   );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_max_cs_perbit_skew_pass   );
        tresult->chb_perbit_skew_train_result_max[1][0] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][0] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_ca0_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_ca0_max_perbit_skew_pass  );
        tresult->chb_perbit_skew_train_result_max[1][1] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][1] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_ca1_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_ca1_max_perbit_skew_pass  );
        tresult->chb_perbit_skew_train_result_max[1][2] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][2] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_ca2_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_ca2_max_perbit_skew_pass  );
        tresult->chb_perbit_skew_train_result_max[1][3] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][3] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_ca3_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_ca3_max_perbit_skew_pass  );
        tresult->chb_perbit_skew_train_result_max[1][4] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][4] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_ca4_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_ca4_max_perbit_skew_pass  );
        tresult->chb_perbit_skew_train_result_max[1][5] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][5] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_ca5_min_perbit_skew_pass  );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_ca5_max_perbit_skew_pass  );
        tresult->chb_perbit_skew_train_result_max[1][6] = read_data_2;
        tresult->chb_perbit_skew_train_result_min[1][6] = read_data_1;
        printf("[INNO_INFO] RANK1 CHB_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
              read_data_1  = phy_apb_rd_cmd( chb_rank1_min_cs_vref_pass          );
              read_data_2  = phy_apb_rd_cmd( chb_rank1_max_cs_vref_pass          );
        printf("[INNO_INFO] RANK1 CHB_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);

        if(def->RANK4){
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_min_cs_perbit_skew_pass   );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_max_cs_perbit_skew_pass   );
//            tresult->cha_perbit_skew_train_result_max[2][0] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][0] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_ca0_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_ca0_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[2][1] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][1] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_ca1_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_ca1_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[2][2] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][2] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_ca2_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_ca2_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[2][3] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][3] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_ca3_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_ca3_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[2][4] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][4] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_ca4_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_ca4_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[2][5] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][5] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_ca5_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_ca5_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[2][6] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[2][6] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHA_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank2_min_cs_vref_pass          );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank2_max_cs_vref_pass          );
//            printf("[INNO_INFO] RANK2 CHA_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_min_cs_perbit_skew_pass   );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_max_cs_perbit_skew_pass   );
//            tresult->chb_perbit_skew_train_result_max[2][0] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][0] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_ca0_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_ca0_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[2][1] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][1] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_ca1_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_ca1_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[2][2] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][2] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_ca2_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_ca2_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[2][3] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][3] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_ca3_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_ca3_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[2][4] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][4] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_ca4_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_ca4_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[2][5] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][5] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_ca5_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_ca5_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[2][6] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[2][6] = read_data_1;
//            printf("[INNO_INFO] RANK2 CHB_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank2_min_cs_vref_pass          );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank2_max_cs_vref_pass          );
//            printf("[INNO_INFO] RANK2 CHB_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//
//
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_min_cs_perbit_skew_pass   );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_max_cs_perbit_skew_pass   );
//            tresult->cha_perbit_skew_train_result_max[3][0] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][0] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_ca0_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_ca0_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[3][1] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][1] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_ca1_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_ca1_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[3][2] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][2] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_ca2_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_ca2_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[3][3] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][3] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_ca3_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_ca3_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[3][4] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][4] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_ca4_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_ca4_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[3][5] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][5] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_ca5_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_ca5_max_perbit_skew_pass  );
//            tresult->cha_perbit_skew_train_result_max[3][6] = read_data_2;
//            tresult->cha_perbit_skew_train_result_min[3][6] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHA_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( cha_rank3_min_cs_vref_pass          );
//                  read_data_2  = phy_apb_rd_cmd( cha_rank3_max_cs_vref_pass          );
//            printf("[INNO_INFO] RANK3 CHA_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_min_cs_perbit_skew_pass   );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_max_cs_perbit_skew_pass   );
//            tresult->chb_perbit_skew_train_result_max[3][0] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][0] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CS Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_ca0_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_ca0_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[3][1] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][1] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CA0 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_ca1_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_ca1_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[3][2] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][2] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CA1 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_ca2_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_ca2_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[3][3] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][3] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CA2 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_ca3_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_ca3_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[3][4] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][4] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CA3 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_ca4_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_ca4_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[3][5] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][5] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CA4 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_ca5_min_perbit_skew_pass  );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_ca5_max_perbit_skew_pass  );
//            tresult->chb_perbit_skew_train_result_max[3][6] = read_data_2;
//            tresult->chb_perbit_skew_train_result_min[3][6] = read_data_1;
//            printf("[INNO_INFO] RANK3 CHB_CA5 Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
//                  read_data_1  = phy_apb_rd_cmd( chb_rank3_min_cs_vref_pass          );
//                  read_data_2  = phy_apb_rd_cmd( chb_rank3_max_cs_vref_pass          );
//            printf("[INNO_INFO] RANK3 CHB_VREF Train range = [0x%x:0x%x].\n", read_data_1,read_data_2);
        }
    }



    for( i=0;i<=5;i=i+1)    {
        phy_apb_wr_cmd( reg_cmd_invdelaysel_sel          , i );
              read_data_1  = phy_apb_rd_cmd( reg_cmd_invdelaysel             );
        printf("[INNO_INFO] RANK0 CHA_CA%d Train result = [0x%x].\n", i,read_data_1);
    }
    for( i=6;i<=11;i=i+1)    {
        phy_apb_wr_cmd( reg_cmd_invdelaysel_sel          , i );
              read_data_1  = phy_apb_rd_cmd( reg_cmd_invdelaysel             );
        printf("[INNO_INFO] RANK0 CHB_CA%d Train result = [0x%x].\n", i-6,read_data_1);
    }
    if(def->RANK2_OR_RANK4){
        for( i=12;i<=17;i=i+1)    {
            phy_apb_wr_cmd( reg_cmd_invdelaysel_sel          , i );
                  read_data_1  = phy_apb_rd_cmd( reg_cmd_invdelaysel             );
            printf("[INNO_INFO] RANK1 CHA_CA%d Train result = [0x%x].\n", i,read_data_1);
        }
        for( i=18;i<=23;i=i+1)    {
            phy_apb_wr_cmd( reg_cmd_invdelaysel_sel          , i );
                  read_data_1  = phy_apb_rd_cmd( reg_cmd_invdelaysel             );
            printf("[INNO_INFO] RANK1 CHB_CA%d Train result = [0x%x].\n", i-6,read_data_1);
        }
        if(def->RANK4){
//            for( i=1;i<=6;i=i+1)    {
//                printf("[INNO_INFO] RANK2 CHA_CA%d Train result = [0x%x].\n", i,(tresult->cha_perbit_skew_train_result_max[2][i]+tresult->cha_perbit_skew_train_result_min[2][i])>>1);
//            }
//            for( i=1;i<=6;i=i+1)    {
//                printf("[INNO_INFO] RANK3 CHA_CA%d Train result = [0x%x].\n", i,(tresult->cha_perbit_skew_train_result_max[3][i]+tresult->cha_perbit_skew_train_result_min[3][i])>>1);
//            }
        }
    }
}//endtask



void all_cmd_perbit_skew_update( int perbit_skew ){
int i;
#ifdef CTRL_SIM
#else
//reg [31:0]  cmd_perbit_skew_offset = 32'hd0;
for( i=0; i<=0x1c; i=i+4 ) {
    phy_apb_wr_cmd( cmd_perbit_skew_offset+i, 7 , 0 , perbit_skew );
    phy_apb_wr_cmd( cmd_perbit_skew_offset+i, 15, 8 , perbit_skew );
    phy_apb_wr_cmd( cmd_perbit_skew_offset+i, 23, 16, perbit_skew );
    phy_apb_wr_cmd( cmd_perbit_skew_offset+i, 31, 24, perbit_skew ); //a0
}
#endif
}//endtask
#endif

