• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2018-2019 NXP
4  */
5 
6 #include <common.h>
7 #include <errno.h>
8 #include <asm/io.h>
9 #include <asm/arch/ddr.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/sys_proto.h>
12 
ddr_cfg_umctl2(struct dram_cfg_param * ddrc_cfg,int num)13 void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
14 {
15 	int i = 0;
16 
17 	for (i = 0; i < num; i++) {
18 		reg32_write(ddrc_cfg->reg, ddrc_cfg->val);
19 		ddrc_cfg++;
20 	}
21 }
22 
ddr_init(struct dram_timing_info * dram_timing)23 void ddr_init(struct dram_timing_info *dram_timing)
24 {
25 	unsigned int tmp, initial_drate, target_freq;
26 
27 	debug("DDRINFO: start DRAM init\n");
28 
29 	/* Step1: Follow the power up procedure */
30 	if (is_imx8mq()) {
31 		reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F00000F);
32 		reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
33 		reg32_write(SRC_DDRC_RCR_ADDR + 0x04, 0x8F000000);
34 	} else {
35 		reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00001F);
36 		reg32_write(SRC_DDRC_RCR_ADDR, 0x8F00000F);
37 	}
38 
39 	debug("DDRINFO: cfg clk\n");
40 	/* change the clock source of dram_apb_clk_root: source 4 800MHz /4 = 200MHz */
41 	clock_set_target_val(DRAM_APB_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(4) |
42 			     CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV4));
43 
44 	/* disable iso */
45 	reg32_write(0x303A00EC, 0x0000ffff); /* PGC_CPU_MAPPING */
46 	reg32setbit(0x303A00F8, 5); /* PU_PGC_SW_PUP_REQ */
47 
48 	initial_drate = dram_timing->fsp_msg[0].drate;
49 	/* default to the frequency point 0 clock */
50 	ddrphy_init_set_dfi_clk(initial_drate);
51 
52 	/* D-aasert the presetn */
53 	reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000006);
54 
55 	/* Step2: Program the dwc_ddr_umctl2 registers */
56 	debug("DDRINFO: ddrc config start\n");
57 	ddr_cfg_umctl2(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num);
58 	debug("DDRINFO: ddrc config done\n");
59 
60 	/* Step3: De-assert reset signal(core_ddrc_rstn & aresetn_n) */
61 	reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000004);
62 	reg32_write(SRC_DDRC_RCR_ADDR, 0x8F000000);
63 
64 	/*
65 	 * Step4: Disable auto-refreshes, self-refresh, powerdown, and
66 	 * assertion of dfi_dram_clk_disable by setting RFSHCTL3.dis_auto_refresh = 1,
67 	 * PWRCTL.powerdown_en = 0, and PWRCTL.selfref_en = 0, PWRCTL.en_dfi_dram_clk_disable = 0
68 	 */
69 	reg32_write(DDRC_DBG1(0), 0x00000000);
70 	reg32_write(DDRC_RFSHCTL3(0), 0x0000001);
71 	reg32_write(DDRC_PWRCTL(0), 0xa0);
72 
73 	/* if ddr type is LPDDR4, do it */
74 	tmp = reg32_read(DDRC_MSTR(0));
75 	if (tmp & (0x1 << 5))
76 		reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */
77 
78 	/* determine the initial boot frequency */
79 	target_freq = reg32_read(DDRC_MSTR2(0)) & 0x3;
80 	target_freq = (tmp & (0x1 << 29)) ? target_freq : 0x0;
81 
82 	/* Step5: Set SWCT.sw_done to 0 */
83 	reg32_write(DDRC_SWCTL(0), 0x00000000);
84 
85 	/* Set the default boot frequency point */
86 	clrsetbits_le32(DDRC_DFIMISC(0), (0x1f << 8), target_freq << 8);
87 	/* Step6: Set DFIMISC.dfi_init_complete_en to 0 */
88 	clrbits_le32(DDRC_DFIMISC(0), 0x1);
89 
90 	/* Step7: Set SWCTL.sw_done to 1; need to polling SWSTAT.sw_done_ack */
91 	reg32_write(DDRC_SWCTL(0), 0x00000001);
92 	do {
93 		tmp = reg32_read(DDRC_SWSTAT(0));
94 	} while ((tmp & 0x1) == 0x0);
95 
96 	/*
97 	 * Step8 ~ Step13: Start PHY initialization and training by
98 	 * accessing relevant PUB registers
99 	 */
100 	debug("DDRINFO:ddrphy config start\n");
101 	ddr_cfg_phy(dram_timing);
102 	debug("DDRINFO: ddrphy config done\n");
103 
104 	/*
105 	 * step14 CalBusy.0 =1, indicates the calibrator is actively
106 	 * calibrating. Wait Calibrating done.
107 	 */
108 	do {
109 		tmp = reg32_read(DDRPHY_CalBusy(0));
110 	} while ((tmp & 0x1));
111 
112 	debug("DDRINFO:ddrphy calibration done\n");
113 
114 	/* Step15: Set SWCTL.sw_done to 0 */
115 	reg32_write(DDRC_SWCTL(0), 0x00000000);
116 
117 	/* Step16: Set DFIMISC.dfi_init_start to 1 */
118 	setbits_le32(DDRC_DFIMISC(0), (0x1 << 5));
119 
120 	/* Step17: Set SWCTL.sw_done to 1; need to polling SWSTAT.sw_done_ack */
121 	reg32_write(DDRC_SWCTL(0), 0x00000001);
122 	do {
123 		tmp = reg32_read(DDRC_SWSTAT(0));
124 	} while ((tmp & 0x1) == 0x0);
125 
126 	/* Step18: Polling DFISTAT.dfi_init_complete = 1 */
127 	do {
128 		tmp = reg32_read(DDRC_DFISTAT(0));
129 	} while ((tmp & 0x1) == 0x0);
130 
131 	/* Step19: Set SWCTL.sw_done to 0 */
132 	reg32_write(DDRC_SWCTL(0), 0x00000000);
133 
134 	/* Step20: Set DFIMISC.dfi_init_start to 0 */
135 	clrbits_le32(DDRC_DFIMISC(0), (0x1 << 5));
136 
137 	/* Step21: optional */
138 
139 	/* Step22: Set DFIMISC.dfi_init_complete_en to 1 */
140 	setbits_le32(DDRC_DFIMISC(0), 0x1);
141 
142 	/* Step23: Set PWRCTL.selfref_sw to 0 */
143 	clrbits_le32(DDRC_PWRCTL(0), (0x1 << 5));
144 
145 	/* Step24: Set SWCTL.sw_done to 1; need polling SWSTAT.sw_done_ack */
146 	reg32_write(DDRC_SWCTL(0), 0x00000001);
147 	do {
148 		tmp = reg32_read(DDRC_SWSTAT(0));
149 	} while ((tmp & 0x1) == 0x0);
150 
151 	/* Step25: Wait for dwc_ddr_umctl2 to move to normal operating mode by monitoring
152 	 * STAT.operating_mode signal */
153 	do {
154 		tmp = reg32_read(DDRC_STAT(0));
155 	} while ((tmp & 0x3) != 0x1);
156 
157 	/* Step26: Set back register in Step4 to the original values if desired */
158 	reg32_write(DDRC_RFSHCTL3(0), 0x0000000);
159 	/* enable selfref_en by default */
160 	setbits_le32(DDRC_PWRCTL(0), 0x1 << 3);
161 
162 	/* enable port 0 */
163 	reg32_write(DDRC_PCTRL_0(0), 0x00000001);
164 	debug("DDRINFO: ddrmix config done\n");
165 
166 	/* save the dram timing config into memory */
167 	dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE);
168 }
169