1 /*
2 * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <string.h>
8
9 #include <common/debug.h>
10
11 #include <ddrphy_phyinit.h>
12
13 /*
14 * This is used to initialize the PhyInit structures before user defaults and overrides are applied.
15 *
16 * @return Void
17 */
ddrphy_phyinit_initstruct(struct stm32mp_ddr_config * config,struct pmu_smb_ddr_1d * mb_ddr_1d)18 void ddrphy_phyinit_initstruct(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
19 {
20 /*
21 * ##############################################################
22 * Basic Message Block Variables
23 * ##############################################################
24 */
25
26 uint8_t msgmisc = 0x00U; /* For fast simulation */
27 uint8_t reserved00 = 0x0U; /*
28 * Set reserved00[7] = 1 (If using T28 attenuated receivers)
29 * Set reserved00[6:0] = 0 (Reserved; must be set to 0)
30 */
31
32 uint8_t hdtctrl = 0xFFU;
33 #if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
34 uint8_t cspresent = 0x01U; /*
35 * Indicates presence of DRAM at each chip select for PHY.
36 *
37 * If the bit is set to 1, the CS is connected to DRAM.
38 * If the bit is set to 0, the CS is not connected to DRAM.
39 *
40 * Set cspresent[0] = 1 (if CS0 is populated with DRAM)
41 * Set cspresent[1] = 1 (if CS1 is populated with DRAM)
42 * Set cspresent[2] = 1 (if CS2 is populated with DRAM)
43 * Set cspresent[3] = 1 (if CS3 is populated with DRAM)
44 * Set cspresent[7:4] = 0 (Reserved; must be set to 0)
45 */
46 uint8_t dfimrlmargin = 0x01U; /* 1 is typically good in DDR3 */
47 #if STM32MP_DDR3_TYPE
48 uint8_t addrmirror = 0x00U; /*
49 * Set addrmirror if CS is mirrored.
50 * (typically odd CS are mirroed in DIMMs)
51 */
52 #else /* STM32MP_DDR4_TYPE */
53 uint8_t addrmirror = 0xAAU;
54 #endif /* STM32MP_DDR3_TYPE */
55 uint8_t wrodtpat_rank0 = 0x01U; /*
56 * When Writing Rank0 : Bits[3:0] should be set to the
57 * desired setting of ODT[3:0] to the DRAM
58 */
59 uint8_t wrodtpat_rank1 = 0x02U; /*
60 * When Writing Rank1 : Bits[3:0] should be set to the
61 * desired setting of ODT[3:0] to the DRAM
62 */
63 #if STM32MP_DDR3_TYPE
64 uint8_t wrodtpat_rank2 = 0x04U; /*
65 * When Writing Rank2 : Bits[3:0] should be set to the
66 * desired setting of ODT[3:0] to the DRAM
67 */
68 uint8_t wrodtpat_rank3 = 0x08U; /*
69 * When Writing Rank3 : Bits[3:0] should be set to the
70 * desired setting of ODT[3:0] to the DRAM
71 */
72 #else /* STM32MP_DDR4_TYPE */
73 uint8_t wrodtpat_rank2 = 0x00U;
74 uint8_t wrodtpat_rank3 = 0x00U;
75 #endif /* STM32MP_DDR3_TYPE */
76 uint8_t rdodtpat_rank0 = 0x20U; /*
77 * When Reading Rank0 : Bits[7:4] should be set to the
78 * desired setting of ODT[3:0] to the DRAM
79 */
80 uint8_t rdodtpat_rank1 = 0x10U; /*
81 * When Reading Rank1 : Bits[7:4] should be set to the
82 * desired setting of ODT[3:0] to the DRAM
83 */
84 #if STM32MP_DDR3_TYPE
85 uint8_t rdodtpat_rank2 = 0x80U; /*
86 * When Reading Rank2 : Bits[7:4] should be set to the
87 * desired setting of ODT[3:0] to the DRAM
88 */
89 uint8_t rdodtpat_rank3 = 0x40U; /*
90 * When Reading Rank3 : Bits[7:4] should be set to the
91 * desired setting of ODT[3:0] to the DRAM
92 */
93 #else /* STM32MP_DDR4_TYPE */
94 uint8_t rdodtpat_rank2 = 0x00U;
95 uint8_t rdodtpat_rank3 = 0x00U;
96
97 uint8_t d4misc = 0x1U; /*
98 * Protect memory reset:
99 * 0x1 = dfi_reset_n cannot control BP_MEMRESERT_L to
100 * devices after training.
101 * 0x0 = dfi_resert_n can control BP_MEMRESERT_L to
102 * devices after training.
103 */
104 #endif /* STM32MP_DDR3_TYPE */
105 #else /* STM32MP_LPDDR4_TYPE */
106 uint8_t caterminatingrankcha = 0x00U; /* Usually Rank0 is terminating rank */
107 uint8_t caterminatingrankchb = 0x00U; /* Usually Rank0 is terminating rank */
108 uint8_t dfimrlmargin = 0x02U; /* This needs to be large enough for max tDQSCK variation */
109 #endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
110
111 #if STM32MP_DDR3_TYPE
112 uint8_t share2dvrefresult = 0x0U; /*
113 * Bitmap that controls which vref generator the
114 * phy will use per pstate
115 * If share2dvrefresult[x] = 1, pstate x will
116 * use the per-lane VrefDAC0/1 CSRs which can be
117 * trained by 2d training. If 2D has not run
118 * yet, VrefDAC0/1 will default to pstate 0's
119 * 1D phyVref messageBlock setting.
120 * If share2dvrefresult[x] = 0, pstate x will
121 * use the per-phy VrefInGlobal CSR, which are
122 * set to pstate x's 1D phyVref messageBlock
123 * setting.
124 */
125 #elif STM32MP_DDR4_TYPE
126 uint8_t share2dvrefresult = 0x1U;
127 #else /* STM32MP_LPDDR4_TYPE */
128 uint8_t share2dvrefresult = 0x1U;
129 uint8_t usebroadcastmr = 0x00U;
130 #endif /* STM32MP_DDR3_TYPE */
131
132 /* 1D message block defaults */
133 memset((void *)mb_ddr_1d, 0, sizeof(struct pmu_smb_ddr_1d));
134
135 mb_ddr_1d->pstate = 0U;
136 mb_ddr_1d->sequencectrl = (uint16_t)config->uia.sequencectrl;
137 mb_ddr_1d->phyconfigoverride = 0x0U;
138 mb_ddr_1d->hdtctrl = hdtctrl;
139 mb_ddr_1d->msgmisc = msgmisc;
140 mb_ddr_1d->reserved00 = reserved00;
141 mb_ddr_1d->dfimrlmargin = dfimrlmargin;
142 mb_ddr_1d->phyvref = (uint8_t)config->uia.phyvref;
143
144 #if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
145 mb_ddr_1d->cspresent = cspresent;
146 mb_ddr_1d->cspresentd0 = cspresent;
147 /* mb_ddr_1d->cspresentd1 = 0x0U; Unused */
148 mb_ddr_1d->addrmirror = addrmirror;
149
150 mb_ddr_1d->acsmodtctrl0 = wrodtpat_rank0 | rdodtpat_rank0;
151 mb_ddr_1d->acsmodtctrl1 = wrodtpat_rank1 | rdodtpat_rank1;
152 mb_ddr_1d->acsmodtctrl2 = wrodtpat_rank2 | rdodtpat_rank2;
153 mb_ddr_1d->acsmodtctrl3 = wrodtpat_rank3 | rdodtpat_rank3;
154
155 /* mb_ddr_1d->acsmodtctrl4 = 0x0U; Unused */
156 /* mb_ddr_1d->acsmodtctrl5 = 0x0U; Unused */
157 /* mb_ddr_1d->acsmodtctrl6 = 0x0U; Unused */
158 /* mb_ddr_1d->acsmodtctrl7 = 0x0U; Unused */
159 mb_ddr_1d->enableddqs = (uint8_t)((config->uib.numactivedbytedfi0 +
160 config->uib.numactivedbytedfi1) * 8U);
161 #if STM32MP_DDR3_TYPE
162 mb_ddr_1d->phycfg = (uint8_t)config->uia.is2ttiming;
163 #else /* STM32MP_DDR4_TYPE */
164 mb_ddr_1d->phycfg = ((config->uim.mr3 & 0x8U) == 0x8U) ?
165 0U : (uint8_t)config->uia.is2ttiming;
166 mb_ddr_1d->x16present = (config->uib.dramdatawidth == 0x10) ?
167 mb_ddr_1d->cspresent : 0x0U;
168 mb_ddr_1d->d4misc = d4misc;
169 mb_ddr_1d->cssetupgddec = 0x1U; /* If Geardown is chosen, dynamically modify CS timing */
170
171 /*
172 * Outputs - just initialize these to zero
173 * mb_ddr_1d->rtt_nom_wr_park<0..7>
174 */
175 #endif /* STM32MP_DDR3_TYPE */
176
177 mb_ddr_1d->mr0 = (uint16_t)config->uim.mr0;
178 mb_ddr_1d->mr1 = (uint16_t)config->uim.mr1;
179 mb_ddr_1d->mr2 = (uint16_t)config->uim.mr2;
180 #if STM32MP_DDR4_TYPE
181 mb_ddr_1d->mr3 = (uint16_t)config->uim.mr3;
182 mb_ddr_1d->mr4 = (uint16_t)config->uim.mr4;
183 mb_ddr_1d->mr5 = (uint16_t)config->uim.mr5;
184 mb_ddr_1d->mr6 = (uint16_t)config->uim.mr6;
185
186 mb_ddr_1d->alt_cas_l = 0x0U;
187 mb_ddr_1d->alt_wcas_l = 0x0U;
188
189 /*
190 * Outputs - just initialize these to zero
191 * mb_ddr_1d->vrefdqr<0..3>nib<0..19>
192 */
193 #endif /* STM32MP_DDR4_TYPE */
194 #else /* STM32MP_LPDDR4_TYPE */
195 mb_ddr_1d->enableddqscha = (uint8_t)(config->uib.numactivedbytedfi0 * 8U);
196 mb_ddr_1d->cspresentcha = (config->uib.numrank_dfi0 == 2U) ?
197 0x3U : (uint8_t)config->uib.numrank_dfi0;
198 mb_ddr_1d->enableddqschb = (uint8_t)(config->uib.numactivedbytedfi1 * 8U);
199 mb_ddr_1d->cspresentchb = (config->uib.numrank_dfi1 == 2U) ?
200 0x3U : (uint8_t)config->uib.numrank_dfi1;
201 mb_ddr_1d->usebroadcastmr = usebroadcastmr;
202
203 mb_ddr_1d->lp4misc = 0x00U;
204 mb_ddr_1d->caterminatingrankcha = caterminatingrankcha;
205 mb_ddr_1d->caterminatingrankchb = caterminatingrankchb;
206 mb_ddr_1d->lp4quickboot = 0x00U;
207 mb_ddr_1d->catrainopt = 0x00U;
208 mb_ddr_1d->x8mode = 0x00U;
209
210 mb_ddr_1d->mr1_a0 = (uint8_t)config->uim.mr1;
211 mb_ddr_1d->mr2_a0 = (uint8_t)config->uim.mr2;
212 mb_ddr_1d->mr3_a0 = (uint8_t)config->uim.mr3;
213 mb_ddr_1d->mr4_a0 = (uint8_t)config->uim.mr4;
214 mb_ddr_1d->mr11_a0 = (uint8_t)config->uim.mr11;
215 mb_ddr_1d->mr12_a0 = (uint8_t)config->uim.mr12;
216 mb_ddr_1d->mr13_a0 = (uint8_t)config->uim.mr13;
217 mb_ddr_1d->mr14_a0 = (uint8_t)config->uim.mr14;
218 mb_ddr_1d->mr16_a0 = 0x00U;
219 mb_ddr_1d->mr17_a0 = 0x00U;
220 mb_ddr_1d->mr22_a0 = (uint8_t)config->uim.mr22;
221 mb_ddr_1d->mr24_a0 = 0x00U;
222 mb_ddr_1d->mr1_a1 = (uint8_t)config->uim.mr1;
223 mb_ddr_1d->mr2_a1 = (uint8_t)config->uim.mr2;
224 mb_ddr_1d->mr3_a1 = (uint8_t)config->uim.mr3;
225 mb_ddr_1d->mr4_a1 = (uint8_t)config->uim.mr4;
226 mb_ddr_1d->mr11_a1 = (uint8_t)config->uim.mr11;
227 mb_ddr_1d->mr12_a1 = (uint8_t)config->uim.mr12;
228 mb_ddr_1d->mr13_a1 = (uint8_t)config->uim.mr13;
229 mb_ddr_1d->mr14_a1 = (uint8_t)config->uim.mr14;
230 mb_ddr_1d->mr16_a1 = 0x00U;
231 mb_ddr_1d->mr17_a1 = 0x00U;
232 mb_ddr_1d->mr22_a1 = (uint8_t)config->uim.mr22;
233 mb_ddr_1d->mr24_a1 = 0x00U;
234
235 mb_ddr_1d->mr1_b0 = (uint8_t)config->uim.mr1;
236 mb_ddr_1d->mr2_b0 = (uint8_t)config->uim.mr2;
237 mb_ddr_1d->mr3_b0 = (uint8_t)config->uim.mr3;
238 mb_ddr_1d->mr4_b0 = (uint8_t)config->uim.mr4;
239 mb_ddr_1d->mr11_b0 = (uint8_t)config->uim.mr11;
240 mb_ddr_1d->mr12_b0 = (uint8_t)config->uim.mr12;
241 mb_ddr_1d->mr13_b0 = (uint8_t)config->uim.mr13;
242 mb_ddr_1d->mr14_b0 = (uint8_t)config->uim.mr14;
243 mb_ddr_1d->mr16_b0 = 0x00U;
244 mb_ddr_1d->mr17_b0 = 0x00U;
245 mb_ddr_1d->mr22_b0 = (uint8_t)config->uim.mr22;
246 mb_ddr_1d->mr24_b0 = 0x00U;
247 mb_ddr_1d->mr1_b1 = (uint8_t)config->uim.mr1;
248 mb_ddr_1d->mr2_b1 = (uint8_t)config->uim.mr2;
249 mb_ddr_1d->mr3_b1 = (uint8_t)config->uim.mr3;
250 mb_ddr_1d->mr4_b1 = (uint8_t)config->uim.mr4;
251 mb_ddr_1d->mr11_b1 = (uint8_t)config->uim.mr11;
252 mb_ddr_1d->mr12_b1 = (uint8_t)config->uim.mr12;
253 mb_ddr_1d->mr13_b1 = (uint8_t)config->uim.mr13;
254 mb_ddr_1d->mr14_b1 = (uint8_t)config->uim.mr14;
255 mb_ddr_1d->mr16_b1 = 0x00U;
256 mb_ddr_1d->mr17_b1 = 0x00U;
257 mb_ddr_1d->mr22_b1 = (uint8_t)config->uim.mr22;
258 mb_ddr_1d->mr24_b1 = 0x00U;
259 #endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
260
261 mb_ddr_1d->share2dvrefresult = share2dvrefresult;
262 }
263