Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/modules/hekate_libsys_minerva/sys_sdrammtc.c
3694 views
1
/*
2
* Minerva Training Cell
3
* DRAM Training for Tegra X1 SoC. Supports LPDDR4.
4
*
5
* Copyright (c) 2018-2025 CTCaer <[email protected]>
6
*
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms and conditions of the GNU General Public License,
9
* version 2, as published by the Free Software Foundation.
10
*
11
* This program is distributed in the hope it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
* more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include <string.h>
21
#include <stdlib.h>
22
#include "mtc.h"
23
#include "mtc_mc_emc_regs.h"
24
#include "mtc_switch_tables.h"
25
#include "types.h"
26
#include <module.h>
27
28
#define DVFS_T21X_CC_VERSION "Minerva Training Cell v0.2_T21X"
29
#define DVFS_T210_CC_VERSION "Minerva Training Cell v1.6_T210"
30
31
#define EPRINTF(...)
32
#define EPRINTFARGS(...)
33
34
bool train_ram_patterns;
35
36
/*
37
* REF: PLL Input reference (OSC_FREQ).
38
* DIVN: PLL feedback divider.
39
* DIVM: PLL input divider.
40
* DIVP: PLL post divider.
41
* PLL_OUT = (REF / DIVM) * DIVN / DIVP
42
*
43
* DIVP | DIVP
44
* Encoded | Real
45
* ----------------------
46
* 0 | 1 (DIVP off)
47
* 1 | 2
48
* 2 | 3
49
* 3 | 4
50
* 4 | 5
51
* 5 | 6
52
* 6 | 8
53
* 7 | 10
54
* 8 | 12
55
* 9 | 16
56
* 10 | 12
57
* 11 | 16
58
* 12 | 20
59
* 13 | 24
60
* 14 | 32
61
*/
62
static pllm_clk_config_t pllm_clk_config_table[] =
63
{
64
// pll_osc_in, pll_out, pll_feedback_div, pll_input_div, pll_post_div.
65
// f_in, f_out, n, m, p.
66
// f_out = ((f_in / m) * n) / p. Example: 1600000 = (38400 / 2) * 97.
67
{38400, 297600, 93, 4, 2},
68
{38400, 400000, 125, 4, 2},
69
{38400, 408000, 85, 4, 1},
70
{38400, 532800, 111, 4, 1},
71
{38400, 665600, 104, 3, 1},
72
{38400, 800000, 125, 3, 1},
73
{38400, 931200, 97, 4, 0},
74
{38400, 1065600, 111, 4, 0},
75
{38400, 1200000, 125, 4, 0},
76
{38400, 1331200, 104, 3, 0},
77
{38400, 1459200, 76, 2, 0},
78
{38400, 1600000, 125, 3, 0},
79
{38400, 1728000, 90, 2, 0}, // Custom. Normalized 1733 MHz.
80
{38400, 1795200, 187, 4, 0}, // Custom. Normalized 1800 MHz.
81
{38400, 1862400, 97, 2, 0}, // JEDEC Standard. (T210 official max).
82
{38400, 1894400, 148, 3, 0}, // Custom. Normalized 1900 MHz.
83
{38400, 1932800, 151, 3, 0}, // Custom. Normalized 1933 MHz.
84
{38400, 1958400, 102, 2, 0}, // Custom. Normalized 1966 MHz.
85
{38400, 1996800, 104, 2, 0}, // Custom. Normalized 2000 MHz.
86
{38400, 2035200, 106, 2, 0}, // Custom. Normalized 2033 MHz.
87
{38400, 2064000, 215, 4, 0}, // Custom. Normalized 2066 MHz.
88
{38400, 2099200, 164, 3, 0}, // Custom. Normalized 2100 MHz.
89
{38400, 2131200, 111, 2, 0}, // JEDEC Standard. (T210B01 official max).
90
{38400, 2163200, 169, 3, 0}, // Custom. Normalized 2166 MHz.
91
{38400, 2188800, 114, 2, 0}, // Custom. Normalized 2200 MHz.
92
{38400, 2227200, 116, 2, 0}, // Custom. Normalized 2233 MHz.
93
{38400, 2265600, 118, 2, 0}, // Custom. Normalized 2266 MHz.
94
{38400, 2291200, 179, 3, 0}, // Custom. Normalized 2300 MHz.
95
{38400, 2329600, 182, 3, 0}, // Custom. Normalized 2333 MHz.
96
{38400, 2361600, 123, 2, 0}, // Custom. Normalized 2366 MHz.
97
{0, 0, 0, 0, 0}
98
};
99
100
static const u32 burst_regs_emc_addr_table[221] = {
101
EMC_RC,
102
EMC_RFC,
103
EMC_RFCPB,
104
EMC_REFCTRL2,
105
EMC_RFC_SLR,
106
EMC_RAS,
107
EMC_RP,
108
EMC_R2W,
109
EMC_W2R,
110
EMC_R2P,
111
EMC_W2P,
112
EMC_R2R,
113
EMC_TPPD,
114
EMC_CCDMW,
115
EMC_RD_RCD,
116
EMC_WR_RCD,
117
EMC_RRD,
118
EMC_REXT,
119
EMC_WEXT,
120
EMC_WDV_CHK,
121
EMC_WDV,
122
EMC_WSV,
123
EMC_WEV,
124
EMC_WDV_MASK,
125
EMC_WS_DURATION,
126
EMC_WE_DURATION,
127
EMC_QUSE,
128
EMC_QUSE_WIDTH,
129
EMC_IBDLY,
130
EMC_OBDLY,
131
EMC_EINPUT,
132
EMC_MRW6,
133
EMC_EINPUT_DURATION,
134
EMC_PUTERM_EXTRA,
135
EMC_PUTERM_WIDTH,
136
EMC_QRST,
137
EMC_QSAFE,
138
EMC_RDV,
139
EMC_RDV_MASK,
140
EMC_RDV_EARLY,
141
EMC_RDV_EARLY_MASK,
142
EMC_REFRESH,
143
EMC_BURST_REFRESH_NUM,
144
EMC_PRE_REFRESH_REQ_CNT,
145
EMC_PDEX2WR,
146
EMC_PDEX2RD,
147
EMC_PCHG2PDEN,
148
EMC_ACT2PDEN,
149
EMC_AR2PDEN,
150
EMC_RW2PDEN,
151
EMC_CKE2PDEN,
152
EMC_PDEX2CKE,
153
EMC_PDEX2MRR,
154
EMC_TXSR,
155
EMC_TXSRDLL,
156
EMC_TCKE,
157
EMC_TCKESR,
158
EMC_TPD,
159
EMC_TFAW,
160
EMC_TRPAB,
161
EMC_TCLKSTABLE,
162
EMC_TCLKSTOP,
163
EMC_MRW7,
164
EMC_TREFBW,
165
EMC_ODT_WRITE,
166
EMC_FBIO_CFG5,
167
EMC_FBIO_CFG7,
168
EMC_CFG_DIG_DLL,
169
EMC_CFG_DIG_DLL_PERIOD,
170
EMC_PMACRO_IB_RXRT,
171
EMC_CFG_PIPE_1,
172
EMC_CFG_PIPE_2,
173
EMC_PMACRO_QUSE_DDLL_RANK0_4,
174
EMC_PMACRO_QUSE_DDLL_RANK0_5,
175
EMC_PMACRO_QUSE_DDLL_RANK1_4,
176
EMC_PMACRO_QUSE_DDLL_RANK1_5,
177
EMC_MRW8,
178
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_4,
179
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_5,
180
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_0,
181
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_1,
182
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_2,
183
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_3,
184
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_4,
185
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK0_5,
186
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_0,
187
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_1,
188
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_2,
189
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_3,
190
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_4,
191
EMC_PMACRO_OB_DDLL_LONG_DQS_RANK1_5,
192
EMC_PMACRO_DDLL_LONG_CMD_0,
193
EMC_PMACRO_DDLL_LONG_CMD_1,
194
EMC_PMACRO_DDLL_LONG_CMD_2,
195
EMC_PMACRO_DDLL_LONG_CMD_3,
196
EMC_PMACRO_DDLL_LONG_CMD_4,
197
EMC_PMACRO_DDLL_SHORT_CMD_0,
198
EMC_PMACRO_DDLL_SHORT_CMD_1,
199
EMC_PMACRO_DDLL_SHORT_CMD_2,
200
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_3,
201
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_3,
202
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_3,
203
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_3,
204
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_3,
205
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_3,
206
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_3,
207
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_3,
208
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_3,
209
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_3,
210
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_3,
211
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_3,
212
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_3,
213
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_3,
214
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_3,
215
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_3,
216
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_3,
217
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_3,
218
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_3,
219
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_3,
220
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_0,
221
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_1,
222
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_2,
223
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD0_3,
224
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_0,
225
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_1,
226
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_2,
227
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD1_3,
228
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_0,
229
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_1,
230
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_2,
231
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD2_3,
232
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_0,
233
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_1,
234
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_2,
235
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_CMD3_3,
236
EMC_TXDSRVTTGEN,
237
EMC_FDPD_CTRL_DQ,
238
EMC_FDPD_CTRL_CMD,
239
EMC_FBIO_SPARE,
240
EMC_ZCAL_INTERVAL,
241
EMC_ZCAL_WAIT_CNT,
242
EMC_MRS_WAIT_CNT,
243
EMC_MRS_WAIT_CNT2,
244
EMC_AUTO_CAL_CHANNEL,
245
EMC_DLL_CFG_0,
246
EMC_DLL_CFG_1,
247
EMC_PMACRO_AUTOCAL_CFG_COMMON,
248
EMC_PMACRO_ZCTRL,
249
EMC_CFG,
250
EMC_CFG_PIPE,
251
EMC_DYN_SELF_REF_CONTROL,
252
EMC_QPOP,
253
EMC_DQS_BRLSHFT_0,
254
EMC_DQS_BRLSHFT_1,
255
EMC_CMD_BRLSHFT_2,
256
EMC_CMD_BRLSHFT_3,
257
EMC_PMACRO_PAD_CFG_CTRL,
258
EMC_PMACRO_DATA_PAD_RX_CTRL,
259
EMC_PMACRO_CMD_PAD_RX_CTRL,
260
EMC_PMACRO_DATA_RX_TERM_MODE,
261
EMC_PMACRO_CMD_RX_TERM_MODE,
262
EMC_PMACRO_CMD_PAD_TX_CTRL,
263
EMC_PMACRO_DATA_PAD_TX_CTRL,
264
EMC_PMACRO_COMMON_PAD_TX_CTRL,
265
EMC_PMACRO_VTTGEN_CTRL_0,
266
EMC_PMACRO_VTTGEN_CTRL_1,
267
EMC_PMACRO_VTTGEN_CTRL_2,
268
EMC_PMACRO_BRICK_CTRL_RFU1,
269
EMC_PMACRO_CMD_BRICK_CTRL_FDPD,
270
EMC_PMACRO_BRICK_CTRL_RFU2,
271
EMC_PMACRO_DATA_BRICK_CTRL_FDPD,
272
EMC_PMACRO_BG_BIAS_CTRL_0,
273
EMC_CFG_3,
274
EMC_PMACRO_TX_PWRD_0,
275
EMC_PMACRO_TX_PWRD_1,
276
EMC_PMACRO_TX_PWRD_2,
277
EMC_PMACRO_TX_PWRD_3,
278
EMC_PMACRO_TX_PWRD_4,
279
EMC_PMACRO_TX_PWRD_5,
280
EMC_CONFIG_SAMPLE_DELAY,
281
EMC_PMACRO_TX_SEL_CLK_SRC_0,
282
EMC_PMACRO_TX_SEL_CLK_SRC_1,
283
EMC_PMACRO_TX_SEL_CLK_SRC_2,
284
EMC_PMACRO_TX_SEL_CLK_SRC_3,
285
EMC_PMACRO_TX_SEL_CLK_SRC_4,
286
EMC_PMACRO_TX_SEL_CLK_SRC_5,
287
EMC_PMACRO_DDLL_BYPASS,
288
EMC_PMACRO_DDLL_PWRD_0,
289
EMC_PMACRO_DDLL_PWRD_1,
290
EMC_PMACRO_DDLL_PWRD_2,
291
EMC_PMACRO_CMD_CTRL_0,
292
EMC_PMACRO_CMD_CTRL_1,
293
EMC_PMACRO_CMD_CTRL_2,
294
EMC_TR_TIMING_0,
295
EMC_TR_DVFS,
296
EMC_TR_CTRL_1,
297
EMC_TR_RDV,
298
EMC_TR_QPOP,
299
EMC_TR_RDV_MASK,
300
EMC_MRW14,
301
EMC_TR_QSAFE,
302
EMC_TR_QRST,
303
EMC_TRAINING_CTRL,
304
EMC_TRAINING_SETTLE,
305
EMC_TRAINING_VREF_SETTLE,
306
EMC_TRAINING_CA_FINE_CTRL,
307
EMC_TRAINING_CA_CTRL_MISC,
308
EMC_TRAINING_CA_CTRL_MISC1,
309
EMC_TRAINING_CA_VREF_CTRL,
310
EMC_TRAINING_QUSE_CORS_CTRL,
311
EMC_TRAINING_QUSE_FINE_CTRL,
312
EMC_TRAINING_QUSE_CTRL_MISC,
313
EMC_TRAINING_QUSE_VREF_CTRL,
314
EMC_TRAINING_READ_FINE_CTRL,
315
EMC_TRAINING_READ_CTRL_MISC,
316
EMC_TRAINING_READ_VREF_CTRL,
317
EMC_TRAINING_WRITE_FINE_CTRL,
318
EMC_TRAINING_WRITE_CTRL_MISC,
319
EMC_TRAINING_WRITE_VREF_CTRL,
320
EMC_TRAINING_MPC,
321
EMC_MRW15
322
};
323
324
static const u32 burst_reg_per_ch_emc01_addr_table[8] = {
325
EMC0_MRW10,
326
EMC1_MRW10,
327
EMC0_MRW11,
328
EMC1_MRW11,
329
EMC0_MRW12,
330
EMC1_MRW12,
331
EMC0_MRW13,
332
EMC1_MRW13
333
};
334
335
static const u32 vref_perch_regs_emc01_addr_table[4] = {
336
EMC0_TRAINING_OPT_DQS_IB_VREF_RANK0,
337
EMC1_TRAINING_OPT_DQS_IB_VREF_RANK0,
338
EMC0_TRAINING_OPT_DQS_IB_VREF_RANK1,
339
EMC1_TRAINING_OPT_DQS_IB_VREF_RANK1
340
};
341
342
static const u32 training_mod_regs_emc01_addr_table[20] = {
343
EMC0_TRAINING_RW_OFFSET_IB_BYTE0,
344
EMC1_TRAINING_RW_OFFSET_IB_BYTE0,
345
EMC0_TRAINING_RW_OFFSET_IB_BYTE1,
346
EMC1_TRAINING_RW_OFFSET_IB_BYTE1,
347
EMC0_TRAINING_RW_OFFSET_IB_BYTE2,
348
EMC1_TRAINING_RW_OFFSET_IB_BYTE2,
349
EMC0_TRAINING_RW_OFFSET_IB_BYTE3,
350
EMC1_TRAINING_RW_OFFSET_IB_BYTE3,
351
EMC0_TRAINING_RW_OFFSET_IB_MISC,
352
EMC1_TRAINING_RW_OFFSET_IB_MISC,
353
EMC0_TRAINING_RW_OFFSET_OB_BYTE0,
354
EMC1_TRAINING_RW_OFFSET_OB_BYTE0,
355
EMC0_TRAINING_RW_OFFSET_OB_BYTE1,
356
EMC1_TRAINING_RW_OFFSET_OB_BYTE1,
357
EMC0_TRAINING_RW_OFFSET_OB_BYTE2,
358
EMC1_TRAINING_RW_OFFSET_OB_BYTE2,
359
EMC0_TRAINING_RW_OFFSET_OB_BYTE3,
360
EMC1_TRAINING_RW_OFFSET_OB_BYTE3,
361
EMC0_TRAINING_RW_OFFSET_OB_MISC,
362
EMC1_TRAINING_RW_OFFSET_OB_MISC
363
};
364
365
static const u32 trim_regs_emc_addr_table[138] = {
366
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0,
367
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1,
368
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2,
369
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3,
370
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0,
371
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1,
372
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2,
373
EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3,
374
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0,
375
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1,
376
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2,
377
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0,
378
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1,
379
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2,
380
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0,
381
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1,
382
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2,
383
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0,
384
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1,
385
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2,
386
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0,
387
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1,
388
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2,
389
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0,
390
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1,
391
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2,
392
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0,
393
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1,
394
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2,
395
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0,
396
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1,
397
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2,
398
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0,
399
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1,
400
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2,
401
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0,
402
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1,
403
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2,
404
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0,
405
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1,
406
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2,
407
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0,
408
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1,
409
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2,
410
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0,
411
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1,
412
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2,
413
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0,
414
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1,
415
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2,
416
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0,
417
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1,
418
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2,
419
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0,
420
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1,
421
EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2,
422
EMC_PMACRO_IB_VREF_DQS_0,
423
EMC_PMACRO_IB_VREF_DQS_1,
424
EMC_PMACRO_IB_VREF_DQ_0,
425
EMC_PMACRO_IB_VREF_DQ_1,
426
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,
427
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,
428
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2,
429
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3,
430
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4,
431
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5,
432
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0,
433
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1,
434
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2,
435
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3,
436
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0,
437
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1,
438
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2,
439
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0,
440
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1,
441
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2,
442
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0,
443
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1,
444
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2,
445
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0,
446
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1,
447
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2,
448
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0,
449
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1,
450
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2,
451
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0,
452
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1,
453
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2,
454
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0,
455
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1,
456
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2,
457
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0,
458
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1,
459
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2,
460
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0,
461
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1,
462
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2,
463
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0,
464
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1,
465
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2,
466
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0,
467
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1,
468
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2,
469
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0,
470
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1,
471
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2,
472
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0,
473
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1,
474
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2,
475
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0,
476
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1,
477
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2,
478
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0,
479
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1,
480
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2,
481
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0,
482
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1,
483
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2,
484
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0,
485
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1,
486
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2,
487
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0,
488
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1,
489
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2,
490
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0,
491
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1,
492
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2,
493
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0,
494
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1,
495
EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2,
496
EMC_PMACRO_QUSE_DDLL_RANK0_0,
497
EMC_PMACRO_QUSE_DDLL_RANK0_1,
498
EMC_PMACRO_QUSE_DDLL_RANK0_2,
499
EMC_PMACRO_QUSE_DDLL_RANK0_3,
500
EMC_PMACRO_QUSE_DDLL_RANK1_0,
501
EMC_PMACRO_QUSE_DDLL_RANK1_1,
502
EMC_PMACRO_QUSE_DDLL_RANK1_2,
503
EMC_PMACRO_QUSE_DDLL_RANK1_3
504
};
505
506
static const u32 trim_perch_regs_emc01_addr_table[10] = {
507
EMC0_CMD_BRLSHFT_0,
508
EMC1_CMD_BRLSHFT_1,
509
EMC0_DATA_BRLSHFT_0,
510
EMC1_DATA_BRLSHFT_0,
511
EMC0_DATA_BRLSHFT_1,
512
EMC1_DATA_BRLSHFT_1,
513
EMC0_QUSE_BRLSHFT_0,
514
EMC1_QUSE_BRLSHFT_1,
515
EMC0_QUSE_BRLSHFT_2,
516
EMC1_QUSE_BRLSHFT_3
517
};
518
519
static const u32 burst_mc_regs_addr_table[33] = {
520
MC_EMEM_ARB_CFG,
521
MC_EMEM_ARB_OUTSTANDING_REQ,
522
MC_EMEM_ARB_REFPB_HP_CTRL,
523
MC_EMEM_ARB_REFPB_BANK_CTRL,
524
MC_EMEM_ARB_TIMING_RCD,
525
MC_EMEM_ARB_TIMING_RP,
526
MC_EMEM_ARB_TIMING_RC,
527
MC_EMEM_ARB_TIMING_RAS,
528
MC_EMEM_ARB_TIMING_FAW,
529
MC_EMEM_ARB_TIMING_RRD,
530
MC_EMEM_ARB_TIMING_RAP2PRE,
531
MC_EMEM_ARB_TIMING_WAP2PRE,
532
MC_EMEM_ARB_TIMING_R2R,
533
MC_EMEM_ARB_TIMING_W2W,
534
MC_EMEM_ARB_TIMING_R2W,
535
MC_EMEM_ARB_TIMING_CCDMW,
536
MC_EMEM_ARB_TIMING_W2R,
537
MC_EMEM_ARB_TIMING_RFCPB,
538
MC_EMEM_ARB_DA_TURNS,
539
MC_EMEM_ARB_DA_COVERS,
540
MC_EMEM_ARB_MISC0,
541
MC_EMEM_ARB_MISC1,
542
MC_EMEM_ARB_MISC2,
543
MC_EMEM_ARB_RING1_THROTTLE,
544
MC_EMEM_ARB_DHYST_CTRL,
545
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_0,
546
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_1,
547
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_2,
548
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_3,
549
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_4,
550
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_5,
551
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_6,
552
MC_EMEM_ARB_DHYST_TIMEOUT_UTIL_7
553
};
554
555
static const u32 la_scale_regs_mc_addr_table[24] = {
556
MC_MLL_MPCORER_PTSA_RATE,
557
MC_FTOP_PTSA_RATE,
558
MC_PTSA_GRANT_DECREMENT,
559
MC_LATENCY_ALLOWANCE_XUSB_0,
560
MC_LATENCY_ALLOWANCE_XUSB_1,
561
MC_LATENCY_ALLOWANCE_TSEC_0,
562
MC_LATENCY_ALLOWANCE_SDMMCA_0,
563
MC_LATENCY_ALLOWANCE_SDMMCAA_0,
564
MC_LATENCY_ALLOWANCE_SDMMC_0,
565
MC_LATENCY_ALLOWANCE_SDMMCAB_0,
566
MC_LATENCY_ALLOWANCE_PPCS_0,
567
MC_LATENCY_ALLOWANCE_PPCS_1,
568
MC_LATENCY_ALLOWANCE_MPCORE_0,
569
MC_LATENCY_ALLOWANCE_HC_0,
570
MC_LATENCY_ALLOWANCE_HC_1,
571
MC_LATENCY_ALLOWANCE_AVPC_0,
572
MC_LATENCY_ALLOWANCE_GPU_0,
573
MC_LATENCY_ALLOWANCE_GPU2_0,
574
MC_LATENCY_ALLOWANCE_NVENC_0,
575
MC_LATENCY_ALLOWANCE_NVDEC_0,
576
MC_LATENCY_ALLOWANCE_VIC_0,
577
MC_LATENCY_ALLOWANCE_VI2_0,
578
MC_LATENCY_ALLOWANCE_ISP2_0,
579
MC_LATENCY_ALLOWANCE_ISP2_1
580
};
581
582
static const u32 periodic_training_addr[10] =
583
{
584
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0,
585
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1,
586
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2,
587
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3,
588
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0,
589
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1,
590
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2,
591
EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3,
592
EMC_DATA_BRLSHFT_0,
593
EMC_DATA_BRLSHFT_1
594
};
595
596
static const u32 ram_pattern_dq_table[0x500] = {
597
/* DQ RAM Patterns Table 0 */
598
0x18181818, 0x61616161, 0x85858585, 0x14141414, 0x51515151,
599
0x47474747, 0x1E1E1E1E, 0x79797979, 0xE5E5E5E5, 0x94949494,
600
0x51515151, 0x46464646, 0x19191919, 0x67676767, 0x9C9C9C9C,
601
0x71717171, 0xC5C5C5C5, 0x17171717, 0x5F5F5F5F, 0x7E7E7E7E,
602
0xFBFBFBFB, 0xEDEDEDED, 0xB4B4B4B4, 0xD2D2D2D2, 0x48484848,
603
0x21212121, 0x85858585, 0x16161616, 0x59595959, 0x66666666,
604
0x9A9A9A9A, 0x69696969, 0xA4A4A4A4, 0x93939393, 0x4F4F4F4F,
605
0x3F3F3F3F, 0xFCFCFCFC, 0xF3F3F3F3, 0xCDCDCDCD, 0x37373737,
606
0xDCDCDCDC, 0x70707070, 0xC3C3C3C3, 0x0F0F0F0F, 0x3E3E3E3E,
607
0xFAFAFAFA, 0xEBEBEBEB, 0xACACACAC, 0xB3B3B3B3, 0xCCCCCCCC,
608
0x31313131, 0xC5C5C5C5, 0x15151515, 0x57575757, 0x5F5F5F5F,
609
0x7F7F7F7F, 0xFDFDFDFD, 0xF4F4F4F4, 0xD0D0D0D0, 0x42424242,
610
0x08080808, 0x23232323, 0x8F8F8F8F, 0x3F3F3F3F, 0x18181818,
611
0x61616161, 0x85858585, 0x14141414, 0x51515151, 0x47474747,
612
0x1E1E1E1E, 0x79797979, 0xE5E5E5E5, 0x94949494, 0x51515151,
613
0x46464646, 0x19191919, 0x67676767, 0x9C9C9C9C, 0x71717171,
614
0xC5C5C5C5, 0x17171717, 0x5F5F5F5F, 0x7E7E7E7E, 0xFBFBFBFB,
615
0xEDEDEDED, 0xB4B4B4B4, 0xD2D2D2D2, 0x48484848, 0x21212121,
616
0x85858585, 0x16161616, 0x59595959, 0x66666666, 0x9A9A9A9A,
617
0x69696969, 0xA4A4A4A4, 0x93939393, 0x4F4F4F4F, 0x3F3F3F3F,
618
0xFCFCFCFC, 0xF3F3F3F3, 0xCDCDCDCD, 0x37373737, 0xDCDCDCDC,
619
0x70707070, 0xC3C3C3C3, 0x0F0F0F0F, 0x3E3E3E3E, 0xFAFAFAFA,
620
0xEBEBEBEB, 0xACACACAC, 0xB3B3B3B3, 0xCCCCCCCC, 0x31313131,
621
0xC5C5C5C5, 0x15151515, 0x57575757, 0x5F5F5F5F, 0x7F7F7F7F,
622
0xFDFDFDFD, 0xF4F4F4F4, 0xD0D0D0D0, 0x42424242, 0x08080808,
623
0x23232323, 0x8F8F8F8F, 0x3F3F3F3F, 0x06060606, 0x18181818,
624
0x21212121, 0x05050505, 0x14141414, 0x11111111, 0x07070707,
625
0x1E1E1E1E, 0x39393939, 0x25252525, 0x14141414, 0x11111111,
626
0x06060606, 0x19191919, 0x27272727, 0x1C1C1C1C, 0x31313131,
627
0x05050505, 0x17171717, 0x1F1F1F1F, 0x3E3E3E3E, 0x3B3B3B3B,
628
0x2D2D2D2D, 0x34343434, 0x12121212, 0x08080808, 0x21212121,
629
0x05050505, 0x16161616, 0x19191919, 0x26262626, 0x1A1A1A1A,
630
0x29292929, 0x24242424, 0x13131313, 0x0F0F0F0F, 0x3F3F3F3F,
631
0x3C3C3C3C, 0x33333333, 0x0D0D0D0D, 0x37373737, 0x1C1C1C1C,
632
0x30303030, 0x03030303, 0x0F0F0F0F, 0x3E3E3E3E, 0x3A3A3A3A,
633
0x2B2B2B2B, 0x2C2C2C2C, 0x33333333, 0x0C0C0C0C, 0x31313131,
634
0x05050505, 0x15151515, 0x17171717, 0x1F1F1F1F, 0x3F3F3F3F,
635
0x3D3D3D3D, 0x34343434, 0x10101010, 0x02020202, 0x08080808,
636
0x23232323, 0x0F0F0F0F, 0x06060606, 0x18181818, 0x21212121,
637
0x05050505, 0x14141414, 0x11111111, 0x07070707, 0x1E1E1E1E,
638
0x39393939, 0x25252525, 0x14141414, 0x11111111, 0x06060606,
639
0x19191919, 0x27272727, 0x1C1C1C1C, 0x31313131, 0x05050505,
640
0x17171717, 0x1F1F1F1F, 0x3E3E3E3E, 0x3B3B3B3B, 0x2D2D2D2D,
641
0x34343434, 0x12121212, 0x08080808, 0x21212121, 0x05050505,
642
0x16161616, 0x19191919, 0x26262626, 0x1A1A1A1A, 0x29292929,
643
0x24242424, 0x13131313, 0x0F0F0F0F, 0x3F3F3F3F, 0x3C3C3C3C,
644
0x33333333, 0x0D0D0D0D, 0x37373737, 0x1C1C1C1C, 0x30303030,
645
0x03030303, 0x0F0F0F0F, 0x3E3E3E3E, 0x3A3A3A3A, 0x2B2B2B2B,
646
0x2C2C2C2C, 0x33333333, 0x0C0C0C0C, 0x31313131, 0x05050505,
647
0x15151515, 0x17171717, 0x1F1F1F1F, 0x3F3F3F3F, 0x3D3D3D3D,
648
0x34343434, 0x10101010, 0x02020202, 0x08080808, 0x23232323,
649
0x0F0F0F0F,
650
651
/* DQ RAM Patterns Table 1 */
652
0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,
653
0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
654
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
655
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
656
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
657
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
658
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
659
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
660
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,
661
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
662
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
663
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
664
0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000,
665
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
666
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
667
0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000,
668
0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
669
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
670
0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
671
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
672
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
673
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF,
674
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
675
0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
676
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
677
0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
678
0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
679
0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000,
680
0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
681
0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,
682
0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F,
683
0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000,
684
0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F,
685
0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
686
0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,
687
0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
688
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,
689
0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000,
690
0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,
691
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
692
0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000,
693
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
694
0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F,
695
0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000,
696
0x00000000, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
697
0x3F3F3F3F, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,
698
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
699
0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F, 0x3F3F3F3F,
700
0x3F3F3F3F, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
701
0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F, 0x3F3F3F3F,
702
0x3F3F3F3F, 0x00000000, 0x00000000, 0x00000000, 0x3F3F3F3F,
703
0x00000000,
704
705
/* DQ RAM Patterns Table 2 */
706
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
707
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
708
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
709
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
710
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
711
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
712
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
713
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
714
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
715
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
716
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
717
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
718
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
719
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
720
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
721
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
722
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
723
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
724
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
725
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
726
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
727
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
728
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
729
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
730
0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
731
0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0x3F3F3F3F,
732
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
733
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
734
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
735
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
736
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
737
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
738
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
739
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
740
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
741
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
742
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
743
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
744
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
745
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
746
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
747
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
748
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
749
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
750
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
751
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
752
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
753
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
754
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
755
0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F,
756
0x00000000, 0x3F3F3F3F, 0x00000000, 0x3F3F3F3F, 0x00000000,
757
0x3F3F3F3F,
758
759
/* DQ RAM Patterns Table 3 */
760
0x80808080, 0x00000000, 0x80808080, 0x00000000, 0x80808080,
761
0x00000000, 0x80808080, 0x40404040, 0x00000000, 0x40404040,
762
0x00000000, 0x40404040, 0x00000000, 0x40404040, 0x20202020,
763
0x00000000, 0x20202020, 0x00000000, 0x20202020, 0x00000000,
764
0x20202020, 0x10101010, 0x00000000, 0x10101010, 0x00000000,
765
0x10101010, 0x00000000, 0x10101010, 0x08080808, 0x00000000,
766
0x08080808, 0x00000000, 0x08080808, 0x00000000, 0x08080808,
767
0x04040404, 0x00000000, 0x04040404, 0x00000000, 0x04040404,
768
0x00000000, 0x04040404, 0x02020202, 0x00000000, 0x02020202,
769
0x00000000, 0x02020202, 0x00000000, 0x02020202, 0x01010101,
770
0x00000000, 0x01010101, 0x00000000, 0x01010101, 0x00000000,
771
0x01010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
772
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80808080,
773
0x00000000, 0x80808080, 0x00000000, 0x80808080, 0x00000000,
774
0x80808080, 0x40404040, 0x00000000, 0x40404040, 0x00000000,
775
0x40404040, 0x00000000, 0x40404040, 0x20202020, 0x00000000,
776
0x20202020, 0x00000000, 0x20202020, 0x00000000, 0x20202020,
777
0x10101010, 0x00000000, 0x10101010, 0x00000000, 0x10101010,
778
0x00000000, 0x10101010, 0x08080808, 0x00000000, 0x08080808,
779
0x00000000, 0x08080808, 0x00000000, 0x08080808, 0x04040404,
780
0x00000000, 0x04040404, 0x00000000, 0x04040404, 0x00000000,
781
0x04040404, 0x02020202, 0x00000000, 0x02020202, 0x00000000,
782
0x02020202, 0x00000000, 0x02020202, 0x01010101, 0x00000000,
783
0x01010101, 0x00000000, 0x01010101, 0x00000000, 0x01010101,
784
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
785
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x20202020,
786
0x00000000, 0x20202020, 0x00000000, 0x20202020, 0x00000000,
787
0x20202020, 0x00000000, 0x20202020, 0x00000000, 0x10101010,
788
0x00000000, 0x10101010, 0x00000000, 0x10101010, 0x00000000,
789
0x10101010, 0x00000000, 0x10101010, 0x00000000, 0x08080808,
790
0x00000000, 0x08080808, 0x00000000, 0x08080808, 0x00000000,
791
0x08080808, 0x00000000, 0x08080808, 0x00000000, 0x04040404,
792
0x00000000, 0x04040404, 0x00000000, 0x04040404, 0x00000000,
793
0x04040404, 0x00000000, 0x04040404, 0x00000000, 0x02020202,
794
0x00000000, 0x02020202, 0x00000000, 0x02020202, 0x00000000,
795
0x02020202, 0x00000000, 0x02020202, 0x00000000, 0x01010101,
796
0x00000000, 0x01010101, 0x00000000, 0x01010101, 0x00000000,
797
0x01010101, 0x00000000, 0x01010101, 0x00000000, 0x00000000,
798
0x00000000, 0x00000000, 0x00000000, 0x20202020, 0x00000000,
799
0x20202020, 0x00000000, 0x20202020, 0x00000000, 0x20202020,
800
0x00000000, 0x20202020, 0x00000000, 0x10101010, 0x00000000,
801
0x10101010, 0x00000000, 0x10101010, 0x00000000, 0x10101010,
802
0x00000000, 0x10101010, 0x00000000, 0x08080808, 0x00000000,
803
0x08080808, 0x00000000, 0x08080808, 0x00000000, 0x08080808,
804
0x00000000, 0x08080808, 0x00000000, 0x04040404, 0x00000000,
805
0x04040404, 0x00000000, 0x04040404, 0x00000000, 0x04040404,
806
0x00000000, 0x04040404, 0x00000000, 0x02020202, 0x00000000,
807
0x02020202, 0x00000000, 0x02020202, 0x00000000, 0x02020202,
808
0x00000000, 0x02020202, 0x00000000, 0x01010101, 0x00000000,
809
0x01010101, 0x00000000, 0x01010101, 0x00000000, 0x01010101,
810
0x00000000, 0x01010101, 0x00000000, 0x00000000, 0x00000000,
811
0x00000000,
812
813
/* DQ RAM Patterns Table 4 */
814
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
815
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
816
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
817
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
818
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
819
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
820
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
821
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
822
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
823
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
824
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
825
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
826
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
827
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
828
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
829
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
830
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
831
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
832
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
833
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
834
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
835
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
836
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
837
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
838
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
839
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
840
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
841
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
842
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
843
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
844
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
845
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
846
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
847
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
848
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
849
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
850
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
851
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
852
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
853
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
854
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
855
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
856
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
857
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
858
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
859
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
860
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
861
0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333,
862
0xAAAAAAAA, 0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA,
863
0x55555555, 0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555,
864
0xCCCCCCCC, 0x33333333, 0xAAAAAAAA, 0x55555555, 0xCCCCCCCC,
865
0x33333333
866
};
867
868
static const u32 ram_pattern_dmi_table[0x500] = {
869
/* DMI RAM Patterns Table 0 */
870
0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,
871
0x0, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,
872
0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0x0, 0x0,
873
0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0x0,
874
0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0x0,
875
0x0, 0xF, 0xF, 0x0, 0x0, 0xF, 0x0, 0xF,
876
0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF,
877
0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,
878
0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,
879
0x0, 0xF, 0x0, 0xF, 0xF, 0x0, 0xF, 0xF,
880
0xF, 0xF, 0x0, 0xF, 0xF, 0x0, 0x0, 0x0,
881
0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0x0,
882
0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0x0,
883
0x0, 0xF, 0xF, 0x0, 0x0, 0xF, 0x0, 0xF,
884
0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF,
885
0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,
886
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
887
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
888
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
889
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
890
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
891
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
892
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
893
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
894
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
895
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
896
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
897
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
898
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
899
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
900
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
901
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
902
903
/* DMI RAM Patterns Table 1 */
904
0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0,
905
0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0,
906
0xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF,
907
0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,
908
0xF, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,
909
0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF,
910
0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0,
911
0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,
912
0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0,
913
0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0,
914
0xF, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF,
915
0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,
916
0xF, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF, 0x0,
917
0xF, 0x0, 0xF, 0x0, 0x0, 0xF, 0xF, 0xF,
918
0xF, 0xF, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0,
919
0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0xF, 0x0,
920
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
921
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
922
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
923
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
924
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
925
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
926
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
927
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
928
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
929
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
930
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
931
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
932
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
933
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
934
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
935
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
936
937
/* DMI RAM Patterns Table 2 */
938
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
939
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
940
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
941
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
942
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
943
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
944
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
945
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
946
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
947
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
948
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
949
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
950
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
951
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
952
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
953
0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF,
954
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
955
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
956
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
957
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
958
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
959
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
960
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
961
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
962
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
963
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
964
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
965
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
966
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
967
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
968
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
969
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
970
971
/* DMI RAM Patterns Table 3 */
972
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
973
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
974
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
975
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
976
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
977
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
978
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
979
0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0,
980
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
981
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
982
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
983
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
984
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
985
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
986
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
987
0xF, 0x0, 0xF, 0x0, 0xF, 0x0, 0xF, 0x0,
988
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
989
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
990
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
991
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
992
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
993
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
994
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
995
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
996
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
997
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
998
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
999
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1000
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1001
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1002
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1003
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1004
1005
/* DMI RAM Patterns Table 4 */
1006
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1007
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1008
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1009
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1010
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1011
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1012
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1013
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1014
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1015
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1016
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1017
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1018
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1019
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1020
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1021
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1022
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1023
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1024
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1025
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1026
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1027
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1028
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1029
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1030
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1031
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1032
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1033
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1034
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1035
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1036
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3,
1037
0xA, 0x5, 0xC, 0x3, 0xA, 0x5, 0xC, 0x3
1038
};
1039
1040
static void _usleep(u32 microseconds)
1041
{
1042
u32 start = TMR(0x10);
1043
while ((u32)(TMR(0x10) - start) <= microseconds)
1044
;
1045
}
1046
1047
static u32 _div_o3(u32 a, u32 b)
1048
{
1049
u32 result = a / b;
1050
1051
if ((b * result) < a)
1052
return result + 1;
1053
else
1054
return result;
1055
}
1056
1057
static u32 _actual_osc_clocks(u32 in)
1058
{
1059
u32 actual_clock;
1060
1061
actual_clock = 16 * in;
1062
if (in > 63)
1063
{
1064
actual_clock = 2048;
1065
if (in > 127)
1066
{
1067
if (in >= 192)
1068
actual_clock = 8192;
1069
else
1070
actual_clock = 4096;
1071
}
1072
}
1073
1074
return actual_clock;
1075
}
1076
1077
static void _ccfifo_write(u32 addr, u32 data_val, u32 delay) //addr and delay are u16
1078
{
1079
EMC(EMC_CCFIFO_DATA) = data_val;
1080
EMC(EMC_CCFIFO_ADDR) = BIT(31) | (addr & 0xffff) | ((delay & 0x7FFF) << 16);
1081
}
1082
1083
static bool _wait_emc_status(u32 reg_offset, u32 bit_mask, bool updated_state, u32 emc_channel)
1084
{
1085
bool err = true;
1086
1087
for (u32 i = 0; i < EMC_STATUS_UPDATE_TIMEOUT; i++)
1088
{
1089
if (emc_channel)
1090
{
1091
if (emc_channel != 1)
1092
goto done;
1093
1094
if (((EMC_CH1(reg_offset) & bit_mask) != 0) == updated_state)
1095
{
1096
err = false;
1097
break;
1098
}
1099
}
1100
else if (((EMC(reg_offset) & bit_mask) != 0) == updated_state)
1101
{
1102
err = false;
1103
break;
1104
}
1105
_usleep(1);
1106
}
1107
1108
done:
1109
return err;
1110
}
1111
1112
static void _request_mmr_data(u32 data, bool dual_channel)
1113
{
1114
EMC(EMC_MRR) = data;
1115
_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, true, EMC_CHANNEL0);
1116
if (dual_channel)
1117
_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, true, EMC_CHANNEL1);
1118
}
1119
1120
static void _start_periodic_compensation()
1121
{
1122
EMC(EMC_MPC) = 0x4B;
1123
(void)EMC(EMC_MPC);
1124
}
1125
1126
static bool _timing_update(u32 dual_channel)
1127
{
1128
bool err = 0;
1129
1130
EMC(EMC_TIMING_CONTROL) = 1;
1131
err = _wait_emc_status(EMC_EMC_STATUS, TIMING_UPDATE_STALLED, false, EMC_CHANNEL0);
1132
if (dual_channel)
1133
err |= _wait_emc_status(EMC_EMC_STATUS, TIMING_UPDATE_STALLED, false, EMC_CHANNEL1);
1134
1135
return err;
1136
}
1137
1138
static u32 _get_dram_temperature()
1139
{
1140
u32 mr4_0 = 0;
1141
u32 mr4_1 = 0;
1142
1143
bool channel1_enabled = (EMC(EMC_FBIO_CFG7) >> 2) & 1;
1144
u32 emc_cfg_o = EMC(EMC_CFG);
1145
1146
_wait_emc_status(EMC_EMC_STATUS, MRR_DIVLD, false, EMC_CHANNEL0);
1147
1148
if (emc_cfg_o & 0x20000000)
1149
{
1150
EMC(EMC_CFG) = emc_cfg_o & 0xDFFFFFFF;
1151
_timing_update(channel1_enabled);
1152
}
1153
1154
_request_mmr_data(0x80040000, EMC_CHANNEL0);
1155
mr4_0 = EMC(EMC_MRR) & 0xFFFF;
1156
1157
if (mr4_0 < 0xF001)
1158
mr4_0 &= 0x7;
1159
else
1160
{
1161
mr4_0 = -1;
1162
goto out;
1163
}
1164
1165
if (channel1_enabled)
1166
{
1167
_request_mmr_data(0x40040000, EMC_CHANNEL1);
1168
mr4_1 = EMC(EMC_MRR) & 0xFFFF;
1169
1170
if (mr4_1 < 0xF001)
1171
mr4_1 &= 0x7;
1172
else
1173
goto out;
1174
1175
if (mr4_1 > mr4_0)
1176
mr4_0 = mr4_1;
1177
}
1178
1179
out:
1180
if (emc_cfg_o & 0x20000000)
1181
{
1182
EMC(EMC_CFG) = emc_cfg_o;
1183
_timing_update(channel1_enabled);
1184
}
1185
1186
return mr4_0;
1187
}
1188
1189
static u32 _pllm_clk_base_cfg(u32 rate_KHz, u32 clk_src_emc, bool new_src_is_PLLMB)
1190
{
1191
u32 dividers = 0;
1192
u32 i = 0;
1193
u32 pll_ref = 38400; // Only 38.4MHz crystal is supported for T210.
1194
1195
pllm_clk_config_t *pllm_clk_config = NULL;
1196
1197
for (i = 0; pllm_clk_config_table[i].pll_osc_in; i++)
1198
{
1199
if (pllm_clk_config_table[i].pll_osc_in == pll_ref && (pllm_clk_config_table[i].pll_out - 19200) <= rate_KHz)
1200
pllm_clk_config = &pllm_clk_config_table[i];
1201
}
1202
1203
if (pllm_clk_config && pllm_clk_config->pll_osc_in)
1204
{
1205
dividers = pllm_clk_config->pll_input_div | (pllm_clk_config->pll_feedback_div << 8) | ((pllm_clk_config->pll_post_div & 0x1F) << 20);
1206
if (new_src_is_PLLMB)
1207
{
1208
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) = dividers;
1209
CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) |= PLLM_ENABLE;
1210
1211
if ((clk_src_emc >> EMC_2X_CLK_SRC_SHIFT) == PLLM_UD)
1212
clk_src_emc = (clk_src_emc & 0x1FFFFFFF) | (PLLMB_UD << EMC_2X_CLK_SRC_SHIFT);
1213
else if (!(clk_src_emc >> EMC_2X_CLK_SRC_SHIFT))
1214
clk_src_emc |= (PLLMB_OUT0 << EMC_2X_CLK_SRC_SHIFT);
1215
1216
while (!(CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) & PLLM_LOCK))
1217
;
1218
}
1219
else
1220
{
1221
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) = dividers;
1222
CLOCK(CLK_RST_CONTROLLER_PLLM_MISC2) |= PLLM_EN_LCKDET;
1223
CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) |= PLLM_ENABLE;
1224
1225
if ((clk_src_emc >> EMC_2X_CLK_SRC_SHIFT) == PLLM_UD)
1226
clk_src_emc = (clk_src_emc & 0x1FFFFFFF) | (PLLM_UD << EMC_2X_CLK_SRC_SHIFT);
1227
while (!(CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) & PLLM_LOCK))
1228
;
1229
}
1230
}
1231
return clk_src_emc;
1232
}
1233
1234
static void _change_dll_src(emc_table_t *mtc_table_entry, u32 clk_src_emc)
1235
{
1236
u32 emc_2x_clk_src = clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;
1237
1238
u32 dll_setting = ((((mtc_table_entry->dll_clk_src & 0x1FFFFFFF)
1239
| (emc_2x_clk_src << EMC_2X_CLK_SRC_SHIFT)) & 0xFFFFFF00)
1240
| (clk_src_emc & 0xFF)) & 0xFFFFF3FF;
1241
1242
if (emc_2x_clk_src == PLLMB_UD)
1243
dll_setting |= EMC_DLL_PLLM_VCOB;
1244
else if (emc_2x_clk_src != PLLM_UD)
1245
dll_setting |= EMC_DLL_SWITCH_OUT;
1246
1247
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL) = dll_setting;
1248
1249
// Commit clock write.
1250
(void)CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X);
1251
_usleep(2);
1252
1253
// Enable/Disable EMC DLL.
1254
if (mtc_table_entry->clk_out_enb_x_0_clk_enb_emc_dll)
1255
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(14);
1256
else
1257
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_CLR) = BIT(14);
1258
1259
// Commit clock write.
1260
(void)CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_X);
1261
_usleep(2);
1262
}
1263
1264
static u32 _digital_dll_prelock(emc_table_t *mtc_table_entry, bool in_training, u32 selected_clk_src_emc)
1265
{
1266
u32 dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);
1267
1268
EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFF824) | 0x3C8;
1269
1270
_timing_update(dual_channel);
1271
1272
while (EMC(EMC_CFG_DIG_DLL) & 1)
1273
;
1274
if (dual_channel)
1275
while (EMC_CH1(EMC_CFG_DIG_DLL) & 1)
1276
;
1277
1278
EMC(EMC_DLL_CFG_0) = mtc_table_entry->burst_regs.emc_dll_cfg_0;
1279
EMC(EMC_DLL_CFG_1) = mtc_table_entry->burst_regs.emc_dll_cfg_1;
1280
1281
_change_dll_src(mtc_table_entry, selected_clk_src_emc);
1282
1283
EMC(EMC_CFG_DIG_DLL) |= 1;
1284
1285
_timing_update(dual_channel);
1286
1287
while (!(EMC(EMC_CFG_DIG_DLL) & 1))
1288
;
1289
if (dual_channel)
1290
while (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))
1291
;
1292
1293
while ((((EMC(EMC_DIG_DLL_STATUS) >> 17) & 1) ^ 1) | (((EMC(EMC_DIG_DLL_STATUS) >> 15) & 1) ^ 1))
1294
;
1295
1296
if (in_training)
1297
{
1298
EMC(EMC_DBG) |= EMC_DBG_WRITE_MUX_ACTIVE;
1299
EMC(EMC_CFG_DIG_DLL) &= 0xFFFFFFFE; // Disable CFG_DLL_EN.
1300
EMC(EMC_DBG) &= ~EMC_DBG_WRITE_MUX_ACTIVE;
1301
1302
while (EMC(EMC_CFG_DIG_DLL) & 1)
1303
;
1304
if (dual_channel)
1305
while (EMC_CH1(EMC_CFG_DIG_DLL) & 1)
1306
;
1307
}
1308
1309
return EMC(EMC_DIG_DLL_STATUS) & 0x7FF;
1310
}
1311
1312
static void _digital_dll_disable()
1313
{
1314
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);
1315
1316
EMC(EMC_CFG_DIG_DLL) &= 0xFFFFFFFE;
1317
1318
_timing_update(dual_channel);
1319
1320
while (EMC(EMC_CFG_DIG_DLL) & 1)
1321
;
1322
if (dual_channel)
1323
while (EMC_CH1(EMC_CFG_DIG_DLL) & 1)
1324
;
1325
}
1326
1327
static void _digital_dll_enable_rs(u32 channel1_enabled)
1328
{
1329
EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF24) | 0x89;
1330
1331
_timing_update(channel1_enabled);
1332
1333
while (!(EMC(EMC_CFG_DIG_DLL) & 1))
1334
;
1335
if (channel1_enabled)
1336
while (!(EMC_CH1(EMC_CFG_DIG_DLL) & 1))
1337
;
1338
}
1339
1340
static u32 _dvfs_power_ramp_down(bool flip_backward, emc_table_t *src_emc_table_entry, emc_table_t *dst_emc_table_entry, u32 src_clock_period)
1341
{
1342
u32 pmacro_cmd_pad;
1343
u32 pmacro_rfu1;
1344
u32 pmacro_cfg5;
1345
u32 pmacro_com_pad;
1346
u32 pmacro_dq_pad;
1347
1348
u32 src_clk_per_pc = (100000 / src_clock_period) + 1;
1349
1350
if (flip_backward)
1351
{
1352
pmacro_cmd_pad = dst_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;
1353
pmacro_dq_pad = dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;
1354
pmacro_rfu1 = dst_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;
1355
pmacro_cfg5 = dst_emc_table_entry->burst_regs.emc_fbio_cfg5;
1356
pmacro_com_pad = dst_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;
1357
}
1358
else
1359
{
1360
pmacro_cmd_pad = src_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;
1361
pmacro_dq_pad = (dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0x101) | src_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;
1362
pmacro_rfu1 = src_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;
1363
pmacro_cfg5 = src_emc_table_entry->burst_regs.emc_fbio_cfg5;
1364
pmacro_com_pad = src_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;
1365
}
1366
1367
u32 pmacro_cmd_pad_drvforceon = pmacro_cmd_pad | 0x4000000;
1368
1369
u32 ramp_down_wait = src_clock_period * 12;
1370
1371
_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon, 0);
1372
_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 | 0x100, 12);
1373
1374
if (src_clock_period >= 1000) // Dvfs high speed threshold.
1375
{
1376
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, (u32)(src_clk_per_pc + 19));
1377
ramp_down_wait += 100000 + (src_clock_period * 20);
1378
}
1379
else
1380
{
1381
if (src_clock_period >= 416) // Iobrick dcc threshold.
1382
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, (u32)src_clk_per_pc);
1383
else
1384
{
1385
pmacro_dq_pad = (pmacro_dq_pad & 0xFEFEFDFD) | 0x10200;
1386
pmacro_cmd_pad_drvforceon = (pmacro_cmd_pad & 0xFAFEFDFD) | 0x4010200;
1387
_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon, (u32)src_clk_per_pc);
1388
_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad, 0);
1389
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, 0);
1390
}
1391
ramp_down_wait += 300000;
1392
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, (u32)src_clk_per_pc);
1393
1394
if (src_clock_period >= 416) // Iobrick dcc threshold.
1395
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, (u32)src_clk_per_pc);
1396
else
1397
{
1398
_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_drvforceon & 0xFEFEFDFD, (u32)src_clk_per_pc);
1399
_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad & 0xFEFEFDFD, 0);
1400
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xF800F800, 0);
1401
}
1402
}
1403
1404
if (src_clock_period >= 1666) // Dvfs mid speed threshold.
1405
_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_com_pad & 0xFFFFFFF0, (u32)src_clk_per_pc);
1406
else
1407
{
1408
ramp_down_wait += 400000;
1409
_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_com_pad & 0xFFFFFFFA, (u32)src_clk_per_pc);
1410
_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_com_pad & 0xFFFFFFF0, (u32)src_clk_per_pc);
1411
_ccfifo_write(EMC_INTSTATUS, 0, (u32)src_clk_per_pc);
1412
}
1413
1414
return ramp_down_wait;
1415
}
1416
1417
static u32 _dvfs_power_ramp_up(bool flip_backward, emc_table_t *src_emc_table_entry, emc_table_t *dst_emc_table_entry, u32 needs_training, u32 dst_clock_period)
1418
{
1419
u32 pmacro_cmd_pad;
1420
u32 pmacro_dq_pad;
1421
u32 pmacro_rfu1;
1422
u32 pmacro_cfg5;
1423
u32 pmacro_com_pad;
1424
u32 pmacro_cmd_pad_data;
1425
u32 ramp_up_wait = 0;
1426
1427
u32 dst_clk_per_pc = (100000 / dst_clock_period) + 1;
1428
1429
if (flip_backward)
1430
{
1431
pmacro_cmd_pad = src_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;
1432
pmacro_dq_pad = src_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;
1433
pmacro_rfu1 = src_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;
1434
pmacro_cfg5 = src_emc_table_entry->burst_regs.emc_fbio_cfg5;
1435
pmacro_com_pad = src_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;
1436
}
1437
else if (needs_training & NEEDS_TRAINING_CA_COMBO)
1438
{
1439
pmacro_cmd_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_cmd_pad_tx_ctrl;
1440
pmacro_dq_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_data_pad_tx_ctrl;
1441
pmacro_rfu1 = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_brick_ctrl_rfu1;
1442
pmacro_cfg5 = dst_emc_table_entry->shadow_regs_ca_train.emc_fbio_cfg5;
1443
pmacro_com_pad = dst_emc_table_entry->shadow_regs_ca_train.emc_pmacro_common_pad_tx_ctrl;
1444
}
1445
else if (needs_training & NEEDS_TRAINING_QUSE_COMBO)
1446
{
1447
pmacro_cmd_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_cmd_pad_tx_ctrl;
1448
pmacro_dq_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_data_pad_tx_ctrl;
1449
pmacro_rfu1 = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_brick_ctrl_rfu1;
1450
pmacro_cfg5 = dst_emc_table_entry->shadow_regs_quse_train.emc_fbio_cfg5;
1451
pmacro_com_pad = dst_emc_table_entry->shadow_regs_quse_train.emc_pmacro_common_pad_tx_ctrl;
1452
}
1453
else if (needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO))
1454
{
1455
pmacro_cmd_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_cmd_pad_tx_ctrl;
1456
pmacro_dq_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_data_pad_tx_ctrl;
1457
pmacro_rfu1 = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_brick_ctrl_rfu1;
1458
pmacro_cfg5 = dst_emc_table_entry->shadow_regs_rdwr_train.emc_fbio_cfg5;
1459
pmacro_com_pad = dst_emc_table_entry->shadow_regs_rdwr_train.emc_pmacro_common_pad_tx_ctrl;
1460
}
1461
else
1462
{
1463
pmacro_cmd_pad = dst_emc_table_entry->burst_regs.emc_pmacro_cmd_pad_tx_ctrl;
1464
pmacro_dq_pad = dst_emc_table_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl;
1465
pmacro_rfu1 = dst_emc_table_entry->burst_regs.emc_pmacro_brick_ctrl_rfu1;
1466
pmacro_cfg5 = dst_emc_table_entry->burst_regs.emc_fbio_cfg5;
1467
pmacro_com_pad = dst_emc_table_entry->burst_regs.emc_pmacro_common_pad_tx_ctrl;
1468
}
1469
1470
pmacro_cmd_pad_data = (pmacro_cmd_pad & 0xFAFEFDFD) | 0x4000000;
1471
1472
if (dst_clock_period >= 1666) // Dvfs mid speed threshold.
1473
{
1474
_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_com_pad | 8, 0);
1475
1476
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x600, 0);
1477
_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, 12);
1478
1479
ramp_up_wait = (dst_clock_period * 12) + 0;
1480
}
1481
else
1482
{
1483
_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_com_pad & 0xA, 0);
1484
_ccfifo_write(EMC_PMACRO_COMMON_PAD_TX_CTRL, pmacro_com_pad & 0xF, dst_clk_per_pc);
1485
1486
if (dst_clock_period < 1000) // Dvfs high speed threshold.
1487
{
1488
if (dst_clock_period >= 416) // Iobrick dcc threshold.
1489
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, dst_clk_per_pc);
1490
else
1491
{
1492
_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, (pmacro_cmd_pad & 0xFAFEFDFD) | 0x4010200, dst_clk_per_pc);
1493
_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, (pmacro_dq_pad & 0xFEFEFDFD) | 0x10200, 0);
1494
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFE40FE40, 0);
1495
}
1496
1497
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 & 0xFEEDFEED, dst_clk_per_pc);
1498
1499
if (dst_clock_period >= 416) // Iobrick dcc threshold.
1500
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, dst_clk_per_pc);
1501
else
1502
{
1503
pmacro_cmd_pad_data = pmacro_cmd_pad | 0x5010202;
1504
_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data, dst_clk_per_pc);
1505
_ccfifo_write(EMC_PMACRO_DATA_PAD_TX_CTRL, pmacro_dq_pad | 0x1010202, 0);
1506
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1, 0);
1507
}
1508
1509
ramp_up_wait = 500000 + (dst_clock_period * 10);
1510
}
1511
else // 1000 > dst_clock_period < 1666.
1512
{
1513
_ccfifo_write(EMC_PMACRO_BRICK_CTRL_RFU1, pmacro_rfu1 | 0x6000600, dst_clk_per_pc);
1514
1515
ramp_up_wait = 200000 + (dst_clock_period * 10);
1516
}
1517
1518
_ccfifo_write(EMC_FBIO_CFG5, pmacro_cfg5 & 0xFFFFFEFF, dst_clk_per_pc + 9);
1519
}
1520
1521
_ccfifo_write(EMC_PMACRO_CMD_PAD_TX_CTRL, pmacro_cmd_pad_data & 0xFBFFFFFF, 5);
1522
1523
return ramp_up_wait;
1524
}
1525
1526
static u32 _minerva_update_clock_tree_delay(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 dram_dev_num, u32 channel1_enabled, enum tree_update_mode_t update_type)
1527
{
1528
u32 cval = 0;
1529
u32 adelta = 0;
1530
s32 tdelta = 0;
1531
1532
u32 temp_ch0_0 = 0;
1533
u32 temp_ch0_1 = 0;
1534
u32 temp_ch1_0 = 0;
1535
u32 temp_ch1_1 = 0;
1536
1537
u32 upd_type_bits = BIT(update_type);
1538
u32 dst_rate_mhz = dst_emc_entry->rate_khz / 1000;
1539
u32 src_rate_mhz = src_emc_entry->rate_khz / 1000;
1540
1541
u32 tval = 1000000 * _actual_osc_clocks(src_emc_entry->run_clocks) / 2;
1542
1543
if (update_type > PERIODIC_TRAINING_UPDATE)
1544
return 0;
1545
1546
if (upd_type_bits & 0x5400)
1547
{
1548
_request_mmr_data(0x80130000, channel1_enabled); // Dev0 MRR 19.
1549
u32 mrr = EMC(EMC_MRR);
1550
temp_ch0_0 = (mrr & 0xFF) << 8;
1551
temp_ch0_1 = mrr & 0xFF00;
1552
if (channel1_enabled)
1553
{
1554
mrr = EMC_CH1(EMC_MRR);
1555
temp_ch1_0 = (mrr & 0xFF) << 8;
1556
temp_ch1_1 = mrr & 0xFF00;
1557
}
1558
1559
_request_mmr_data(0x80120000, channel1_enabled); // Dev0 MRR 18.
1560
mrr = EMC(EMC_MRR);
1561
temp_ch0_0 |= mrr & 0xFF;
1562
temp_ch0_1 |= (mrr & 0xFF00) >> 8;
1563
if (channel1_enabled)
1564
{
1565
mrr = EMC_CH1(EMC_MRR);
1566
temp_ch1_0 |= mrr & 0xFF;
1567
temp_ch1_1 |= (mrr & 0xFF00) >> 8;
1568
}
1569
}
1570
1571
cval = tval / (src_rate_mhz * temp_ch0_0);
1572
switch (update_type)
1573
{
1574
case DVFS_PT1:
1575
case TRAINING_PT1:
1576
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 += 100 * cval;
1577
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1578
goto calc_td0_0;
1579
break;
1580
case DVFS_UPDATE:
1581
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 =
1582
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1583
break;
1584
case TRAINING_UPDATE:
1585
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 =
1586
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1587
break;
1588
case PERIODIC_TRAINING_UPDATE:
1589
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 =
1590
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0)
1591
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1592
break;
1593
default:
1594
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1595
goto calc_td0_0;
1596
break;
1597
}
1598
1599
tdelta = dst_emc_entry->current_dram_clktree_c0d0u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / 100);
1600
if (tdelta < 0)
1601
tdelta *= -1;
1602
adelta = tdelta;
1603
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1604
dst_emc_entry->current_dram_clktree_c0d0u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 / 100;
1605
1606
calc_td0_0:
1607
cval = tval / (src_rate_mhz * temp_ch0_1);
1608
switch (update_type)
1609
{
1610
case DVFS_PT1:
1611
case TRAINING_PT1:
1612
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 += 100 * cval;
1613
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1614
goto calc_td1_0;
1615
break;
1616
case DVFS_UPDATE:
1617
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 =
1618
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1619
break;
1620
case TRAINING_UPDATE:
1621
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 =
1622
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1623
break;
1624
case PERIODIC_TRAINING_UPDATE:
1625
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 =
1626
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1)
1627
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1628
break;
1629
default:
1630
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1631
goto calc_td1_0;
1632
break;
1633
}
1634
1635
tdelta = dst_emc_entry->current_dram_clktree_c0d0u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / 100);
1636
if (tdelta < 0)
1637
tdelta *= -1;
1638
if ((u32)tdelta > adelta)
1639
adelta = tdelta;
1640
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1641
dst_emc_entry->current_dram_clktree_c0d0u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 / 100;
1642
1643
calc_td1_0:
1644
if (channel1_enabled)
1645
{
1646
cval = tval / (src_rate_mhz * temp_ch1_0);
1647
switch (update_type)
1648
{
1649
case DVFS_PT1:
1650
case TRAINING_PT1:
1651
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 += 100 * cval;
1652
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1653
goto calc_td1_1;
1654
break;
1655
case DVFS_UPDATE:
1656
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 =
1657
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1658
break;
1659
case TRAINING_UPDATE:
1660
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 =
1661
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1662
break;
1663
case PERIODIC_TRAINING_UPDATE:
1664
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 =
1665
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0)
1666
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1667
break;
1668
default:
1669
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1670
goto calc_td1_1;
1671
break;
1672
}
1673
1674
tdelta = dst_emc_entry->current_dram_clktree_c1d0u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / 100);
1675
if (tdelta < 0)
1676
tdelta *= -1;
1677
if ((u32)tdelta > adelta)
1678
adelta = tdelta;
1679
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1680
dst_emc_entry->current_dram_clktree_c1d0u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 / 100;
1681
1682
calc_td1_1:
1683
cval = tval / (src_rate_mhz * temp_ch1_1);
1684
switch (update_type)
1685
{
1686
case DVFS_PT1:
1687
case TRAINING_PT1:
1688
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 += 100 * cval;
1689
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1690
goto calc_dev2;
1691
break;
1692
case DVFS_UPDATE:
1693
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 =
1694
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1695
break;
1696
case TRAINING_UPDATE:
1697
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 =
1698
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1699
break;
1700
case PERIODIC_TRAINING_UPDATE:
1701
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 =
1702
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1)
1703
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1704
break;
1705
default:
1706
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1707
goto calc_dev2;
1708
break;
1709
}
1710
1711
tdelta = dst_emc_entry->current_dram_clktree_c1d0u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / 100);
1712
if (tdelta < 0)
1713
tdelta *= -1;
1714
if ((u32)tdelta > adelta)
1715
adelta = tdelta;
1716
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1717
dst_emc_entry->current_dram_clktree_c1d0u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 / 100;
1718
}
1719
1720
calc_dev2:
1721
if (dram_dev_num != TWO_RANK)
1722
goto out;
1723
1724
if (update_type <= PERIODIC_TRAINING_UPDATE && upd_type_bits & 0x5400)
1725
{
1726
_request_mmr_data(0x40130000, channel1_enabled); // Dev1 MRR 19.
1727
u32 mrr = EMC(EMC_MRR);
1728
temp_ch0_0 = (mrr & 0xFF) << 8;
1729
temp_ch0_1 = mrr & 0xFF00;
1730
if (channel1_enabled)
1731
{
1732
mrr = EMC_CH1(EMC_MRR);
1733
temp_ch1_0 = (mrr & 0xFF) << 8;
1734
temp_ch1_1 = mrr & 0xFF00;
1735
}
1736
1737
_request_mmr_data(0x40120000, channel1_enabled); // Dev1 MRR 18
1738
mrr = EMC(EMC_MRR);
1739
temp_ch0_0 |= mrr & 0xFF;
1740
temp_ch0_1 |= (mrr & 0xFF00) >> 8;
1741
if (channel1_enabled)
1742
{
1743
mrr = EMC_CH1(EMC_MRR);
1744
temp_ch1_0 |= mrr & 0xFF;
1745
temp_ch1_1 |= (mrr & 0xFF00) >> 8;
1746
}
1747
}
1748
1749
cval = tval / (src_rate_mhz * temp_ch0_0);
1750
switch (update_type )
1751
{
1752
case DVFS_PT1:
1753
case TRAINING_PT1:
1754
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 += 100 * cval;
1755
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1756
goto calc_tmp_td0_1;
1757
break;
1758
case DVFS_UPDATE:
1759
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 =
1760
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1761
break;
1762
case TRAINING_UPDATE:
1763
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 =
1764
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1765
break;
1766
case PERIODIC_TRAINING_UPDATE:
1767
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 =
1768
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0)
1769
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1770
break;
1771
default:
1772
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1773
goto calc_tmp_td0_1;
1774
break;
1775
}
1776
1777
tdelta = dst_emc_entry->current_dram_clktree_c0d1u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / 100);
1778
if (tdelta < 0)
1779
tdelta *= -1;
1780
if ((u32)tdelta > adelta)
1781
adelta = tdelta;
1782
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1783
dst_emc_entry->current_dram_clktree_c0d1u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 / 100;
1784
1785
calc_tmp_td0_1:
1786
cval = tval / (src_rate_mhz * temp_ch0_1);
1787
switch (update_type)
1788
{
1789
case DVFS_PT1:
1790
case TRAINING_PT1:
1791
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 += 100 * cval;
1792
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1793
goto calc_tmp_td1_0;
1794
break;
1795
case DVFS_UPDATE:
1796
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 =
1797
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1798
break;
1799
case TRAINING_UPDATE:
1800
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 =
1801
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1802
break;
1803
case PERIODIC_TRAINING_UPDATE:
1804
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 =
1805
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1)
1806
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1807
break;
1808
default:
1809
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1810
goto calc_tmp_td1_0;
1811
break;
1812
}
1813
1814
tdelta = dst_emc_entry->current_dram_clktree_c0d1u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / 100);
1815
if (tdelta < 0)
1816
tdelta *= -1;
1817
if ((u32)tdelta > adelta)
1818
adelta = tdelta;
1819
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1820
dst_emc_entry->current_dram_clktree_c0d1u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 / 100;
1821
1822
calc_tmp_td1_0:
1823
if (channel1_enabled)
1824
{
1825
cval = tval / (src_rate_mhz * temp_ch1_0);
1826
switch (update_type)
1827
{
1828
case DVFS_PT1:
1829
case TRAINING_PT1:
1830
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 += 100 * cval;
1831
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1832
goto calc_tmp_td1_1;
1833
break;
1834
case DVFS_UPDATE:
1835
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 =
1836
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1837
break;
1838
case TRAINING_UPDATE:
1839
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 =
1840
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1841
break;
1842
case PERIODIC_TRAINING_UPDATE:
1843
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 =
1844
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0)
1845
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1846
break;
1847
default:
1848
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1849
goto calc_tmp_td1_1;
1850
break;
1851
}
1852
1853
tdelta = dst_emc_entry->current_dram_clktree_c1d1u0 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / 100);
1854
if (tdelta < 0)
1855
tdelta *= -1;
1856
if ((u32)tdelta > adelta)
1857
adelta = tdelta;
1858
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1859
dst_emc_entry->current_dram_clktree_c1d1u0 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 / 100;
1860
1861
calc_tmp_td1_1:
1862
cval = tval / (src_rate_mhz * temp_ch1_1);
1863
switch (update_type)
1864
{
1865
case DVFS_PT1:
1866
case TRAINING_PT1:
1867
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 += 100 * cval;
1868
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1869
goto out;
1870
break;
1871
case DVFS_UPDATE:
1872
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 =
1873
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1874
break;
1875
case TRAINING_UPDATE:
1876
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 =
1877
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / dst_emc_entry->ptfv_list.ptfv_write_samples;
1878
break;
1879
case PERIODIC_TRAINING_UPDATE:
1880
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 =
1881
(100 * cval + dst_emc_entry->ptfv_list.ptfv_movavg_weight * dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1)
1882
/ (dst_emc_entry->ptfv_list.ptfv_movavg_weight + 1);
1883
break;
1884
default:
1885
if (update_type > PERIODIC_TRAINING_UPDATE || !(upd_type_bits & 0x6800))
1886
goto out;
1887
break;
1888
}
1889
1890
tdelta = dst_emc_entry->current_dram_clktree_c1d1u1 - (dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / 100);
1891
if (tdelta < 0)
1892
tdelta *= -1;
1893
if ((u32)tdelta > adelta)
1894
adelta = tdelta;
1895
if (update_type == TRAINING_UPDATE || ((dst_rate_mhz * tdelta * 128) / 1000000) > dst_emc_entry->tree_margin)
1896
dst_emc_entry->current_dram_clktree_c1d1u1 = dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 / 100;
1897
}
1898
1899
out:
1900
if (update_type == TRAINING_UPDATE)
1901
{
1902
dst_emc_entry->trained_dram_clktree_c0d0u0 = dst_emc_entry->current_dram_clktree_c0d0u0;
1903
dst_emc_entry->trained_dram_clktree_c0d0u1 = dst_emc_entry->current_dram_clktree_c0d0u1;
1904
dst_emc_entry->trained_dram_clktree_c0d1u0 = dst_emc_entry->current_dram_clktree_c0d1u0;
1905
dst_emc_entry->trained_dram_clktree_c0d1u1 = dst_emc_entry->current_dram_clktree_c0d1u1;
1906
dst_emc_entry->trained_dram_clktree_c1d0u0 = dst_emc_entry->current_dram_clktree_c1d0u0;
1907
dst_emc_entry->trained_dram_clktree_c1d0u1 = dst_emc_entry->current_dram_clktree_c1d0u1;
1908
dst_emc_entry->trained_dram_clktree_c1d1u0 = dst_emc_entry->current_dram_clktree_c1d1u0;
1909
dst_emc_entry->trained_dram_clktree_c1d1u1 = dst_emc_entry->current_dram_clktree_c1d1u1;
1910
}
1911
1912
return (u32)adelta;
1913
}
1914
1915
static u32 _minerva_periodic_compensation_handler(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 dram_dev_num, u32 channel1_enabled, enum comp_seq_t seq_type)
1916
{
1917
if (!dst_emc_entry->periodic_training)
1918
return 0;
1919
1920
u32 delay = 1000 * _actual_osc_clocks(src_emc_entry->run_clocks) / src_emc_entry->rate_khz + 2;
1921
1922
if (seq_type == DVFS_SEQUENCE)
1923
{
1924
if (src_emc_entry->periodic_training && dst_emc_entry->ptfv_list.ptfv_config_ctrl & 1)
1925
{
1926
u32 samples = dst_emc_entry->ptfv_list.ptfv_dvfs_samples;
1927
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 * samples;
1928
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 * samples;
1929
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 * samples;
1930
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 * samples;
1931
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 * samples;
1932
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 * samples;
1933
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 * samples;
1934
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 = src_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 * samples;
1935
}
1936
else
1937
{
1938
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 = 0;
1939
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 = 0;
1940
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 = 0;
1941
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 = 0;
1942
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 = 0;
1943
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 = 0;
1944
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 = 0;
1945
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 = 0;
1946
1947
for (u32 i = 0; i < dst_emc_entry->ptfv_list.ptfv_dvfs_samples; i++)
1948
{
1949
_start_periodic_compensation();
1950
_usleep(delay);
1951
_minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_PT1);
1952
}
1953
}
1954
1955
return _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_UPDATE);
1956
}
1957
else if (seq_type == WRITE_TRAINING_SEQUENCE)
1958
{
1959
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u0 = 0;
1960
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d0u1 = 0;
1961
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u0 = 0;
1962
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d0u1 = 0;
1963
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u0 = 0;
1964
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c0d1u1 = 0;
1965
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u0 = 0;
1966
dst_emc_entry->ptfv_list.ptfv_dqsosc_movavg_c1d1u1 = 0;
1967
1968
for (u32 i = 0; i < dst_emc_entry->ptfv_list.ptfv_write_samples; i++)
1969
{
1970
_start_periodic_compensation();
1971
_usleep(delay);
1972
_minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, TRAINING_PT1);
1973
}
1974
1975
return _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, TRAINING_UPDATE);
1976
}
1977
else if (seq_type == PERIODIC_TRAINING_SEQUENCE)
1978
{
1979
_start_periodic_compensation();
1980
_usleep(delay);
1981
return _minerva_update_clock_tree_delay(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, PERIODIC_TRAINING_UPDATE);
1982
}
1983
1984
return seq_type;
1985
}
1986
1987
#define STORE_TRIM_VAL(chan, rank, reg, byte) \
1988
((mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank##rank##_##reg >> \
1989
EMC_PMACRO_OB_DDLL_LONG_DQ_BYTE##byte##_SHIFT) & 0x7FF) \
1990
+ \
1991
(((mtc_table_entry->trim_perch_regs.emc##chan##_data_brlshft_##rank >> \
1992
EMC_DATA_BRLSHFT_##rank##_RANK##rank##_BYTE##byte##_DATA_BRLSHFT_SHIFT) & 0x7) << 6)
1993
1994
static u32 _minerva_apply_periodic_compensation_trimmer(emc_table_t *mtc_table_entry, u32 trim_emc_reg_addr)
1995
{
1996
u32 trimmer = 0;
1997
s32 tree_delta[4] = {0};
1998
s32 tree_delta_taps[4] = {0};
1999
s32 new_trim[] = {
2000
// chan, rank, reg, byte.
2001
STORE_TRIM_VAL(0, 0, 0, 0),
2002
STORE_TRIM_VAL(0, 0, 0, 1),
2003
STORE_TRIM_VAL(0, 0, 1, 2),
2004
STORE_TRIM_VAL(0, 0, 1, 3),
2005
2006
STORE_TRIM_VAL(1, 0, 2, 4),
2007
STORE_TRIM_VAL(1, 0, 2, 5),
2008
STORE_TRIM_VAL(1, 0, 3, 6),
2009
STORE_TRIM_VAL(1, 0, 3, 7),
2010
2011
STORE_TRIM_VAL(0, 1, 0, 0),
2012
STORE_TRIM_VAL(0, 1, 0, 1),
2013
STORE_TRIM_VAL(0, 1, 1, 2),
2014
STORE_TRIM_VAL(0, 1, 1, 3),
2015
2016
STORE_TRIM_VAL(1, 1, 2, 4),
2017
STORE_TRIM_VAL(1, 1, 2, 5),
2018
STORE_TRIM_VAL(1, 1, 3, 6),
2019
STORE_TRIM_VAL(1, 1, 3, 7)
2020
};
2021
2022
u32 dst_rate_mhz = mtc_table_entry->rate_khz / 1000;
2023
2024
switch (trim_emc_reg_addr)
2025
{
2026
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0:
2027
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1:
2028
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2:
2029
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3:
2030
case EMC_DATA_BRLSHFT_0:
2031
tree_delta[0] = (mtc_table_entry->current_dram_clktree_c0d0u0 - mtc_table_entry->trained_dram_clktree_c0d0u0) * 128;
2032
tree_delta[1] = (mtc_table_entry->current_dram_clktree_c0d0u1 - mtc_table_entry->trained_dram_clktree_c0d0u1) * 128;
2033
tree_delta[2] = (mtc_table_entry->current_dram_clktree_c1d0u0 - mtc_table_entry->trained_dram_clktree_c1d0u0) * 128;
2034
tree_delta[3] = (mtc_table_entry->current_dram_clktree_c1d0u1 - mtc_table_entry->trained_dram_clktree_c1d0u1) * 128;
2035
tree_delta_taps[0] = (tree_delta[0] * (s32)dst_rate_mhz) / 1000000;
2036
tree_delta_taps[1] = (tree_delta[1] * (s32)dst_rate_mhz) / 1000000;
2037
tree_delta_taps[2] = (tree_delta[2] * (s32)dst_rate_mhz) / 1000000;
2038
tree_delta_taps[3] = (tree_delta[3] * (s32)dst_rate_mhz) / 1000000;
2039
for (u32 i = 0; i < 4; i++)
2040
{
2041
// Check if tap exceeds margins and apply it.
2042
if ((tree_delta_taps[i] > (s32)mtc_table_entry->tree_margin) || (tree_delta_taps[i] < (-1 * (s32)mtc_table_entry->tree_margin)))
2043
{
2044
new_trim[i * 2] += tree_delta_taps[i];
2045
new_trim[i * 2 + 1] += tree_delta_taps[i];
2046
}
2047
}
2048
if (trim_emc_reg_addr == EMC_DATA_BRLSHFT_0)
2049
{
2050
for (u32 i = 0; i < 8; i++)
2051
new_trim[i] /= 64;
2052
}
2053
else
2054
{
2055
for (u32 i = 0; i < 8; i++)
2056
new_trim[i] %= 64;
2057
}
2058
break;
2059
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0:
2060
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1:
2061
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2:
2062
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3:
2063
case EMC_DATA_BRLSHFT_1:
2064
tree_delta[0] = (mtc_table_entry->current_dram_clktree_c0d1u0 - mtc_table_entry->trained_dram_clktree_c0d1u0) * 128;
2065
tree_delta[1] = (mtc_table_entry->current_dram_clktree_c0d1u1 - mtc_table_entry->trained_dram_clktree_c0d1u1) * 128;
2066
tree_delta[2] = (mtc_table_entry->current_dram_clktree_c1d1u0 - mtc_table_entry->trained_dram_clktree_c1d1u0) * 128;
2067
tree_delta[3] = (mtc_table_entry->current_dram_clktree_c1d1u1 - mtc_table_entry->trained_dram_clktree_c1d1u1) * 128;
2068
tree_delta_taps[0] = (tree_delta[0] * (s32)dst_rate_mhz) / 1000000;
2069
tree_delta_taps[1] = (tree_delta[1] * (s32)dst_rate_mhz) / 1000000;
2070
tree_delta_taps[2] = (tree_delta[2] * (s32)dst_rate_mhz) / 1000000;
2071
tree_delta_taps[3] = (tree_delta[3] * (s32)dst_rate_mhz) / 1000000;
2072
for (u32 i = 0; i < 4; i++)
2073
{
2074
// Check if tap exceeds margins and apply it.
2075
if ((tree_delta_taps[i] > (s32)mtc_table_entry->tree_margin) || (tree_delta_taps[i] < (-1 * (s32)mtc_table_entry->tree_margin)))
2076
{
2077
new_trim[8 + i * 2] += tree_delta_taps[i];
2078
new_trim[8 + i * 2 + 1] += tree_delta_taps[i];
2079
}
2080
}
2081
if (trim_emc_reg_addr == EMC_DATA_BRLSHFT_1)
2082
{
2083
for (u32 i = 0; i < 8; i++)
2084
new_trim[i + 8] /= 64;
2085
}
2086
else
2087
{
2088
for (u32 i = 0; i < 8; i++)
2089
new_trim[i + 8] %= 64;
2090
}
2091
break;
2092
default:
2093
break;
2094
}
2095
2096
switch (trim_emc_reg_addr)
2097
{
2098
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0:
2099
trimmer = (new_trim[0] & 0x7FF) | ((new_trim[1] & 0x7FF) << 16);
2100
break;
2101
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1:
2102
trimmer = (new_trim[2] & 0x7FF) | ((new_trim[3] & 0x7FF) << 16);
2103
break;
2104
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2:
2105
trimmer = (new_trim[4] & 0x7FF) | ((new_trim[5] & 0x7FF) << 16);
2106
break;
2107
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3:
2108
trimmer = (new_trim[6] & 0x7FF) | ((new_trim[7] & 0x7FF) << 16);
2109
break;
2110
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0:
2111
trimmer = (new_trim[8] & 0x7FF) | ((new_trim[9] & 0x7FF) << 16);
2112
break;
2113
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1:
2114
trimmer = (new_trim[10] & 0x7FF) | ((new_trim[11] & 0x7FF) << 16);
2115
break;
2116
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2:
2117
trimmer = (new_trim[12] & 0x7FF) | ((new_trim[13] & 0x7FF) << 16);
2118
break;
2119
case EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3:
2120
trimmer = (new_trim[14] & 0x7FF) | ((new_trim[15] & 0x7FF) << 16);
2121
break;
2122
case EMC_DATA_BRLSHFT_0:
2123
trimmer = ((new_trim[0] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE0_DATA_BRLSHFT_SHIFT)
2124
| ((new_trim[1] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE1_DATA_BRLSHFT_SHIFT)
2125
| ((new_trim[2] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE2_DATA_BRLSHFT_SHIFT)
2126
| ((new_trim[3] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE3_DATA_BRLSHFT_SHIFT)
2127
| ((new_trim[4] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE4_DATA_BRLSHFT_SHIFT)
2128
| ((new_trim[5] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE5_DATA_BRLSHFT_SHIFT)
2129
| ((new_trim[6] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE6_DATA_BRLSHFT_SHIFT)
2130
| ((new_trim[7] & 7) << EMC_DATA_BRLSHFT_0_RANK0_BYTE7_DATA_BRLSHFT_SHIFT);
2131
break;
2132
case EMC_DATA_BRLSHFT_1:
2133
trimmer = ((new_trim[8] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE0_DATA_BRLSHFT_SHIFT)
2134
| ((new_trim[9] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE1_DATA_BRLSHFT_SHIFT)
2135
| ((new_trim[10] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE2_DATA_BRLSHFT_SHIFT)
2136
| ((new_trim[11] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE3_DATA_BRLSHFT_SHIFT)
2137
| ((new_trim[12] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE4_DATA_BRLSHFT_SHIFT)
2138
| ((new_trim[13] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE5_DATA_BRLSHFT_SHIFT)
2139
| ((new_trim[14] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE6_DATA_BRLSHFT_SHIFT)
2140
| ((new_trim[15] & 7) << EMC_DATA_BRLSHFT_1_RANK1_BYTE7_DATA_BRLSHFT_SHIFT);
2141
break;
2142
default:
2143
break;
2144
}
2145
2146
return trimmer;
2147
}
2148
2149
static bool _check_freq_changed(u32 dst_entry_rate_KHz, u32 dst_entry_clk_src_emc, u32 src_entry_rate_KHz, u32 src_entry_clk_src_emc)
2150
{
2151
u64 dst_div_clock;
2152
u64 src_div_clock;
2153
u32 src_end_div_clk_ratio;
2154
2155
u32 src_entry_emc_2X_clk_src = src_entry_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;
2156
u32 dst_entry_emc_2X_clk_src = dst_entry_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;
2157
u32 src_entry_emc_2X_clk_src_div = src_entry_clk_src_emc & 0xFF;
2158
u32 dst_entry_emc_2X_clk_src_div = dst_entry_clk_src_emc & 0xFF;
2159
u32 pll_post_divider = 0;
2160
2161
switch (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) >> EMC_2X_CLK_SRC_SHIFT)
2162
{
2163
case PLLM_OUT0:
2164
case PLLM_UD:
2165
pll_post_divider = (CLOCK(CLK_RST_CONTROLLER_PLLM_BASE) >> 20) & 0x1F;
2166
break;
2167
case PLLMB_UD:
2168
case PLLMB_OUT0:
2169
pll_post_divider = (CLOCK(CLK_RST_CONTROLLER_PLLMB_BASE) >> 20) & 0x1F;
2170
break;
2171
default:
2172
break;
2173
}
2174
2175
// Hang if post div is wrong.
2176
if (pll_post_divider > 5)
2177
while (true)
2178
;
2179
2180
if (src_entry_emc_2X_clk_src <= PLLMB_UD)
2181
src_entry_emc_2X_clk_src_div = 0;
2182
if (dst_entry_emc_2X_clk_src <= PLLMB_UD)
2183
dst_entry_emc_2X_clk_src_div = 0;
2184
2185
if (dst_entry_emc_2X_clk_src != src_entry_emc_2X_clk_src
2186
&& (dst_entry_emc_2X_clk_src & 0xFFFFFFFB || src_entry_emc_2X_clk_src & 0xFFFFFFFB))
2187
return true;
2188
2189
dst_div_clock = dst_entry_rate_KHz * (pll_post_divider + 1)
2190
* ((dst_entry_emc_2X_clk_src_div >> 1) * 10 + (dst_entry_emc_2X_clk_src_div & 1) * 5 + 10) / 10; // Accounting for 7.1 div.
2191
src_div_clock = src_entry_rate_KHz * (pll_post_divider + 1)
2192
* ((src_entry_emc_2X_clk_src_div >> 1) * 10 + (src_entry_emc_2X_clk_src_div & 1) * 5 + 10) / 10; // Accounting for 7.1 div.
2193
2194
src_end_div_clk_ratio = (src_div_clock * 1000) / dst_div_clock;
2195
2196
if (src_end_div_clk_ratio > 1010 || src_end_div_clk_ratio < 990)
2197
return true;
2198
else
2199
return false;
2200
}
2201
2202
static void _save_train_results(emc_table_t *mtc_table_entry, u32 needs_training, u32 dram_dev_num, bool channel1_enabled)
2203
{
2204
bool needs_ca_training = !!(needs_training & NEEDS_TRAINING_CA);
2205
bool needs_ca_vref_training = !!(needs_training & NEEDS_TRAINING_CA_VREF);
2206
bool needs_quse_training = !!(needs_training & NEEDS_TRAINING_QUSE);
2207
bool needs_quse_vref_training = !!(needs_training & NEEDS_TRAINING_QUSE_VREF);
2208
bool needs_wr_training = !!(needs_training & NEEDS_TRAINING_WR);
2209
bool needs_wr_vref_training = !!(needs_training & NEEDS_TRAINING_WR_VREF);
2210
bool needs_rd_training = !!(needs_training & NEEDS_TRAINING_RD);
2211
bool needs_rd_vref_training = !!(needs_training & NEEDS_TRAINING_RD_VREF);
2212
bool needs_training_in_self_refresh = !!(needs_training & NEEDS_TRAINING_IN_SELF_REFRESH);
2213
2214
if (needs_ca_training)
2215
{
2216
mtc_table_entry->trim_perch_regs.emc_cmd_brlshft_0 = EMC_CH0(EMC_CMD_BRLSHFT_0);
2217
mtc_table_entry->trim_perch_regs.emc_cmd_brlshft_1 = channel1_enabled ? EMC_CH1(EMC_CMD_BRLSHFT_1) : 0;
2218
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_4 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_4);
2219
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_5 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_5) : 0;
2220
2221
if (needs_training_in_self_refresh)
2222
{
2223
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_0);
2224
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_1);
2225
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd0_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD0_2);
2226
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_0);
2227
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_1);
2228
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd1_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD1_2);
2229
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_0);
2230
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_1);
2231
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd2_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD2_2);
2232
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_0 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_0);
2233
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_1 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_1);
2234
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_cmd3_2 = EMC(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_CMD3_2);
2235
}
2236
}
2237
2238
if (needs_ca_vref_training)
2239
{
2240
mtc_table_entry->burst_reg_per_ch.emc0_mrw10 = (EMC_CH0(EMC_TRAINING_OPT_CA_VREF) & 0xFFFF) | 0x880C0000;
2241
mtc_table_entry->burst_reg_per_ch.emc1_mrw10 = (channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) & 0xFFFF : 0) | 0x880C0000;
2242
2243
u32 mrw11_dev_selectn;
2244
if (dram_dev_num == TWO_RANK)
2245
mrw11_dev_selectn = 0x480C0000;
2246
else
2247
mrw11_dev_selectn = 0xC80C0000;
2248
2249
mtc_table_entry->burst_reg_per_ch.emc0_mrw11 =
2250
((EMC_CH0(EMC_TRAINING_OPT_CA_VREF) >> 16) & 0xFF)
2251
| (EMC_CH0(EMC_TRAINING_OPT_CA_VREF) >> 24 << 8)
2252
| (mrw11_dev_selectn & 0xFFFFFF00);
2253
2254
mtc_table_entry->burst_reg_per_ch.emc1_mrw11 =
2255
(((channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) : 0) >> 16) & 0xFF)
2256
| ((channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_CA_VREF) : 0) >> 24 << 8)
2257
| (mrw11_dev_selectn & 0xFFFFFF00);
2258
}
2259
2260
if (needs_quse_training || needs_rd_training)
2261
{
2262
mtc_table_entry->trim_perch_regs.emc_quse_brlshft_0 = EMC_CH0(EMC_QUSE_BRLSHFT_0);
2263
mtc_table_entry->trim_perch_regs.emc_quse_brlshft_1 = channel1_enabled ? EMC_CH1(EMC_QUSE_BRLSHFT_1) : 0;
2264
2265
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_0 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK0_0);
2266
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_1 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK0_1);
2267
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK0_2) : 0;
2268
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank0_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK0_3) : 0;
2269
2270
if (dram_dev_num == TWO_RANK)
2271
{
2272
mtc_table_entry->trim_perch_regs.emc_quse_brlshft_2 = EMC_CH0(EMC_QUSE_BRLSHFT_2);
2273
mtc_table_entry->trim_perch_regs.emc_quse_brlshft_3 = channel1_enabled ? EMC_CH1(EMC_QUSE_BRLSHFT_3) : 0;
2274
2275
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_0 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK1_0);
2276
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_1 = EMC_CH0(EMC_PMACRO_QUSE_DDLL_RANK1_1);
2277
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK1_2) : 0;
2278
mtc_table_entry->trim_regs.emc_pmacro_quse_ddll_rank1_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_QUSE_DDLL_RANK1_3) : 0;
2279
}
2280
}
2281
2282
if (needs_quse_vref_training)
2283
{
2284
if (dram_dev_num == TWO_RANK)
2285
{
2286
u32 emc0_opt_dqs_array[4] = {0};
2287
u32 emc1_opt_dqs_array[4] = {0};
2288
u32 emc1_training_opt_dqs_ib_vref_rank0_val = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQS_IB_VREF_RANK0) : 0;
2289
u32 emc1_training_opt_dqs_ib_vref_rank1_val = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQS_IB_VREF_RANK1) : 0;
2290
2291
for (u32 i = 0; i < 4; i++)
2292
{
2293
emc0_opt_dqs_array[i] = (EMC_CH0(EMC_TRAINING_OPT_DQS_IB_VREF_RANK0) >> (8 * i)) & 0xFF;
2294
emc1_opt_dqs_array[i] = (emc1_training_opt_dqs_ib_vref_rank0_val >> (8 * i)) & 0xFF;
2295
}
2296
2297
u32 ib_vref_dqs_0 = 0;
2298
u32 ib_vref_dqs_1 = 0;
2299
for (u32 i = 0; i < 4; i++)
2300
{
2301
ib_vref_dqs_0 |= (emc0_opt_dqs_array[i] + ((EMC_CH0(EMC_TRAINING_OPT_DQS_IB_VREF_RANK1) >> (8 * i)) & 0xFF)) >> 1 << (8 * i);
2302
ib_vref_dqs_1 |= (emc1_opt_dqs_array[i] + ((emc1_training_opt_dqs_ib_vref_rank1_val >> (8 * i)) & 0xFF)) >> 1 << (8 * i);
2303
}
2304
2305
mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_0 = ib_vref_dqs_0;
2306
mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_1 = ib_vref_dqs_1;
2307
}
2308
else
2309
{
2310
mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_0 = EMC(EMC_PMACRO_IB_VREF_DQS_0);
2311
mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dqs_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_VREF_DQS_1) : 0;
2312
}
2313
}
2314
2315
if (needs_rd_training)
2316
{
2317
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_0);
2318
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_1);
2319
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_2) : 0;
2320
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank0_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK0_3) : 0;
2321
2322
if (dram_dev_num == TWO_RANK)
2323
{
2324
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_0);
2325
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_1);
2326
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_2) : 0;
2327
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_long_dqs_rank1_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_LONG_DQS_RANK1_3) : 0;
2328
}
2329
2330
if (needs_training_in_self_refresh)
2331
{
2332
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_0);
2333
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_1);
2334
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte0_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE0_2);
2335
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_0);
2336
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_1);
2337
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte1_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE1_2);
2338
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_0);
2339
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_1);
2340
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte2_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE2_2);
2341
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_0);
2342
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_1);
2343
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte3_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE3_2);
2344
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_0) : 0;
2345
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_1) : 0;
2346
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE4_2) : 0;
2347
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_0) : 0;
2348
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_1) : 0;
2349
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE5_2) : 0;
2350
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_0) : 0;
2351
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_1) : 0;
2352
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE6_2) : 0;
2353
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_0) : 0;
2354
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_1) : 0;
2355
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank0_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK0_BYTE7_2) : 0;
2356
2357
if (dram_dev_num == TWO_RANK)
2358
{
2359
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_0);
2360
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_1);
2361
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte0_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE0_2);
2362
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_0);
2363
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_1);
2364
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte1_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE1_2);
2365
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_0);
2366
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_1);
2367
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte2_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE2_2);
2368
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_0 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_0);
2369
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_1 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_1);
2370
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte3_2 = EMC_CH0(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE3_2);
2371
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_0) : 0;
2372
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_1) : 0;
2373
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE4_2) : 0;
2374
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_0) : 0;
2375
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_1) : 0;
2376
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE5_2) : 0;
2377
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_0) : 0;
2378
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_1) : 0;
2379
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE6_2) : 0;
2380
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_0) : 0;
2381
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_1) : 0;
2382
mtc_table_entry->trim_regs.emc_pmacro_ib_ddll_short_dq_rank1_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_IB_DDLL_SHORT_DQ_RANK1_BYTE7_2) : 0;
2383
}
2384
}
2385
2386
if (needs_rd_vref_training)
2387
{
2388
char ib_vref_dq_byte0_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_0) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[0] & 0x7F);
2389
if (mtc_table_entry->save_restore_mod_regs[0] & 0x80000000) // < 0 check.
2390
ib_vref_dq_byte0_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_0) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[0] & 0x7F);
2391
2392
char ib_vref_dq_byte1_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 8) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[1] & 0x7F);
2393
if (mtc_table_entry->save_restore_mod_regs[1] & 0x80000000)
2394
ib_vref_dq_byte1_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 8) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[1] & 0x7F);
2395
2396
char ib_vref_dq_byte2_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 16) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[2] & 0x7F);
2397
if (mtc_table_entry->save_restore_mod_regs[2] & 0x80000000)
2398
ib_vref_dq_byte2_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 16) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[2] & 0x7F);
2399
2400
char ib_vref_dq_byte3_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 24) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[3] & 0x7F);
2401
if (mtc_table_entry->save_restore_mod_regs[3] & 0x80000000)
2402
ib_vref_dq_byte3_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_0) >> 24) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[3] & 0x7F);
2403
2404
mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dq_0 =
2405
((ib_vref_dq_byte0_icr & 0x7F)
2406
| (ib_vref_dq_byte1_icr & 0x7F) << 8)
2407
| ((ib_vref_dq_byte2_icr & 0x7F) << 16)
2408
| ((ib_vref_dq_byte3_icr & 0x7F) << 24);
2409
2410
char ib_vref_dq_byte4_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_1) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[4] & 0x7F);
2411
if (mtc_table_entry->save_restore_mod_regs[4] & 0x80000000)
2412
ib_vref_dq_byte4_icr = (EMC(EMC_PMACRO_IB_VREF_DQ_1) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[4] & 0x7F);
2413
2414
char ib_vref_dq_byte5_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 8) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[5] & 0x7F);
2415
if (mtc_table_entry->save_restore_mod_regs[5] & 0x80000000)
2416
ib_vref_dq_byte5_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 8) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[5] & 0x7F);
2417
2418
char ib_vref_dq_byte6_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 16) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[6] & 0x7F);
2419
if (mtc_table_entry->save_restore_mod_regs[6] & 0x80000000)
2420
ib_vref_dq_byte6_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 16) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[6] & 0x7F);
2421
2422
char ib_vref_dq_byte7_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 24) & 0x7F) + (mtc_table_entry->save_restore_mod_regs[7] & 0x7F);
2423
if (mtc_table_entry->save_restore_mod_regs[7] & 0x80000000)
2424
ib_vref_dq_byte7_icr = ((EMC(EMC_PMACRO_IB_VREF_DQ_1) >> 24) & 0x7F) - (mtc_table_entry->save_restore_mod_regs[7] & 0x7F);
2425
2426
mtc_table_entry->trim_regs.emc_pmacro_ib_vref_dq_1 =
2427
((ib_vref_dq_byte4_icr & 0x7F)
2428
| (ib_vref_dq_byte5_icr & 0x7F) << 8)
2429
| ((ib_vref_dq_byte6_icr & 0x7F) << 16)
2430
| ((ib_vref_dq_byte7_icr & 0x7F) << 24);
2431
}
2432
}
2433
2434
if (needs_wr_training)
2435
{
2436
mtc_table_entry->trim_perch_regs.emc0_data_brlshft_0 = EMC_CH0(EMC_DATA_BRLSHFT_0);
2437
mtc_table_entry->trim_perch_regs.emc1_data_brlshft_0 = channel1_enabled ? EMC_CH1(EMC_DATA_BRLSHFT_0) : 0;
2438
2439
if (dram_dev_num == TWO_RANK)
2440
{
2441
mtc_table_entry->trim_perch_regs.emc0_data_brlshft_1 = EMC_CH0(EMC_DATA_BRLSHFT_1);
2442
mtc_table_entry->trim_perch_regs.emc1_data_brlshft_1 = channel1_enabled ? EMC_CH1(EMC_DATA_BRLSHFT_1) : 0;
2443
}
2444
2445
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0);
2446
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_1);
2447
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_2) : 0;
2448
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank0_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_3) : 0;
2449
2450
if (dram_dev_num == TWO_RANK)
2451
{
2452
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0);
2453
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_1);
2454
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_2) : 0;
2455
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_long_dq_rank1_3 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_3) : 0;
2456
}
2457
2458
if (needs_training_in_self_refresh)
2459
{
2460
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_0);
2461
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_1);
2462
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte0_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE0_2);
2463
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_0);
2464
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_1);
2465
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte1_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE1_2);
2466
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_0);
2467
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_1);
2468
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte2_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE2_2);
2469
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_0);
2470
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_1);
2471
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte3_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE3_2);
2472
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_0) : 0;
2473
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_1) : 0;
2474
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE4_2) : 0;
2475
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_0) : 0;
2476
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_1) : 0;
2477
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE5_2) : 0;
2478
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_0) : 0;
2479
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_1) : 0;
2480
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE6_2) : 0;
2481
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_0) : 0;
2482
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_1) : 0;
2483
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank0_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK0_BYTE7_2) : 0;
2484
2485
if (dram_dev_num == TWO_RANK)
2486
{
2487
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_0);
2488
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_1);
2489
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte0_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE0_2);
2490
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_0);
2491
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_1);
2492
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte1_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE1_2);
2493
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_0);
2494
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_1);
2495
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte2_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE2_2);
2496
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_0 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_0);
2497
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_1 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_1);
2498
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte3_2 = EMC_CH0(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE3_2);
2499
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_0) : 0;
2500
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_1) : 0;
2501
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte4_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE4_2) : 0;
2502
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_0) : 0;
2503
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_1) : 0;
2504
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte5_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE5_2) : 0;
2505
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_0) : 0;
2506
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_1) : 0;
2507
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte6_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE6_2) : 0;
2508
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_0 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_0) : 0;
2509
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_1 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_1) : 0;
2510
mtc_table_entry->trim_regs.emc_pmacro_ob_ddll_short_dq_rank1_byte7_2 = channel1_enabled ? EMC_CH1(EMC_PMACRO_OB_DDLL_SHORT_DQ_RANK1_BYTE7_2) : 0;
2511
}
2512
}
2513
2514
if (needs_wr_vref_training) // mode 12/13 (MRW).
2515
{
2516
u32 emc1_ranks_sub_partitions = 0;
2517
emc1_ranks_sub_partitions = channel1_enabled ? EMC_CH1(EMC_TRAINING_OPT_DQ_OB_VREF) : 0;
2518
2519
u8 emc0_ib_vref_dq_byte8_modded_plus = mtc_table_entry->save_restore_mod_regs[8] + EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF);
2520
if (mtc_table_entry->save_restore_mod_regs[8] & 0x80000000) // < 0 check.
2521
emc0_ib_vref_dq_byte8_modded_plus = EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) - mtc_table_entry->save_restore_mod_regs[8];
2522
2523
u8 emc0_mrw12_op_sp1 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) & 0xFFFF) >> 8) + mtc_table_entry->save_restore_mod_regs[9];
2524
if (mtc_table_entry->save_restore_mod_regs[9] & 0x80000000)
2525
emc0_mrw12_op_sp1 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) & 0xFFFF) >> 8) - mtc_table_entry->save_restore_mod_regs[9];
2526
2527
u8 emc0_mrw13_op_sp0 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 16) & 0xFF) + mtc_table_entry->save_restore_mod_regs[8];
2528
if (mtc_table_entry->save_restore_mod_regs[8] & 0x80000000)
2529
emc0_mrw13_op_sp0 = ((EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 16) & 0xFF) - mtc_table_entry->save_restore_mod_regs[8];
2530
2531
u8 emc0_ib_vref_dq_byte9_modded_a_plus = mtc_table_entry->save_restore_mod_regs[9] + (EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 24);
2532
if (mtc_table_entry->save_restore_mod_regs[9] & 0x80000000)
2533
emc0_ib_vref_dq_byte9_modded_a_plus = (EMC_CH0(EMC_TRAINING_OPT_DQ_OB_VREF) >> 24) - (u8)mtc_table_entry->save_restore_mod_regs[9];
2534
2535
u8 emc0_ib_vref_dq_byte10_modded_plus = emc1_ranks_sub_partitions + mtc_table_entry->save_restore_mod_regs[10];
2536
if (mtc_table_entry->save_restore_mod_regs[10] & 0x80000000)
2537
emc0_ib_vref_dq_byte10_modded_plus = emc1_ranks_sub_partitions - mtc_table_entry->save_restore_mod_regs[10];
2538
2539
u8 emc0_ib_vref_dq_byte11_modded_plus = ((emc1_ranks_sub_partitions & 0xFFFF) >> 8) + mtc_table_entry->save_restore_mod_regs[11];
2540
if (mtc_table_entry->save_restore_mod_regs[11] & 0x80000000)
2541
emc0_ib_vref_dq_byte11_modded_plus = ((emc1_ranks_sub_partitions & 0xFFFF) >> 8) - mtc_table_entry->save_restore_mod_regs[11];
2542
2543
u8 emc1_mrw13_op_sp0 = ((emc1_ranks_sub_partitions >> 16) & 0xFF) + mtc_table_entry->save_restore_mod_regs[10];
2544
if (mtc_table_entry->save_restore_mod_regs[10] & 0x80000000)
2545
emc1_mrw13_op_sp0 = ((emc1_ranks_sub_partitions >> 16) & 0xFF) - mtc_table_entry->save_restore_mod_regs[10];
2546
2547
u8 emc1_mrw13_op_sp1 = (emc1_ranks_sub_partitions >> 24) + mtc_table_entry->save_restore_mod_regs[11];
2548
if (mtc_table_entry->save_restore_mod_regs[11] & 0x80000000)
2549
emc1_mrw13_op_sp1 = (emc1_ranks_sub_partitions >> 24) - mtc_table_entry->save_restore_mod_regs[11];
2550
2551
u32 mr13_dev_ext_cnt_sp_addr = 0xC80E0000;
2552
if (dram_dev_num == TWO_RANK)
2553
mr13_dev_ext_cnt_sp_addr = 0x480E0000;
2554
2555
mtc_table_entry->burst_reg_per_ch.emc1_mrw12 = (u8)emc0_ib_vref_dq_byte10_modded_plus | 0x880E0000 | (emc0_ib_vref_dq_byte11_modded_plus << 8);
2556
mtc_table_entry->burst_reg_per_ch.emc0_mrw12 = emc0_ib_vref_dq_byte8_modded_plus | 0x880E0000 | (emc0_mrw12_op_sp1 << 8);
2557
mtc_table_entry->burst_reg_per_ch.emc0_mrw13 = emc0_ib_vref_dq_byte9_modded_a_plus << 8 | emc0_mrw13_op_sp0 | mr13_dev_ext_cnt_sp_addr;
2558
mtc_table_entry->burst_reg_per_ch.emc1_mrw13 = (emc1_mrw13_op_sp1 << 8) | emc1_mrw13_op_sp0 | mr13_dev_ext_cnt_sp_addr;
2559
}
2560
}
2561
}
2562
2563
static u32 _minerva_change_clock(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, u32 needs_training, u32 selected_clk_src_emc)
2564
{
2565
u32 emc_dbg_o;
2566
u32 emc_pin_o;
2567
u32 emc_cfg_pipe_clk_o;
2568
u32 emc_sel_dpd_ctrl;
2569
u32 emc_cfg;
2570
u32 emc_dbg_val;
2571
u32 emc_zq_cal = 0;
2572
u32 ramp_up_wait;
2573
u32 ramp_down_wait;
2574
u32 bg_regulator_mode_change;
2575
u32 mr13_flip_fspop;
2576
u32 mr13_flip_fspwr;
2577
u32 mr13_catr_enable;
2578
2579
/* needs_training flags */
2580
/*
2581
| bit | Description |
2582
|-----|----------------------------------|
2583
| 0 | Needs CA training |
2584
| 1 | Needs CA_VREF training |
2585
| 2 | Needs QUSE training |
2586
| 3 | Needs QUSE_VREF training |
2587
| 4 | Needs WR training |
2588
| 5 | Needs WR_VREF training |
2589
| 6 | Needs RD training |
2590
| 7 | Needs RD_VREF training |
2591
| 8 | Needs SWAP_RANK training |
2592
| 9 | Needs IN_SELF_REFRESH training |
2593
*/
2594
2595
bool compensate_trimmer_applicable = false;
2596
bool in_training = !!(needs_training & NEEDS_TRAINING);
2597
2598
bool needs_ca_combo_training = !!(needs_training & NEEDS_TRAINING_CA_COMBO);
2599
bool needs_ca_training = !!(needs_training & NEEDS_TRAINING_CA);
2600
bool needs_ca_vref_training = !!(needs_training & NEEDS_TRAINING_CA_VREF);
2601
bool needs_quse_training = !!(needs_training & NEEDS_TRAINING_QUSE);
2602
bool needs_quse_vref_training = !!(needs_training & NEEDS_TRAINING_QUSE_VREF);
2603
bool needs_wr_training = !!(needs_training & NEEDS_TRAINING_WR);
2604
bool needs_wr_vref_training = !!(needs_training & NEEDS_TRAINING_WR_VREF);
2605
bool needs_rd_training = !!(needs_training & NEEDS_TRAINING_RD);
2606
bool needs_rd_vref_training = !!(needs_training & NEEDS_TRAINING_RD_VREF);
2607
bool needs_swap_rank_training = !!(needs_training & NEEDS_TRAINING_SWAP_RANK);
2608
2609
bool zcal_resistor_shared = (src_emc_entry->burst_regs.emc_zcal_wait_cnt >> 31) & 1;
2610
bool enable_bg_regulator = (dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 1) ^ 1;
2611
bool channel1_enabled = (src_emc_entry->burst_regs.emc_fbio_cfg7 >> 2) & 1;
2612
u32 dram_type = EMC(EMC_FBIO_CFG5) & 3;
2613
u32 dram_dev_num = (MC(MC_EMEM_ADR_CFG) & 1) + 1;
2614
2615
u32 src_clock_period = 1000000000 / src_emc_entry->rate_khz; // In picoseconds.
2616
u32 dst_clock_period = 1000000000 / dst_emc_entry->rate_khz; // In picoseconds.
2617
2618
// Get current FSP op/write value.
2619
bool enable_fsp_opwr = !(EMC(EMC_MRW3) & 0xC0);
2620
2621
if (dram_type != DRAM_TYPE_LPDDR4)
2622
{
2623
EPRINTF("MTC Error: DRAM is not LPDDR4");
2624
return 5;
2625
}
2626
2627
u32 tFC_lpddr4 = dst_emc_entry->dram_timings.t_fc_lpddr4 * 1000;
2628
u32 tZQCAL_lpddr4 = 1000000;
2629
if (dst_clock_period <= 2000)
2630
tZQCAL_lpddr4 -= tFC_lpddr4;
2631
s32 tZQCAL_lpddr4_fc_adj = tZQCAL_lpddr4 / dst_clock_period;
2632
2633
(void)EMC(EMC_CFG);
2634
(void)EMC(EMC_AUTO_CAL_CONFIG);
2635
2636
// Step 1 - Pre DVFS SW sequence.
2637
EPRINTF("Step 1");
2638
emc_dbg_o = EMC(EMC_DBG);
2639
emc_pin_o = EMC(EMC_PIN);
2640
emc_cfg = dst_emc_entry->burst_regs.emc_cfg & 0xFFFFFFF;
2641
emc_sel_dpd_ctrl = dst_emc_entry->emc_sel_dpd_ctrl & 0xFFFFFEC3;
2642
emc_cfg_pipe_clk_o = EMC(EMC_CFG_PIPE_CLK);
2643
_digital_dll_disable();
2644
2645
// Step 1.2 - Disable AUTOCAL temporarily.
2646
EPRINTF("Step 1.2");
2647
EMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FF) | 0x600;
2648
(void)EMC(EMC_AUTO_CAL_CONFIG);
2649
2650
// Step 1.3 - Disable other power features.
2651
EPRINTF("Step 1.3");
2652
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
2653
EMC(EMC_CFG) = emc_cfg;
2654
EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl;
2655
EMC(EMC_DBG) = emc_dbg_o;
2656
2657
if (!in_training && dst_emc_entry->periodic_training)
2658
{
2659
if (dram_dev_num == TWO_RANK)
2660
{
2661
_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_BOTH_MASK, false, EMC_CHANNEL0);
2662
if (channel1_enabled)
2663
_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_BOTH_MASK, false, EMC_CHANNEL1);
2664
}
2665
else
2666
{
2667
_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_1DEV_MASK, false, EMC_CHANNEL0);
2668
if (channel1_enabled)
2669
_wait_emc_status(EMC_EMC_STATUS, IN_POWERDOWN_1DEV_MASK, false, EMC_CHANNEL1);
2670
}
2671
2672
_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, false, EMC_CHANNEL0);
2673
if (channel1_enabled)
2674
_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, false, EMC_CHANNEL1);
2675
2676
// Reset clock tree delays.
2677
dst_emc_entry->current_dram_clktree_c0d0u0 = dst_emc_entry->trained_dram_clktree_c0d0u0;
2678
dst_emc_entry->current_dram_clktree_c0d0u1 = dst_emc_entry->trained_dram_clktree_c0d0u1;
2679
dst_emc_entry->current_dram_clktree_c0d1u0 = dst_emc_entry->trained_dram_clktree_c0d1u0;
2680
dst_emc_entry->current_dram_clktree_c0d1u1 = dst_emc_entry->trained_dram_clktree_c0d1u1;
2681
dst_emc_entry->current_dram_clktree_c1d0u0 = dst_emc_entry->trained_dram_clktree_c1d0u0;
2682
dst_emc_entry->current_dram_clktree_c1d0u1 = dst_emc_entry->trained_dram_clktree_c1d0u1;
2683
dst_emc_entry->current_dram_clktree_c1d1u0 = dst_emc_entry->trained_dram_clktree_c1d1u0;
2684
dst_emc_entry->current_dram_clktree_c1d1u1 = dst_emc_entry->trained_dram_clktree_c1d1u1;
2685
2686
u32 adelta = _minerva_periodic_compensation_handler(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, DVFS_SEQUENCE);
2687
2688
if (((dst_emc_entry->rate_khz / 1000) * 128) * adelta / 1000000 > dst_emc_entry->tree_margin)
2689
compensate_trimmer_applicable = true;
2690
}
2691
2692
EMC(EMC_INTSTATUS) = CLKCHANGE_COMPLETE_INT;
2693
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
2694
EMC(EMC_CFG) = emc_cfg;
2695
EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl;
2696
EMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o | 1; // CLK_ALWAYS_ON.
2697
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = dst_emc_entry->emc_fdpd_ctrl_cmd_no_ramp & 0xFFFFFFFE;
2698
2699
bg_regulator_mode_change = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 ^ dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0;
2700
bg_regulator_mode_change = (bg_regulator_mode_change | (bg_regulator_mode_change >> 2)) & 1;
2701
2702
if (bg_regulator_mode_change)
2703
{
2704
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
2705
if (enable_bg_regulator)
2706
EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFE;
2707
else
2708
EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFB;
2709
}
2710
2711
// Check if we need to turn on VREF generator.
2712
if ((!(src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0x100) && (dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0x100)) ||
2713
(!(src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 1) && (dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 1)))
2714
{
2715
EMC(EMC_PMACRO_DATA_PAD_TX_CTRL) =
2716
(((dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 1) | (src_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl & 0xFFFFFFFE)) & 0xFFFFFEFF)
2717
| (((dst_emc_entry->burst_regs.emc_pmacro_data_pad_tx_ctrl >> 8) & 0x1) << 8);
2718
}
2719
2720
_usleep(1);
2721
2722
EMC(EMC_DBG) = emc_dbg_o;
2723
2724
// Step 2 - Prelock the DLL.
2725
EPRINTF("Step 2");
2726
if (dst_emc_entry->burst_regs.emc_cfg_dig_dll & 1)
2727
_digital_dll_prelock(dst_emc_entry, in_training, selected_clk_src_emc); // Prelock enabled for target frequency.
2728
else
2729
{
2730
_change_dll_src(dst_emc_entry, selected_clk_src_emc);
2731
_digital_dll_disable(); // Disabling DLL for target frequency.
2732
}
2733
2734
// Step 3 - Prepare autocal for the clock change.
2735
EPRINTF("Step 3");
2736
EMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FF) | 0x600;
2737
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
2738
EMC(EMC_AUTO_CAL_CONFIG2) = dst_emc_entry->emc_auto_cal_config2;
2739
EMC(EMC_AUTO_CAL_CONFIG3) = dst_emc_entry->emc_auto_cal_config3;
2740
EMC(EMC_AUTO_CAL_CONFIG4) = dst_emc_entry->emc_auto_cal_config4;
2741
EMC(EMC_AUTO_CAL_CONFIG5) = dst_emc_entry->emc_auto_cal_config5;
2742
EMC(EMC_AUTO_CAL_CONFIG6) = dst_emc_entry->emc_auto_cal_config6;
2743
EMC(EMC_AUTO_CAL_CONFIG7) = dst_emc_entry->emc_auto_cal_config7;
2744
EMC(EMC_AUTO_CAL_CONFIG8) = dst_emc_entry->emc_auto_cal_config8;
2745
EMC(EMC_DBG) = emc_dbg_o;
2746
EMC(EMC_AUTO_CAL_CONFIG) = (dst_emc_entry->emc_auto_cal_config & 0x7FFFF9FE) | 0x601;
2747
2748
// Step 4 - Update EMC_CFG.
2749
EPRINTF("Step 4");
2750
if (src_clock_period <= 50000)
2751
EMC(EMC_CFG_2) = dst_emc_entry->emc_cfg_2;
2752
else
2753
_ccfifo_write(EMC_SELF_REF, 1, 0);
2754
2755
// Step 5 - Prepare reference variables for ZQCAL regs.
2756
EPRINTF("Step 5");
2757
// u32 zq_wait_long = 0;
2758
// u32 zq_wait_short = 0;
2759
2760
// zq_wait_long = _fceil(1000.0f / dst_clock_period);
2761
2762
// Step 7 - Bug 200024907 - Patch RP R2P.
2763
EPRINTF("Step 7");
2764
if (needs_ca_combo_training && dram_dev_num == TWO_RANK)
2765
EMC(EMC_PIN) = 0x107;
2766
2767
u32 R2P_war = 0;
2768
u32 TRPab_war = 0;
2769
u32 RP_war = 0;
2770
u32 W2P_war = 0;
2771
2772
u32 nRTP = 8; // <= 1066MHz.
2773
if ( src_clock_period < 1000000 / 266 // 266MHz - 3759.39 ps.
2774
&& src_clock_period < 1000000 / 533 // 533MHz - 1876.17 ps.
2775
&& src_clock_period < 1000000 / 800 // 800MHz - 1250.00 ps.
2776
&& src_clock_period < 1000000 / 1066) // 1066MHz - 938.09 ps.
2777
nRTP = 10; // 1067MHz < x <= 1333MHz.
2778
if (src_clock_period < 1000000 / 1333) // 1333MHz - 750.19 ps.
2779
nRTP = 12; // 1333MHz < x <= 1600MHz.
2780
if (src_clock_period < 1000000 / 1600) // 1600MHz - 625.00 ps.
2781
nRTP = 14; // 1600MHz < x <= 1866MHz.
2782
if (src_clock_period < 1000000 / 1866) // 1866MHz - 535.91 ps.
2783
nRTP = 16; // > 1866MHz
2784
2785
u32 tRPST = (src_emc_entry->emc_mrw >> 7) & 1;
2786
2787
u32 deltaTWATM = _div_o3(7500, src_clock_period);
2788
if (deltaTWATM < 8)
2789
deltaTWATM = 8;
2790
2791
u32 tRTM = src_emc_entry->dram_timings.rl + _div_o3(3600, src_clock_period) + deltaTWATM + tRPST + nRTP + 1;
2792
2793
if (tRTM <= src_emc_entry->burst_regs.emc_rp + src_emc_entry->burst_regs.emc_r2p)
2794
{
2795
TRPab_war = src_emc_entry->burst_regs.emc_trpab;
2796
R2P_war = src_emc_entry->burst_regs.emc_r2p;
2797
RP_war = src_emc_entry->burst_regs.emc_rp;
2798
}
2799
else
2800
{
2801
R2P_war = tRTM - src_emc_entry->burst_regs.emc_rp;
2802
TRPab_war = src_emc_entry->burst_regs.emc_trpab;
2803
RP_war = src_emc_entry->burst_regs.emc_rp;
2804
if (R2P_war > 63)
2805
{
2806
RP_war = tRTM - 63;
2807
R2P_war = 63;
2808
if (src_emc_entry->burst_regs.emc_trpab < tRTM - 63)
2809
TRPab_war = tRTM - 63;
2810
else
2811
TRPab_war = src_emc_entry->burst_regs.emc_trpab;
2812
}
2813
}
2814
2815
if (RP_war >= deltaTWATM)
2816
W2P_war = src_emc_entry->burst_regs.emc_w2p;
2817
else
2818
{
2819
u32 W2P_war_temp = deltaTWATM + src_emc_entry->burst_regs.emc_w2p;
2820
W2P_war = W2P_war_temp - RP_war;
2821
if (W2P_war > 63)
2822
{
2823
RP_war = W2P_war_temp - 63;
2824
W2P_war = 63;
2825
if (TRPab_war < RP_war)
2826
TRPab_war = RP_war;
2827
}
2828
}
2829
2830
if (src_emc_entry->burst_regs.emc_w2p != W2P_war ||
2831
src_emc_entry->burst_regs.emc_rp != RP_war ||
2832
src_emc_entry->burst_regs.emc_r2p != R2P_war ||
2833
src_emc_entry->burst_regs.emc_trpab != TRPab_war)
2834
{
2835
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
2836
EMC(EMC_RP) = RP_war;
2837
EMC(EMC_R2P) = R2P_war;
2838
EMC(EMC_W2P) = W2P_war;
2839
EMC(EMC_TRPAB) = TRPab_war;
2840
EMC(EMC_DBG) = emc_dbg_o;
2841
(void)EMC(EMC_TRPAB);
2842
_usleep(1);
2843
}
2844
2845
// Step 7.2 - Program FSP reference registers and send MRWs to new FSPWR.
2846
EPRINTF("Step 7.2");
2847
if (enable_fsp_opwr)
2848
{
2849
mr13_flip_fspop = dst_emc_entry->emc_mrw3 | 0xC0;
2850
mr13_flip_fspwr = (dst_emc_entry->emc_mrw3 & 0xFFFFFF3F) | 0x40;
2851
}
2852
else
2853
{
2854
mr13_flip_fspop = dst_emc_entry->emc_mrw3 & 0xFFFFFF3F;
2855
mr13_flip_fspwr = mr13_flip_fspop | 0x80;
2856
}
2857
2858
if (dram_dev_num == TWO_RANK)
2859
{
2860
if (needs_swap_rank_training)
2861
mr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x40000001;
2862
else
2863
mr13_catr_enable = (mr13_flip_fspwr & 0x3FFFFFFF) | 0x80000001;
2864
2865
if (needs_ca_combo_training)
2866
{
2867
if (needs_swap_rank_training)
2868
mr13_flip_fspop = (mr13_flip_fspop & 0x3FFFFFFF) | 0x80000000;
2869
else
2870
mr13_flip_fspop = (mr13_flip_fspop & 0x3FFFFFFF) | 0x40000000;
2871
}
2872
}
2873
else
2874
mr13_catr_enable = mr13_flip_fspwr | 1;
2875
2876
EMC(EMC_MRW3) = mr13_flip_fspwr;
2877
EMC(EMC_MRW) = dst_emc_entry->emc_mrw;
2878
EMC(EMC_MRW2) = dst_emc_entry->emc_mrw2;
2879
2880
// Step 8 - Program the shadow registers.
2881
EPRINTF("Step 8");
2882
// Writing burst_regs.
2883
u32 reg_addr = 0;
2884
u32 reg_val = 0;
2885
burst_regs_table_t *dst_burst_regs = (burst_regs_table_t *)&dst_emc_entry->burst_regs;
2886
u32 *burst_val_table = dst_burst_regs->burst_regs;
2887
2888
if (in_training)
2889
{
2890
if (needs_ca_combo_training)
2891
burst_val_table = dst_burst_regs->shadow_regs_ca_train;
2892
else if (needs_training & NEEDS_TRAINING_QUSE_COMBO)
2893
burst_val_table = dst_burst_regs->shadow_regs_quse_train;
2894
else if (needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO))
2895
burst_val_table = dst_burst_regs->shadow_regs_rdwr_train;
2896
else
2897
burst_val_table = NULL;
2898
}
2899
2900
for (u32 i = 0; burst_val_table && i < dst_emc_entry->num_burst; i++)
2901
{
2902
reg_addr = burst_regs_emc_addr_table[i];
2903
reg_val = burst_val_table[i];
2904
2905
switch (reg_addr)
2906
{
2907
case EMC_CFG:
2908
reg_val &= 0xFFFFFFF;
2909
break;
2910
case EMC_ZCAL_INTERVAL:
2911
reg_val = 0;
2912
break;
2913
case EMC_PMACRO_BRICK_CTRL_RFU1:
2914
reg_val &= 0xF800F800;
2915
break;
2916
case EMC_PMACRO_CMD_PAD_TX_CTRL:
2917
reg_val = (reg_val & 0xFAFEFDFD) | BIT(26); // CMD_CMD_TX_DRVFORCEON.
2918
break;
2919
case EMC_PMACRO_DATA_PAD_TX_CTRL:
2920
reg_val &= 0xFEFEFDFD;
2921
break;
2922
case EMC_PMACRO_COMMON_PAD_TX_CTRL:
2923
reg_val &= 0xFFFFFFF0;
2924
break;
2925
case EMC_PMACRO_AUTOCAL_CFG_COMMON:
2926
reg_val |= BIT(16); // E_CAL_BYPASS_DVFS.
2927
break;
2928
case EMC_TRAINING_CTRL:
2929
reg_val |= needs_swap_rank_training << 14;
2930
break;
2931
}
2932
2933
EMC(reg_addr) = reg_val;
2934
}
2935
2936
if (in_training)
2937
EMC(EMC_MRW) = (src_emc_entry->run_clocks & 0xFF) | 0x170000;
2938
else
2939
EMC(EMC_MRW) = (dst_emc_entry->run_clocks & 0xFF) | 0x170000;
2940
2941
// Writing burst_regs_per_ch.
2942
for (u32 i = 0; dst_emc_entry->num_burst_per_ch > i; i++)
2943
{
2944
reg_addr = burst_reg_per_ch_emc01_addr_table[i];
2945
if (reg_addr && (channel1_enabled || ((reg_addr - 0x4000) > 0xFFF)))
2946
{
2947
EMC(reg_addr) = dst_burst_regs->burst_reg_per_ch[i];
2948
}
2949
}
2950
2951
// Writing vref_regs.
2952
trim_regs_table_t *trim_regs_table = (trim_regs_table_t *)&dst_emc_entry->trim_regs;
2953
for (u32 i = 0; dst_emc_entry->vref_num > i; i++)
2954
{
2955
reg_addr = vref_perch_regs_emc01_addr_table[i];
2956
if (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))
2957
EMC(reg_addr) = trim_regs_table->vref_perch_regs[i];
2958
}
2959
2960
// Writing training mod regs.
2961
if (in_training)
2962
{
2963
for (u32 i = 0; dst_emc_entry->training_mod_num > i; i++)
2964
{
2965
reg_addr = training_mod_regs_emc01_addr_table[i];
2966
if (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))
2967
EMC(reg_addr) = dst_emc_entry->training_mod_regs[i];
2968
}
2969
}
2970
2971
// Writing trim_regs
2972
for (u32 i = 0; dst_emc_entry->num_trim > i; i++)
2973
{
2974
reg_addr = trim_regs_emc_addr_table[i];
2975
if (reg_addr)
2976
{
2977
if (((reg_addr & 0xFFFFFFF0) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK1_0 ||
2978
(reg_addr & 0xFFFFFFF0) == EMC_PMACRO_OB_DDLL_LONG_DQ_RANK0_0 ||
2979
(reg_addr & 0xFFFFFFF8) == EMC_DATA_BRLSHFT_0)
2980
&& compensate_trimmer_applicable)
2981
{
2982
EMC(reg_addr) = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr);
2983
}
2984
else
2985
EMC(reg_addr) = trim_regs_table->trim_regs[i];
2986
}
2987
}
2988
2989
// Writing trim_regs_per_ch
2990
for (u32 i = 0; dst_emc_entry->num_trim_per_ch > i; i++)
2991
{
2992
reg_addr = trim_perch_regs_emc01_addr_table[i];
2993
if (reg_addr && (channel1_enabled || (reg_addr - 0x4000) > 0xFFF))
2994
{
2995
if (((reg_addr & 0xFFFFFFF8) == EMC0_DATA_BRLSHFT_0 ||
2996
(reg_addr & 0xFFFFFFF8) == EMC1_DATA_BRLSHFT_0)
2997
&& compensate_trimmer_applicable)
2998
{
2999
EMC(reg_addr) = _minerva_apply_periodic_compensation_trimmer(dst_emc_entry, reg_addr & 0xFFF);
3000
}
3001
else
3002
EMC(reg_addr) = trim_regs_table->trim_perch_regs[i];
3003
}
3004
}
3005
3006
if (in_training)
3007
{
3008
// Check delta wrt previous values (save value if margin exceeds what is set in table).
3009
if (needs_wr_training && dst_emc_entry->periodic_training)
3010
_minerva_periodic_compensation_handler(src_emc_entry, dst_emc_entry, dram_dev_num, channel1_enabled, WRITE_TRAINING_SEQUENCE);
3011
}
3012
else
3013
{
3014
// Writing burst_mc_regs.
3015
for (u32 i = 0; dst_emc_entry->num_mc_regs > i; i++)
3016
MC(burst_mc_regs_addr_table[i]) = dst_emc_entry->burst_mc_regs[i];
3017
3018
// Writing la_scale_regs.
3019
if (dst_emc_entry->rate_khz < src_emc_entry->rate_khz)
3020
{
3021
for (u32 i = 0; dst_emc_entry->num_up_down > i; i++)
3022
MC(la_scale_regs_mc_addr_table[i]) = dst_emc_entry->la_scale_regs[i];
3023
}
3024
}
3025
3026
// Step 9 - LPDDR4.
3027
EPRINTF("Step 9");
3028
EMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval & 0xFF000000;
3029
EMC(EMC_ZCAL_WAIT_CNT) = dst_emc_entry->burst_regs.emc_zcal_wait_cnt & 0xFFFFF800;
3030
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_ACTIVE_ONLY | EMC_DBG_WRITE_MUX_ACTIVE;
3031
EMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval & 0xFF000000;
3032
EMC(EMC_DBG) = emc_dbg_o;
3033
3034
if (in_training)
3035
{
3036
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
3037
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = dst_emc_entry->burst_regs.emc_pmacro_autocal_cfg_common | 0x10000;
3038
3039
if (needs_ca_combo_training)
3040
EMC(EMC_FBIO_CFG5) = src_emc_entry->burst_regs.emc_fbio_cfg5 | 0x8000000;
3041
3042
EMC(EMC_DBG) = emc_dbg_o;
3043
3044
if (channel1_enabled)
3045
_ccfifo_write(EMC_CFG_SYNC, 0, 0);
3046
3047
_ccfifo_write(EMC_DBG, (emc_dbg_o & ~EMC_DBG_CFG_SWAP_MASK) | EMC_DBG_CFG_SWAP_SWAP, 0);
3048
}
3049
3050
// Step 10 - Self refresh
3051
EPRINTF("Step 10");
3052
_ccfifo_write(EMC_SELF_REF, 0x101, 0);
3053
3054
if (!needs_ca_combo_training && (dst_clock_period <= 2000))
3055
{
3056
_ccfifo_write(EMC_MRW3, mr13_flip_fspwr ^ 0x40, 0);
3057
_ccfifo_write(EMC_MRW6, (src_emc_entry->burst_regs.emc_mrw6 & 0xC0C0) | (dst_emc_entry->burst_regs.emc_mrw6 & 0xFFFF3F3F), 0);
3058
_ccfifo_write(EMC_MRW14, (src_emc_entry->burst_regs.emc_mrw14 & 0x3838) | (dst_emc_entry->burst_regs.emc_mrw14 & 0xFFFF0707), 0);
3059
if (dram_dev_num == TWO_RANK)
3060
{
3061
_ccfifo_write(EMC_MRW7, (src_emc_entry->burst_regs.emc_mrw7 & 0xC0C0) | (dst_emc_entry->burst_regs.emc_mrw7 & 0xFFFF3F3F), 0);
3062
_ccfifo_write(EMC_MRW15, (src_emc_entry->burst_regs.emc_mrw15 & 0x3838) | (dst_emc_entry->burst_regs.emc_mrw15 & 0xFFFF0707), 0);
3063
}
3064
3065
if (dram_dev_num == ONE_RANK || zcal_resistor_shared)
3066
emc_zq_cal = 0x80000001;
3067
else
3068
emc_zq_cal = 1;
3069
3070
_ccfifo_write(EMC_ZQ_CAL, emc_zq_cal, 0);
3071
}
3072
3073
emc_dbg_val = emc_dbg_o;
3074
u32 tRP_src_timing = (src_emc_entry->dram_timings.t_rp * 1000) / src_clock_period;
3075
u32 ref_delay = 0;
3076
3077
if (in_training)
3078
{
3079
emc_dbg_val = (emc_dbg_o & ~EMC_DBG_CFG_SWAP_MASK) | EMC_DBG_WRITE_ACTIVE_ONLY | EMC_DBG_CFG_SWAP_SWAP;
3080
_ccfifo_write(EMC_DBG, emc_dbg_val, 0);
3081
}
3082
3083
if (needs_ca_combo_training)
3084
{
3085
_ccfifo_write(EMC_PMACRO_DATA_RX_TERM_MODE, src_emc_entry->burst_regs.emc_pmacro_data_rx_term_mode & 0xFFFFFCCC, 0);
3086
3087
if (dram_dev_num == TWO_RANK && needs_swap_rank_training)
3088
{
3089
_ccfifo_write(EMC_MRW3, mr13_flip_fspop | 8, tRP_src_timing);
3090
_ccfifo_write(EMC_MRW3, mr13_catr_enable | 8, 0);
3091
}
3092
else
3093
_ccfifo_write(EMC_MRW3, mr13_catr_enable | 8, tRP_src_timing);
3094
3095
_ccfifo_write(EMC_TR_CTRL_0, 0x15A, 0);
3096
ref_delay = 1000000 / src_clock_period;
3097
}
3098
else
3099
{
3100
_ccfifo_write(EMC_MRW3, mr13_flip_fspop | 8, tRP_src_timing);
3101
ref_delay = tFC_lpddr4 / src_clock_period;
3102
}
3103
3104
_ccfifo_write(EMC_INTSTATUS, 0, ref_delay);
3105
_ccfifo_write(EMC_PIN, emc_pin_o & 0xFFFFFFF8, 30);
3106
3107
// Step 11 - Ramp down.
3108
EPRINTF("Step 11");
3109
_ccfifo_write(EMC_CFG_SYNC, 0, 0);
3110
_ccfifo_write(EMC_DBG, emc_dbg_val | EMC_DBG_WRITE_ACTIVE_ONLY | EMC_DBG_WRITE_MUX_ACTIVE, 0); // WRITE_MUX_ACTIVE | WRITE_ACTIVE_ONLY
3111
3112
ramp_down_wait = _dvfs_power_ramp_down(false, src_emc_entry, dst_emc_entry, src_clock_period);
3113
3114
// Step 12 - Trigger clock change.
3115
EPRINTF("Step 12");
3116
_ccfifo_write(EMC_STALL_THEN_EXE_AFTER_CLKCHANGE, 1, 0);
3117
if (!in_training)
3118
_ccfifo_write(EMC_DBG, (emc_dbg_val & ~EMC_DBG_WRITE_ACTIVE_ONLY) | EMC_DBG_WRITE_MUX_ACTIVE, 0);
3119
3120
// Step 13 - Ramp up.
3121
EPRINTF("Step 13");
3122
ramp_up_wait = _dvfs_power_ramp_up(false, src_emc_entry, dst_emc_entry, needs_training, dst_clock_period);
3123
3124
_ccfifo_write(EMC_DBG, emc_dbg_val, 0);
3125
3126
// Step 14 - Bringup CKE pins.
3127
EPRINTF("Step 14");
3128
u32 emc_pin_val_final = 0;
3129
if (needs_ca_combo_training)
3130
{
3131
emc_pin_val_final = emc_pin_o & 0xFFFFFFF8;
3132
if (dram_dev_num == TWO_RANK)
3133
{
3134
if (needs_swap_rank_training)
3135
emc_pin_val_final |= 5;
3136
else
3137
emc_pin_val_final |= 6;
3138
}
3139
}
3140
else if (dram_dev_num == TWO_RANK)
3141
emc_pin_val_final = emc_pin_o | 7;
3142
else
3143
emc_pin_val_final = (emc_pin_o & 0xFFFFFFF8) | 1;
3144
3145
_ccfifo_write(EMC_PIN, emc_pin_val_final, 0);
3146
3147
// Step 15 - Zqlatch.
3148
EPRINTF("Step 15");
3149
if (!needs_ca_combo_training)
3150
{
3151
s32 zq_latch_dvfs_wait_time;
3152
u32 T_PDEX_timing = _div_o3(dst_emc_entry->dram_timings.t_pdex * 1000, dst_clock_period);
3153
3154
if (dst_clock_period > 2000)
3155
zq_latch_dvfs_wait_time = (s32)tZQCAL_lpddr4_fc_adj - (s32)T_PDEX_timing;
3156
else
3157
zq_latch_dvfs_wait_time =
3158
(s32)tZQCAL_lpddr4_fc_adj - (ramp_up_wait + ramp_down_wait) / dst_clock_period;
3159
3160
if (dram_dev_num == ONE_RANK)
3161
{
3162
if (dst_clock_period > 2000)
3163
_ccfifo_write(EMC_ZQ_CAL, 0x80000001, T_PDEX_timing);
3164
3165
if (!in_training)
3166
_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, T_PDEX_timing);
3167
3168
emc_zq_cal = 0x80000002;
3169
}
3170
else if (zcal_resistor_shared)
3171
{
3172
if (dst_clock_period > 2000)
3173
_ccfifo_write(EMC_ZQ_CAL, 0x80000001, T_PDEX_timing);
3174
3175
s32 T_PDEX_timing_final = zq_latch_dvfs_wait_time + (s32)T_PDEX_timing;
3176
3177
if (T_PDEX_timing_final < 0)
3178
T_PDEX_timing_final = 0;
3179
3180
_ccfifo_write(EMC_ZQ_CAL, 0x80000002, T_PDEX_timing_final);
3181
_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);
3182
3183
if (!in_training)
3184
_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, 0);
3185
3186
emc_zq_cal = 0x40000002;
3187
zq_latch_dvfs_wait_time = 1000000 / dst_clock_period;
3188
}
3189
else
3190
{
3191
if (dst_clock_period > 2000)
3192
_ccfifo_write(EMC_ZQ_CAL, 1, T_PDEX_timing);
3193
3194
if (!in_training)
3195
_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) | 0xC000000, T_PDEX_timing);
3196
3197
emc_zq_cal = 2;
3198
}
3199
3200
// Disable self-refresh.
3201
if (!in_training)
3202
{
3203
_ccfifo_write(EMC_SELF_REF, 0, 0);
3204
_ccfifo_write(EMC_REF, 0, 0);
3205
}
3206
3207
if (zq_latch_dvfs_wait_time < 0)
3208
zq_latch_dvfs_wait_time = 0;
3209
3210
_ccfifo_write(EMC_ZQ_CAL, emc_zq_cal, (u32)zq_latch_dvfs_wait_time);
3211
}
3212
3213
_ccfifo_write(EMC_INTSTATUS, 0, 10); // WAR: delay for zqlatch.
3214
3215
// Step 16 - LPDDR4 Conditional training kickoff.
3216
EPRINTF("Step 16");
3217
if (in_training)
3218
{
3219
_ccfifo_write(EMC_INTSTATUS, 0, 1020000 / dst_clock_period);
3220
3221
u32 training_command = 0;
3222
3223
if (needs_ca_training)
3224
training_command |= BIT(1); // CA: Initiates CA Training.
3225
if (needs_ca_vref_training)
3226
training_command |= BIT(5); // CA_VREF: Initiates CA_VREF Training.
3227
if (needs_quse_training)
3228
training_command |= BIT(4); // QUSE: Initiates QUSE Training.
3229
if (needs_quse_vref_training)
3230
training_command |= BIT(8); // QUSE_VREF: Initiates DQS_VREF Training.
3231
if (needs_wr_training)
3232
training_command |= BIT(3); // WR: Initiates WR Training.
3233
if (needs_wr_vref_training)
3234
training_command |= BIT(6); // WR_VREF: Initiates OB (write) DRAM_VREF Training.
3235
if (needs_rd_training)
3236
training_command |= BIT(2); // RD: Initiates RD Training.
3237
if (needs_rd_vref_training)
3238
training_command |= BIT(7); // RD_VREF: Initiates IB_DQ_VREF Training.
3239
training_command |= BIT(31); // GO: Start the Training.
3240
3241
_ccfifo_write(EMC_TRAINING_CMD, training_command, 0);
3242
3243
if (bg_regulator_mode_change)
3244
{
3245
if (enable_bg_regulator)
3246
_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,
3247
src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFE, 0);
3248
else
3249
_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,
3250
src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFB, 0);
3251
}
3252
3253
_ccfifo_write(EMC_SWITCH_BACK_CTRL, 1, 0);
3254
3255
if (!needs_ca_combo_training || needs_swap_rank_training)
3256
{
3257
_ccfifo_write(EMC_MRW3, mr13_flip_fspop ^ 0xC0, 0);
3258
_ccfifo_write(EMC_INTSTATUS, 0, 1000000 / dst_clock_period);
3259
}
3260
3261
_ccfifo_write(EMC_PIN, emc_pin_o & 0xFFFFFFF8, 0);
3262
_ccfifo_write(EMC_CFG_SYNC, 0, 0);
3263
_ccfifo_write(EMC_DBG, emc_dbg_val | EMC_DBG_WRITE_ACTIVE_ONLY | EMC_DBG_WRITE_MUX_ACTIVE, 0);
3264
3265
_dvfs_power_ramp_down(true, src_emc_entry, dst_emc_entry, dst_clock_period);
3266
3267
_ccfifo_write(EMC_STALL_THEN_EXE_AFTER_CLKCHANGE, 1, 0);
3268
_ccfifo_write(EMC_DBG, (emc_dbg_val & ~EMC_DBG_WRITE_ACTIVE_ONLY) | EMC_DBG_WRITE_MUX_ACTIVE, 0);
3269
3270
_dvfs_power_ramp_up(true, src_emc_entry, dst_emc_entry, needs_training, src_clock_period);
3271
3272
_ccfifo_write(EMC_DBG, emc_dbg_val, 0);
3273
3274
if (dram_dev_num == TWO_RANK)
3275
_ccfifo_write(EMC_PIN, emc_pin_o | 7, 0);
3276
else
3277
_ccfifo_write(EMC_PIN, (emc_pin_o & 0xFFFFFFF8) | 1, 0);
3278
3279
if (needs_ca_combo_training)
3280
{
3281
_ccfifo_write(EMC_TR_CTRL_0, 0x4A, 200000 / src_clock_period);
3282
_ccfifo_write(EMC_TR_CTRL_0, 0x40, 1000000 / src_clock_period);
3283
_ccfifo_write(EMC_MRW3, mr13_catr_enable & 0xFFFFFFFE, 0);
3284
_ccfifo_write(EMC_INTSTATUS, 0, 1000000 / src_clock_period);
3285
_ccfifo_write(EMC_PMACRO_DATA_RX_TERM_MODE, src_emc_entry->burst_regs.emc_pmacro_data_rx_term_mode, 0);
3286
}
3287
3288
_ccfifo_write(EMC_DBG, emc_dbg_o, 0);
3289
3290
_ccfifo_write(EMC_ZQ_CAL, 0x80000001, 0);
3291
_ccfifo_write(EMC_ZQ_CAL, 0x80000002, 1000000 / src_clock_period);
3292
3293
if ((!needs_ca_combo_training || needs_swap_rank_training) && dram_dev_num == TWO_RANK)
3294
{
3295
3296
_ccfifo_write(EMC_ZQ_CAL, 0x40000001, 0);
3297
_ccfifo_write(EMC_ZQ_CAL, 0x40000002, 1000000 / src_clock_period);
3298
}
3299
3300
if (!needs_ca_combo_training)
3301
_ccfifo_write(EMC_MRW3, (mr13_flip_fspop & 0xF3FFFFF7) ^ 0xC0000C0, 0);
3302
3303
_ccfifo_write(EMC_SELF_REF, 0, 0);
3304
}
3305
3306
// Step 19.2.
3307
EPRINTF("Step 19.2");
3308
if (bg_regulator_mode_change)
3309
{
3310
_ccfifo_write(EMC_DBG, emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE, 0);
3311
3312
u32 bg_regulator_switch_complete_wait_clks = 0;
3313
if (in_training)
3314
{
3315
bg_regulator_switch_complete_wait_clks = 1250000 / src_clock_period;
3316
_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,
3317
src_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0, bg_regulator_switch_complete_wait_clks);
3318
}
3319
else
3320
{
3321
if (ramp_up_wait <= 1250000)
3322
bg_regulator_switch_complete_wait_clks = (1250000 - ramp_up_wait) / dst_clock_period;
3323
_ccfifo_write(EMC_PMACRO_BG_BIAS_CTRL_0,
3324
dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0, bg_regulator_switch_complete_wait_clks);
3325
}
3326
3327
_ccfifo_write(EMC_DBG, emc_dbg_o, 0);
3328
}
3329
3330
// Step 20 - Issue ref and optional QRST.
3331
EPRINTF("Step 20");
3332
if (in_training)
3333
_ccfifo_write(EMC_REF, 0, 0);
3334
3335
// Step 21 - Restore ZCAL and ZCAL interval.
3336
EPRINTF("Step 21");
3337
_ccfifo_write(EMC_DBG, emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE, 0);
3338
3339
if (in_training)
3340
_ccfifo_write(EMC_ZCAL_INTERVAL, src_emc_entry->burst_regs.emc_zcal_interval, 0);
3341
3342
_ccfifo_write(EMC_CFG, dst_emc_entry->burst_regs.emc_cfg & 0xEFFFFFFF, 0);
3343
3344
// Step 22 - Restore EMC_CFG_PIPE_CLK.
3345
EPRINTF("Step 22");
3346
//if (in_training && dram_type == DRAM_TYPE_LPDDR4)////////////////
3347
if (in_training)
3348
_ccfifo_write(EMC_SEL_DPD_CTRL, src_emc_entry->emc_sel_dpd_ctrl, 0);
3349
3350
_ccfifo_write(EMC_DBG, emc_dbg_o, 0);
3351
_ccfifo_write(EMC_CFG_PIPE_CLK, emc_cfg_pipe_clk_o, 0);
3352
3353
if (bg_regulator_mode_change)
3354
{
3355
if (enable_bg_regulator)
3356
EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFB;
3357
else
3358
EMC(EMC_PMACRO_BG_BIAS_CTRL_0) = dst_emc_entry->burst_regs.emc_pmacro_bg_bias_ctrl_0 & 0xFFFFFFFE;
3359
}
3360
3361
// Step 23 - Clock Change.
3362
EPRINTF("Step 23 - Clock Change");
3363
// During training save current clock.
3364
if (in_training)
3365
{
3366
u32 emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
3367
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC_SAFE) = emc_clk_src;
3368
_change_dll_src(src_emc_entry, emc_clk_src);
3369
}
3370
3371
// Set CFG_DLL_MODE to RUN_PERIODIC.
3372
EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF24) | 0x88;
3373
(void)EMC(EMC_CFG_DIG_DLL);
3374
3375
(void)EMC(EMC_FBIO_CFG7);
3376
(void)MC(MC_EMEM_ADR_CFG);
3377
(void)EMC(EMC_INTSTATUS);
3378
3379
// Do clock change.
3380
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = selected_clk_src_emc;
3381
(void)CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
3382
3383
if (_wait_emc_status(EMC_INTSTATUS, CLKCHANGE_COMPLETE_INT, true, 0))
3384
return 4; // Clkchange handshake timeout error.
3385
3386
// Step 24 - Save training results.
3387
EPRINTF("Step 24");
3388
if (in_training)
3389
{
3390
(void)MC(MC_EMEM_ADR_CFG);
3391
emc_dbg_val = EMC(EMC_DBG);
3392
EMC(EMC_DBG) |= EMC_DBG_READ_MUX_ASSEMBLY;
3393
3394
_save_train_results(dst_emc_entry, needs_training, dram_dev_num, channel1_enabled);
3395
3396
EMC(EMC_DBG) = emc_dbg_val;
3397
}
3398
3399
// Step 25 - Program MC updown regs.
3400
EPRINTF("Step 25");
3401
if (!in_training && (dst_emc_entry->rate_khz > src_emc_entry->rate_khz))
3402
{
3403
for (u32 i = 0; dst_emc_entry->num_up_down > i; i++)
3404
MC(la_scale_regs_mc_addr_table[i]) = dst_emc_entry->la_scale_regs[i];
3405
3406
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);
3407
if (_timing_update(dual_channel))
3408
return 4;
3409
}
3410
3411
// Step 26 - Restore ZCAL regs.
3412
EPRINTF("Step 26");
3413
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
3414
EMC(EMC_ZCAL_WAIT_CNT) = dst_emc_entry->burst_regs.emc_zcal_wait_cnt;
3415
EMC(EMC_ZCAL_INTERVAL) = dst_emc_entry->burst_regs.emc_zcal_interval;
3416
EMC(EMC_DBG) = emc_dbg_o;
3417
3418
// Step 27 - Restore EMC_CFG, FDPD regs.
3419
EPRINTF("Step 27");
3420
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
3421
EMC(EMC_CFG) = dst_emc_entry->burst_regs.emc_cfg;
3422
EMC(EMC_DBG) = emc_dbg_o;
3423
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = dst_emc_entry->emc_fdpd_ctrl_cmd_no_ramp;
3424
EMC(EMC_SEL_DPD_CTRL) = dst_emc_entry->emc_sel_dpd_ctrl;
3425
3426
// Step 28 - Training recover.
3427
EPRINTF("Step 28");
3428
if (in_training)
3429
{
3430
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
3431
EMC(EMC_CFG) = dst_emc_entry->burst_regs.emc_cfg;
3432
EMC(EMC_SEL_DPD_CTRL) = dst_emc_entry->emc_sel_dpd_ctrl;
3433
EMC(EMC_ZCAL_WAIT_CNT) = src_emc_entry->burst_regs.emc_zcal_wait_cnt;
3434
EMC(EMC_ZCAL_INTERVAL) = src_emc_entry->burst_regs.emc_zcal_interval;
3435
EMC(EMC_AUTO_CAL_CONFIG2) = src_emc_entry->emc_auto_cal_config2;
3436
EMC(EMC_AUTO_CAL_CONFIG3) = src_emc_entry->emc_auto_cal_config3;
3437
EMC(EMC_AUTO_CAL_CONFIG4) = src_emc_entry->emc_auto_cal_config4;
3438
EMC(EMC_AUTO_CAL_CONFIG5) = src_emc_entry->emc_auto_cal_config5;
3439
EMC(EMC_AUTO_CAL_CONFIG6) = src_emc_entry->emc_auto_cal_config6;
3440
EMC(EMC_AUTO_CAL_CONFIG7) = src_emc_entry->emc_auto_cal_config7;
3441
EMC(EMC_AUTO_CAL_CONFIG8) = src_emc_entry->emc_auto_cal_config8;
3442
EMC(EMC_DBG) = emc_dbg_o;
3443
EMC(EMC_TR_DVFS) = dst_emc_entry->burst_regs.emc_tr_dvfs & 0xFFFFFFFE;
3444
}
3445
3446
EMC(EMC_DBG) = emc_dbg_o | EMC_DBG_WRITE_MUX_ACTIVE;
3447
EMC(EMC_PMACRO_AUTOCAL_CFG_COMMON) = dst_emc_entry->burst_regs.emc_pmacro_autocal_cfg_common;
3448
EMC(EMC_DBG) = emc_dbg_o;
3449
3450
// Step 29 - Power fix WAR.
3451
EPRINTF("Step 29");
3452
EMC(EMC_PMACRO_CFG_PM_GLOBAL_0) = 0xFF0000;
3453
EMC(EMC_PMACRO_TRAINING_CTRL_0) = CH0_TRAINING_E_WRPTR;
3454
EMC(EMC_PMACRO_TRAINING_CTRL_1) = CH0_TRAINING_E_WRPTR;
3455
EMC(EMC_PMACRO_CFG_PM_GLOBAL_0) = 0;
3456
3457
// Step 30 - Re-enable autocal.
3458
EPRINTF("Step 30");
3459
if (in_training)
3460
EMC(EMC_AUTO_CAL_CONFIG) = src_emc_entry->emc_auto_cal_config;
3461
else
3462
{
3463
if (dst_emc_entry->burst_regs.emc_cfg_dig_dll & 1)
3464
_digital_dll_enable_rs(channel1_enabled);
3465
EMC(EMC_AUTO_CAL_CONFIG) = dst_emc_entry->emc_auto_cal_config;
3466
}
3467
3468
return 0;
3469
}
3470
3471
static void _minerva_train(emc_table_t *src_emc_entry, emc_table_t *dst_emc_entry, bool switch_rate, u32 selected_clk_src_emc)
3472
{
3473
u32 needs_training_num = 0;
3474
u32 emc_cfg_dig_dll_val = 0;
3475
u32 needs_training_emc_table[8] = {0};
3476
3477
u32 needs_training = dst_emc_entry->needs_training;
3478
3479
// Must start as true.
3480
if (train_ram_patterns)
3481
{
3482
u32 train_table_off = dst_emc_entry->training_pattern * 256;
3483
for (u32 i = 0; i < 256; i++)
3484
{
3485
EMC(EMC_TRAINING_PATRAM_DQ) = ram_pattern_dq_table[train_table_off + i];
3486
EMC(EMC_TRAINING_PATRAM_DMI) = ram_pattern_dmi_table[train_table_off + i] & 0xF;
3487
EMC(EMC_TRAINING_PATRAM_CTRL) = 0x80000000 + i;
3488
}
3489
train_ram_patterns = false;
3490
}
3491
3492
if (!dst_emc_entry->trained)
3493
{
3494
if (needs_training & NEEDS_TRAINING_CA_COMBO)
3495
{
3496
needs_training_emc_table[needs_training_num++] =
3497
needs_training & (NEEDS_TRAINING_CA_COMBO | NEEDS_TRAINING_IN_SELF_REFRESH);
3498
if (MC(MC_EMEM_ADR_CFG) & 1) // if mapping W8 (1KB page).
3499
needs_training_emc_table[needs_training_num++] =
3500
needs_training & (NEEDS_TRAINING_CA_COMBO | NEEDS_TRAINING_SWAP_RANK | NEEDS_TRAINING_IN_SELF_REFRESH);
3501
}
3502
3503
if (needs_training & NEEDS_TRAINING_QUSE_COMBO)
3504
{
3505
needs_training_emc_table[needs_training_num++] =
3506
needs_training & (NEEDS_TRAINING_QUSE_COMBO | NEEDS_TRAINING_IN_SELF_REFRESH);
3507
if (MC(MC_EMEM_ADR_CFG) & 1)
3508
needs_training_emc_table[needs_training_num++] =
3509
needs_training & (NEEDS_TRAINING_QUSE | NEEDS_TRAINING_IN_SELF_REFRESH);
3510
}
3511
3512
if (needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO))
3513
needs_training_emc_table[needs_training_num++] =
3514
needs_training & (NEEDS_TRAINING_WR_COMBO | NEEDS_TRAINING_RD_COMBO | NEEDS_TRAINING_IN_SELF_REFRESH);
3515
3516
for (u32 i = 0; needs_training_num > i; i++) // Runs more than once for needs_training CA/QUSE/WR/RD.
3517
{
3518
_minerva_change_clock(src_emc_entry, dst_emc_entry, needs_training_emc_table[i], selected_clk_src_emc);
3519
3520
bool dual_channel = (EMC(EMC_FBIO_CFG7) >> 1) & ((EMC(EMC_FBIO_CFG7) >> 2) & 1);
3521
3522
EMC(EMC_DBG) = (EMC(EMC_DBG) & ~EMC_DBG_CFG_SWAP_MASK) | EMC_DBG_CFG_SWAP_ASSEMBLY_ONLY;
3523
EMC(EMC_CFG_UPDATE) = (EMC(EMC_CFG_UPDATE) & 0xFFFFFFF9) | 4;
3524
_timing_update(dual_channel);
3525
3526
EMC(EMC_CFG_UPDATE) &= 0xFFFFFFF9;
3527
EMC(EMC_DBG) &= ~EMC_DBG_CFG_SWAP_MASK; // EMC_DBG_CFG_SWAP_ACTIVE_ONLY.
3528
EMC(EMC_CFG_DIG_DLL) = (EMC(EMC_CFG_DIG_DLL) & 0xFFFFFF3E) | 0x80;
3529
_timing_update(dual_channel);
3530
3531
emc_cfg_dig_dll_val = EMC(EMC_CFG_DIG_DLL) & 0xFFFFFFFE;
3532
if (dst_emc_entry->burst_regs.emc_cfg_dig_dll == 1)
3533
emc_cfg_dig_dll_val = EMC(EMC_CFG_DIG_DLL) | 1;
3534
EMC(EMC_CFG_DIG_DLL) = (emc_cfg_dig_dll_val & 0xFFFFFF3F) | 0x80;
3535
_timing_update(dual_channel);
3536
3537
while (!(EMC(EMC_DIG_DLL_STATUS) & 0x8000))
3538
;
3539
3540
// Bug 200024907.
3541
EMC(EMC_RP) = src_emc_entry->burst_regs.emc_rp;
3542
EMC(EMC_R2P) = src_emc_entry->burst_regs.emc_r2p;
3543
EMC(EMC_W2P) = src_emc_entry->burst_regs.emc_w2p;
3544
EMC(EMC_TRPAB) = src_emc_entry->burst_regs.emc_trpab;
3545
3546
_timing_update(dual_channel);
3547
}
3548
3549
EPRINTF("Trained");
3550
dst_emc_entry->trained = 1;
3551
}
3552
3553
if (switch_rate)
3554
_minerva_change_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);
3555
}
3556
3557
void _minerva_do_over_temp_compensation(mtc_config_t *mtc_cfg)
3558
{
3559
if (!mtc_cfg->current_emc_table)
3560
return;
3561
3562
u32 dram_type = EMC(EMC_FBIO_CFG5) & 3;
3563
3564
// Only LPDDR chips are supported.
3565
if (dram_type != DRAM_TYPE_LPDDR4)
3566
return;
3567
3568
s32 dram_temp = _get_dram_temperature();
3569
3570
if (dram_temp < 0 || mtc_cfg->prev_temp == (u32)dram_temp)
3571
return;
3572
3573
u32 refr = mtc_cfg->current_emc_table->burst_regs.emc_refresh;
3574
u32 pre_refr = mtc_cfg->current_emc_table->burst_regs.emc_pre_refresh_req_cnt;
3575
u32 dyn_self_ref = mtc_cfg->current_emc_table->burst_regs.emc_dyn_self_ref_control;
3576
3577
switch (dram_temp)
3578
{
3579
// Normal temp (<= 85 oC).
3580
case 0:
3581
case 1:
3582
case 2:
3583
case 3:
3584
if (mtc_cfg->prev_temp < 4)
3585
{
3586
mtc_cfg->prev_temp = (u32)dram_temp;
3587
return;
3588
}
3589
break;
3590
// Over temp (> 85 oC).
3591
case 4: // 2x refresh.
3592
refr = (refr & 0xFFFF0000) | ((refr & 0xFFFF) >> REFRESH_X2);
3593
pre_refr = (pre_refr & 0xFFFF0000) | ((pre_refr & 0xFFFF) >> REFRESH_X2);
3594
dyn_self_ref = (dyn_self_ref & 0xFFFF0000) | ((dyn_self_ref & 0xFFFF) >> REFRESH_X2);
3595
break;
3596
case 5: // 4x refresh.
3597
case 6: // Temp 6 normally needs a derating emc table.
3598
refr = (refr & 0xFFFF0000) | ((refr & 0xFFFF) >> REFRESH_X4);
3599
pre_refr = (pre_refr & 0xFFFF0000) | ((pre_refr & 0xFFFF) >> REFRESH_X4);
3600
dyn_self_ref = (dyn_self_ref & 0xFFFF0000) | ((dyn_self_ref & 0xFFFF) >> REFRESH_X4);
3601
break;
3602
default:
3603
break;
3604
}
3605
3606
mtc_cfg->prev_temp = dram_temp;
3607
3608
EMC(EMC_REFRESH) = refr;
3609
EMC(EMC_PRE_REFRESH_REQ_CNT) = pre_refr;
3610
EMC(EMC_DYN_SELF_REF_CONTROL) = dyn_self_ref;
3611
}
3612
3613
u32 _minerva_do_periodic_compensation(emc_table_t *mtc_table_entry)
3614
{
3615
if (mtc_table_entry && mtc_table_entry->periodic_training)
3616
{
3617
u32 dram_dev_num = (MC(MC_EMEM_ADR_CFG) & 1) + 1;
3618
u32 pd_mask = (dram_dev_num == TWO_RANK) ? IN_POWERDOWN_BOTH_MASK : IN_POWERDOWN_1DEV_MASK;
3619
bool channel1_enabled = (mtc_table_entry->burst_regs.emc_fbio_cfg7 >> 2) & 1;
3620
3621
(void)EMC(EMC_DBG);
3622
3623
// Safekeep current config.
3624
u32 emc_cfg_o = EMC(EMC_CFG);
3625
u32 emc_cfg_dig_dll_o = EMC(EMC_CFG_DIG_DLL);
3626
u32 emc_cfg_update_o = EMC(EMC_CFG_UPDATE);
3627
3628
// Step 1 - Disable digital DLL.
3629
EMC(EMC_CFG_DIG_DLL) = emc_cfg_dig_dll_o & 0xFFFFFFFE;
3630
3631
// Step 1.2 - Always update auto cal in clock change.
3632
EMC(EMC_CFG_UPDATE) = (emc_cfg_update_o & 0xFFFFF9FF) | 0x400;
3633
3634
// Step 1.3 - Disable other power features.
3635
EMC(EMC_CFG) = emc_cfg_o & 0xFFFFFFF;
3636
3637
// Timing update and wait for everything to power down.
3638
_timing_update(channel1_enabled);
3639
3640
_wait_emc_status(EMC_EMC_STATUS, pd_mask, 0, EMC_CHANNEL0);
3641
if (channel1_enabled)
3642
_wait_emc_status(EMC_EMC_STATUS, pd_mask, 0, EMC_CHANNEL1);
3643
3644
_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, 0, EMC_CHANNEL0);
3645
if (channel1_enabled)
3646
_wait_emc_status(EMC_EMC_STATUS, IN_SELF_REFRESH_MASK, 0, EMC_CHANNEL1);
3647
3648
_wait_emc_status(EMC_CFG_DIG_DLL, 1, 0, EMC_CHANNEL0);
3649
if (channel1_enabled)
3650
_wait_emc_status(EMC_CFG_DIG_DLL, 1, 0, EMC_CHANNEL1);
3651
3652
// Step 2 - Osc kick off - this assumes training and dvfs have set correct MR23.
3653
_start_periodic_compensation();
3654
3655
// Step 3 - Let dram capture its clock tree delays.
3656
_usleep(1000 * _actual_osc_clocks(mtc_table_entry->run_clocks) / mtc_table_entry->rate_khz + 2);
3657
3658
// Step 4 - Check delta wrt previous values (save value if margin exceeds what is set in table).
3659
u32 adelta = _minerva_update_clock_tree_delay(mtc_table_entry, mtc_table_entry, dram_dev_num, channel1_enabled, PERIODIC_TRAINING_UPDATE);
3660
3661
// Step 5 - Apply compensation w.r.t. trained values (if clock tree has drifted more than the set margin).
3662
if (adelta && ((mtc_table_entry->rate_khz / 1000) * 128) * adelta / 1000000 > mtc_table_entry->tree_margin)
3663
{
3664
for (u32 i = 0; i < 10; i++)
3665
{
3666
EMC(periodic_training_addr[i]) =
3667
_minerva_apply_periodic_compensation_trimmer(mtc_table_entry, periodic_training_addr[i]);
3668
}
3669
}
3670
3671
// Step 6 - Restore other power features.
3672
EMC(EMC_CFG) = emc_cfg_o;
3673
3674
// Step 6.1 - Restore the DLL.
3675
EMC(EMC_CFG_DIG_DLL) = emc_cfg_dig_dll_o;
3676
3677
// Step 6.2 - Timing update for applying the new trimmers.
3678
_timing_update(channel1_enabled);
3679
3680
// Step 6.3 - Restore the UPDATE_DLL_IN_UPDATE field.
3681
EMC(EMC_CFG_UPDATE) = emc_cfg_update_o;
3682
}
3683
3684
return 0;
3685
}
3686
3687
static int _minerva_set_ir_boost(mtc_config_t *mtc_cfg)
3688
{
3689
switch (mtc_cfg->train_mode)
3690
{
3691
case OP_SWITCH:
3692
break;
3693
case OP_TRAIN:
3694
return 4;
3695
case OP_TRAIN_SWITCH:
3696
break;
3697
default:
3698
return 4;
3699
}
3700
3701
EPRINTFARGS("Requested op %d from %d to %d.", OP_SWITCH, src_rate_khz, dst_rate_khz);
3702
3703
bool boost = mtc_cfg->rate_to > MTC_INIT_FREQUENCY;
3704
3705
u32 clk_new = (PLLP_OUT0 << 29u) | 0x188000 | (boost ? 0 : 2);
3706
u32 clk_cur = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
3707
u32 clk_cur_src = clk_cur >> 29u;
3708
3709
// Already at requested clock.
3710
if (clk_new == clk_cur)
3711
{
3712
mtc_cfg->rate_from = mtc_cfg->rate_to;
3713
return 0;
3714
}
3715
3716
if (clk_cur_src != PLLP_OUT0)
3717
return 3;
3718
3719
// Clear clock change interrupt.
3720
EMC(EMC_INTSTATUS) = CLKCHANGE_COMPLETE_INT;
3721
3722
u32 emc_dbg_o = EMC(EMC_DBG);
3723
u32 emc_dbg_c = emc_dbg_o & ~(EMC_DBG_WRITE_MUX_ACTIVE | EMC_DBG_READ_MUX_ASSEMBLY);
3724
EMC(EMC_DBG) = emc_dbg_c;
3725
(void)EMC(EMC_DBG);
3726
3727
// Save registers.
3728
u32 emc_cfg_o = EMC(EMC_CFG);
3729
u32 emc_auto_cal_cfg_o = EMC(EMC_AUTO_CAL_CONFIG);
3730
u32 emc_sel_dpd_ctrl_o = EMC(EMC_SEL_DPD_CTRL);
3731
u32 emc_cfg_pipe_clk_o = EMC(EMC_CFG_PIPE_CLK);
3732
u32 emc_fdpd_ctl_cmd_o = EMC(EMC_FDPD_CTRL_CMD_NO_RAMP);
3733
3734
EMC(EMC_DBG) = emc_dbg_c | EMC_DBG_WRITE_MUX_ACTIVE;
3735
(void)EMC(EMC_DBG);
3736
3737
// Disable autocal.
3738
EMC(EMC_AUTO_CAL_CONFIG) = (emc_auto_cal_cfg_o & 0x7FFFF9FE) | 0x601;
3739
(void)EMC(EMC_AUTO_CAL_CONFIG);
3740
3741
// Disable other power features.
3742
EMC(EMC_CFG) = emc_cfg_o & 0xFFFFFFF;
3743
EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl_o & 0xFFFFFEC3;
3744
EMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o | BIT(0);
3745
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = emc_fdpd_ctl_cmd_o & ~BIT(0);
3746
3747
EMC(EMC_DBG) = emc_dbg_c;
3748
(void)EMC(EMC_DBG);
3749
_usleep(5);
3750
3751
if (boost)
3752
{
3753
// Program arbiter regs.
3754
MC(MC_EMEM_ARB_CFG) = 0x1000003;
3755
MC(MC_EMEM_ARB_TIMING_RP) = 1;
3756
MC(MC_EMEM_ARB_TIMING_RC) = 6;
3757
MC(MC_EMEM_ARB_TIMING_RAS) = 3;
3758
MC(MC_EMEM_ARB_TIMING_FAW) = 4;
3759
MC(MC_EMEM_ARB_TIMING_RFCPB) = 0xE;
3760
MC(MC_EMEM_ARB_DA_COVERS) = 0x30203;
3761
MC(MC_EMEM_ARB_MISC0) = 0x71E30507;
3762
3763
// Program base timings.
3764
EMC(EMC_RP) = 8;
3765
EMC(EMC_TRPAB) = 9;
3766
EMC(EMC_RC) = 25;
3767
EMC(EMC_RAS) = 18;
3768
EMC(EMC_R2W) = 15;
3769
EMC(EMC_RD_RCD) = 8;
3770
EMC(EMC_WR_RCD) = 8;
3771
EMC(EMC_TFAW) = 17; // 13 on 2133 MHz modules.
3772
3773
// ZQ calibration.
3774
EMC(EMC_ZCAL_WAIT_CNT) = 0xE0198;
3775
3776
// Set refresh timings.
3777
EMC(EMC_RFC) = 115;
3778
EMC(EMC_RFCPB) = 58;
3779
EMC(EMC_TREFBW) = 0x18DD; // 0x638.
3780
EMC(EMC_REFRESH) = 0x181E; // 0x607.
3781
EMC(EMC_PRE_REFRESH_REQ_CNT) = 0x607; // 0x181.
3782
EMC(EMC_DYN_SELF_REF_CONTROL) = (EMC(EMC_DYN_SELF_REF_CONTROL) & 0xFFFF0000) | 0xD22;
3783
}
3784
else
3785
{
3786
// Program arbiter regs.
3787
MC(MC_EMEM_ARB_CFG) = 0x8000001;
3788
MC(MC_EMEM_ARB_TIMING_RP) = 0;
3789
MC(MC_EMEM_ARB_TIMING_RC) = 3;
3790
MC(MC_EMEM_ARB_TIMING_RAS) = 1;
3791
MC(MC_EMEM_ARB_TIMING_FAW) = 2;
3792
MC(MC_EMEM_ARB_TIMING_RFCPB) = 7;
3793
MC(MC_EMEM_ARB_DA_COVERS) = 0x30201;
3794
MC(MC_EMEM_ARB_MISC0) = 0x72A30504;
3795
3796
// Program base timings.
3797
EMC(EMC_RP) = 4;
3798
EMC(EMC_TRPAB) = 5;
3799
EMC(EMC_RC) = 13;
3800
EMC(EMC_RAS) = 9;
3801
EMC(EMC_R2W) = 11;
3802
EMC(EMC_RD_RCD) = 6;
3803
EMC(EMC_WR_RCD) = 6;
3804
EMC(EMC_TFAW) = 9; // 8 on 2133 MHz modules.
3805
3806
// Program ZQ calibration.
3807
EMC(EMC_ZCAL_WAIT_CNT) = 0x900CC;
3808
3809
// Program refresh timings.
3810
EMC(EMC_RFC) = 58;
3811
EMC(EMC_RFCPB) = 29;
3812
EMC(EMC_TREFBW) = 0x31C;
3813
EMC(EMC_REFRESH) = 0x304;
3814
EMC(EMC_PRE_REFRESH_REQ_CNT) = 0xC1;
3815
EMC(EMC_DYN_SELF_REF_CONTROL) = (EMC(EMC_DYN_SELF_REF_CONTROL) & 0xFFFF0000) | 0x713;
3816
}
3817
3818
// Restore power features and pipe clock.
3819
EMC(EMC_CFG) = emc_cfg_o & 0xEFFFFFFF;
3820
EMC(EMC_CFG_PIPE_CLK) = emc_cfg_pipe_clk_o;
3821
EMC(EMC_DBG) = emc_dbg_o;
3822
(void)EMC(EMC_DBG);
3823
3824
// Do clock change.
3825
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) = clk_new;
3826
(void)CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC);
3827
3828
// Clock change handshake.
3829
_wait_emc_status(EMC_INTSTATUS, CLKCHANGE_COMPLETE_INT, true, 0);
3830
3831
// Restore regs.
3832
EMC(EMC_CFG) = emc_cfg_o;
3833
EMC(EMC_FDPD_CTRL_CMD_NO_RAMP) = emc_fdpd_ctl_cmd_o;
3834
EMC(EMC_SEL_DPD_CTRL) = emc_sel_dpd_ctrl_o;
3835
EMC(EMC_AUTO_CAL_CONFIG) = emc_auto_cal_cfg_o;
3836
3837
EMC(EMC_TIMING_CONTROL) = 1;
3838
3839
// Min 20us before next clock change.
3840
_usleep(20);
3841
3842
mtc_cfg->rate_from = mtc_cfg->rate_to;
3843
3844
return 0;
3845
}
3846
3847
static u32 _minerva_do_training_switch(mtc_config_t *mtc_cfg)
3848
{
3849
u32 src_emc_entry_idx = 100;
3850
u32 dst_emc_entry_idx = 100;
3851
u32 selected_clk_src_emc;
3852
u32 emc_clk_src;
3853
bool freq_changed = false;
3854
bool src_is_pllmb;
3855
emc_table_t *src_emc_entry;
3856
emc_table_t *dst_emc_entry;
3857
3858
if (mtc_cfg->table_entries > 32)
3859
return 4;
3860
3861
if (mtc_cfg->mtc_table[0].rev == MTC_IRB_MAGIC)
3862
return _minerva_set_ir_boost(mtc_cfg);
3863
3864
// Find tables.
3865
for (u32 i = 0; i < mtc_cfg->table_entries; i++)
3866
{
3867
u32 table_entry_rate = mtc_cfg->mtc_table[i].rate_khz;
3868
if (mtc_cfg->rate_from == table_entry_rate)
3869
src_emc_entry_idx = i;
3870
if (mtc_cfg->rate_to == table_entry_rate)
3871
dst_emc_entry_idx = i;
3872
}
3873
3874
// Check if tables were found.
3875
if (src_emc_entry_idx >= mtc_cfg->table_entries ||
3876
dst_emc_entry_idx >= mtc_cfg->table_entries)
3877
return 4;
3878
3879
src_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[src_emc_entry_idx];
3880
dst_emc_entry = (emc_table_t *)&mtc_cfg->mtc_table[dst_emc_entry_idx];
3881
3882
u32 src_rate_khz = src_emc_entry->rate_khz;
3883
u32 dst_rate_khz = dst_emc_entry->rate_khz;
3884
u32 src_clk_src_emc = src_emc_entry->clk_src_emc;
3885
u32 dst_clk_src_emc = dst_emc_entry->clk_src_emc;
3886
3887
freq_changed = _check_freq_changed(dst_rate_khz, dst_clk_src_emc, src_rate_khz, src_clk_src_emc);
3888
EPRINTFARGS("Requested op %d from %d to %d.", mtc_cfg->train_mode, src_rate_khz, dst_rate_khz);
3889
3890
// Get current clock source.
3891
emc_clk_src = CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_EMC) >> EMC_2X_CLK_SRC_SHIFT;
3892
src_is_pllmb = emc_clk_src == PLLMB_UD || emc_clk_src == PLLMB_OUT0;
3893
3894
if (freq_changed)
3895
{
3896
if (emc_clk_src == PLLM_UD ||
3897
emc_clk_src == PLLM_OUT0) // Clock source is PLLM. Switch based on src_is_pllmb.
3898
{
3899
src_is_pllmb = !src_is_pllmb;
3900
}
3901
else if (emc_clk_src == PLLMB_UD ||
3902
emc_clk_src == PLLMB_OUT0) // Clock source is PLLMB. Switch to PLLM.
3903
{
3904
src_is_pllmb = false;
3905
}
3906
selected_clk_src_emc = _pllm_clk_base_cfg(dst_rate_khz, dst_clk_src_emc, src_is_pllmb);
3907
}
3908
else
3909
{
3910
selected_clk_src_emc = dst_clk_src_emc;
3911
emc_clk_src = selected_clk_src_emc >> EMC_2X_CLK_SRC_SHIFT;
3912
if (src_is_pllmb)
3913
{
3914
if (emc_clk_src == PLLM_UD || emc_clk_src == PLLMB_UD)
3915
selected_clk_src_emc = (selected_clk_src_emc & 0x1FFFFFFF) | (PLLMB_UD << EMC_2X_CLK_SRC_SHIFT);
3916
else if (emc_clk_src == PLLM_OUT0 || emc_clk_src == PLLMB_OUT0)
3917
selected_clk_src_emc = (selected_clk_src_emc & 0x1FFFFFFF) | (PLLMB_OUT0 << EMC_2X_CLK_SRC_SHIFT);
3918
}
3919
}
3920
3921
switch (mtc_cfg->train_mode)
3922
{
3923
case OP_SWITCH:
3924
_minerva_change_clock(src_emc_entry, dst_emc_entry, 0, selected_clk_src_emc);
3925
mtc_cfg->current_emc_table = dst_emc_entry;
3926
mtc_cfg->rate_from = dst_emc_entry->rate_khz;
3927
if (dst_emc_entry->periodic_training)
3928
_minerva_do_periodic_compensation(dst_emc_entry);
3929
return 0;
3930
case OP_TRAIN:
3931
_minerva_train(src_emc_entry, dst_emc_entry, false, selected_clk_src_emc);
3932
return 0;
3933
case OP_TRAIN_SWITCH:
3934
_minerva_train(src_emc_entry, dst_emc_entry, true, selected_clk_src_emc);
3935
mtc_cfg->current_emc_table = dst_emc_entry;
3936
mtc_cfg->rate_from = dst_emc_entry->rate_khz;
3937
if (dst_emc_entry->periodic_training)
3938
_minerva_do_periodic_compensation(dst_emc_entry);
3939
return 0;
3940
default:
3941
return 4;
3942
}
3943
}
3944
3945
static void _minerva_get_table(mtc_config_t *mtc_cfg)
3946
{
3947
u32 hidrev = APB_MISC(APB_MISC_GP_HIDREV);
3948
u32 chip_id = (hidrev >> 8) & 0xFF;
3949
u32 major = (hidrev >> 4) & 0xF;
3950
3951
// Check that SoC is T210/T210B01.
3952
if (chip_id != HIDREV_CHIPID_T210)
3953
goto error;
3954
3955
// Check if SoC SKU is ODIN.
3956
if (FUSE(FUSE_SKU_INFO) != SKU_ODIN)
3957
goto error;
3958
3959
// Clear table storage.
3960
memcpy(mtc_cfg->mtc_table, DVFS_T21X_CC_VERSION, sizeof(DVFS_T21X_CC_VERSION));
3961
memcpy(mtc_cfg->mtc_table, DVFS_T210_CC_VERSION, sizeof(DVFS_T210_CC_VERSION));
3962
memset(mtc_cfg->mtc_table, 0, EMC_TABLE_ENTRY_SIZE_R7 * 10);
3963
3964
// Check if init rate boost mode.
3965
if (mtc_cfg->init_done == MTC_IRB_MAGIC)
3966
{
3967
mtc_cfg->mtc_table[0].rev = MTC_IRB_MAGIC;
3968
mtc_cfg->table_entries = 1; // Avoid OOB.
3969
3970
goto init_cfg;
3971
}
3972
3973
// Check if ODINX02.
3974
if (major != HIDREV_MAJOR_T210)
3975
goto error;
3976
3977
// ODINX02 table: 204, 408, 666, 800, 1066, 1333, 1600 MHz.
3978
mtc_cfg->table_entries = EMC_TABLE_SIZE_ODINX02_R7 / EMC_TABLE_ENTRY_SIZE_R7;
3979
3980
switch (mtc_cfg->sdram_id)
3981
{
3982
case DRAM_4GB_HYNIX_H9HCNNNBPUMLHR_NLN:
3983
memcpy(mtc_cfg->mtc_table, odinx02_a2_2_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_ODINX02_R7);
3984
break;
3985
case DRAM_8GB_SAMSUNG_K4FBE3D4HM_MGXX:
3986
memcpy(mtc_cfg->mtc_table, odinx02_a2_7_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_ODINX02_R7);
3987
break;
3988
case DRAM_4GB_SAMSUNG_K4F6E304HB_MGCH:
3989
case DRAM_4GB_MICRON_MT53B512M32D2NP_062_WT:
3990
case DRAM_4GB_COPPER_SAMSUNG:
3991
case DRAM_6GB_SAMSUNG_K4FHE3D4HM_MFCH:
3992
default:
3993
memcpy(mtc_cfg->mtc_table, odinx02_a2_0_3_10NoCfgVersion_V9_8_7_V1_6, EMC_TABLE_SIZE_ODINX02_R7);
3994
break;
3995
}
3996
3997
init_cfg:
3998
mtc_cfg->rate_to = 0;
3999
mtc_cfg->rate_from = 0;
4000
mtc_cfg->train_mode = -1;
4001
mtc_cfg->prev_temp = 0;
4002
mtc_cfg->current_emc_table = NULL;
4003
4004
// Important!
4005
mtc_cfg->train_ram_patterns = true;
4006
mtc_cfg->init_done = MTC_INIT_MAGIC;
4007
4008
return;
4009
4010
error:
4011
mtc_cfg->init_done = 0;
4012
return;
4013
}
4014
4015
void minerva_entry(mtc_config_t *mtc_cfg, bdk_params_t *bp)
4016
{
4017
EPRINTF("-- Minerva Training Cell --");
4018
4019
train_ram_patterns = mtc_cfg->train_ram_patterns;
4020
4021
if (mtc_cfg->init_done != MTC_INIT_MAGIC)
4022
{
4023
if (mtc_cfg->init_done == MTC_NEW_MAGIC ||
4024
mtc_cfg->init_done == MTC_IRB_MAGIC)
4025
_minerva_get_table(mtc_cfg);
4026
4027
return;
4028
}
4029
4030
switch (mtc_cfg->train_mode)
4031
{
4032
case OP_SWITCH:
4033
EPRINTF("Switching..");
4034
_minerva_do_training_switch(mtc_cfg);
4035
break;
4036
case OP_TRAIN:
4037
EPRINTF("Training..");
4038
_minerva_do_training_switch(mtc_cfg);
4039
break;
4040
case OP_TRAIN_SWITCH:
4041
EPRINTF("Training and switching..");
4042
_minerva_do_training_switch(mtc_cfg);
4043
break;
4044
case OP_PERIODIC_TRAIN:
4045
EPRINTF("Periodic training..");
4046
_minerva_do_periodic_compensation(mtc_cfg->current_emc_table);
4047
break;
4048
case OP_TEMP_COMP:
4049
EPRINTF("Over temperature compensation..");
4050
_minerva_do_over_temp_compensation(mtc_cfg);
4051
break;
4052
}
4053
4054
mtc_cfg->train_ram_patterns = train_ram_patterns;
4055
}
4056
4057