1 # This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2013-2020 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2017 whitequark <whitequark@whitequark.org>
4 # This file is Copyright (c) 2014 Yann Sionneau <ys@m-labs.hk>
5 # This file is Copyright (c) 2018 bunnie <bunnie@kosagi.com>
6 # This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
9 from nmigen
.utils
import log2_int
12 "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
13 "MODE_REGISTER": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
14 "AUTO_REFRESH": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
15 "UNRESET": "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
16 "CKE": "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
19 # SDR ----------------------------------------------------------------------------------------------
21 def get_sdr_phy_init_sequence(phy_settings
, timing_settings
):
24 mr
= log2_int(bl
) + (cl
<< 4)
28 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 20000),
29 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
30 ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
31 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
32 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
33 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
34 ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
37 return init_sequence
, None
39 # DDR ----------------------------------------------------------------------------------------------
41 def get_ddr_phy_init_sequence(phy_settings
, timing_settings
):
44 mr
= log2_int(bl
) + (cl
<< 4)
49 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 20000),
50 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
51 ("Load Extended Mode Register", emr
, 1, cmds
["MODE_REGISTER"], 0),
52 ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
53 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
54 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
55 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
56 ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
59 return init_sequence
, None
61 # LPDDR --------------------------------------------------------------------------------------------
63 def get_lpddr_phy_init_sequence(phy_settings
, timing_settings
):
66 mr
= log2_int(bl
) + (cl
<< 4)
71 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 20000),
72 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
73 ("Load Extended Mode Register", emr
, 2, cmds
["MODE_REGISTER"], 0),
74 ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
75 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
76 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
77 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
78 ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200)
81 return init_sequence
, None
83 # DDR2 ---------------------------------------------------------------------------------------------
85 def get_ddr2_phy_init_sequence(phy_settings
, timing_settings
):
89 mr
= log2_int(bl
) + (cl
<< 4) + (wr
<< 9)
97 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 20000),
98 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
99 ("Load Extended Mode Register 3", emr3
, 3, cmds
["MODE_REGISTER"], 0),
100 ("Load Extended Mode Register 2", emr2
, 2, cmds
["MODE_REGISTER"], 0),
101 ("Load Extended Mode Register", emr
, 1, cmds
["MODE_REGISTER"], 0),
102 ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl
, bl
), mr
+ reset_dll
, 0, cmds
["MODE_REGISTER"], 200),
103 ("Precharge All", 0x0400, 0, cmds
["PRECHARGE_ALL"], 0),
104 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
105 ("Auto Refresh", 0x0, 0, cmds
["AUTO_REFRESH"], 4),
106 ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl
, bl
), mr
, 0, cmds
["MODE_REGISTER"], 200),
107 ("Load Extended Mode Register / OCD Default", emr
+ocd
, 1, cmds
["MODE_REGISTER"], 0),
108 ("Load Extended Mode Register / OCD Exit", emr
, 1, cmds
["MODE_REGISTER"], 0),
111 return init_sequence
, None
113 # DDR3 ---------------------------------------------------------------------------------------------
115 def get_ddr3_phy_init_sequence(phy_settings
, timing_settings
):
118 cwl
= phy_settings
.cwl
120 def format_mr0(bl
, cl
, wr
, dll_reset
):
148 mr0 |
= (cl_to_mr0
[cl
] & 1) << 2
149 mr0 |
= ((cl_to_mr0
[cl
] >> 1) & 0b111) << 4
150 mr0 |
= dll_reset
<< 8
151 mr0 |
= wr_to_mr0
[wr
] << 9
154 def format_mr1(ron
, rtt_nom
):
155 mr1
= ((ron
>> 0) & 1) << 1
156 mr1 |
= ((ron
>> 1) & 1) << 5
157 mr1 |
= ((rtt_nom
>> 0) & 1) << 2
158 mr1 |
= ((rtt_nom
>> 1) & 1) << 6
159 mr1 |
= ((rtt_nom
>> 2) & 1) << 9
162 def format_mr2(cwl
, rtt_wr
):
187 # default electrical settings (point to point)
192 # override electrical settings if specified
193 if hasattr(phy_settings
, "rtt_nom"):
194 rtt_nom
= phy_settings
.rtt_nom
195 if hasattr(phy_settings
, "rtt_wr"):
196 rtt_wr
= phy_settings
.rtt_wr
197 if hasattr(phy_settings
, "ron"):
198 ron
= phy_settings
.ron
200 wr
= max(timing_settings
.tWTR
*phy_settings
.nphases
, 5) # >= ceiling(tWR/tCK)
201 mr0
= format_mr0(bl
, cl
, wr
, 1)
202 mr1
= format_mr1(z_to_ron
[ron
], z_to_rtt_nom
[rtt_nom
])
203 mr2
= format_mr2(cwl
, z_to_rtt_wr
[rtt_wr
])
207 ("Release reset", 0x0000, 0, cmds
["UNRESET"], 50000),
208 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 10000),
209 ("Load Mode Register 2, CWL={0:d}".format(cwl
), mr2
, 2, cmds
["MODE_REGISTER"], 0),
210 ("Load Mode Register 3", mr3
, 3, cmds
["MODE_REGISTER"], 0),
211 ("Load Mode Register 1", mr1
, 1, cmds
["MODE_REGISTER"], 0),
212 ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl
, bl
), mr0
, 0, cmds
["MODE_REGISTER"], 200),
213 ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
216 return init_sequence
, mr1
218 # DDR4 ---------------------------------------------------------------------------------------------
220 def get_ddr4_phy_init_sequence(phy_settings
, timing_settings
):
223 cwl
= phy_settings
.cwl
225 def format_mr0(bl
, cl
, wr
, dll_reset
):
269 mr0 |
= (cl_to_mr0
[cl
] & 0b1) << 2
270 mr0 |
= ((cl_to_mr0
[cl
] >> 1) & 0b111) << 4
271 mr0 |
= ((cl_to_mr0
[cl
] >> 4) & 0b1) << 12
272 mr0 |
= dll_reset
<< 8
273 mr0 |
= (wr_to_mr0
[wr
] & 0b111) << 9
274 mr0 |
= (wr_to_mr0
[wr
] >> 3) << 13
277 def format_mr1(dll_enable
, ron
, rtt_nom
):
279 mr1 |
= ((ron
>> 0) & 0b1) << 1
280 mr1 |
= ((ron
>> 1) & 0b1) << 2
281 mr1 |
= ((rtt_nom
>> 0) & 0b1) << 8
282 mr1 |
= ((rtt_nom
>> 1) & 0b1) << 9
283 mr1 |
= ((rtt_nom
>> 2) & 0b1) << 10
286 def format_mr2(cwl
, rtt_wr
):
297 mr2
= cwl_to_mr2
[cwl
] << 3
301 def format_mr3(fine_refresh_mode
):
302 fine_refresh_mode_to_mr3
= {
307 mr3
= fine_refresh_mode_to_mr3
[fine_refresh_mode
] << 6
310 def format_mr6(tccd
):
318 mr6
= tccd_to_mr6
[tccd
] << 10
345 # default electrical settings (point to point)
350 # override electrical settings if specified
351 if hasattr(phy_settings
, "rtt_nom"):
352 rtt_nom
= phy_settings
.rtt_nom
353 if hasattr(phy_settings
, "rtt_wr"):
354 rtt_wr
= phy_settings
.rtt_wr
355 if hasattr(phy_settings
, "ron"):
356 ron
= phy_settings
.ron
358 wr
= max(timing_settings
.tWTR
*phy_settings
.nphases
, 10) # >= ceiling(tWR/tCK)
359 mr0
= format_mr0(bl
, cl
, wr
, 1)
360 mr1
= format_mr1(1, z_to_ron
[ron
], z_to_rtt_nom
[rtt_nom
])
361 mr2
= format_mr2(cwl
, z_to_rtt_wr
[rtt_wr
])
362 mr3
= format_mr3(timing_settings
.fine_refresh_mode
)
365 mr6
= format_mr6(4) # FIXME: tCCD
368 if phy_settings
.is_rdimm
:
369 def get_coarse_speed(tck
, pll_bypass
):
371 f_to_coarse_speed
= {
383 for f
, speed
in f_to_coarse_speed
.items():
387 def get_fine_speed(tck
):
390 fine_speed
= (freq
- 1240e6
) // 20e6
391 fine_speed
= max(fine_speed
, 0)
392 fine_speed
= min(fine_speed
, 0b1100001)
395 coarse_speed
= get_coarse_speed(phy_settings
.tck
, phy_settings
.rcd_pll_bypass
)
396 fine_speed
= get_fine_speed(phy_settings
.tck
)
398 rcd_reset
= 0x060 |
0x0 # F0RC06: command space control; 0: reset RCD
400 f0rc0f
= 0x0F0 |
0x4 # F0RC05: 0 nCK latency adder
402 f0rc03
= 0x030 | phy_settings
.rcd_ca_cs_drive
# F0RC03: CA/CS drive strength
403 f0rc04
= 0x040 | phy_settings
.rcd_odt_cke_drive
# F0RC04: ODT/CKE drive strength
404 f0rc05
= 0x050 | phy_settings
.rcd_clk_drive
# F0RC04: ODT/CKE drive strength
406 f0rc0a
= 0x0A0 | coarse_speed
# F0RC0A: coarse speed selection and PLL bypass
407 f0rc3x
= 0x300 | fine_speed
# F0RC3x: fine speed selection
410 ("Reset RCD", rcd_reset
, 7, cmds
["MODE_REGISTER"], 50000),
411 ("Load RCD F0RC0F", f0rc0f
, 7, cmds
["MODE_REGISTER"], 100),
412 ("Load RCD F0RC03", f0rc03
, 7, cmds
["MODE_REGISTER"], 100),
413 ("Load RCD F0RC04", f0rc04
, 7, cmds
["MODE_REGISTER"], 100),
414 ("Load RCD F0RC05", f0rc05
, 7, cmds
["MODE_REGISTER"], 100),
415 ("Load RCD F0RC0A", f0rc0a
, 7, cmds
["MODE_REGISTER"], 100),
416 ("Load RCD F0RC3X", f0rc3x
, 7, cmds
["MODE_REGISTER"], 100),
420 ("Release reset", 0x0000, 0, cmds
["UNRESET"], 50000),
421 ("Bring CKE high", 0x0000, 0, cmds
["CKE"], 10000),
423 ("Load Mode Register 3", mr3
, 3, cmds
["MODE_REGISTER"], 0),
424 ("Load Mode Register 6", mr6
, 6, cmds
["MODE_REGISTER"], 0),
425 ("Load Mode Register 5", mr5
, 5, cmds
["MODE_REGISTER"], 0),
426 ("Load Mode Register 4", mr4
, 4, cmds
["MODE_REGISTER"], 0),
427 ("Load Mode Register 2, CWL={0:d}".format(cwl
), mr2
, 2, cmds
["MODE_REGISTER"], 0),
428 ("Load Mode Register 1", mr1
, 1, cmds
["MODE_REGISTER"], 0),
429 ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl
, bl
), mr0
, 0, cmds
["MODE_REGISTER"], 200),
430 ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
433 return init_sequence
, mr1
435 # Init Sequence ------------------------------------------------------------------------------------
437 def get_sdram_phy_init_sequence(phy_settings
, timing_settings
):
439 "SDR" : get_sdr_phy_init_sequence
,
440 "DDR" : get_ddr_phy_init_sequence
,
441 "LPDDR": get_lpddr_phy_init_sequence
,
442 "DDR2" : get_ddr2_phy_init_sequence
,
443 "DDR3" : get_ddr3_phy_init_sequence
,
444 "DDR4" : get_ddr4_phy_init_sequence
,
445 }[phy_settings
.memtype
](phy_settings
, timing_settings
)
447 # C Header -----------------------------------------------------------------------------------------
449 def get_sdram_phy_c_header(phy_settings
, timing_settings
):
450 r
= "#ifndef __GENERATED_SDRAM_PHY_H\n#define __GENERATED_SDRAM_PHY_H\n"
451 r
+= "#include <hw/common.h>\n"
452 r
+= "#include <generated/csr.h>\n"
455 r
+= "#define DFII_CONTROL_SEL 0x01\n"
456 r
+= "#define DFII_CONTROL_CKE 0x02\n"
457 r
+= "#define DFII_CONTROL_ODT 0x04\n"
458 r
+= "#define DFII_CONTROL_RESET_N 0x08\n"
461 r
+= "#define DFII_COMMAND_CS 0x01\n"
462 r
+= "#define DFII_COMMAND_WE 0x02\n"
463 r
+= "#define DFII_COMMAND_CAS 0x04\n"
464 r
+= "#define DFII_COMMAND_RAS 0x08\n"
465 r
+= "#define DFII_COMMAND_WRDATA 0x10\n"
466 r
+= "#define DFII_COMMAND_RDDATA 0x20\n"
469 phytype
= phy_settings
.phytype
.upper()
470 nphases
= phy_settings
.nphases
472 # Define PHY type and number of phases
473 r
+= "#define SDRAM_PHY_"+phytype
+"\n"
474 r
+= "#define SDRAM_PHY_PHASES "+str(nphases
)+"\n"
476 # Define Read/Write Leveling capability
477 if phytype
in ["USDDRPHY", "USPDDRPHY", "K7DDRPHY", "V7DDRPHY"]:
478 r
+= "#define SDRAM_PHY_WRITE_LEVELING_CAPABLE\n"
479 if phytype
in ["USDDRPHY", "USPDDRPHY"]:
480 r
+= "#define SDRAM_PHY_WRITE_LEVELING_REINIT\n"
481 if phytype
in ["USDDRPHY", "USPDDRPHY", "A7DDRPHY", "K7DDRPHY", "V7DDRPHY", "ECP5DDRPHY"]:
482 r
+= "#define SDRAM_PHY_READ_LEVELING_CAPABLE\n"
484 # Define number of modules/delays/bitslips
485 if phytype
in ["USDDRPHY", "USPDDRPHY"]:
486 r
+= "#define SDRAM_PHY_MODULES DFII_PIX_DATA_BYTES/2\n"
487 r
+= "#define SDRAM_PHY_DELAYS 512\n"
488 r
+= "#define SDRAM_PHY_BITSLIPS 16\n"
489 elif phytype
in ["A7DDRPHY", "K7DDRPHY", "V7DDRPHY"]:
490 r
+= "#define SDRAM_PHY_MODULES DFII_PIX_DATA_BYTES/2\n"
491 r
+= "#define SDRAM_PHY_DELAYS 32\n"
492 r
+= "#define SDRAM_PHY_BITSLIPS 16\n"
493 elif phytype
in ["ECP5DDRPHY"]:
494 r
+= "#define SDRAM_PHY_MODULES DFII_PIX_DATA_BYTES/4\n"
495 r
+= "#define SDRAM_PHY_DELAYS 8\n"
496 r
+= "#define SDRAM_PHY_BITSLIPS 4\n"
498 if phy_settings
.is_rdimm
:
499 assert phy_settings
.memtype
== "DDR4"
500 r
+= "#define SDRAM_PHY_DDR4_RDIMM\n"
504 r
+= "static void cdelay(int i);\n"
506 # commands_px functions
507 for n
in range(nphases
):
509 __attribute__((unused)) static void command_p{n}(int cmd)
511 sdram_dfii_pi{n}_command_write(cmd);
512 sdram_dfii_pi{n}_command_issue_write(1);
513 }}""".format(n
=str(n
))
516 # rd/wr access macros
518 #define sdram_dfii_pird_address_write(X) sdram_dfii_pi{rdphase}_address_write(X)
519 #define sdram_dfii_piwr_address_write(X) sdram_dfii_pi{wrphase}_address_write(X)
520 #define sdram_dfii_pird_baddress_write(X) sdram_dfii_pi{rdphase}_baddress_write(X)
521 #define sdram_dfii_piwr_baddress_write(X) sdram_dfii_pi{wrphase}_baddress_write(X)
522 #define command_prd(X) command_p{rdphase}(X)
523 #define command_pwr(X) command_p{wrphase}(X)
524 """.format(rdphase
=str(phy_settings
.rdphase
), wrphase
=str(phy_settings
.wrphase
))
528 # sdrrd/sdrwr functions utilities
530 r
+= "#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE\n"
531 sdram_dfii_pix_wrdata_addr
= []
532 for n
in range(nphases
):
533 sdram_dfii_pix_wrdata_addr
.append("CSR_SDRAM_DFII_PI{n}_WRDATA_ADDR".format(n
=n
))
535 const unsigned long sdram_dfii_pix_wrdata_addr[SDRAM_PHY_PHASES] = {{
536 \t{sdram_dfii_pix_wrdata_addr}
538 """.format(sdram_dfii_pix_wrdata_addr
=",\n\t".join(sdram_dfii_pix_wrdata_addr
))
540 sdram_dfii_pix_rddata_addr
= []
541 for n
in range(nphases
):
542 sdram_dfii_pix_rddata_addr
.append("CSR_SDRAM_DFII_PI{n}_RDDATA_ADDR".format(n
=n
))
544 const unsigned long sdram_dfii_pix_rddata_addr[SDRAM_PHY_PHASES] = {{
545 \t{sdram_dfii_pix_rddata_addr}
547 """.format(sdram_dfii_pix_rddata_addr
=",\n\t".join(sdram_dfii_pix_rddata_addr
))
550 init_sequence
, mr1
= get_sdram_phy_init_sequence(phy_settings
, timing_settings
)
552 if phy_settings
.memtype
in ["DDR3", "DDR4"]:
553 # the value of MR1 needs to be modified during write leveling
554 r
+= "#define DDRX_MR1 {}\n\n".format(mr1
)
556 r
+= "static void init_sequence(void)\n{\n"
557 for comment
, a
, ba
, cmd
, delay
in init_sequence
:
558 invert_masks
= [(0, 0), ]
559 if phy_settings
.is_rdimm
:
560 assert phy_settings
.memtype
== "DDR4"
563 # B-side chips have certain usually-inconsequential address and BA
564 # bits inverted by the RCD to reduce SSO current. For mode register
565 # writes, however, we must compensate for this. BG[1] also directs
566 # writes either to the A side (BG[1]=0) or B side (BG[1]=1)
568 # The 'ba != 7' is because we don't do this to writes to the RCD
571 invert_masks
.append((0b10101111111000, 0b1111))
573 for a_inv
, ba_inv
in invert_masks
:
574 r
+= "\t/* {0} */\n".format(comment
)
575 r
+= "\tsdram_dfii_pi0_address_write({0:#x});\n".format(a ^ a_inv
)
576 r
+= "\tsdram_dfii_pi0_baddress_write({0:d});\n".format(ba ^ ba_inv
)
577 if cmd
[:12] == "DFII_CONTROL":
578 r
+= "\tsdram_dfii_control_write({0});\n".format(cmd
)
580 r
+= "\tcommand_p0({0});\n".format(cmd
)
582 r
+= "\tcdelay({0:d});\n".format(delay
)
590 # Python Header ------------------------------------------------------------------------------------
592 def get_sdram_phy_py_header(phy_settings
, timing_settings
):
594 r
+= "dfii_control_sel = 0x01\n"
595 r
+= "dfii_control_cke = 0x02\n"
596 r
+= "dfii_control_odt = 0x04\n"
597 r
+= "dfii_control_reset_n = 0x08\n"
599 r
+= "dfii_command_cs = 0x01\n"
600 r
+= "dfii_command_we = 0x02\n"
601 r
+= "dfii_command_cas = 0x04\n"
602 r
+= "dfii_command_ras = 0x08\n"
603 r
+= "dfii_command_wrdata = 0x10\n"
604 r
+= "dfii_command_rddata = 0x20\n"
607 init_sequence
, mr1
= get_sdram_phy_init_sequence(phy_settings
, timing_settings
)
610 r
+= "ddrx_mr1 = 0x{:x}\n".format(mr1
)
613 r
+= "init_sequence = [\n"
614 for comment
, a
, ba
, cmd
, delay
in init_sequence
:
616 r
+= "(\"" + comment
+ "\", "
619 r
+= cmd
.lower() + ", "
620 r
+= str(delay
) + "),"