// void inline orbit_writel(volatile void __iomem *addr, uint32_t data);
// void inline orbit_readl_poll(volatile void __iomem *addr, uint32_t expected, uint32_t strobe);
// void orbit_nsleep(int ns); // Sleep ns nano-seconds
// void orbit_usleep(int us); // Sleep us micro-seconds
//cdns_phy_initialize(1);

apb_write(OMC_APB_BASE_ADDR + 32'h0, 32'h00000401);//ignore_phy_rresp=1(Ignore dfi_rddata_valid from PHY,Only used in booting period);dram type=LPDDR4
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf00, 32'h40001030);//enable address region 0; 2ranks; bit15?
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf04, 32'h00000001);//logic page size; 256bit interleaving
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf10, 32'h00800000);//region0_start //32'h00800000
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf14, 32'h01ffffff);//region0_end,SOC addr shift right 8bits
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf18, 32'h00000001);//2-channel interleaving
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf30, 32'h0f000031);//chip0:rank_size=128MB*(f+1)(2GB?);bg=0;row_width=16;col_width=10
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'hf34, 32'h0f000031);//chip1
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'h110, 32'hc0000001);//region0 attribute: allow secure write/read;enable security check for this region
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'h114, 32'hffffffff);//region0: [31:16]:nsaid_wr_en(allow non-secure write); [15:0]:nsaid_rd_en(allow non-secure read)
apb_write(OMC_APB_BASE_ADDR + 32'h10c, 32'h00000505);//Temperature monitor reads to determine the maximum re-fresh interval
apb_write(OMC_APB_BASE_ADDR + 32'h11c, 32'h00000000);//no register
apb_write(OMC_APB_BASE_ADDR + 32'h500, 32'h00000201);//retimer_rddata; freq_ratio
apb_write(OMC_APB_BASE_ADDR + 32'h514, 32'h00000100);//phymstr_ack_disable=1
apb_write(OMC_APB_BASE_ADDR + 32'h6a8, 32'h00040000);//Keep OMC idle for additional idle_num_upd cycles (ACLK) after dfi_phyupd_ack assertion
apb_write(OMC_APB_BASE_ADDR + 32'hea8, 32'h00040000);//Keep OMC idle for additional idle_num_upd cycles (ACLK) after dfi_phyupd_ack assertion
// Memory frequency should be changed below 50MHz somewhere before here
apb_write(OMC_APB_BASE_ADDR + 32'h504, 32'h40000000);//assert dfi_init_start
//cdns_dll_rst_deassert()


apb_read(OMC_APB_BASE_ADDR + 32'h504, tmp);//wait for dfi_init_complete
while((tmp & 32'h80000000) != 32'h80000000) begin
  orbit_usleep(1);
  apb_read(OMC_APB_BASE_ADDR + 32'h504, tmp);
end

apb_write(OMC_APB_BASE_ADDR + 32'h504, 32'h00000000);//de-assert dfi_init_start; de-assert dfi_ctrlupd_req on exit from self-refresh mode
// tINIT0 is controlled by System
apb_write(OMC_APB_BASE_ADDR + 32'h50c, 32'h00000000);//Drive DRAM_RST_N low
// Waits tINIT1 (200 us): Minimum RESET_n LOW time after completion of voltage ramp
orbit_usleep(200);
apb_write(OMC_APB_BASE_ADDR + 32'h50c, 32'h00000001);//Drive DRAM_RST_N high
// Waits tINIT3 (2 ms): Minimum CKE low time after RESET_n high
orbit_usleep(2000);
// Drive CKE high
apb_write(OMC_APB_BASE_ADDR + 32'h10, 32'h0000003c);//dram_command_cs: rank0/1; dram_command: power-down exit
apb_write(OMC_APB_BASE_ADDR + 32'h14, 32'h00000001);//dram_command_start
// Waits tINIT5 (2 us): Minimum idle time before first MRW/MRR command
orbit_usleep(2);
apb_write(OMC_APB_BASE_ADDR + 32'h10, 32'h00000010);//rank0; ZQ start/ZQ long calibration
apb_write(OMC_APB_BASE_ADDR + 32'h14, 32'h00000001);
// Waits tZQCAL (1 us)
orbit_usleep(1);
apb_write(OMC_APB_BASE_ADDR + 32'h10, 32'h00000011);//rank0; ZQ latch/ZQ short calibration
apb_write(OMC_APB_BASE_ADDR + 32'h14, 32'h00000001);
apb_write(OMC_APB_BASE_ADDR + 32'h10, 32'h00000020);//rank1; ZQ start/ZQ long calibration
apb_write(OMC_APB_BASE_ADDR + 32'h14, 32'h00000001);
// Waits tZQCAL (1 us)
orbit_usleep(1);
apb_write(OMC_APB_BASE_ADDR + 32'h10, 32'h00000021);//rank1; ZQ latch/ZQ short calibration
apb_write(OMC_APB_BASE_ADDR + 32'h14, 32'h00000001);
apb_write(OMC_APB_BASE_ADDR + 32'h310, 32'h00020000);//dfs_dfi_frequency=2
apb_write(OMC_APB_BASE_ADDR + 32'h310, 32'h00020001);//dfs_dfi_init_start_toggle; assert dfi_init_start when dfi_frequency change
// Write down RCLK-related CRs
apb_write(OMC_APB_BASE_ADDR + 32'h600, 32'h002e0176);//Per-bank(31:16)/all-bank(15:0) refresh interval in OSC clock cycles for each of eight MR4 values.
apb_write(OMC_APB_BASE_ADDR + 32'h604, 32'h002e0176);
apb_write(OMC_APB_BASE_ADDR + 32'h608, 32'h001700bb);
apb_write(OMC_APB_BASE_ADDR + 32'h60c, 32'h000b005d);
apb_write(OMC_APB_BASE_ADDR + 32'h610, 32'h0005002e);
apb_write(OMC_APB_BASE_ADDR + 32'h614, 32'h00020017);
apb_write(OMC_APB_BASE_ADDR + 32'h618, 32'h00020017);
apb_write(OMC_APB_BASE_ADDR + 32'h61c, 32'h00020017);//Per-bank(31:16)/all-bank(15:0) refresh interval in OSC clock cycles for each of eight MR4 values.
apb_write(OMC_APB_BASE_ADDR + 32'h678, 32'h00000019);//t_zqcal(lpddr4) >= 1us(12'h640) 
apb_write(OMC_APB_BASE_ADDR + 32'h100, 32'h000000fc);//abr_en[7:0]
apb_write(OMC_APB_BASE_ADDR + 32'h620, 32'h03030404);//error: tCKCKEH(tCKSRX)>=3,tCMDCKE>=3,tRPpb(tRP)>=29,tRPab(tRP)>=34
apb_write(OMC_APB_BASE_ADDR + 32'h624, 32'h04030505);//error: tCKE>=12,tSR(tCKESR)>=24,tCKELCK>=8,tXP>=12
apb_write(OMC_APB_BASE_ADDR + 32'h628, 32'h07030884);
apb_write(OMC_APB_BASE_ADDR + 32'h62c, 32'h13150401);
apb_write(OMC_APB_BASE_ADDR + 32'h630, 32'h17150604);
apb_write(OMC_APB_BASE_ADDR + 32'h634, 32'h000d0000);
apb_write(OMC_APB_BASE_ADDR + 32'h638, 32'h200a0a08);
apb_write(OMC_APB_BASE_ADDR + 32'h63c, 32'h173b0003);
apb_write(OMC_APB_BASE_ADDR + 32'h640, 32'h00060c00);
apb_write(OMC_APB_BASE_ADDR + 32'h644, 32'ha0030006);
apb_write(OMC_APB_BASE_ADDR + 32'h648, 32'h00000000);
apb_write(OMC_APB_BASE_ADDR + 32'h64c, 32'h00081306);
apb_write(OMC_APB_BASE_ADDR + 32'h650, 32'h04070304);
apb_write(OMC_APB_BASE_ADDR + 32'h654, 32'h00000404);
apb_write(OMC_APB_BASE_ADDR + 32'h658, 32'h00000060);
apb_write(OMC_APB_BASE_ADDR + 32'h65c, 32'h00020008);
apb_write(OMC_APB_BASE_ADDR + 32'h660, 32'h00000000);
apb_write(OMC_APB_BASE_ADDR + 32'h680, 32'h00000400);//DFI_timing
apb_write(OMC_APB_BASE_ADDR + 32'h684, 32'h02000202);
apb_write(OMC_APB_BASE_ADDR + 32'h688, 32'h04130409);
apb_write(OMC_APB_BASE_ADDR + 32'h68c, 32'h20002420);
apb_write(OMC_APB_BASE_ADDR + 32'h690, 32'h00140000);
apb_write(OMC_APB_BASE_ADDR + 32'h69c, 32'h01240074);
apb_write(OMC_APB_BASE_ADDR + 32'h6a0, 32'h03e80000);
apb_write(OMC_APB_BASE_ADDR + 32'h6a4, 32'h20240c00);
apb_write(OMC_APB_BASE_ADDR + 32'h6a8, 32'h00040000);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30010006);
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30020000);
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30030031);
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30160006);
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h514, 32'h00000000);//phymstr_ack_disable=0

apb_read(OMC_APB_BASE_ADDR + 32'h518, tmp);//wait for dfi_phymstr_ack=1
while((tmp & 32'h00000002) != 32'h00000002) begin
  orbit_usleep(1);
  apb_read(OMC_APB_BASE_ADDR + 32'h518, tmp);
end


apb_read(OMC_APB_BASE_ADDR + 32'h518, tmp);//wait for dfi_phymstr_ack=0
while((tmp & 32'h00000002) != 32'h00000000) begin
  orbit_usleep(1);
  apb_read(OMC_APB_BASE_ADDR + 32'h518, tmp);
end

apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd11 <<2), tmp);//`DENALI_PI_11_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd11 <<2), 32'h03000803);//set PI_CS_MAP=3
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd83 <<2), tmp);//`DENALI_PI_83_DATA //read PI_INT_STATUS=0be02001(lpddr4) is ok
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd84 <<2), tmp);//`DENALI_PI_84_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd84 <<2), 32'h00000000); //clear the associated bit in the pi_init_status to 0
//cdns_pi_en( 3);

apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd46 <<2), tmp);//`DENALI_PI_46_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd46 <<2), 32'h030f0000);//PI_RDLVL_GATE_CS_MAP=3
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd33 <<2), tmp);//`DENALI_PI_33_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd33 <<2), 32'h00000000);//PI_RDLVL_GATE_REQ=0(don't trigger gate training)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), tmp);//`DENALI_PI_44_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), 32'h01000000);//PI_RDLVL_GATE_ON_SREF_EXIT=0(disable automatic gate training sequence at sref exit)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), tmp);//`DENALI_PI_44_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), 32'h00000000);//PI_RDLVL_GATE_ON_DPDX=0(disable automatic gate training sequence at dpd exit)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd45 <<2), tmp);//`DENALI_PI_45_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd45 <<2), 32'h00000001);//PI_RDLVL_GATE_DISABLE_DFS=1(disable automatic gate training sequence on dfs)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd146 <<2), tmp);//`DENALI_PI_146_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd146 <<2), 32'h03011808);//PI_RDLVL_GATE_EN_F0=3(enable post-/initalization rdlvl gate training for frq set 0)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), tmp);//`DENALI_PI_147_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), 32'h01010301);//PI_RDLVL_GATE_EN_F1=3(enable post-/initalization rdlvl gate training for frq set 1)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), tmp);//`DENALI_PI_147_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), 32'h03010301);//PI_RDLVL_GATE_EN_F2=3(enable post-/initalization rdlvl gate training for frq set 2)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), tmp);//`DENALI_PI_44_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), 32'h00000100);//PI_RDLVL_GATE_PERIODIC=1(subsequent gate training is tuning orther than full training)
//cdns_rdlvl_gate_tr_init( 3,0,0,0,0);

apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd46 <<2), tmp);//`DENALI_PI_46_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd46 <<2), 32'h03030000);//PI_RDLVL_CS_MAP=3
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd33 <<2), tmp);//`DENALI_PI_33_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd33 <<2), 32'h00000000);//PI_RDLVL_REQ=0(don't trigger data eye training)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd43 <<2), tmp);//`DENALI_PI_43_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd43 <<2), 32'h01000000);//PI_RDLVL_ON_SREF_EXIT=0(disable automatic eye training sequence at sref exit)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd43 <<2), tmp);//`DENALI_PI_43_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd43 <<2), 32'h00000000);//PI_RDLVL_ON_DPDX=0(disable automatic data eye training sequence at dpd exit)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), tmp);//`DENALI_PI_44_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd44 <<2), 32'h00000101);//PI_RDLVL_DISABLE_DFS=1(disable automatic eye training sequence on dfs)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd146 <<2), tmp);//`DENALI_PI_146_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd146 <<2), 32'h03031808);//PI_RDLVL_EN_F0=3(enable post-/initalization rdlvl eye training for frq set 0)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), tmp);//`DENALI_PI_147_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), 32'h03010303);//PI_RDLVL_EN_F1=3(enable post-/initalization rdlvl eye training for frq set 1)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), tmp);//`DENALI_PI_147_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd147 <<2), 32'h03030303);//PI_RDLVL_EN_F2=3(enable post-/initalization rdlvl eye training for frq set 2)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd148 <<2), tmp);//`DENALI_PI_148_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd148 <<2), 32'h03170a0a);//PI_RDLVL_PAT0_EN_F0=3(post-/initalization dfi_lvl_pattern==0 used for frq set 0)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd149 <<2), tmp);//`DENALI_PI_149_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd149 <<2), 32'h03000000);//PI_RDLVL_PAT0_EN_F0=3(post-/initalization dfi_lvl_pattern==0 used for frq set 1)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd150 <<2), tmp);//`DENALI_PI_150_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd150 <<2), 32'h03000000);//PI_RDLVL_PAT0_EN_F0=3(post-/initalization dfi_lvl_pattern==0 used for frq set 2)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd43 <<2), tmp);//`DENALI_PI_43_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd43 <<2), 32'h00000100);//PI_RDLVL_PERIODIC=1(subsequent eye training is tuning orther than full training)
//cdns_rdlvl_tr_init( 3,0,0,0,0);

apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd67 <<2), tmp);//`DENALI_PI_67_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd67 <<2), 32'h01010300);//PI_WDQLVL_CS_MAP=3
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd68 <<2), tmp);//`DENALI_PI_68_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd68 <<2), 32'h34000000);//PI_WDQLVL_REQ=0(don't trigger write dq training)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd71 <<2), tmp);//`DENALI_PI_71_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd71 <<2), 32'h01000000);//PI_WDQLVL_ON_SREF_EXIT(disable automatic write dq training sequence at sref exit)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd71 <<2), tmp);//`DENALI_PI_71_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd71 <<2), 32'h00000000);//PI_WDQLVL_ON_DPDX(disable automatic write dq training sequence at dpd exit)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd72 <<2), tmp);//`DENALI_PI_72_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd72 <<2), 32'h00000100);//PI_WDQLVL_DISABLE_DFS=1(disable automatic eye training sequence on dfs)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd180 <<2), tmp);//`DENALI_PI_180_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd180 <<2), 32'h06000301);//PI_WDQLVL_EN_F0=3(enable post-/initalization write dq training for frq set 0)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd183 <<2), tmp);//`DENALI_PI_183_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd183 <<2), 32'h01000301);//PI_WDQLVL_EN_F1=3(enable post-/initalization write dq training for frq set 1)
apb_read(PHY_APB_BASE_ADDR + (16'd2048 +16'd186 <<2), tmp);//`DENALI_PI_186_DATA
apb_write(PHY_APB_BASE_ADDR + (16'd2048 +16'd186 <<2), 32'h13000301);//PI_WDQLVL_EN_F2=3(enable post-/initalization write dq training for frq set 2)
//cdns_wdqlvl_tr_init( 3,0,0,0,0);

apb_write(OMC_APB_BASE_ADDR + 32'h100, 32'h000000e0);//abr_en[7:5]
apb_write(OMC_APB_BASE_ADDR + 32'h620, 32'h04031d22);//tCKCKEH(tCKSRX)>=3,tCMDCKE>=3,tRPpb(tRP)>=29,tRPab(tRP)>=34
apb_write(OMC_APB_BASE_ADDR + 32'h624, 32'h0c18080c);//tCKE>=12,tSR(tCKESR)>=24,tCKELCK>=8,tXP>=12
apb_write(OMC_APB_BASE_ADDR + 32'h628, 32'h60440c9d);//tRC>=(60||63)/tCK,tRAS>=44,tRTP>=12,adv_al=1,tRCD>=0x1d
apb_write(OMC_APB_BASE_ADDR + 32'h62c, 32'h34271040);
apb_write(OMC_APB_BASE_ADDR + 32'h630, 32'h36231c0e);
apb_write(OMC_APB_BASE_ADDR + 32'h634, 32'h001e0000);
apb_write(OMC_APB_BASE_ADDR + 32'h638, 32'h20171708);
apb_write(OMC_APB_BASE_ADDR + 32'h63c, 32'h36420004);
apb_write(OMC_APB_BASE_ADDR + 32'h640, 32'h01cf2cd6);//tXSR>=0x1CC(287.5ns_8gibx16);tXP+tmrri?
apb_write(OMC_APB_BASE_ADDR + 32'h644, 32'h00e001c0);//tRFC>=0x230(350ns_8gib)
apb_write(OMC_APB_BASE_ADDR + 32'h648, 32'h00000000);//tXSDLL,tXSfast>=0x110(170ns_8gib)
apb_write(OMC_APB_BASE_ADDR + 32'h64c, 32'h000c351e);
apb_write(OMC_APB_BASE_ADDR + 32'h650, 32'h20664713);
apb_write(OMC_APB_BASE_ADDR + 32'h654, 32'h00002520);
apb_write(OMC_APB_BASE_ADDR + 32'h658, 32'h00000060);
apb_write(OMC_APB_BASE_ADDR + 32'h65c, 32'h00900030);
apb_write(OMC_APB_BASE_ADDR + 32'h660, 32'h00000000);
apb_write(OMC_APB_BASE_ADDR + 32'h680, 32'h16000416);//DFI_timing
apb_write(OMC_APB_BASE_ADDR + 32'h684, 32'h08000a04);
apb_write(OMC_APB_BASE_ADDR + 32'h688, 32'h0415040a);
apb_write(OMC_APB_BASE_ADDR + 32'h68c, 32'h20003320);
apb_write(OMC_APB_BASE_ADDR + 32'h690, 32'h00140000);
apb_write(OMC_APB_BASE_ADDR + 32'h69c, 32'h01240074);
apb_write(OMC_APB_BASE_ADDR + 32'h6a0, 32'h03e80000);
apb_write(OMC_APB_BASE_ADDR + 32'h6a4, 32'h20330c00);
apb_write(OMC_APB_BASE_ADDR + 32'h6a8, 32'h00040000);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30010056);//nWR=30,BL=on the fly
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h3002002d);//WL/RL for 1333M~1600M
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30030031);//PDDS=RZQ/6,PU-CAl=VDDQ/3(default)
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h4, 32'h30160006);//soc_ODT=RZQ/6
apb_write(OMC_APB_BASE_ADDR + 32'hc, 32'h00000002);
apb_write(OMC_APB_BASE_ADDR + 32'h410, 32'h00101010);//generation/urgent<->oldest request
apb_write(OMC_APB_BASE_ADDR + 32'h420, 32'h0c181006);
apb_write(OMC_APB_BASE_ADDR + 32'h424, 32'h20200820);
apb_write(OMC_APB_BASE_ADDR + 32'h428, 32'h80000020);
apb_write(OMC_APB_BASE_ADDR + 32'h0, 32'h00000001);//ignore_phy_rresp=0(Ignore dfi_rddata_valid from PHY,Only used in booting period);dram type=LPDDR4
apb_write(OMC_APB_BASE_ADDR + 32'h108, 32'h00003000);
apb_write(OMC_APB_BASE_ADDR + 32'h508, 32'h00000033);
apb_write(OMC_APB_BASE_ADDR + 32'h324, 32'h8000a000);//enable dynamic DRAM power down/self-refresh;aref_between_srefs
apb_write(OMC_APB_BASE_ADDR + 32'h104, 32'h90000000);//Enable auto-refresh;Opportunistic selection of target bank refresh to reduce bank confliction
apb_write(OMC_APB_BASE_ADDR + 32'h510, 32'h00000100);//Issue {num_phyupd_abr} number of all-bank-refresh commands before ac-knowledging phyupd_req.
apb_write(OMC_APB_BASE_ADDR + 32'h514, 32'h00000000);//phymstr_ack_disable=0
apb_write(OMC_SECURE_APB_BASE_ADDR + 32'h700, 32'h00000003);//CR_UPDATE_CTRL
apb_write(OMC_APB_BASE_ADDR + 32'h514, 32'h00000600);//Wait dfi_phymstr_* handshake after (POWER Gating mode/DFS completed) exited
apb_write(OMC_APB_BASE_ADDR + 32'h20, 32'h00000001);//DRAM_INIT_DONE
// Initialization done
