1.配置DDR时钟
void config_ddr(
unsigned int pll,
unsigned int ioctrl,
const struct ddr_data *data,
const struct cmd_control *ctrl,
const struct emif_regs *regs)
{
/*使能CM_PER_EMIF_FW_CLKCTRL和CM_PER_EMIF_CLKCTRL寄存器*/
enable_emif_clocks();
ddr_pll_config(pll);
/*使能VTP*/
config_vtp();
/*配置DDR CMD 控制寄存器
*CMD0_REG_PHY_CTRL_SLAVE_RATIO_0 <--NT5CB128M16HPD1_0_RATIO :
*CMD0_REG_PHY_DLL_LOCK_DIFF_0 <--NT5CB128M16HPD1_0_DLL_LOCK_DIFF :
*CMD0_REG_PHY_INVERT_CLKOUT_0 <--NT5CB128M16HPD1_0_INVERT_CLKOUT :是否反转CCLK电平
*CMD1_REG_PHY_CTRL_SLAVE_RATIO_0
*CMD1_REG_PHY_DLL_LOCK_DIFF_0
*CMD1_REG_PHY_INVERT_CLKOUT_0
*CMD2_REG_PHY_CTRL_SLAVE_RATIO_0
*CMD2_REG_PHY_DLL_LOCK_DIFF_0
*CMD2_REG_PHY_INVERT_CLKOUT_0
*/
config_cmd_ctrl(ctrl);
/*配置DDR DATA控制器
*DATA0_REG_PHY_RD_DQS_SLAVE_RATIO_0
*DATA0_REG_PHY_WR_DQS_SLAVE_RATIO_0
*DATA0_REG_PHY_WRLVL_INIT_RATIO_0
*DATA0_REG_PHY_GATELVL_INIT_RATIO_0
*DATA0_REG_PHY_FIFO_WE_SLAVE_RATIO_0
*DATA0_REG_PHY_WR_DATA_SLAVE_RATIO_0
*DATA0_REG_PHY_USE_RANK0_DELAYS
*DATA0_REG_PHY_DLL_LOCK_DIFF_0
*/
config_ddr_data(0, data);
config_ddr_data(1, data);
/*
*ddr_cmd0_ioctrl
*ddr_cmd0_ioctrl
*/
config_io_ctrl(ioctrl);
/* Set CKE to be controlled by EMIF/DDR PHY */
writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl);
/* Program EMIF instance */
config_ddr_phy(regs);
set_sdram_timings(regs);
config_sdram(regs);
}
DDR时钟配置
void ddr_pll_config(unsigned int ddrpll_m)
{
u32 clkmode, clksel, div_m2;
/*读取当前值*/
clkmode = readl(&cmwkup->clkmoddpllddr);
clksel = readl(&cmwkup->clkseldpllddr);
div_m2 = readl(&cmwkup->divm2dpllddr);
/* Set the PLL to bypass Mode */
clkmode = (clkmode & CLK_MODE_MASK) | PLL_BYPASS_MODE;
writel(clkmode, &cmwkup->clkmoddpllddr);
/* Wait till bypass mode is enabled */
while ((readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS)
!= ST_MN_BYPASS)
;
clksel = clksel & (~CLK_SEL_MASK);
clksel = clksel | ((ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N);
writel(clksel, &cmwkup->clkseldpllddr);
div_m2 = div_m2 & CLK_DIV_SEL;
div_m2 = div_m2 | DDRPLL_M2;
writel(div_m2, &cmwkup->divm2dpllddr);
clkmode = (clkmode & CLK_MODE_MASK) | CLK_MODE_SEL;
writel(clkmode, &cmwkup->clkmoddpllddr);
/* Wait till dpll is locked */
while ((readl(&cmwkup->idlestdpllddr) & ST_DPLL_CLK) != ST_DPLL_CLK)
;
}