blob: 25f5ae705d82619a088b306bbd9bb3f9f73e2138 [file] [log] [blame]
Angel Pons1c505f82020-11-11 20:55:35 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <commonlib/helpers.h>
4#include <console/console.h>
5#include <delay.h>
6#include <types.h>
7
8#include "raminit_native.h"
9#include "raminit_common.h"
10#include "raminit_tables.h"
11#include "sandybridge.h"
12
13/* FIXME: no support for 3-channel chipsets */
14
15/* Number of programmed IOSAV subsequences. */
16static unsigned int ssq_count = 0;
17
Angel Pons8f0757e2020-11-11 23:03:36 +010018void iosav_write_sequence(const int ch, const struct iosav_ssq *seq, const unsigned int length)
Angel Pons1c505f82020-11-11 20:55:35 +010019{
Angel Pons8f0757e2020-11-11 23:03:36 +010020 for (unsigned int i = 0; i < length; i++) {
21 MCHBAR32(IOSAV_n_SP_CMD_CTRL_ch(ch, i)) = seq[i].sp_cmd_ctrl.raw;
22 MCHBAR32(IOSAV_n_SUBSEQ_CTRL_ch(ch, i)) = seq[i].subseq_ctrl.raw;
23 MCHBAR32(IOSAV_n_SP_CMD_ADDR_ch(ch, i)) = seq[i].sp_cmd_addr.raw;
24 MCHBAR32(IOSAV_n_ADDR_UPDATE_ch(ch, i)) = seq[i].addr_update.raw;
25 }
Angel Pons1c505f82020-11-11 20:55:35 +010026
Angel Pons8f0757e2020-11-11 23:03:36 +010027 ssq_count = length;
Angel Pons1c505f82020-11-11 20:55:35 +010028}
29
30void iosav_run_queue(const int ch, const u8 loops, const u8 as_timer)
31{
Angel Pons8f0757e2020-11-11 23:03:36 +010032 /* Should never happen */
33 if (ssq_count == 0)
34 return;
Angel Pons1c505f82020-11-11 20:55:35 +010035
Angel Pons8f0757e2020-11-11 23:03:36 +010036 MCHBAR32(IOSAV_SEQ_CTL_ch(ch)) = loops | ((ssq_count - 1) << 18) | (as_timer << 22);
Angel Pons1c505f82020-11-11 20:55:35 +010037}
38
39void iosav_run_once(const int ch)
40{
41 iosav_run_queue(ch, 1, 0);
42}
43
44void wait_for_iosav(int channel)
45{
46 while (1) {
47 if (MCHBAR32(IOSAV_STATUS_ch(channel)) & 0x50)
48 return;
49 }
50}
Angel Ponsffd50152020-11-12 11:03:10 +010051
52void iosav_write_zqcs_sequence(int channel, int slotrank, u32 gap, u32 post, u32 wrap)
53{
Angel Pons9f58bb22020-11-12 11:56:07 +010054 const struct iosav_ssq sequence[] = {
55 /* DRAM command ZQCS */
56 [0] = {
57 .sp_cmd_ctrl = {
58 .command = IOSAV_ZQCS,
59 },
60 .subseq_ctrl = {
61 .cmd_executions = 1,
62 .cmd_delay_gap = gap,
63 .post_ssq_wait = post,
64 .data_direction = SSQ_NA,
65 },
66 .sp_cmd_addr = {
67 .address = 0,
68 .rowbits = 6,
69 .bank = 0,
70 .rank = slotrank,
71 },
72 .addr_update = {
73 .addr_wrap = wrap,
74 },
75 },
76 };
Angel Ponsffd50152020-11-12 11:03:10 +010077 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
78}
79
80void iosav_write_prea_sequence(int channel, int slotrank, u32 post, u32 wrap)
81{
Angel Pons9f58bb22020-11-12 11:56:07 +010082 const struct iosav_ssq sequence[] = {
83 /* DRAM command PREA */
84 [0] = {
85 .sp_cmd_ctrl = {
86 .command = IOSAV_PRE,
87 .ranksel_ap = 1,
88 },
89 .subseq_ctrl = {
90 .cmd_executions = 1,
91 .cmd_delay_gap = 3,
92 .post_ssq_wait = post,
93 .data_direction = SSQ_NA,
94 },
95 .sp_cmd_addr = {
96 .address = 1024,
97 .rowbits = 6,
98 .bank = 0,
99 .rank = slotrank,
100 },
101 .addr_update = {
102 .addr_wrap = wrap,
103 },
104 },
105 };
Angel Ponsffd50152020-11-12 11:03:10 +0100106 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
107}
108
109void iosav_write_read_mpr_sequence(
110 int channel, int slotrank, u32 tMOD, u32 loops, u32 gap, u32 loops2, u32 post2)
111{
Angel Pons9f58bb22020-11-12 11:56:07 +0100112 const struct iosav_ssq sequence[] = {
113 /*
114 * DRAM command MRS
115 *
116 * Write MR3 MPR enable. In this mode only RD and RDA
117 * are allowed, and all reads return a predefined pattern.
118 */
119 [0] = {
120 .sp_cmd_ctrl = {
121 .command = IOSAV_MRS,
122 .ranksel_ap = 1,
123 },
124 .subseq_ctrl = {
125 .cmd_executions = 1,
126 .cmd_delay_gap = 3,
127 .post_ssq_wait = tMOD,
128 .data_direction = SSQ_NA,
129 },
130 .sp_cmd_addr = {
131 .address = 4,
132 .rowbits = 6,
133 .bank = 3,
134 .rank = slotrank,
135 },
136 },
137 /* DRAM command RD */
138 [1] = {
139 .sp_cmd_ctrl = {
140 .command = IOSAV_RD,
141 .ranksel_ap = 1,
142 },
143 .subseq_ctrl = {
144 .cmd_executions = loops,
145 .cmd_delay_gap = gap,
146 .post_ssq_wait = 4,
147 .data_direction = SSQ_RD,
148 },
149 .sp_cmd_addr = {
150 .address = 0,
151 .rowbits = 0,
152 .bank = 0,
153 .rank = slotrank,
154 },
155 },
156 /* DRAM command RD */
157 [2] = {
158 .sp_cmd_ctrl = {
159 .command = IOSAV_RD,
160 .ranksel_ap = 1,
161 },
162 .subseq_ctrl = {
163 .cmd_executions = loops2,
164 .cmd_delay_gap = 4,
165 .post_ssq_wait = post2,
166 .data_direction = SSQ_NA,
167 },
168 .sp_cmd_addr = {
169 .address = 0,
170 .rowbits = 6,
171 .bank = 0,
172 .rank = slotrank,
173 },
174 },
175 /*
176 * DRAM command MRS
177 *
178 * Write MR3 MPR disable.
179 */
180 [3] = {
181 .sp_cmd_ctrl = {
182 .command = IOSAV_MRS,
183 .ranksel_ap = 1,
184 },
185 .subseq_ctrl = {
186 .cmd_executions = 1,
187 .cmd_delay_gap = 3,
188 .post_ssq_wait = tMOD,
189 .data_direction = SSQ_NA,
190 },
191 .sp_cmd_addr = {
192 .address = 0,
193 .rowbits = 6,
194 .bank = 3,
195 .rank = slotrank,
196 },
197 },
198 };
Angel Ponsffd50152020-11-12 11:03:10 +0100199 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
200}
201
Angel Pons94267212020-11-14 16:49:29 +0100202void iosav_write_jedec_write_leveling_sequence(
203 ramctr_timing *ctrl, int channel, int slotrank, int bank, u32 mr1reg)
204{
205 /* First DQS/DQS# rising edge after write leveling mode is programmed */
206 const u32 tWLMRD = 40;
207
208 const struct iosav_ssq sequence[] = {
209 /* DRAM command MRS: enable DQs on this slotrank */
210 [0] = {
211 .sp_cmd_ctrl = {
212 .command = IOSAV_MRS,
213 .ranksel_ap = 1,
214 },
215 .subseq_ctrl = {
216 .cmd_executions = 1,
217 .cmd_delay_gap = 3,
218 .post_ssq_wait = tWLMRD,
219 .data_direction = SSQ_NA,
220 },
221 .sp_cmd_addr = {
222 .address = mr1reg,
223 .rowbits = 6,
224 .bank = bank,
225 .rank = slotrank,
226 },
227 },
228 /* DRAM command NOP */
229 [1] = {
230 .sp_cmd_ctrl = {
231 .command = IOSAV_NOP,
232 .ranksel_ap = 1,
233 },
234 .subseq_ctrl = {
235 .cmd_executions = 1,
236 .cmd_delay_gap = 3,
237 .post_ssq_wait = ctrl->CWL + ctrl->tWLO,
238 .data_direction = SSQ_WR,
239 },
240 .sp_cmd_addr = {
241 .address = 8,
242 .rowbits = 0,
243 .bank = 0,
244 .rank = slotrank,
245 },
246 },
247 /* DRAM command NOP */
248 [2] = {
249 .sp_cmd_ctrl = {
250 .command = IOSAV_NOP_ALT,
251 .ranksel_ap = 1,
252 },
253 .subseq_ctrl = {
254 .cmd_executions = 1,
255 .cmd_delay_gap = 3,
256 .post_ssq_wait = ctrl->CAS + 38,
257 .data_direction = SSQ_RD,
258 },
259 .sp_cmd_addr = {
260 .address = 4,
261 .rowbits = 0,
262 .bank = 0,
263 .rank = slotrank,
264 },
265 },
266 /* DRAM command MRS: disable DQs on this slotrank */
267 [3] = {
268 .sp_cmd_ctrl = {
269 .command = IOSAV_MRS,
270 .ranksel_ap = 1,
271 },
272 .subseq_ctrl = {
273 .cmd_executions = 1,
274 .cmd_delay_gap = 3,
275 .post_ssq_wait = ctrl->tMOD,
276 .data_direction = SSQ_NA,
277 },
278 .sp_cmd_addr = {
279 .address = mr1reg | 1 << 12,
280 .rowbits = 6,
281 .bank = bank,
282 .rank = slotrank,
283 },
284 },
285 };
286 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
287}
288
Angel Ponsffd50152020-11-12 11:03:10 +0100289void iosav_write_misc_write_sequence(ramctr_timing *ctrl, int channel, int slotrank,
290 u32 gap0, u32 loops0, u32 gap1, u32 loops2, u32 wrap2)
291{
Angel Pons9f58bb22020-11-12 11:56:07 +0100292 const struct iosav_ssq sequence[] = {
293 /* DRAM command ACT */
294 [0] = {
295 .sp_cmd_ctrl = {
296 .command = IOSAV_ACT,
297 .ranksel_ap = 1,
298 },
299 .subseq_ctrl = {
300 .cmd_executions = loops0,
301 .cmd_delay_gap = gap0,
302 .post_ssq_wait = ctrl->tRCD,
303 .data_direction = SSQ_NA,
304 },
305 .sp_cmd_addr = {
306 .address = 0,
307 .rowbits = 6,
308 .bank = 0,
309 .rank = slotrank,
310 },
311 .addr_update = {
312 .inc_bank = loops0 == 1 ? 0 : 1,
313 .addr_wrap = loops0 == 1 ? 0 : 18,
314 },
315 },
316 /* DRAM command NOP */
317 [1] = {
318 .sp_cmd_ctrl = {
319 .command = IOSAV_NOP,
320 .ranksel_ap = 1,
321 },
322 .subseq_ctrl = {
323 .cmd_executions = 1,
324 .cmd_delay_gap = gap1,
325 .post_ssq_wait = 4,
326 .data_direction = SSQ_WR,
327 },
328 .sp_cmd_addr = {
329 .address = 8,
330 .rowbits = 0,
331 .bank = 0,
332 .rank = slotrank,
333 },
334 .addr_update = {
335 .addr_wrap = 31,
336 },
337 },
338 /* DRAM command WR */
339 [2] = {
340 .sp_cmd_ctrl = {
341 .command = IOSAV_WR,
342 .ranksel_ap = 1,
343 },
344 .subseq_ctrl = {
345 .cmd_executions = loops2,
346 .cmd_delay_gap = 4,
347 .post_ssq_wait = 4,
348 .data_direction = SSQ_WR,
349 },
350 .sp_cmd_addr = {
351 .address = 0,
352 .rowbits = 0,
353 .bank = 0,
354 .rank = slotrank,
355 },
356 .addr_update = {
357 .inc_addr_8 = 1,
358 .addr_wrap = wrap2,
359 },
360 },
361 /* DRAM command NOP */
362 [3] = {
363 .sp_cmd_ctrl = {
364 .command = IOSAV_NOP,
365 .ranksel_ap = 1,
366 },
367 .subseq_ctrl = {
368 .cmd_executions = 1,
369 .cmd_delay_gap = 3,
370 .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 5,
371 .data_direction = SSQ_WR,
372 },
373 .sp_cmd_addr = {
374 .address = 8,
375 .rowbits = 0,
376 .bank = 0,
377 .rank = slotrank,
378 },
379 .addr_update = {
380 .addr_wrap = 31,
381 },
382 },
383 };
Angel Ponsffd50152020-11-12 11:03:10 +0100384 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
385}
386
387void iosav_write_command_training_sequence(
388 ramctr_timing *ctrl, int channel, int slotrank, unsigned int address)
389{
Angel Pons9f58bb22020-11-12 11:56:07 +0100390 const struct iosav_ssq sequence[] = {
391 /* DRAM command ACT */
392 [0] = {
393 .sp_cmd_ctrl = {
394 .command = IOSAV_ACT,
395 .ranksel_ap = 1,
396 },
397 .subseq_ctrl = {
398 .cmd_executions = 8,
399 .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
400 .post_ssq_wait = ctrl->tRCD,
401 .data_direction = SSQ_NA,
402 },
403 .sp_cmd_addr = {
404 .address = address,
405 .rowbits = 6,
406 .bank = 0,
407 .rank = slotrank,
408 },
409 .addr_update = {
410 .inc_bank = 1,
411 .addr_wrap = 18,
412 },
413 },
414 /* DRAM command WR */
415 [1] = {
416 .sp_cmd_ctrl = {
417 .command = IOSAV_WR,
418 .ranksel_ap = 1,
419 },
420 .subseq_ctrl = {
421 .cmd_executions = 32,
422 .cmd_delay_gap = 4,
423 .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8,
424 .data_direction = SSQ_WR,
425 },
426 .sp_cmd_addr = {
427 .address = 0,
428 .rowbits = 0,
429 .bank = 0,
430 .rank = slotrank,
431 },
432 .addr_update = {
433 .inc_addr_8 = 1,
434 .addr_wrap = 18,
435 .lfsr_upd = 3,
436 .lfsr_xors = 2,
437 },
438 },
439 /* DRAM command RD */
440 [2] = {
441 .sp_cmd_ctrl = {
442 .command = IOSAV_RD,
443 .ranksel_ap = 1,
444 },
445 .subseq_ctrl = {
446 .cmd_executions = 32,
447 .cmd_delay_gap = 4,
448 .post_ssq_wait = MAX(ctrl->tRTP, 8),
449 .data_direction = SSQ_RD,
450 },
451 .sp_cmd_addr = {
452 .address = 0,
453 .rowbits = 0,
454 .bank = 0,
455 .rank = slotrank,
456 },
457 .addr_update = {
458 .inc_addr_8 = 1,
459 .addr_wrap = 18,
460 .lfsr_upd = 3,
461 .lfsr_xors = 2,
462 },
463 },
464 /* DRAM command PRE */
465 [3] = {
466 .sp_cmd_ctrl = {
467 .command = IOSAV_PRE,
468 .ranksel_ap = 1,
469 },
470 .subseq_ctrl = {
471 .cmd_executions = 1,
472 .cmd_delay_gap = 4,
473 .post_ssq_wait = 15,
474 .data_direction = SSQ_NA,
475 },
476 .sp_cmd_addr = {
477 .address = 1024,
478 .rowbits = 6,
479 .bank = 0,
480 .rank = slotrank,
481 },
482 .addr_update = {
483 .addr_wrap = 18,
484 },
485 },
486 };
Angel Ponsffd50152020-11-12 11:03:10 +0100487 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
488}
489
490void iosav_write_data_write_sequence(ramctr_timing *ctrl, int channel, int slotrank)
491{
Angel Pons9f58bb22020-11-12 11:56:07 +0100492 const struct iosav_ssq sequence[] = {
493 /* DRAM command ACT */
494 [0] = {
495 .sp_cmd_ctrl = {
496 .command = IOSAV_ACT,
497 .ranksel_ap = 1,
498 },
499 .subseq_ctrl = {
500 .cmd_executions = 4,
501 .cmd_delay_gap = MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1),
502 .post_ssq_wait = ctrl->tRCD,
503 .data_direction = SSQ_NA,
504 },
505 .sp_cmd_addr = {
506 .address = 0,
507 .rowbits = 6,
508 .bank = 0,
509 .rank = slotrank,
510 },
511 .addr_update = {
512 .inc_bank = 0,
513 .addr_wrap = 18,
514 },
515 },
516 /* DRAM command WR */
517 [1] = {
518 .sp_cmd_ctrl = {
519 .command = IOSAV_WR,
520 .ranksel_ap = 1,
521 },
522 .subseq_ctrl = {
523 .cmd_executions = 32,
524 .cmd_delay_gap = 20,
525 .post_ssq_wait = ctrl->CWL + ctrl->tWTR + 8,
526 .data_direction = SSQ_WR,
527 },
528 .sp_cmd_addr = {
529 .address = 0,
530 .rowbits = 0,
531 .bank = 0,
532 .rank = slotrank,
533 },
534 .addr_update = {
535 .inc_addr_8 = 1,
536 .addr_wrap = 18,
537 },
538 },
539 /* DRAM command RD */
540 [2] = {
541 .sp_cmd_ctrl = {
542 .command = IOSAV_RD,
543 .ranksel_ap = 1,
544 },
545 .subseq_ctrl = {
546 .cmd_executions = 32,
547 .cmd_delay_gap = 20,
548 .post_ssq_wait = MAX(ctrl->tRTP, 8),
549 .data_direction = SSQ_RD,
550 },
551 .sp_cmd_addr = {
552 .address = 0,
553 .rowbits = 0,
554 .bank = 0,
555 .rank = slotrank,
556 },
557 .addr_update = {
558 .inc_addr_8 = 1,
559 .addr_wrap = 18,
560 },
561 },
562 /* DRAM command PRE */
563 [3] = {
564 .sp_cmd_ctrl = {
565 .command = IOSAV_PRE,
566 .ranksel_ap = 1,
567 },
568 .subseq_ctrl = {
569 .cmd_executions = 1,
570 .cmd_delay_gap = 3,
571 .post_ssq_wait = ctrl->tRP,
572 .data_direction = SSQ_NA,
573 },
574 .sp_cmd_addr = {
575 .address = 1024,
576 .rowbits = 6,
577 .bank = 0,
578 .rank = slotrank,
579 },
580 },
581 };
Angel Ponsffd50152020-11-12 11:03:10 +0100582 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
583}
584
585void iosav_write_aggressive_write_read_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->tFAW >> 2) + 1, ctrl->tRRD),
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 = 1,
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 = 480,
619 .cmd_delay_gap = 4,
620 .post_ssq_wait = ctrl->tWTR + ctrl->CWL + 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 = 480,
642 .cmd_delay_gap = 4,
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 = 4,
666 .post_ssq_wait = ctrl->tRP,
667 .data_direction = SSQ_NA,
668 },
669 .sp_cmd_addr = {
670 .address = 1024,
671 .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_memory_test_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 = 8,
692 .post_ssq_wait = 40,
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 = 100,
714 .cmd_delay_gap = 4,
715 .post_ssq_wait = 40,
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 = 100,
737 .cmd_delay_gap = 4,
738 .post_ssq_wait = 40,
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 = 3,
761 .post_ssq_wait = 40,
762 .data_direction = SSQ_NA,
763 },
764 .sp_cmd_addr = {
765 .address = 1024,
766 .rowbits = 6,
767 .bank = 0,
768 .rank = slotrank,
769 },
770 .addr_update = {
771 .addr_wrap = 18,
772 },
773 },
774 };
Angel Ponsffd50152020-11-12 11:03:10 +0100775 iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
776}