blob: 885eec55e97f120c117fca22235652eb1fbc5aef [file] [log] [blame]
/* SPDX-License-Identifier: BSD-3-Clause */
#include "dramc_dv_init.h"
DRAM_TYPE_T MEM_TYPE = LPDDR4;
LP4_DRAM_CONFIG_T LP4_INIT;
LP5_DRAM_CONFIG_T LP5_INIT;
ANA_top_config_T ana_top_p;
ANA_DVFS_CORE_T ANA_option;
DRAMC_DVFS_GROUP_CONFIG_T DFS_TOP[DFS_GROUP_NUM];
DRAMC_SUBSYS_CONFIG_T DV_p;
void ANA_TOP_FUNCTION_CFG(ANA_top_config_T *tr,U16 data_rate)
{
// tr-> DLL_ASYNC_EN = 0 ; //from DV random
// tr-> NEW_RANK_MODE = 1 ; //from DV random
// tr-> DLL_IDLE_MODE = 1 ; //from DV random
// tr-> LP45_APHY_COMB_EN= 1 ; //from DV define
// tr-> NEW_8X_MODE = 1 ;
tr->ALL_SLAVE_EN = (data_rate <= 1866)?1:0;
if(LPDDR5_EN_S == 1)
{
tr->TX_ODT_DIS = (data_rate <=3200) ? 1 : 0 ;
} else {
tr->TX_ODT_DIS = (data_rate <=2400) ? 1 : 0 ;
}
msg("=================================== \n");
msg("ANA top config\n" );
msg("=================================== \n");
msg("DLL_ASYNC_EN = %2d\n",tr->DLL_ASYNC_EN );
msg("ALL_SLAVE_EN = %2d\n",tr->ALL_SLAVE_EN );
msg("NEW_RANK_MODE = %2d\n",tr->NEW_RANK_MODE );
msg("DLL_IDLE_MODE = %2d\n",tr->DLL_IDLE_MODE );
msg("LP45_APHY_COMB_EN = %2d\n",tr->LP45_APHY_COMB_EN);
msg("TX_ODT_DIS = %2d\n",tr->TX_ODT_DIS );
msg("NEW_8X_MODE = %2d\n",tr->NEW_8X_MODE );
msg("=================================== \n");
}
void ANA_CLK_DIV_config( ANA_DVFS_CORE_T *tr,DRAMC_DVFS_GROUP_CONFIG_T *dfs)
{
U32 SEMI_OPEN_FMIN = 300;
U32 SEMI_OPEN_FMAX = 500;//lp4 600
U32 PI_FMIN = 600;
U32 DQ_PICK;
U32 CA_PICK; //U
U32 CA_MCKIO; //S
U32 MCKIO_SEMI; //Q
U16 data_rate;
data_rate = dfs->data_rate;
tr->DQ_P2S_RATIO = dfs->DQ_P2S_RATIO;
tr->CKR = dfs->CKR;
//tr->CA_P2S_RATIO
tr->CA_P2S_RATIO = tr->DQ_P2S_RATIO/tr->CKR;
//tr->DQ_CA_OPEN
tr->DQ_CA_OPEN = ( data_rate < (SEMI_OPEN_FMIN * 2) ) ? 1 : 0;
tr->DQ_SEMI_OPEN = ( data_rate/2 < PI_FMIN ) ? (1-tr->DQ_CA_OPEN) : ((data_rate <= SEMI_OPEN_FMAX*2) ? (1-tr->DQ_CA_OPEN) : 0);
tr->CA_SEMI_OPEN = (( data_rate/(tr->CKR*2) < PI_FMIN ) ? ((data_rate/(tr->CKR*2) > SEMI_OPEN_FMAX) ? 0 : (((tr->CA_P2S_RATIO>2)||(tr->DQ_SEMI_OPEN))*(1-tr->DQ_CA_OPEN))) : tr->DQ_SEMI_OPEN);
tr->CA_FULL_RATE = (tr->DQ_CA_OPEN == 1) ? ((tr->CKR>1)?1:0) : ((tr->DQ_SEMI_OPEN*tr->CA_SEMI_OPEN*(tr->CKR>>1)) + (( data_rate/(tr->CKR*2) < PI_FMIN) ? (1-tr->CA_SEMI_OPEN) : 0 ));
tr->DQ_CKDIV4_EN = ( tr->DQ_SEMI_OPEN == 1) ? DONT_CARE_VALUE : ((( (data_rate/2) < 1200 ) ? 1 : 0 ) * (1-tr->DQ_CA_OPEN)) ;
CA_MCKIO = (data_rate/(tr->CKR*2))*(1+tr->CA_FULL_RATE);
DQ_PICK = (tr->DQ_SEMI_OPEN == 1) ? 0 : (data_rate/2) ;
CA_PICK = (tr->CA_SEMI_OPEN == 1) ? CA_MCKIO*2 : ((CA_MCKIO>=PI_FMIN) ? CA_MCKIO : (( CA_MCKIO >= (PI_FMIN/2) ) ? CA_MCKIO*2 : CA_MCKIO *4 ));
tr->CA_CKDIV4_EN = ((CA_PICK < 1200 ) ? 1 : 0 ) * ( 1- tr->DQ_CA_OPEN) ;
tr->CA_PREDIV_EN = (data_rate >= 4800) ? 1 : 0 ;
#if SA_CONFIG_EN
if(LPDDR4_EN_S)
{
// @Darren, for LP4 8PH Delay
if (data_rate <= 1866)
tr->PH8_DLY = 0;
else if (data_rate <= 2400)
tr->PH8_DLY = 0x11;
else if (data_rate <= 3200)
tr->PH8_DLY = 0xc;
else if (data_rate <= 3733)
tr->PH8_DLY = 0x9;
else
tr->PH8_DLY = 0x7;
}
else
#endif
{
tr->PH8_DLY = ((tr->DQ_CA_OPEN == 0) && (tr->DQ_SEMI_OPEN == 0) && (tr->DQ_CKDIV4_EN == 0)) ? ( (1000000>>4)/data_rate -4) : DONT_CARE_VALUE;
}
MCKIO_SEMI = (tr->DQ_SEMI_OPEN * tr->CA_SEMI_OPEN * (data_rate/2)) + (1-tr->DQ_SEMI_OPEN) * tr->CA_SEMI_OPEN * CA_MCKIO;
tr->SEMI_OPEN_CA_PICK_MCK_RATIO = ( MCKIO_SEMI == 0) ? DONT_CARE_VALUE : (CA_PICK*tr->DQ_P2S_RATIO)/data_rate ; //need to be improved
tr->DQ_AAMCK_DIV = (tr->DQ_SEMI_OPEN == 0) ? ((tr->DQ_P2S_RATIO/2)*(1-tr->DQ_SEMI_OPEN)) : DONT_CARE_VALUE;
tr->CA_AAMCK_DIV = (tr->CA_SEMI_OPEN == 0) ? ((tr->DQ_P2S_RATIO/(2*tr->CKR))*(1+tr->CA_FULL_RATE)) : DONT_CARE_VALUE;
tr->CA_ADMCK_DIV = CA_PICK/(data_rate/tr->DQ_P2S_RATIO); //need to be improved
//tr->DQ_TRACK_CA_EN = ((data_rate/2) >= 2133) ? 1 : 0 ; //for Alucary confirm that 'interface timing' sign NOT OK.
tr->DQ_TRACK_CA_EN = 0 ;
tr->PLL_FREQ = ((DQ_PICK*2*(tr->DQ_CKDIV4_EN+1)) > (CA_PICK*2*(tr->CA_CKDIV4_EN+1))) ? (DQ_PICK*2*(tr->DQ_CKDIV4_EN+1)) : (CA_PICK*2*(tr->CA_CKDIV4_EN+1));
#if SA_CONFIG_EN
//de-sense
if(data_rate==2400)
tr->PLL_FREQ = 2366; //DDR2366
else if(data_rate==1200)
tr->PLL_FREQ = 2288; //DDR1144
else if(data_rate==3200 || data_rate==1600)
tr->PLL_FREQ = 3068; //DDR3068 DDR1534
else if(data_rate==800)
tr->PLL_FREQ = 3016; //DDR754
else if(data_rate==400)
tr->PLL_FREQ = 4000; //DDR250 Op
#endif
tr->DQ_UI_PI_RATIO = 32; //TODO:notice here. infact if DQ_SEMI_OPEM == 1 UI_PI_RATIO will only 4 lower 2bit wihtout use
tr->CA_UI_PI_RATIO = (tr->CA_SEMI_OPEN == 0) ? ((tr->CA_FULL_RATE == 1)? 64 : DONT_CARE_VALUE) : 32;
msg("=================================== \n");
msg("data_rate = %4d\n" ,data_rate );
msg("CKR = %1d\n" ,tr->CKR );
msg("DQ_P2S_RATIO = %1d\n" ,tr->DQ_P2S_RATIO );
msg("=================================== \n");
msg("CA_P2S_RATIO = %1d\n" ,tr->CA_P2S_RATIO );
msg("DQ_CA_OPEN = %1d\n" ,tr->DQ_CA_OPEN );
msg("DQ_SEMI_OPEN = %1d\n" ,tr->DQ_SEMI_OPEN );
msg("CA_SEMI_OPEN = %1d\n" ,tr->CA_SEMI_OPEN );
msg("CA_FULL_RATE = %1d\n" ,tr->CA_FULL_RATE );
msg("DQ_CKDIV4_EN = %1d\n" ,tr->DQ_CKDIV4_EN );
msg("CA_CKDIV4_EN = %1d\n" ,tr->CA_CKDIV4_EN );
msg("CA_PREDIV_EN = %1d\n" ,tr->CA_PREDIV_EN );
msg("PH8_DLY = %1d\n" ,tr->PH8_DLY );
msg("SEMI_OPEN_CA_PICK_MCK_RATIO= %1d\n" ,tr->SEMI_OPEN_CA_PICK_MCK_RATIO);
msg("DQ_AAMCK_DIV = %1d\n" ,tr->DQ_AAMCK_DIV );
msg("CA_AAMCK_DIV = %1d\n" ,tr->CA_AAMCK_DIV );
msg("CA_ADMCK_DIV = %1d\n" ,tr->CA_ADMCK_DIV );
msg("DQ_TRACK_CA_EN = %1d\n" ,tr->DQ_TRACK_CA_EN );
msg("CA_PICK = %2d\n" ,CA_PICK );
msg("CA_MCKIO = %1d\n" ,CA_MCKIO );
msg("MCKIO_SEMI = %1d\n" ,MCKIO_SEMI );
msg("PLL_FREQ = %1d\n" ,tr->PLL_FREQ );
msg("DQ_UI_PI_RATIO = %1d\n" ,tr->DQ_UI_PI_RATIO );
msg("CA_UI_PI_RATIO = %1d\n" ,tr->CA_UI_PI_RATIO );
msg("=================================== \n");
}
void DRAMC_SUBSYS_PRE_CONFIG(DRAMC_CTX_T *p, DRAMC_SUBSYS_CONFIG_T *tr)
{
U8 gp_id;
tr->SRAM_EN = 1;
tr->MD32_EN = 1;
tr->a_cfg = &ana_top_p;
tr->a_opt = &ANA_option;
tr->lp4_init = &LP4_INIT;
tr->lp5_init = &LP5_INIT;
for(gp_id = 0; gp_id < DFS_GROUP_NUM; gp_id++)
{
tr->DFS_GP[gp_id] = &DFS_TOP[gp_id];
}
if(LPDDR4_EN_S)
{
(tr->DFS_GP[0])->data_rate = 4266; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
(tr->DFS_GP[1])->data_rate = 3200; (tr->DFS_GP[1])->DQ_P2S_RATIO = 8;
(tr->DFS_GP[2])->data_rate = 2400; (tr->DFS_GP[2])->DQ_P2S_RATIO = 8;
(tr->DFS_GP[3])->data_rate = 1866; (tr->DFS_GP[3])->DQ_P2S_RATIO = 8;
(tr->DFS_GP[4])->data_rate = 1600; (tr->DFS_GP[4])->DQ_P2S_RATIO = 4;
(tr->DFS_GP[5])->data_rate = 1200; (tr->DFS_GP[5])->DQ_P2S_RATIO = 4;
(tr->DFS_GP[6])->data_rate = 800 ; (tr->DFS_GP[6])->DQ_P2S_RATIO = 4;
(tr->DFS_GP[7])->data_rate = 400 ; (tr->DFS_GP[7])->DQ_P2S_RATIO = 4;
(tr->DFS_GP[8])->data_rate = 4266; (tr->DFS_GP[8])->DQ_P2S_RATIO = 4;
(tr->DFS_GP[9])->data_rate = 1600; (tr->DFS_GP[9])->DQ_P2S_RATIO = 4;
for(gp_id = 0; gp_id < DFS_GROUP_NUM; gp_id++)
{
(tr->DFS_GP[gp_id])->CKR = 1;
(tr->DFS_GP[gp_id])->DQSIEN_MODE = 1;
}
#if 0//DV_CONFIG_EN==1
tr->lp4_init->LP4Y_EN = DUT_p.LP4Y_EN ;
tr->lp4_init->WR_PST = DUT_p.LP4_WR_PST ;
tr->lp4_init->OTF = DUT_p.LP4_OTF ;
tr->a_cfg->NEW_8X_MODE = DUT_p.NEW_8X_MODE ;
tr->a_cfg->LP45_APHY_COMB_EN = 1 ;
tr->a_cfg->DLL_IDLE_MODE = DUT_p.DLL_IDLE_MODE ;
tr->a_cfg->NEW_RANK_MODE = DUT_p.NEW_RANK_MODE ;
tr->a_cfg->DLL_ASYNC_EN = DUT_p.DLL_ASYNC_EN ;
tr->MD32_EN = DUT_p.MD32_EN ;
tr->SRAM_EN = DUT_p.SRAM_EN ;
tr->GP_NUM = DUT_p.GP_NUM ;
for(gp_id = 0; gp_id < DV_p.GP_NUM; gp_id++)
{
tr->DFS_GP[gp_id]->data_rate = DUT_shu_p[gp_id].data_rate ;
tr->DFS_GP[gp_id]->DQSIEN_MODE = DUT_shu_p[gp_id].DQSIEN_MODE ;
tr->DFS_GP[gp_id]->DQ_P2S_RATIO = DUT_shu_p[gp_id].DQ_P2S_RATIO;
tr->DFS_GP[gp_id]->CKR = DUT_shu_p[gp_id].CKR ;
}
#endif
#if SA_CONFIG_EN
tr->lp4_init->EX_ROW_EN[0] = p->u110GBEn[RANK_0] ;
tr->lp4_init->EX_ROW_EN[1] = p->u110GBEn[RANK_1] ;
tr->lp4_init->BYTE_MODE[0] = 0 ;
tr->lp4_init->BYTE_MODE[1] = 0 ;
tr->lp4_init->LP4Y_EN = 0;//DUT_p.LP4Y_EN ;
tr->lp4_init->WR_PST = 1;//DUT_p.LP4_WR_PST ;
tr->lp4_init->OTF = 1;//DUT_p.LP4_OTF ;
tr->a_cfg->NEW_8X_MODE = 1;//DUT_p.NEW_8X_MODE ;
tr->a_cfg->LP45_APHY_COMB_EN = 1 ;
tr->a_cfg->DLL_IDLE_MODE = 1;//DUT_p.DLL_IDLE_MODE ;
tr->a_cfg->NEW_RANK_MODE = 1;//DUT_p.NEW_RANK_MODE ;
tr->a_cfg->DLL_ASYNC_EN = 0;//DUT_p.DLL_ASYNC_EN ;
tr->MD32_EN = 0;//DUT_p.MD32_EN ;
tr->SRAM_EN = 1;//DUT_p.SRAM_EN ;
tr->GP_NUM = 10;//DUT_p.GP_NUM ;
if(p->freq_sel==LP4_DDR4266)
{
(tr->DFS_GP[0])->data_rate = 4266; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR3733)
{
(tr->DFS_GP[0])->data_rate = 3733; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR3200)
{
(tr->DFS_GP[0])->data_rate = 3200; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR2400)
{
(tr->DFS_GP[0])->data_rate = 2400; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR1866)
{
(tr->DFS_GP[0])->data_rate = 1866; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR1600)
{
(tr->DFS_GP[0])->data_rate = 1600; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR1200)
{
(tr->DFS_GP[0])->data_rate = 1200; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8;
}
else if(p->freq_sel==LP4_DDR800)
{
(tr->DFS_GP[0])->data_rate = 800; (tr->DFS_GP[0])->DQ_P2S_RATIO = 4;
}
else if(p->freq_sel==LP4_DDR400)
{
(tr->DFS_GP[0])->data_rate = 400; (tr->DFS_GP[0])->DQ_P2S_RATIO = 4;
}
#endif
//==============================================
//Oterwise, SA should rebuild Top configuration.
//==============================================
LP4_DRAM_config(tr->DFS_GP[0]->data_rate,tr->lp4_init);
}
//TODO for LPDDR5
//data_rate DQ_P2S_RATIO
//[4800:6400] 16
//[1600:4800) 8
//[400 :1600] 4
//=========================
//data_rate CKR
//[3733:6400] 4
//[400 :3733) 2
else if (MEM_TYPE == LPDDR5)
{
#if SA_CONFIG_EN
if(p->freq_sel==LP5_DDR4266)
{
(tr->DFS_GP[0])->data_rate = 4266; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8 ; tr->DFS_GP[0]->CKR = 4;tr->DFS_GP[0]->DQSIEN_MODE = 2;
}
else if(p->freq_sel==LP5_DDR5500)
{
(tr->DFS_GP[0])->data_rate = 5500; (tr->DFS_GP[0])->DQ_P2S_RATIO = 16 ; tr->DFS_GP[0]->CKR = 4;tr->DFS_GP[0]->DQSIEN_MODE = 2;
}
else
{
(tr->DFS_GP[0])->data_rate = 3200; (tr->DFS_GP[0])->DQ_P2S_RATIO = 8 ; tr->DFS_GP[0]->CKR = 2;tr->DFS_GP[0]->DQSIEN_MODE = 1;
}
#else
(tr->DFS_GP[0])->data_rate = 6400; (tr->DFS_GP[0])->DQ_P2S_RATIO = 16; tr->DFS_GP[0]->CKR = 4;tr->DFS_GP[0]->DQSIEN_MODE = 1;
#endif
(tr->DFS_GP[1])->data_rate = 3200; (tr->DFS_GP[1])->DQ_P2S_RATIO = 8 ; tr->DFS_GP[1]->CKR = 2;tr->DFS_GP[1]->DQSIEN_MODE = 1;
(tr->DFS_GP[2])->data_rate = 1600; (tr->DFS_GP[2])->DQ_P2S_RATIO = 4 ; tr->DFS_GP[2]->CKR = 2;tr->DFS_GP[2]->DQSIEN_MODE = 1;
(tr->DFS_GP[3])->data_rate = 4266; (tr->DFS_GP[3])->DQ_P2S_RATIO = 8 ; tr->DFS_GP[3]->CKR = 4;tr->DFS_GP[3]->DQSIEN_MODE = 1;
(tr->DFS_GP[4])->data_rate = 3733; (tr->DFS_GP[4])->DQ_P2S_RATIO = 8 ; tr->DFS_GP[4]->CKR = 4;tr->DFS_GP[4]->DQSIEN_MODE = 1;
(tr->DFS_GP[5])->data_rate = 1600; (tr->DFS_GP[5])->DQ_P2S_RATIO = 8 ; tr->DFS_GP[5]->CKR = 2;tr->DFS_GP[5]->DQSIEN_MODE = 1;
(tr->DFS_GP[6])->data_rate = 1200; (tr->DFS_GP[6])->DQ_P2S_RATIO = 4 ; tr->DFS_GP[6]->CKR = 2;tr->DFS_GP[6]->DQSIEN_MODE = 1;
(tr->DFS_GP[7])->data_rate = 800 ; (tr->DFS_GP[7])->DQ_P2S_RATIO = 4 ; tr->DFS_GP[7]->CKR = 2;tr->DFS_GP[7]->DQSIEN_MODE = 1;
(tr->DFS_GP[8])->data_rate = 400 ; (tr->DFS_GP[8])->DQ_P2S_RATIO = 4 ; tr->DFS_GP[8]->CKR = 2;tr->DFS_GP[8]->DQSIEN_MODE = 1;
(tr->DFS_GP[9])->data_rate = 5500; (tr->DFS_GP[9])->DQ_P2S_RATIO = 16; tr->DFS_GP[9]->CKR = 4;tr->DFS_GP[9]->DQSIEN_MODE = 1;
LP5_DRAM_config(tr->DFS_GP[0],tr->lp5_init);
}
ANA_TOP_FUNCTION_CFG(tr->a_cfg,tr->DFS_GP[0]->data_rate);
ANA_CLK_DIV_config(tr->a_opt,tr->DFS_GP[0]);
msg("=================================== \n");
msg("memory_type:%s \n",LPDDR5_EN_S?"LPDDR5":"LPDDR4" );
msg("GP_NUM : %1d \n",tr->GP_NUM );
msg("SRAM_EN : %1d \n",tr->SRAM_EN );
msg("MD32_EN : %1d \n",tr->MD32_EN );
msg("=================================== \n");
}