blob: fbbbfba0f69f7139398d0b9fa31eaacf941807ca [file] [log] [blame]
Angel Pons1c505f82020-11-11 20:55:35 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <commonlib/helpers.h>
Angel Pons1c505f82020-11-11 20:55:35 +01004#include <types.h>
5
Angel Pons1c505f82020-11-11 20:55:35 +01006#include "raminit_common.h"
7#include "raminit_tables.h"
8#include "sandybridge.h"
9
10/* FIXME: no support for 3-channel chipsets */
11
12/* Number of programmed IOSAV subsequences. */
13static unsigned int ssq_count = 0;
14
Angel Pons8f0757e2020-11-11 23:03:36 +010015void iosav_write_sequence(const int ch, const struct iosav_ssq *seq, const unsigned int length)
Angel Pons1c505f82020-11-11 20:55:35 +010016{
Angel Pons8f0757e2020-11-11 23:03:36 +010017 for (unsigned int i = 0; i < length; i++) {
Angel Pons66780a02021-03-26 13:33:22 +010018 mchbar_write32(IOSAV_n_SP_CMD_CTRL_ch(ch, i), seq[i].sp_cmd_ctrl.raw);
19 mchbar_write32(IOSAV_n_SUBSEQ_CTRL_ch(ch, i), seq[i].subseq_ctrl.raw);
20 mchbar_write32(IOSAV_n_SP_CMD_ADDR_ch(ch, i), seq[i].sp_cmd_addr.raw);
21 mchbar_write32(IOSAV_n_ADDR_UPDATE_ch(ch, i), seq[i].addr_update.raw);
Angel Pons8f0757e2020-11-11 23:03:36 +010022 }
Angel Pons1c505f82020-11-11 20:55:35 +010023
Angel Pons8f0757e2020-11-11 23:03:36 +010024 ssq_count = length;
Angel Pons1c505f82020-11-11 20:55:35 +010025}
26
27void iosav_run_queue(const int ch, const u8 loops, const u8 as_timer)
28{
Angel Pons8f0757e2020-11-11 23:03:36 +010029 /* Should never happen */
30 if (ssq_count == 0)
31 return;
Angel Pons1c505f82020-11-11 20:55:35 +010032
Angel Pons66780a02021-03-26 13:33:22 +010033 mchbar_write32(IOSAV_SEQ_CTL_ch(ch), loops | (ssq_count - 1) << 18 | as_timer << 22);
Angel Pons1c505f82020-11-11 20:55:35 +010034}
35
Angel Pons1c505f82020-11-11 20:55:35 +010036void wait_for_iosav(int channel)
37{
38 while (1) {
Angel Pons66780a02021-03-26 13:33:22 +010039 if (mchbar_read32(IOSAV_STATUS_ch(channel)) & 0x50)
Angel Pons1c505f82020-11-11 20:55:35 +010040 return;
41 }
42}
Angel Ponsffd50152020-11-12 11:03:10 +010043
Angel Ponsa853e7a2020-12-07 12:28:38 +010044void iosav_run_once_and_wait(const int ch)
45{
Angel Pons9f4ed3b2020-12-07 12:34:36 +010046 iosav_run_queue(ch, 1, 0);
Angel Ponsa853e7a2020-12-07 12:28:38 +010047 wait_for_iosav(ch);
48}
49
Angel Ponsffd50152020-11-12 11:03:10 +010050void iosav_write_zqcs_sequence(int channel, int slotrank, u32 gap, u32 post, u32 wrap)
51{
Angel Pons9f58bb22020-11-12 11:56:07 +010052 const struct iosav_ssq sequence[] = {
53 /* DRAM command ZQCS */
54 [0] = {
55 .sp_cmd_ctrl = {
56 .command = IOSAV_ZQCS,
57 },
58 .subseq_ctrl = {
59 .cmd_executions = 1,
60 .cmd_delay_gap = gap,
61 .post_ssq_wait = post,
62 .data_direction = SSQ_NA,
63 },
64 .sp_cmd_addr = {
65 .address = 0,
66 .rowbits = 6,
67 .bank = 0,
68 .rank = slotrank,
69 },
70 .addr_update = {
71 .addr_wrap = wrap,
72 },
73 },
74 };
Angel Ponsffd50152020-11-12 11:03:10 +010075 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
76}
77
78void iosav_write_prea_sequence(int channel, int slotrank, u32 post, u32 wrap)
79{
Angel Pons9f58bb22020-11-12 11:56:07 +010080 const struct iosav_ssq sequence[] = {
81 /* DRAM command PREA */
82 [0] = {
83 .sp_cmd_ctrl = {
84 .command = IOSAV_PRE,
85 .ranksel_ap = 1,
86 },
87 .subseq_ctrl = {
88 .cmd_executions = 1,
89 .cmd_delay_gap = 3,
90 .post_ssq_wait = post,
91 .data_direction = SSQ_NA,
92 },
93 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +010094 .address = 1 << 10,
Angel Pons9f58bb22020-11-12 11:56:07 +010095 .rowbits = 6,
96 .bank = 0,
97 .rank = slotrank,
98 },
99 .addr_update = {
100 .addr_wrap = wrap,
101 },
102 },
103 };
Angel Ponsffd50152020-11-12 11:03:10 +0100104 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
105}
106
107void iosav_write_read_mpr_sequence(
108 int channel, int slotrank, u32 tMOD, u32 loops, u32 gap, u32 loops2, u32 post2)
109{
Angel Pons9f58bb22020-11-12 11:56:07 +0100110 const struct iosav_ssq sequence[] = {
111 /*
112 * DRAM command MRS
113 *
114 * Write MR3 MPR enable. In this mode only RD and RDA
115 * are allowed, and all reads return a predefined pattern.
116 */
117 [0] = {
118 .sp_cmd_ctrl = {
119 .command = IOSAV_MRS,
120 .ranksel_ap = 1,
121 },
122 .subseq_ctrl = {
123 .cmd_executions = 1,
124 .cmd_delay_gap = 3,
125 .post_ssq_wait = tMOD,
126 .data_direction = SSQ_NA,
127 },
128 .sp_cmd_addr = {
129 .address = 4,
130 .rowbits = 6,
131 .bank = 3,
132 .rank = slotrank,
133 },
134 },
135 /* DRAM command RD */
136 [1] = {
137 .sp_cmd_ctrl = {
138 .command = IOSAV_RD,
139 .ranksel_ap = 1,
140 },
141 .subseq_ctrl = {
142 .cmd_executions = loops,
143 .cmd_delay_gap = gap,
144 .post_ssq_wait = 4,
145 .data_direction = SSQ_RD,
146 },
147 .sp_cmd_addr = {
148 .address = 0,
149 .rowbits = 0,
150 .bank = 0,
151 .rank = slotrank,
152 },
153 },
154 /* DRAM command RD */
155 [2] = {
156 .sp_cmd_ctrl = {
157 .command = IOSAV_RD,
158 .ranksel_ap = 1,
159 },
160 .subseq_ctrl = {
161 .cmd_executions = loops2,
162 .cmd_delay_gap = 4,
163 .post_ssq_wait = post2,
164 .data_direction = SSQ_NA,
165 },
166 .sp_cmd_addr = {
167 .address = 0,
168 .rowbits = 6,
169 .bank = 0,
170 .rank = slotrank,
171 },
172 },
173 /*
174 * DRAM command MRS
175 *
176 * Write MR3 MPR disable.
177 */
178 [3] = {
179 .sp_cmd_ctrl = {
180 .command = IOSAV_MRS,
181 .ranksel_ap = 1,
182 },
183 .subseq_ctrl = {
184 .cmd_executions = 1,
185 .cmd_delay_gap = 3,
186 .post_ssq_wait = tMOD,
187 .data_direction = SSQ_NA,
188 },
189 .sp_cmd_addr = {
190 .address = 0,
191 .rowbits = 6,
192 .bank = 3,
193 .rank = slotrank,
194 },
195 },
196 };
Angel Ponsffd50152020-11-12 11:03:10 +0100197 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
198}
199
Angel Pons801a5cb2020-11-15 15:48:29 +0100200void iosav_write_prea_act_read_sequence(ramctr_timing *ctrl, int channel, int slotrank)
201{
202 const struct iosav_ssq sequence[] = {
203 /* DRAM command PREA */
204 [0] = {
205 .sp_cmd_ctrl = {
206 .command = IOSAV_PRE,
207 .ranksel_ap = 1,
208 },
209 .subseq_ctrl = {
210 .cmd_executions = 1,
211 .cmd_delay_gap = 3,
212 .post_ssq_wait = ctrl->tRP,
213 .data_direction = SSQ_NA,
214 },
215 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +0100216 .address = 1 << 10,
Angel Pons801a5cb2020-11-15 15:48:29 +0100217 .rowbits = 6,
218 .bank = 0,
219 .rank = slotrank,
220 },
221 .addr_update = {
222 .addr_wrap = 18,
223 },
224 },
225 /* DRAM command ACT */
226 [1] = {
227 .sp_cmd_ctrl = {
228 .command = IOSAV_ACT,
229 .ranksel_ap = 1,
230 },
231 .subseq_ctrl = {
232 .cmd_executions = 8,
233 .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
234 .post_ssq_wait = ctrl->CAS,
235 .data_direction = SSQ_NA,
236 },
237 .sp_cmd_addr = {
238 .address = 0,
239 .rowbits = 6,
240 .bank = 0,
241 .rank = slotrank,
242 },
243 .addr_update = {
244 .inc_bank = 1,
245 .addr_wrap = 18,
246 },
247 },
248 /* DRAM command RD */
249 [2] = {
250 .sp_cmd_ctrl = {
251 .command = IOSAV_RD,
252 .ranksel_ap = 1,
253 },
254 .subseq_ctrl = {
255 .cmd_executions = 500,
256 .cmd_delay_gap = 4,
257 .post_ssq_wait = MAX(ctrl->tRTP, 8),
258 .data_direction = SSQ_RD,
259 },
260 .sp_cmd_addr = {
261 .address = 0,
262 .rowbits = 0,
263 .bank = 0,
264 .rank = slotrank,
265 },
266 .addr_update = {
267 .inc_addr_8 = 1,
268 .addr_wrap = 18,
269 },
270 },
271 /* DRAM command PREA */
272 [3] = {
273 .sp_cmd_ctrl = {
274 .command = IOSAV_PRE,
275 .ranksel_ap = 1,
276 },
277 .subseq_ctrl = {
278 .cmd_executions = 1,
279 .cmd_delay_gap = 3,
280 .post_ssq_wait = ctrl->tRP,
281 .data_direction = SSQ_NA,
282 },
283 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +0100284 .address = 1 << 10,
Angel Pons801a5cb2020-11-15 15:48:29 +0100285 .rowbits = 6,
286 .bank = 0,
287 .rank = slotrank,
288 },
289 .addr_update = {
290 .addr_wrap = 18,
291 },
292 },
293 };
294 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
295}
296
Angel Pons94267212020-11-14 16:49:29 +0100297void iosav_write_jedec_write_leveling_sequence(
298 ramctr_timing *ctrl, int channel, int slotrank, int bank, u32 mr1reg)
299{
300 /* First DQS/DQS# rising edge after write leveling mode is programmed */
301 const u32 tWLMRD = 40;
302
303 const struct iosav_ssq sequence[] = {
304 /* DRAM command MRS: enable DQs on this slotrank */
305 [0] = {
306 .sp_cmd_ctrl = {
307 .command = IOSAV_MRS,
308 .ranksel_ap = 1,
309 },
310 .subseq_ctrl = {
311 .cmd_executions = 1,
312 .cmd_delay_gap = 3,
313 .post_ssq_wait = tWLMRD,
314 .data_direction = SSQ_NA,
315 },
316 .sp_cmd_addr = {
317 .address = mr1reg,
318 .rowbits = 6,
319 .bank = bank,
320 .rank = slotrank,
321 },
322 },
323 /* DRAM command NOP */
324 [1] = {
325 .sp_cmd_ctrl = {
326 .command = IOSAV_NOP,
327 .ranksel_ap = 1,
328 },
329 .subseq_ctrl = {
330 .cmd_executions = 1,
331 .cmd_delay_gap = 3,
332 .post_ssq_wait = ctrl->CWL + ctrl->tWLO,
333 .data_direction = SSQ_WR,
334 },
335 .sp_cmd_addr = {
336 .address = 8,
337 .rowbits = 0,
338 .bank = 0,
339 .rank = slotrank,
340 },
341 },
342 /* DRAM command NOP */
343 [2] = {
344 .sp_cmd_ctrl = {
345 .command = IOSAV_NOP_ALT,
346 .ranksel_ap = 1,
347 },
348 .subseq_ctrl = {
349 .cmd_executions = 1,
350 .cmd_delay_gap = 3,
351 .post_ssq_wait = ctrl->CAS + 38,
352 .data_direction = SSQ_RD,
353 },
354 .sp_cmd_addr = {
355 .address = 4,
356 .rowbits = 0,
357 .bank = 0,
358 .rank = slotrank,
359 },
360 },
361 /* DRAM command MRS: disable DQs on this slotrank */
362 [3] = {
363 .sp_cmd_ctrl = {
364 .command = IOSAV_MRS,
365 .ranksel_ap = 1,
366 },
367 .subseq_ctrl = {
368 .cmd_executions = 1,
369 .cmd_delay_gap = 3,
370 .post_ssq_wait = ctrl->tMOD,
371 .data_direction = SSQ_NA,
372 },
373 .sp_cmd_addr = {
374 .address = mr1reg | 1 << 12,
375 .rowbits = 6,
376 .bank = bank,
377 .rank = slotrank,
378 },
379 },
380 };
381 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
382}
383
Angel Ponsffd50152020-11-12 11:03:10 +0100384void iosav_write_misc_write_sequence(ramctr_timing *ctrl, int channel, int slotrank,
385 u32 gap0, u32 loops0, u32 gap1, u32 loops2, u32 wrap2)
386{
Angel Pons9f58bb22020-11-12 11:56:07 +0100387 const struct iosav_ssq sequence[] = {
388 /* DRAM command ACT */
389 [0] = {
390 .sp_cmd_ctrl = {
391 .command = IOSAV_ACT,
392 .ranksel_ap = 1,
393 },
394 .subseq_ctrl = {
395 .cmd_executions = loops0,
396 .cmd_delay_gap = gap0,
397 .post_ssq_wait = ctrl->tRCD,
398 .data_direction = SSQ_NA,
399 },
400 .sp_cmd_addr = {
401 .address = 0,
402 .rowbits = 6,
403 .bank = 0,
404 .rank = slotrank,
405 },
406 .addr_update = {
407 .inc_bank = loops0 == 1 ? 0 : 1,
408 .addr_wrap = loops0 == 1 ? 0 : 18,
409 },
410 },
411 /* DRAM command NOP */
412 [1] = {
413 .sp_cmd_ctrl = {
414 .command = IOSAV_NOP,
415 .ranksel_ap = 1,
416 },
417 .subseq_ctrl = {
418 .cmd_executions = 1,
419 .cmd_delay_gap = gap1,
420 .post_ssq_wait = 4,
421 .data_direction = SSQ_WR,
422 },
423 .sp_cmd_addr = {
424 .address = 8,
425 .rowbits = 0,
426 .bank = 0,
427 .rank = slotrank,
428 },
429 .addr_update = {
430 .addr_wrap = 31,
431 },
432 },
433 /* DRAM command WR */
434 [2] = {
435 .sp_cmd_ctrl = {
436 .command = IOSAV_WR,
437 .ranksel_ap = 1,
438 },
439 .subseq_ctrl = {
440 .cmd_executions = loops2,
441 .cmd_delay_gap = 4,
442 .post_ssq_wait = 4,
443 .data_direction = SSQ_WR,
444 },
445 .sp_cmd_addr = {
446 .address = 0,
447 .rowbits = 0,
448 .bank = 0,
449 .rank = slotrank,
450 },
451 .addr_update = {
452 .inc_addr_8 = 1,
453 .addr_wrap = wrap2,
454 },
455 },
456 /* DRAM command NOP */
457 [3] = {
458 .sp_cmd_ctrl = {
459 .command = IOSAV_NOP,
460 .ranksel_ap = 1,
461 },
462 .subseq_ctrl = {
463 .cmd_executions = 1,
464 .cmd_delay_gap = 3,
465 .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 5,
466 .data_direction = SSQ_WR,
467 },
468 .sp_cmd_addr = {
469 .address = 8,
470 .rowbits = 0,
471 .bank = 0,
472 .rank = slotrank,
473 },
474 .addr_update = {
475 .addr_wrap = 31,
476 },
477 },
478 };
Angel Ponsffd50152020-11-12 11:03:10 +0100479 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
480}
481
482void iosav_write_command_training_sequence(
483 ramctr_timing *ctrl, int channel, int slotrank, unsigned int address)
484{
Angel Pons9f58bb22020-11-12 11:56:07 +0100485 const struct iosav_ssq sequence[] = {
486 /* DRAM command ACT */
487 [0] = {
488 .sp_cmd_ctrl = {
489 .command = IOSAV_ACT,
490 .ranksel_ap = 1,
491 },
492 .subseq_ctrl = {
493 .cmd_executions = 8,
494 .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
495 .post_ssq_wait = ctrl->tRCD,
496 .data_direction = SSQ_NA,
497 },
498 .sp_cmd_addr = {
499 .address = address,
500 .rowbits = 6,
501 .bank = 0,
502 .rank = slotrank,
503 },
504 .addr_update = {
505 .inc_bank = 1,
506 .addr_wrap = 18,
507 },
508 },
509 /* DRAM command WR */
510 [1] = {
511 .sp_cmd_ctrl = {
512 .command = IOSAV_WR,
513 .ranksel_ap = 1,
514 },
515 .subseq_ctrl = {
516 .cmd_executions = 32,
517 .cmd_delay_gap = 4,
518 .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8,
519 .data_direction = SSQ_WR,
520 },
521 .sp_cmd_addr = {
522 .address = 0,
523 .rowbits = 0,
524 .bank = 0,
525 .rank = slotrank,
526 },
527 .addr_update = {
528 .inc_addr_8 = 1,
529 .addr_wrap = 18,
530 .lfsr_upd = 3,
531 .lfsr_xors = 2,
532 },
533 },
534 /* DRAM command RD */
535 [2] = {
536 .sp_cmd_ctrl = {
537 .command = IOSAV_RD,
538 .ranksel_ap = 1,
539 },
540 .subseq_ctrl = {
541 .cmd_executions = 32,
542 .cmd_delay_gap = 4,
543 .post_ssq_wait = MAX(ctrl->tRTP, 8),
544 .data_direction = SSQ_RD,
545 },
546 .sp_cmd_addr = {
547 .address = 0,
548 .rowbits = 0,
549 .bank = 0,
550 .rank = slotrank,
551 },
552 .addr_update = {
553 .inc_addr_8 = 1,
554 .addr_wrap = 18,
555 .lfsr_upd = 3,
556 .lfsr_xors = 2,
557 },
558 },
559 /* DRAM command PRE */
560 [3] = {
561 .sp_cmd_ctrl = {
562 .command = IOSAV_PRE,
563 .ranksel_ap = 1,
564 },
565 .subseq_ctrl = {
566 .cmd_executions = 1,
567 .cmd_delay_gap = 4,
568 .post_ssq_wait = 15,
569 .data_direction = SSQ_NA,
570 },
571 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +0100572 .address = 1 << 10,
Angel Pons9f58bb22020-11-12 11:56:07 +0100573 .rowbits = 6,
574 .bank = 0,
575 .rank = slotrank,
576 },
577 .addr_update = {
578 .addr_wrap = 18,
579 },
580 },
581 };
Angel Ponsffd50152020-11-12 11:03:10 +0100582 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
583}
584
585void iosav_write_data_write_sequence(ramctr_timing *ctrl, int channel, int slotrank)
586{
Angel Pons9f58bb22020-11-12 11:56:07 +0100587 const struct iosav_ssq sequence[] = {
588 /* DRAM command ACT */
589 [0] = {
590 .sp_cmd_ctrl = {
591 .command = IOSAV_ACT,
592 .ranksel_ap = 1,
593 },
594 .subseq_ctrl = {
595 .cmd_executions = 4,
596 .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
597 .post_ssq_wait = ctrl->tRCD,
598 .data_direction = SSQ_NA,
599 },
600 .sp_cmd_addr = {
601 .address = 0,
602 .rowbits = 6,
603 .bank = 0,
604 .rank = slotrank,
605 },
606 .addr_update = {
607 .inc_bank = 0,
608 .addr_wrap = 18,
609 },
610 },
611 /* DRAM command WR */
612 [1] = {
613 .sp_cmd_ctrl = {
614 .command = IOSAV_WR,
615 .ranksel_ap = 1,
616 },
617 .subseq_ctrl = {
618 .cmd_executions = 32,
619 .cmd_delay_gap = 20,
620 .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8,
621 .data_direction = SSQ_WR,
622 },
623 .sp_cmd_addr = {
624 .address = 0,
625 .rowbits = 0,
626 .bank = 0,
627 .rank = slotrank,
628 },
629 .addr_update = {
630 .inc_addr_8 = 1,
631 .addr_wrap = 18,
632 },
633 },
634 /* DRAM command RD */
635 [2] = {
636 .sp_cmd_ctrl = {
637 .command = IOSAV_RD,
638 .ranksel_ap = 1,
639 },
640 .subseq_ctrl = {
641 .cmd_executions = 32,
642 .cmd_delay_gap = 20,
643 .post_ssq_wait = MAX(ctrl->tRTP, 8),
644 .data_direction = SSQ_RD,
645 },
646 .sp_cmd_addr = {
647 .address = 0,
648 .rowbits = 0,
649 .bank = 0,
650 .rank = slotrank,
651 },
652 .addr_update = {
653 .inc_addr_8 = 1,
654 .addr_wrap = 18,
655 },
656 },
657 /* DRAM command PRE */
658 [3] = {
659 .sp_cmd_ctrl = {
660 .command = IOSAV_PRE,
661 .ranksel_ap = 1,
662 },
663 .subseq_ctrl = {
664 .cmd_executions = 1,
665 .cmd_delay_gap = 3,
666 .post_ssq_wait = ctrl->tRP,
667 .data_direction = SSQ_NA,
668 },
669 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +0100670 .address = 1 << 10,
Angel Pons9f58bb22020-11-12 11:56:07 +0100671 .rowbits = 6,
672 .bank = 0,
673 .rank = slotrank,
674 },
675 },
676 };
Angel Ponsffd50152020-11-12 11:03:10 +0100677 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
678}
679
680void iosav_write_aggressive_write_read_sequence(ramctr_timing *ctrl, int channel, int slotrank)
681{
Angel Pons9f58bb22020-11-12 11:56:07 +0100682 const struct iosav_ssq sequence[] = {
683 /* DRAM command ACT */
684 [0] = {
685 .sp_cmd_ctrl = {
686 .command = IOSAV_ACT,
687 .ranksel_ap = 1,
688 },
689 .subseq_ctrl = {
690 .cmd_executions = 4,
691 .cmd_delay_gap = MAX((ctrl->tFAW >> 2) + 1, ctrl->tRRD),
692 .post_ssq_wait = ctrl->tRCD,
693 .data_direction = SSQ_NA,
694 },
695 .sp_cmd_addr = {
696 .address = 0,
697 .rowbits = 6,
698 .bank = 0,
699 .rank = slotrank,
700 },
701 .addr_update = {
702 .inc_bank = 1,
703 .addr_wrap = 18,
704 },
705 },
706 /* DRAM command WR */
707 [1] = {
708 .sp_cmd_ctrl = {
709 .command = IOSAV_WR,
710 .ranksel_ap = 1,
711 },
712 .subseq_ctrl = {
713 .cmd_executions = 480,
714 .cmd_delay_gap = 4,
715 .post_ssq_wait = ctrl->tWTR + ctrl->CWL + 8,
716 .data_direction = SSQ_WR,
717 },
718 .sp_cmd_addr = {
719 .address = 0,
720 .rowbits = 0,
721 .bank = 0,
722 .rank = slotrank,
723 },
724 .addr_update = {
725 .inc_addr_8 = 1,
726 .addr_wrap = 18,
727 },
728 },
729 /* DRAM command RD */
730 [2] = {
731 .sp_cmd_ctrl = {
732 .command = IOSAV_RD,
733 .ranksel_ap = 1,
734 },
735 .subseq_ctrl = {
736 .cmd_executions = 480,
737 .cmd_delay_gap = 4,
738 .post_ssq_wait = MAX(ctrl->tRTP, 8),
739 .data_direction = SSQ_RD,
740 },
741 .sp_cmd_addr = {
742 .address = 0,
743 .rowbits = 0,
744 .bank = 0,
745 .rank = slotrank,
746 },
747 .addr_update = {
748 .inc_addr_8 = 1,
749 .addr_wrap = 18,
750 },
751 },
752 /* DRAM command PRE */
753 [3] = {
754 .sp_cmd_ctrl = {
755 .command = IOSAV_PRE,
756 .ranksel_ap = 1,
757 },
758 .subseq_ctrl = {
759 .cmd_executions = 1,
760 .cmd_delay_gap = 4,
761 .post_ssq_wait = ctrl->tRP,
762 .data_direction = SSQ_NA,
763 },
764 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +0100765 .address = 1 << 10,
Angel Pons9f58bb22020-11-12 11:56:07 +0100766 .rowbits = 6,
767 .bank = 0,
768 .rank = slotrank,
769 },
770 },
771 };
Angel Ponsffd50152020-11-12 11:03:10 +0100772 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
773}
774
775void iosav_write_memory_test_sequence(ramctr_timing *ctrl, int channel, int slotrank)
776{
Angel Pons9f58bb22020-11-12 11:56:07 +0100777 const struct iosav_ssq sequence[] = {
778 /* DRAM command ACT */
779 [0] = {
780 .sp_cmd_ctrl = {
781 .command = IOSAV_ACT,
782 .ranksel_ap = 1,
783 },
784 .subseq_ctrl = {
785 .cmd_executions = 4,
786 .cmd_delay_gap = 8,
787 .post_ssq_wait = 40,
788 .data_direction = SSQ_NA,
789 },
790 .sp_cmd_addr = {
791 .address = 0,
792 .rowbits = 6,
793 .bank = 0,
794 .rank = slotrank,
795 },
796 .addr_update = {
797 .inc_bank = 1,
798 .addr_wrap = 18,
799 },
800 },
801 /* DRAM command WR */
802 [1] = {
803 .sp_cmd_ctrl = {
804 .command = IOSAV_WR,
805 .ranksel_ap = 1,
806 },
807 .subseq_ctrl = {
808 .cmd_executions = 100,
809 .cmd_delay_gap = 4,
810 .post_ssq_wait = 40,
811 .data_direction = SSQ_WR,
812 },
813 .sp_cmd_addr = {
814 .address = 0,
815 .rowbits = 0,
816 .bank = 0,
817 .rank = slotrank,
818 },
819 .addr_update = {
820 .inc_addr_8 = 1,
821 .addr_wrap = 18,
822 },
823 },
824 /* DRAM command RD */
825 [2] = {
826 .sp_cmd_ctrl = {
827 .command = IOSAV_RD,
828 .ranksel_ap = 1,
829 },
830 .subseq_ctrl = {
831 .cmd_executions = 100,
832 .cmd_delay_gap = 4,
833 .post_ssq_wait = 40,
834 .data_direction = SSQ_RD,
835 },
836 .sp_cmd_addr = {
837 .address = 0,
838 .rowbits = 0,
839 .bank = 0,
840 .rank = slotrank,
841 },
842 .addr_update = {
843 .inc_addr_8 = 1,
844 .addr_wrap = 18,
845 },
846 },
847 /* DRAM command PRE */
848 [3] = {
849 .sp_cmd_ctrl = {
850 .command = IOSAV_PRE,
851 .ranksel_ap = 1,
852 },
853 .subseq_ctrl = {
854 .cmd_executions = 1,
855 .cmd_delay_gap = 3,
856 .post_ssq_wait = 40,
857 .data_direction = SSQ_NA,
858 },
859 .sp_cmd_addr = {
Angel Pons5db1b152020-12-13 16:37:53 +0100860 .address = 1 << 10,
Angel Pons9f58bb22020-11-12 11:56:07 +0100861 .rowbits = 6,
862 .bank = 0,
863 .rank = slotrank,
864 },
865 .addr_update = {
866 .addr_wrap = 18,
867 },
868 },
869 };
Angel Ponsffd50152020-11-12 11:03:10 +0100870 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
871}