blob: a1d953026f3390f647b57e678bce3e715b6632f5 [file] [log] [blame]
Ye Lib2cfc422022-07-26 16:41:07 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2022 NXP
4 */
5
6#include <common.h>
7#include <errno.h>
8#include <log.h>
9#include <asm/io.h>
10#include <asm/arch/ddr.h>
11#include <asm/arch/clock.h>
12#include <asm/arch/sys_proto.h>
13#include <linux/delay.h>
14
Ye Lia5163fa2023-04-28 12:08:39 +080015static unsigned int g_cdd_rr_max[4];
16static unsigned int g_cdd_rw_max[4];
17static unsigned int g_cdd_wr_max[4];
18static unsigned int g_cdd_ww_max[4];
19
20#define MAX(a, b) (((a) > (b)) ? (a) : (b))
21
Ye Lib2cfc422022-07-26 16:41:07 +080022void ddrphy_coldreset(void)
23{
24 /* dramphy_apb_n default 1 , assert -> 0, de_assert -> 1 */
25 /* dramphy_reset_n default 0 , assert -> 0, de_assert -> 1 */
26 /* dramphy_PwrOKIn default 0 , assert -> 1, de_assert -> 0 */
27
28 /* src_gen_dphy_apb_sw_rst_de_assert */
29 clrbits_le32(REG_SRC_DPHY_SW_CTRL, BIT(0));
30 /* src_gen_dphy_sw_rst_de_assert */
31 clrbits_le32(REG_SRC_DPHY_SINGLE_RESET_SW_CTRL, BIT(2));
32 /* src_gen_dphy_PwrOKIn_sw_rst_de_assert() */
33 setbits_le32(REG_SRC_DPHY_SINGLE_RESET_SW_CTRL, BIT(0));
34 mdelay(10);
35
36 /* src_gen_dphy_apb_sw_rst_assert */
37 setbits_le32(REG_SRC_DPHY_SW_CTRL, BIT(0));
38 /* src_gen_dphy_sw_rst_assert */
39 setbits_le32(REG_SRC_DPHY_SINGLE_RESET_SW_CTRL, BIT(2));
40 mdelay(10);
41 /* src_gen_dphy_PwrOKIn_sw_rst_assert */
42 clrbits_le32(REG_SRC_DPHY_SINGLE_RESET_SW_CTRL, BIT(0));
43 mdelay(10);
44
45 /* src_gen_dphy_apb_sw_rst_de_assert */
46 clrbits_le32(REG_SRC_DPHY_SW_CTRL, BIT(0));
47 /* src_gen_dphy_sw_rst_de_assert() */
48 clrbits_le32(REG_SRC_DPHY_SINGLE_RESET_SW_CTRL, BIT(2));
49}
50
51void check_ddrc_idle(void)
52{
53 u32 regval;
54
55 do {
56 regval = readl(REG_DDRDSR_2);
57 if (regval & BIT(31))
58 break;
59 } while (1);
60}
61
62void check_dfi_init_complete(void)
63{
64 u32 regval;
65
66 do {
67 regval = readl(REG_DDRDSR_2);
68 if (regval & BIT(2))
69 break;
70 } while (1);
71 setbits_le32(REG_DDRDSR_2, BIT(2));
72}
73
74void ddrc_config(struct dram_cfg_param *ddrc_config, int num)
75{
76 int i = 0;
77
78 for (i = 0; i < num; i++) {
79 writel(ddrc_config->val, (ulong)ddrc_config->reg);
80 ddrc_config++;
81 }
Ye Lia5163fa2023-04-28 12:08:39 +080082}
83
84static unsigned int look_for_max(unsigned int data[], unsigned int addr_start,
85 unsigned int addr_end)
86{
87 unsigned int i, imax = 0;
88
89 for (i = addr_start; i <= addr_end; i++) {
90 if (((data[i] >> 7) == 0) && data[i] > imax)
91 imax = data[i];
92 }
93
94 return imax;
Ye Lib2cfc422022-07-26 16:41:07 +080095}
96
97void get_trained_CDD(u32 fsp)
98{
Ye Lia5163fa2023-04-28 12:08:39 +080099 unsigned int i, tmp;
100 unsigned int cdd_cha[12], cdd_chb[12];
101 unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max;
102 unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max;
103
104 for (i = 0; i < 6; i++) {
105 tmp = dwc_ddrphy_apb_rd(0x54013 + i);
106 cdd_cha[i * 2] = tmp & 0xff;
107 cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff;
108 }
109
110 for (i = 0; i < 7; i++) {
111 tmp = dwc_ddrphy_apb_rd(0x5402c + i);
112
113 if (i == 0) {
114 cdd_chb[0] = (tmp >> 8) & 0xff;
115 } else if (i == 6) {
116 cdd_chb[11] = tmp & 0xff;
117 } else {
118 cdd_chb[i * 2 - 1] = tmp & 0xff;
119 cdd_chb[i * 2] = (tmp >> 8) & 0xff;
120 }
121 }
122
123 cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1);
124 cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5);
125 cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9);
126 cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11);
127 cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1);
128 cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5);
129 cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9);
130 cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11);
131 g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max;
132 g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max;
133 g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max;
134 g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max;
135}
136
137void update_umctl2_rank_space_setting(unsigned int pstat_num)
138{
139 u32 tmp, tmp_t;
140
141 int wwt, rrt, wrt, rwt;
142 int ext_wwt, ext_rrt, ext_wrt, ext_rwt;
143 int max_wwt, max_rrt, max_wrt, max_rwt;
144
145 /* read wwt, rrt, wrt, rwt fields from timing_cfg_0 */
146 tmp = readl(REG_DDR_TIMING_CFG_0);
147 wwt = (tmp >> 24) & 0x3;
148 rrt = (tmp >> 26) & 0x3;
149 wrt = (tmp >> 28) & 0x3;
150 rwt = (tmp >> 30) & 0x3;
151
152 /* read rxt_wwt, ext_rrt, ext_wrt, ext_rwt fields from timing_cfg_4 */
153 tmp_t = readl(REG_DDR_TIMING_CFG_4);
154 ext_wwt = (tmp >> 8) & 0x1;
155 ext_rrt = (tmp >> 10) & 0x1;
156 ext_wrt = (tmp >> 12) & 0x1;
157 ext_rwt = (tmp >> 14) & 0x3;
158
159 wwt = (ext_wwt << 2) | wwt;
160 rrt = (ext_rrt << 2) | wwt;
161 wrt = (ext_wrt << 2) | wrt;
162 rwt = (ext_rwt << 2) | rwt;
163
164 /* calculate the maximum between controller and cdd values */
165 max_wwt = MAX(g_cdd_ww_max[0], wwt);
166 max_rrt = MAX(g_cdd_rr_max[0], rrt);
167 max_wrt = MAX(g_cdd_wr_max[0], wrt);
168 max_rwt = MAX(g_cdd_rw_max[0], rwt);
169
170 /* verify values to see if are bigger then 7 or 15 (3 bits or 4 bits) */
171 if (max_wwt > 7)
172 max_wwt = 7;
173 if (max_rrt > 7)
174 max_rrt = 7;
175 if (max_wrt > 7)
176 max_wrt = 7;
177 if (max_rwt > 15)
178 max_rwt = 15;
179
180 /* recalculate timings for controller registers */
181 wwt = max_wwt & 0x3;
182 rrt = max_rrt & 0x3;
183 wrt = max_wrt & 0x3;
184 rwt = max_rwt & 0x3;
185
186 ext_wwt = (max_wwt & 0x4) >> 2;
187 ext_rrt = (max_rrt & 0x4) >> 2;
188 ext_wrt = (max_wrt & 0x4) >> 2;
189 ext_rwt = (max_rwt & 0xC) >> 2;
190
191 /* update timing_cfg_0 and timing_cfg_4 */
192 tmp = (tmp & 0x00ffffff) | (rwt << 30) | (wrt << 28) |
193 (rrt << 26) | (wwt << 24);
194 writel(tmp, REG_DDR_TIMING_CFG_0);
195
196 tmp_t = (tmp_t & 0xFFFF2AFF) | (ext_rwt << 14) |
197 (ext_wrt << 12) | (ext_rrt << 10) | (ext_wwt << 8);
198 writel(tmp_t, REG_DDR_TIMING_CFG_4);
Ye Lib2cfc422022-07-26 16:41:07 +0800199}
200
201int ddr_init(struct dram_timing_info *dram_timing)
202{
203 unsigned int initial_drate;
204 int ret;
205 u32 regval;
206
207 debug("DDRINFO: start DRAM init\n");
208
209 /* reset ddrphy */
210 ddrphy_coldreset();
211
212 debug("DDRINFO: cfg clk\n");
213
214 initial_drate = dram_timing->fsp_msg[0].drate;
215 /* default to the frequency point 0 clock */
216 ddrphy_init_set_dfi_clk(initial_drate);
217
218 /*
219 * Start PHY initialization and training by
220 * accessing relevant PUB registers
221 */
222 debug("DDRINFO:ddrphy config start\n");
223
224 ret = ddr_cfg_phy(dram_timing);
225 if (ret)
226 return ret;
227
228 debug("DDRINFO: ddrphy config done\n");
229
230 /* rogram the ddrc registers */
231 debug("DDRINFO: ddrc config start\n");
232 ddrc_config(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num);
233 debug("DDRINFO: ddrc config done\n");
234
Ye Lia5163fa2023-04-28 12:08:39 +0800235 update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1);
236
Ye Lif188a4f2022-07-26 16:41:08 +0800237#ifdef CONFIG_IMX9_DRAM_PM_COUNTER
238 writel(0x200000, REG_DDR_DEBUG_19);
239#endif
240
Ye Lib2cfc422022-07-26 16:41:07 +0800241 check_dfi_init_complete();
242
243 regval = readl(REG_DDR_SDRAM_CFG);
244 writel((regval | 0x80000000), REG_DDR_SDRAM_CFG);
245
246 check_ddrc_idle();
247
248 /* save the dram timing config into memory */
249 dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE);
250
251 return 0;
252}
253
254ulong ddrphy_addr_remap(u32 paddr_apb_from_ctlr)
255{
256 u32 paddr_apb_qual;
257 u32 paddr_apb_unqual_dec_22_13;
258 u32 paddr_apb_unqual_dec_19_13;
259 u32 paddr_apb_unqual_dec_12_1;
260 u32 paddr_apb_unqual;
261 u32 paddr_apb_phy;
262
263 paddr_apb_qual = (paddr_apb_from_ctlr << 1);
264 paddr_apb_unqual_dec_22_13 = ((paddr_apb_qual & 0x7fe000) >> 13);
265 paddr_apb_unqual_dec_12_1 = ((paddr_apb_qual & 0x1ffe) >> 1);
266
267 switch (paddr_apb_unqual_dec_22_13) {
268 case 0x000:
269 paddr_apb_unqual_dec_19_13 = 0x00;
270 break;
271 case 0x001:
272 paddr_apb_unqual_dec_19_13 = 0x01;
273 break;
274 case 0x002:
275 paddr_apb_unqual_dec_19_13 = 0x02;
276 break;
277 case 0x003:
278 paddr_apb_unqual_dec_19_13 = 0x03;
279 break;
280 case 0x004:
281 paddr_apb_unqual_dec_19_13 = 0x04;
282 break;
283 case 0x005:
284 paddr_apb_unqual_dec_19_13 = 0x05;
285 break;
286 case 0x006:
287 paddr_apb_unqual_dec_19_13 = 0x06;
288 break;
289 case 0x007:
290 paddr_apb_unqual_dec_19_13 = 0x07;
291 break;
292 case 0x008:
293 paddr_apb_unqual_dec_19_13 = 0x08;
294 break;
295 case 0x009:
296 paddr_apb_unqual_dec_19_13 = 0x09;
297 break;
298 case 0x00a:
299 paddr_apb_unqual_dec_19_13 = 0x0a;
300 break;
301 case 0x00b:
302 paddr_apb_unqual_dec_19_13 = 0x0b;
303 break;
304 case 0x100:
305 paddr_apb_unqual_dec_19_13 = 0x0c;
306 break;
307 case 0x101:
308 paddr_apb_unqual_dec_19_13 = 0x0d;
309 break;
310 case 0x102:
311 paddr_apb_unqual_dec_19_13 = 0x0e;
312 break;
313 case 0x103:
314 paddr_apb_unqual_dec_19_13 = 0x0f;
315 break;
316 case 0x104:
317 paddr_apb_unqual_dec_19_13 = 0x10;
318 break;
319 case 0x105:
320 paddr_apb_unqual_dec_19_13 = 0x11;
321 break;
322 case 0x106:
323 paddr_apb_unqual_dec_19_13 = 0x12;
324 break;
325 case 0x107:
326 paddr_apb_unqual_dec_19_13 = 0x13;
327 break;
328 case 0x108:
329 paddr_apb_unqual_dec_19_13 = 0x14;
330 break;
331 case 0x109:
332 paddr_apb_unqual_dec_19_13 = 0x15;
333 break;
334 case 0x10a:
335 paddr_apb_unqual_dec_19_13 = 0x16;
336 break;
337 case 0x10b:
338 paddr_apb_unqual_dec_19_13 = 0x17;
339 break;
340 case 0x200:
341 paddr_apb_unqual_dec_19_13 = 0x18;
342 break;
343 case 0x201:
344 paddr_apb_unqual_dec_19_13 = 0x19;
345 break;
346 case 0x202:
347 paddr_apb_unqual_dec_19_13 = 0x1a;
348 break;
349 case 0x203:
350 paddr_apb_unqual_dec_19_13 = 0x1b;
351 break;
352 case 0x204:
353 paddr_apb_unqual_dec_19_13 = 0x1c;
354 break;
355 case 0x205:
356 paddr_apb_unqual_dec_19_13 = 0x1d;
357 break;
358 case 0x206:
359 paddr_apb_unqual_dec_19_13 = 0x1e;
360 break;
361 case 0x207:
362 paddr_apb_unqual_dec_19_13 = 0x1f;
363 break;
364 case 0x208:
365 paddr_apb_unqual_dec_19_13 = 0x20;
366 break;
367 case 0x209:
368 paddr_apb_unqual_dec_19_13 = 0x21;
369 break;
370 case 0x20a:
371 paddr_apb_unqual_dec_19_13 = 0x22;
372 break;
373 case 0x20b:
374 paddr_apb_unqual_dec_19_13 = 0x23;
375 break;
376 case 0x300:
377 paddr_apb_unqual_dec_19_13 = 0x24;
378 break;
379 case 0x301:
380 paddr_apb_unqual_dec_19_13 = 0x25;
381 break;
382 case 0x302:
383 paddr_apb_unqual_dec_19_13 = 0x26;
384 break;
385 case 0x303:
386 paddr_apb_unqual_dec_19_13 = 0x27;
387 break;
388 case 0x304:
389 paddr_apb_unqual_dec_19_13 = 0x28;
390 break;
391 case 0x305:
392 paddr_apb_unqual_dec_19_13 = 0x29;
393 break;
394 case 0x306:
395 paddr_apb_unqual_dec_19_13 = 0x2a;
396 break;
397 case 0x307:
398 paddr_apb_unqual_dec_19_13 = 0x2b;
399 break;
400 case 0x308:
401 paddr_apb_unqual_dec_19_13 = 0x2c;
402 break;
403 case 0x309:
404 paddr_apb_unqual_dec_19_13 = 0x2d;
405 break;
406 case 0x30a:
407 paddr_apb_unqual_dec_19_13 = 0x2e;
408 break;
409 case 0x30b:
410 paddr_apb_unqual_dec_19_13 = 0x2f;
411 break;
412 case 0x010:
413 paddr_apb_unqual_dec_19_13 = 0x30;
414 break;
415 case 0x011:
416 paddr_apb_unqual_dec_19_13 = 0x31;
417 break;
418 case 0x012:
419 paddr_apb_unqual_dec_19_13 = 0x32;
420 break;
421 case 0x013:
422 paddr_apb_unqual_dec_19_13 = 0x33;
423 break;
424 case 0x014:
425 paddr_apb_unqual_dec_19_13 = 0x34;
426 break;
427 case 0x015:
428 paddr_apb_unqual_dec_19_13 = 0x35;
429 break;
430 case 0x016:
431 paddr_apb_unqual_dec_19_13 = 0x36;
432 break;
433 case 0x017:
434 paddr_apb_unqual_dec_19_13 = 0x37;
435 break;
436 case 0x018:
437 paddr_apb_unqual_dec_19_13 = 0x38;
438 break;
439 case 0x019:
440 paddr_apb_unqual_dec_19_13 = 0x39;
441 break;
442 case 0x110:
443 paddr_apb_unqual_dec_19_13 = 0x3a;
444 break;
445 case 0x111:
446 paddr_apb_unqual_dec_19_13 = 0x3b;
447 break;
448 case 0x112:
449 paddr_apb_unqual_dec_19_13 = 0x3c;
450 break;
451 case 0x113:
452 paddr_apb_unqual_dec_19_13 = 0x3d;
453 break;
454 case 0x114:
455 paddr_apb_unqual_dec_19_13 = 0x3e;
456 break;
457 case 0x115:
458 paddr_apb_unqual_dec_19_13 = 0x3f;
459 break;
460 case 0x116:
461 paddr_apb_unqual_dec_19_13 = 0x40;
462 break;
463 case 0x117:
464 paddr_apb_unqual_dec_19_13 = 0x41;
465 break;
466 case 0x118:
467 paddr_apb_unqual_dec_19_13 = 0x42;
468 break;
469 case 0x119:
470 paddr_apb_unqual_dec_19_13 = 0x43;
471 break;
472 case 0x210:
473 paddr_apb_unqual_dec_19_13 = 0x44;
474 break;
475 case 0x211:
476 paddr_apb_unqual_dec_19_13 = 0x45;
477 break;
478 case 0x212:
479 paddr_apb_unqual_dec_19_13 = 0x46;
480 break;
481 case 0x213:
482 paddr_apb_unqual_dec_19_13 = 0x47;
483 break;
484 case 0x214:
485 paddr_apb_unqual_dec_19_13 = 0x48;
486 break;
487 case 0x215:
488 paddr_apb_unqual_dec_19_13 = 0x49;
489 break;
490 case 0x216:
491 paddr_apb_unqual_dec_19_13 = 0x4a;
492 break;
493 case 0x217:
494 paddr_apb_unqual_dec_19_13 = 0x4b;
495 break;
496 case 0x218:
497 paddr_apb_unqual_dec_19_13 = 0x4c;
498 break;
499 case 0x219:
500 paddr_apb_unqual_dec_19_13 = 0x4d;
501 break;
502 case 0x310:
503 paddr_apb_unqual_dec_19_13 = 0x4e;
504 break;
505 case 0x311:
506 paddr_apb_unqual_dec_19_13 = 0x4f;
507 break;
508 case 0x312:
509 paddr_apb_unqual_dec_19_13 = 0x50;
510 break;
511 case 0x313:
512 paddr_apb_unqual_dec_19_13 = 0x51;
513 break;
514 case 0x314:
515 paddr_apb_unqual_dec_19_13 = 0x52;
516 break;
517 case 0x315:
518 paddr_apb_unqual_dec_19_13 = 0x53;
519 break;
520 case 0x316:
521 paddr_apb_unqual_dec_19_13 = 0x54;
522 break;
523 case 0x317:
524 paddr_apb_unqual_dec_19_13 = 0x55;
525 break;
526 case 0x318:
527 paddr_apb_unqual_dec_19_13 = 0x56;
528 break;
529 case 0x319:
530 paddr_apb_unqual_dec_19_13 = 0x57;
531 break;
532 case 0x020:
533 paddr_apb_unqual_dec_19_13 = 0x58;
534 break;
535 case 0x120:
536 paddr_apb_unqual_dec_19_13 = 0x59;
537 break;
538 case 0x220:
539 paddr_apb_unqual_dec_19_13 = 0x5a;
540 break;
541 case 0x320:
542 paddr_apb_unqual_dec_19_13 = 0x5b;
543 break;
544 case 0x040:
545 paddr_apb_unqual_dec_19_13 = 0x5c;
546 break;
547 case 0x140:
548 paddr_apb_unqual_dec_19_13 = 0x5d;
549 break;
550 case 0x240:
551 paddr_apb_unqual_dec_19_13 = 0x5e;
552 break;
553 case 0x340:
554 paddr_apb_unqual_dec_19_13 = 0x5f;
555 break;
556 case 0x050:
557 paddr_apb_unqual_dec_19_13 = 0x60;
558 break;
559 case 0x051:
560 paddr_apb_unqual_dec_19_13 = 0x61;
561 break;
562 case 0x052:
563 paddr_apb_unqual_dec_19_13 = 0x62;
564 break;
565 case 0x053:
566 paddr_apb_unqual_dec_19_13 = 0x63;
567 break;
568 case 0x054:
569 paddr_apb_unqual_dec_19_13 = 0x64;
570 break;
571 case 0x055:
572 paddr_apb_unqual_dec_19_13 = 0x65;
573 break;
574 case 0x056:
575 paddr_apb_unqual_dec_19_13 = 0x66;
576 break;
577 case 0x057:
578 paddr_apb_unqual_dec_19_13 = 0x67;
579 break;
580 case 0x070:
581 paddr_apb_unqual_dec_19_13 = 0x68;
582 break;
583 case 0x090:
584 paddr_apb_unqual_dec_19_13 = 0x69;
585 break;
586 case 0x190:
587 paddr_apb_unqual_dec_19_13 = 0x6a;
588 break;
589 case 0x290:
590 paddr_apb_unqual_dec_19_13 = 0x6b;
591 break;
592 case 0x390:
593 paddr_apb_unqual_dec_19_13 = 0x6c;
594 break;
595 case 0x0c0:
596 paddr_apb_unqual_dec_19_13 = 0x6d;
597 break;
598 case 0x0d0:
599 paddr_apb_unqual_dec_19_13 = 0x6e;
600 break;
601 default:
602 paddr_apb_unqual_dec_19_13 = 0x00;
603 break;
604 }
605
606 paddr_apb_unqual = ((paddr_apb_unqual_dec_19_13 << 13) | (paddr_apb_unqual_dec_12_1 << 1));
607
608 paddr_apb_phy = (paddr_apb_unqual << 1);
609
610 return paddr_apb_phy;
611}