Commit 01b3f229 authored by Peng Fan's avatar Peng Fan

MLK-18243-18: arm: imx: add i.MX8MM EVK board support

Add i.MX8MM EVK board support
LPDDR4 code is still keep in old coding style to ease updating
if there is no code released.
dts is synced from kernel with sd2 regulator start up delay and off on
delay added.
Signed-off-by: 's avatarPeng Fan <peng.fan@nxp.com>
parent 3e4123fb
......@@ -36,6 +36,11 @@ config TARGET_IMX8MQ_DDR4_ARM2
select IMX8MQ
select SUPPORT_SPL
config TARGET_IMX8MM_EVK
bool "imx8mm evk"
select IMX8MM
select SUPPORT_SPL
endchoice
config SYS_SOC
......@@ -44,5 +49,6 @@ config SYS_SOC
source "board/freescale/imx8mq_phanbell/Kconfig"
source "board/freescale/imx8mq_evk/Kconfig"
source "board/freescale/imx8mq_arm2/Kconfig"
source "board/freescale/imx8mm_evk/Kconfig"
endif
......@@ -389,7 +389,8 @@ dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-evk.dtb \
dtb-$(CONFIG_ARCH_IMX8M) += fsl-imx8mq-evk.dtb \
fsl-imx8mq-ddr3l-arm2.dtb \
fsl-imx8mq-phanbell.dtb \
fsl-imx8mq-ddr4-arm2.dtb
fsl-imx8mq-ddr4-arm2.dtb \
fsl-imx8mm-evk.dtb
dtb-$(CONFIG_ARCH_IMX8) += fsl-imx8qm-lpddr4-arm2.dtb \
fsl-imx8qm-ddr4-arm2.dtb \
......
This diff is collapsed.
if TARGET_IMX8MM_EVK
config SYS_BOARD
default "imx8mm_evk"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "imx8mm_evk"
source "board/freescale/common/Kconfig"
endif
#
# Copyright 2018 NXP
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += imx8mm_evk.o
ifdef CONFIG_SPL_BUILD
obj-y += spl.o
obj-y += ddr/
endif
#
# Copyright 2018 NXP
#
# SPDX-License-Identifier: GPL-2.0+
#
ifdef CONFIG_SPL_BUILD
obj-y += helper.o
obj-y += lpddr4_cfg_umctl2_m845.o
obj-y += lpddr4_phyinit_train_3000mts_fw09.o
obj-y += lpddr4_pmu_training_3000mts_fw09.o
obj-y += lpddr4_phyinit_task.o
endif
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
* Common file for ddr code
*/
#ifndef __M845S_DDR_H_
#define __M845S_DDR_H_
#ifdef DDR_DEBUG
#define ddr_dbg(fmt, ...) printf("DDR: debug:" fmt "\n", ##__VA_ARGS__)
#else
#define ddr_dbg(fmt, ...)
#endif
/*******************************************************************
Desc: user data type
*******************************************************************/
enum fw_type {
FW_1D_IMAGE,
FW_2D_IMAGE,
};
/*******************************************************************
Desc: prototype
*******************************************************************/
void ddr_init(void);
void lpddr4_3000mts_cfg_umctl2(void);
void ddr_load_train_code(enum fw_type type);
void dwc_ddrphy_phyinit_userCustom_E_setDfiClk(int pstate);
void dwc_ddrphy_phyinit_userCustom_J_enterMissionMode(void);
void dwc_ddrphy_phyinit_userCustom_customPostTrain(void);
void dwc_ddrphy_phyinit_userCustom_B_startClockResetPhy(void);
void dwc_ddrphy_phyinit_userCustom_A_bringupPower(void);
void dwc_ddrphy_phyinit_userCustom_overrideUserInput(void);
void dwc_ddrphy_phyinit_userCustom_H_readMsgBlock(unsigned long run_2D);
int dwc_ddrphy_phyinit_userCustom_G_waitFwDone(void);
void lpddr4_750M_cfg_phy(void);
/*******************************************************************
Desc: definition
*******************************************************************/
static inline void reg32_write(unsigned long addr, u32 val)
{
writel(val, addr);
}
static inline uint32_t reg32_read(unsigned long addr)
{
return readl(addr);
}
static inline void reg32setbit(unsigned long addr, u32 bit)
{
setbits_le32(addr, (1 << bit));
}
#endif
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <spl.h>
#include <asm/io.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/ddr_memory_map.h>
#include <asm/sections.h>
#include "ddr.h"
DECLARE_GLOBAL_DATA_PTR;
#define IMEM_LEN 32768//23400 //byte
#define DMEM_LEN 16384//1720 //byte
#define IMEM_2D_OFFSET 49152
#define IMEM_OFFSET_ADDR 0x00050000
#define DMEM_OFFSET_ADDR 0x00054000
#define DDR_TRAIN_CODE_BASE_ADDR IP2APB_DDRPHY_IPS_BASE_ADDR(0)
/* We need PHY iMEM PHY is 32KB padded */
void ddr_load_train_code(enum fw_type type)
{
u32 tmp32, i;
u32 error = 0;
unsigned long pr_to32, pr_from32;
unsigned long fw_offset = type ? IMEM_2D_OFFSET : 0;
unsigned long imem_start = (unsigned long)&_end + fw_offset;
unsigned long dmem_start = imem_start + IMEM_LEN;
pr_from32 = imem_start;
pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR;
for(i = 0x0; i < IMEM_LEN; ){
tmp32 = readl(pr_from32);
writew(tmp32 & 0x0000ffff, pr_to32);
pr_to32 += 4;
writew((tmp32 >> 16) & 0x0000ffff, pr_to32);
pr_to32 += 4;
pr_from32 += 4;
i += 4;
}
pr_from32 = dmem_start;
pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR;
for(i = 0x0; i < DMEM_LEN;){
tmp32 = readl(pr_from32);
writew(tmp32 & 0x0000ffff, pr_to32);
pr_to32 += 4;
writew((tmp32 >> 16) & 0x0000ffff, pr_to32);
pr_to32 += 4;
pr_from32 += 4;
i += 4;
}
printf("check ddr4_pmu_train_imem code\n");
pr_from32 = imem_start;
pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR;
for(i = 0x0; i < IMEM_LEN;){
tmp32 = (readw(pr_to32) & 0x0000ffff);
pr_to32 += 4;
tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16);
if(tmp32 != readl(pr_from32)){
printf("%lx %lx\n", pr_from32, pr_to32);
error++;
}
pr_from32 += 4;
pr_to32 += 4;
i += 4;
}
if(error){
printf("check ddr4_pmu_train_imem code fail=%d\n",error);
}else{
printf("check ddr4_pmu_train_imem code pass\n");
}
printf("check ddr4_pmu_train_dmem code\n");
pr_from32 = dmem_start;
pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR;
for(i = 0x0; i < DMEM_LEN;){
tmp32 = (readw(pr_to32) & 0x0000ffff);
pr_to32 += 4;
tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16);
if(tmp32 != readl(pr_from32)){
printf("%lx %lx\n", pr_from32, pr_to32);
error++;
}
pr_from32 += 4;
pr_to32 += 4;
i += 4;
}
if(error){
printf("check ddr4_pmu_train_dmem code fail=%d",error);
}else{
printf("check ddr4_pmu_train_dmem code pass\n");
}
}
This diff is collapsed.
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef LPDDR4_DEFINE_H
#define LPDDR4_DEFINE_H
#include "ddr.h"
#define RUN_ON_SILICON
#define DFI_BUG_WR
#define DEVINIT_PHY
#define DDR_ONE_RANK
#define BUG_WR_DFI
#define M845S_4GBx2
#ifdef LPDDR4_667MTS
#define P0_667
#endif
#ifdef LPDDR4_1600MTS
#define P0_1600
#endif
#ifdef LPDDR4_DVFS
#define DVFS_TEST
#define PHY_TRAIN
#define DDR_BOOT_P1
#endif
#ifdef LPDDR4_RETENTION
#define NORMAL_RET_EN
#endif
#ifdef P0_667
#define P0_DRATE 667
#else
#ifdef P0_1600
#define P0_DRATE 1600
#else
#define P0_DRATE 3000
#endif
#endif
#define P1_DRATE 667
#define P2_DRATE 100
#ifdef RUN_ON_SILICON
#define PHY_TRAIN
#define ADD_P0_2D_BF_P1
#ifdef HWFFC
#define ADD_TRAIN_1D_P2
#endif
#else
#define DDR_FAST_SIM
#endif
#ifdef PHY_TRAIN
#define ADD_TRAIN_1D_P0
#ifdef DVFS_TEST
#define ADD_TRAIN_1D_P1
#endif
#endif
/* define BOOT FREQ, not modify */
#ifdef DDR_BOOT_P1
#define BOOT_FREQ P1_DRATE
#else
#ifdef DDR_BOOT_P2
#define BOOT_FREQ P2_DRATE
#else
#define BOOT_FREQ P0_DRATE
#endif
#endif
/* #define P1_FREQ 167 */
#ifdef PHY_TRAIN
#define CLOCK_SWITCH_PLL P0_DRATE
#else
#define CLOCK_SWITCH_PLL BOOT_FREQ
#endif
#define DDR_CSD2_BASE_ADDR 0x80000000
#define GPC_PU_PWRHSK 0x303A01FC
//----------------------------------------------------------------
// PHY training feature
//----------------------------------------------------------------
#define LPDDR4_HDT_CTL_2D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_3200_1D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_400_1D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_100_1D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_2D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_3200_1D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_400_1D 0xC8 //stage completion
#define LPDDR4_HDT_CTL_100_1D 0xC8 //stage completion
#ifdef RUN_ON_SILICON
// 400/100 training seq
#define LPDDR4_TRAIN_SEQ_P2 0x121f
#define LPDDR4_TRAIN_SEQ_P1 0x121f
#define LPDDR4_TRAIN_SEQ_P0 0x121f
#else
#define LPDDR4_TRAIN_SEQ_P2 0x7
#define LPDDR4_TRAIN_SEQ_P1 0x7
#define LPDDR4_TRAIN_SEQ_P0 0x7
#endif
//2D share & weight
#define LPDDR4_2D_WEIGHT 0x1f7f
#define LPDDR4_2D_SHARE 1
#define LPDDR4_CATRAIN_3200_1d 0
#define LPDDR4_CATRAIN_400 0
#define LPDDR4_CATRAIN_100 0
#define LPDDR4_CATRAIN_3200_2d 0
/* MRS parameter */
/* for LPDDR4 Rtt */
#define LPDDR4_RTT40 6
#define LPDDR4_RTT48 5
#define LPDDR4_RTT60 4
#define LPDDR4_RTT80 3
#define LPDDR4_RTT120 2
#define LPDDR4_RTT240 1
#define LPDDR4_RTT_DIS 0
/* for LPDDR4 Ron */
#define LPDDR4_RON34 7
#define LPDDR4_RON40 6
#define LPDDR4_RON48 5
#define LPDDR4_RON60 4
#define LPDDR4_RON80 3
#define LPDDR4_PHY_ADDR_RON60 0x1
#define LPDDR4_PHY_ADDR_RON40 0x3
#define LPDDR4_PHY_ADDR_RON30 0x7
#define LPDDR4_PHY_ADDR_RON24 0xf
#define LPDDR4_PHY_ADDR_RON20 0x1f
/* for read channel */
#define LPDDR4_RON LPDDR4_RON40 /* MR3[5:3] */
#define LPDDR4_PHY_RTT 30 /* //30//40//28 */
/* #define LPDDR4_PHY_VREF_VALUE 27//17//17//20//16///17,//for M845S */
#define LPDDR4_PHY_VREF_VALUE 17 /*//17//20//16///17,//for M850D*/
/* for write channel */
#define LPDDR4_PHY_RON 30
#define LPDDR4_PHY_ADDR_RON LPDDR4_PHY_ADDR_RON40
#define LPDDR4_RTT_DQ LPDDR4_RTT40
#define LPDDR4_RTT_CA LPDDR4_RTT40
#define LPDDR4_RTT_CA_BANK0 LPDDR4_RTT40
#define LPDDR4_RTT_CA_BANK1 LPDDR4_RTT40
#define LPDDR4_VREF_VALUE_CA ((1 << 6)|0xd)
#define LPDDR4_VREF_VALUE_DQ_RANK0 ((1 << 6)|0xd)
#define LPDDR4_VREF_VALUE_DQ_RANK1 ((1 << 6)|0xd)
#define LPDDR4_MR22_RANK0 ((0 << 5)|(0 << 4)|(0 << 3)|(LPDDR4_RTT40))
#define LPDDR4_MR22_RANK1 ((1 << 5)|(0 << 4)|(1 << 3)|(LPDDR4_RTT40))
#define LPDDR4_MR3_PU_CAL 1
#endif
/*
* Copyright 2018 NXP
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/ddr_memory_map.h>
#include <asm/arch/clock.h>
#include "lpddr4_define.h"
void dwc_ddrphy_phyinit_userCustom_E_setDfiClk(int pstate)
{
if(pstate==2)
dram_pll_init(DRAM_PLL_OUT_100M);
else if(pstate==1)
dram_pll_init(DRAM_PLL_OUT_667M);
else
dram_pll_init(DRAM_PLL_OUT_750M);
}
int dwc_ddrphy_phyinit_userCustom_G_waitFwDone(void)
{
volatile unsigned int tmp, tmp_t;
volatile unsigned int train_ok;
volatile unsigned int train_fail;
volatile unsigned int stream_msg;
int ret = 0;
train_ok = 0;
train_fail = 0;
stream_msg = 0;
while (train_ok == 0 && train_fail == 0) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
tmp_t = tmp & 0x01;
while (tmp_t){
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
tmp_t = tmp & 0x01;
}
#ifdef PRINT_PMU
printf("get the training message\n");
#endif
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
#ifdef PRINT_PMU
printf("PMU major stream =0x%x\n",tmp);
#endif
if (tmp==0x08) {
stream_msg = 1;
#ifdef DDR_PRINT_ALL_MESSAGE
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x0);
do {
tmp_t = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
}while((tmp_t & 0x1) == 0x0);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x1);
do {
tmp_t = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
}while((tmp_t & 0x1) == 0x1);
/* read_mbox_mssg */
stream_nb_args = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) +4 * 0xd0032);
/* read_mbox_msb */
stream_index = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0034);
stream_index = (stream_index << 16) | stream_nb_args;
#ifdef PRINT_PMU
printf("PMU stream_index=0x%x nb_args=%d\n",stream_index, stream_nb_args);
#endif
stream_arg_pos = 0;
while (stream_nb_args > 0) {
/* Need to complete previous handshake first... */
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x0);
/* poll_mbox_from_uc(1); */
do {
tmp_t = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
} while((tmp_t & 0x1) == 0x0);
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x1);
/* Read the next argument... */
do {
tmp_t = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
}while((tmp_t & 0x1) == 0x1);
/* read_mbox_mssg */
message = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
/* read_mbox_msb */
stream_arg_val = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0034);
stream_arg_val = (stream_arg_val << 16) | message;
#ifdef PRINT_PMU
printf("PMU stream_arg[%d]=0x%x\n",stream_arg_pos, stream_arg_val);
#endif
stream_nb_args--;
stream_arg_pos++;
}
#endif
} else if(tmp==0x07) {
train_ok = 1;
ret = 0;
} else if(tmp==0xff) {
train_fail = 1;
printf("%c[31;40m",0x1b);
printf("------- training vt_fail\n");
printf("%c[0m",0x1b);
ret = -1;
} else {
train_ok = 0;
train_fail = 0;
stream_msg = 0;
}
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0031,0x0);
if (stream_msg == 1) {
tmp_t = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0034);
tmp_t = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0034);
}
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0004);
tmp_t = tmp & 0x01;
while(tmp_t==0){
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0004);
tmp_t = tmp & 0x01;
}
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0)+4*0xd0031,0x1);
}
return ret;
}
void dwc_ddrphy_phyinit_userCustom_H_readMsgBlock(unsigned long run_2D)
{
}
void dwc_ddrphy_phyinit_userCustom_overrideUserInput(void)
{
}
void dwc_ddrphy_phyinit_userCustom_A_bringupPower(void)
{
}
void dwc_ddrphy_phyinit_userCustom_B_startClockResetPhy(void)
{
}
void dwc_ddrphy_phyinit_userCustom_customPostTrain(void)
{
}
void dwc_ddrphy_phyinit_userCustom_J_enterMissionMode(void)
{
}
/*
* Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/ddr_memory_map.h>
#include <asm/arch/clock.h>
#include "lpddr4_define.h"
#include "ddr.h"
void ddr_init(void)
{
volatile unsigned int tmp;
/*
* Desc: assert [0]ddr1_preset_n, [1]ddr1_core_reset_n,
* [2]ddr1_phy_reset, [3]ddr1_phy_pwrokin_n,
* [4]src_system_rst_b!
*/
reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00003F);
/* Desc: deassert [4]src_system_rst_b! */
reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
/*
* Desc: change the clock source of dram_apb_clk_root
* to source 4 --800MHz/4
*/
#if 0
reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_CLR(1),(0x7<<24)|(0x7<<16));
reg32_write(CCM_IP_CLK_ROOT_GEN_TAGET_SET(1),(0x4<<24)|(0x3<<16));
#else
clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | \
CLK_ROOT_SOURCE_SEL(0) | \
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1));
clock_set_target_val(DRAM_ALT_CLK_ROOT, CLK_ROOT_ON | \
CLK_ROOT_SOURCE_SEL(0) | \
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1));
clock_set_target_val(NOC_CLK_ROOT, CLK_ROOT_ON | \
CLK_ROOT_SOURCE_SEL(0) | \
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1));
clock_set_target_val(NOC_APB_CLK_ROOT, CLK_ROOT_ON | \
CLK_ROOT_SOURCE_SEL(0) | \
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1));
#endif
/* Desc: disable iso PGC_CPU_MAPPING,PU_PGC_SW_PUP_REQ */
reg32_write(0x303A00EC,0x0000ffff);
reg32setbit(0x303A00F8,5);
/*
* Desc: configure dram pll to 750M
*/
dram_pll_init(DRAM_PLL_OUT_750M);
/*
* Desc: release [0]ddr1_preset_n, [1]ddr1_core_reset_n,
* [2]ddr1_phy_reset, [3]ddr1_phy_pwrokin_n
*/
reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000006);
/* Desc: Configure uMCTL2's registers */
lpddr4_3000mts_cfg_umctl2();
/* Desc: diable ctlupd */
reg32_write(DDRC_DFIUPD0(0), 0xE0300018);
/*
* Desc: release [1]ddr1_core_reset_n, [2]ddr1_phy_reset,
* [3]ddr1_phy_pwrokin_n
*/
reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000004);
/*
* Desc: release [1]ddr1_core_reset_n, [2]ddr1_phy_reset,
* [3]ddr1_phy_pwrokin_n
*/
reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000000);
/*
* Desc: ('b00000000_00000000_00000000_00000000) ('d0)
*/
reg32_write(DDRC_DBG1(0), 0x00000000);
/*
* Desc: [8]--1: lpddr4_sr allowed; [5]--1: software entry to SR
*/
reg32_write(DDRC_PWRCTL(0), 0x000000a8);
tmp=0;
while(tmp != 0x223) {
tmp = 0x33f & (reg32_read(DDRC_STAT(0)));
ddr_dbg("C: waiting for STAT selfref_type= Self Refresh\n");
}
/*
* Desc: ('b00000000_00000000_00000000_00000000) ('d0)
*/
reg32_write(DDRC_SWCTL(0), 0x00000000);
/*
* Desc: LPDDR4 mode
*/
reg32_write(DDRC_DDR_SS_GPR0, 0x01);
/*
* Desc: [12:8]dfi_freq, [5]dfi_init_start, [4]ctl_idle_en
*/
reg32_write(DDRC_DFIMISC(0), 0x00000010);
/*
* Desc: Configure LPDDR4 PHY's registers
*/
lpddr4_750M_cfg_phy();
reg32_write(DDRC_RFSHCTL3(0), 0x00000000);
reg32_write(DDRC_SWCTL(0), 0x0000);
/*
* Desc: Set DFIMISC.dfi_init_start to 1
* [5]--1: dfi_init_start, [4] ctl_idle_en
*/
reg32_write(DDRC_DFIMISC(0), 0x00000030);
reg32_write(DDRC_SWCTL(0), 0x0001);
/*
* Desc: wait DFISTAT.dfi_init_complete to 1
*/
while(!(0x1 & (reg32_read(DDRC_DFISTAT(0)))));
reg32_write(DDRC_SWCTL(0), 0x0000);
/*
* Desc: clear DFIMISC.dfi_init_complete_en
* ('b00000000_00000000_00000000_00010000) ('d16)
*/
reg32_write(DDRC_DFIMISC(0), 0x00000010);
/*
* Desc: set DFIMISC.dfi_init_complete_en again
* ('b00000000_00000000_00000000_00010001) ('d17)
*/
reg32_write(DDRC_DFIMISC(0), 0x00000011);
/*
* Desc: ('b00000000_00000000_00000000_10001000) ('d136)
*/
reg32_write(DDRC_PWRCTL(0), 0x00000088);
/*
* Desc: set SWCTL.sw_done to enable quasi-dynamic
* register programming outside reset.
* ('b00000000_00000000_00000000_00000001) ('d1)
*/
reg32_write(DDRC_SWCTL(0), 0x00000001);
/*
* Desc: wait SWSTAT.sw_done_ack to 1
*/
while(!(0x1 & (reg32_read(DDRC_SWSTAT(0)))));
/*