modules/init: add DDR4 fine refresh mode support: x1, x2 and x4 (x1=previous and default behavior)

This commit is contained in:
Florent Kermarrec 2019-12-03 12:17:57 +01:00
parent 6c9c45f313
commit eddd6e4eaf
2 changed files with 42 additions and 18 deletions

View File

@ -298,6 +298,15 @@ def get_ddr4_phy_init_sequence(phy_settings, timing_settings):
mr2 |= rtt_wr << 9 mr2 |= rtt_wr << 9
return mr2 return mr2
def format_mr3(fine_refresh_mode):
fine_refresh_mode_to_mr3 = {
"1x": 0b000,
"2x": 0b001,
"4x": 0b010
}
mr3 = fine_refresh_mode_to_mr3[fine_refresh_mode] << 6
return mr3
def format_mr6(tccd): def format_mr6(tccd):
tccd_to_mr6 = { tccd_to_mr6 = {
4: 0b000, 4: 0b000,
@ -350,7 +359,7 @@ def get_ddr4_phy_init_sequence(phy_settings, timing_settings):
mr0 = format_mr0(bl, cl, wr, 1) mr0 = format_mr0(bl, cl, wr, 1)
mr1 = format_mr1(1, z_to_ron[ron], z_to_rtt_nom[rtt_nom]) mr1 = format_mr1(1, z_to_ron[ron], z_to_rtt_nom[rtt_nom])
mr2 = format_mr2(cwl, z_to_rtt_wr[rtt_wr]) mr2 = format_mr2(cwl, z_to_rtt_wr[rtt_wr])
mr3 = 0 mr3 = format_mr3(timing_settings.fine_refresh_mode)
mr4 = 0 mr4 = 0
mr5 = 0 mr5 = 0
mr6 = format_mr6(4) # FIXME: tCCD mr6 = format_mr6(4) # FIXME: tCCD

View File

@ -46,7 +46,7 @@ class SDRAMModule:
SDRAM modules with the same geometry exist can have SDRAM modules with the same geometry exist can have
various speedgrades. various speedgrades.
""" """
def __init__(self, clk_freq, rate, speedgrade=None): def __init__(self, clk_freq, rate, speedgrade=None, fine_refresh_mode=None):
self.clk_freq = clk_freq self.clk_freq = clk_freq
self.rate = rate self.rate = rate
self.speedgrade = speedgrade self.speedgrade = speedgrade
@ -55,12 +55,16 @@ class SDRAMModule:
rowbits = log2_int(self.nrows), rowbits = log2_int(self.nrows),
colbits = log2_int(self.ncols), colbits = log2_int(self.ncols),
) )
assert not (self.memtype != "DDR4" and fine_refresh_mode != None)
assert fine_refresh_mode in [None, "1x", "2x", "4x"]
if (fine_refresh_mode is None) and (self.memtype == "DDR4"):
fine_refresh_mode = "1x"
self.timing_settings = TimingSettings( self.timing_settings = TimingSettings(
tRP = self.ns_to_cycles(self.get("tRP")), tRP = self.ns_to_cycles(self.get("tRP")),
tRCD = self.ns_to_cycles(self.get("tRCD")), tRCD = self.ns_to_cycles(self.get("tRCD")),
tWR = self.ns_to_cycles(self.get("tWR")), tWR = self.ns_to_cycles(self.get("tWR")),
tREFI = self.ns_to_cycles(self.get("tREFI"), False), tREFI = self.ns_to_cycles(self.get("tREFI", fine_refresh_mode), False),
tRFC = self.ck_ns_to_cycles(*self.get("tRFC")), tRFC = self.ck_ns_to_cycles(*self.get("tRFC", fine_refresh_mode)),
tWTR = self.ck_ns_to_cycles(*self.get("tWTR")), tWTR = self.ck_ns_to_cycles(*self.get("tWTR")),
tFAW = None if self.get("tFAW") is None else self.ck_ns_to_cycles(*self.get("tFAW")), tFAW = None if self.get("tFAW") is None else self.ck_ns_to_cycles(*self.get("tFAW")),
tCCD = None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")), tCCD = None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")),
@ -69,26 +73,31 @@ class SDRAMModule:
tRAS = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS")), tRAS = None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS")),
tZQCS = None if self.get("tZQCS") is None else self.ck_ns_to_cycles(*self.get("tZQCS")) tZQCS = None if self.get("tZQCS") is None else self.ck_ns_to_cycles(*self.get("tZQCS"))
) )
self.timing_settings.fine_refresh_mode = fine_refresh_mode
def get(self, name): def get(self, name, key=None):
r = None
if name in _speedgrade_timings: if name in _speedgrade_timings:
if hasattr(self, "speedgrade_timings"): if hasattr(self, "speedgrade_timings"):
speedgrade = "default" if self.speedgrade is None else self.speedgrade speedgrade = "default" if self.speedgrade is None else self.speedgrade
return getattr(self.speedgrade_timings[speedgrade], name) r = getattr(self.speedgrade_timings[speedgrade], name)
else: else:
name = name + "_" + self.speedgrade if self.speedgrade is not None else name name = name + "_" + self.speedgrade if self.speedgrade is not None else name
try: try:
return getattr(self, name) r = getattr(self, name)
except: except:
return None pass
else: else:
if hasattr(self, "technology_timings"): if hasattr(self, "technology_timings"):
return getattr(self.technology_timings, name) r = getattr(self.technology_timings, name)
else: else:
try: try:
return getattr(self, name) r = getattr(self, name)
except: except:
return None pass
if (r is not None) and (key is not None):
r = r[key]
return r
def ns_to_cycles(self, t, margin=True): def ns_to_cycles(self, t, margin=True):
clk_period_ns = 1e9/self.clk_freq clk_period_ns = 1e9/self.clk_freq
@ -462,9 +471,11 @@ class EDY4016A(SDRAMModule):
nrows = 32768 nrows = 32768
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80)) trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
trfc = {"1x": (None, 260), "2x": (None, 160), "4x": (None, 110)}
technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
speedgrade_timings = { speedgrade_timings = {
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 260), tFAW=(28, 30), tRAS=32), "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(28, 30), tRAS=32),
} }
speedgrade_timings["default"] = speedgrade_timings["2400"] speedgrade_timings["default"] = speedgrade_timings["2400"]
@ -478,10 +489,12 @@ class MT40A1G8(SDRAMModule):
nrows = 65536 nrows = 65536
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4), tZQCS=(128, 80)) trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 6.4), tZQCS=(128, 80))
speedgrade_timings = { speedgrade_timings = {
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32), "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
"2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=(None, 350), tFAW=(20, 21), tRAS=32), "2666": _SpeedgradeTimings(tRP=13.50, tRCD=13.50, tWR=15, tRFC=trfc, tFAW=(20, 21), tRAS=32),
} }
speedgrade_timings["default"] = speedgrade_timings["2400"] speedgrade_timings["default"] = speedgrade_timings["2400"]
@ -495,8 +508,10 @@ class MT40A512M16(SDRAMModule):
nrows = 65536 nrows = 65536
ncols = 1024 ncols = 1024
# timings # timings
technology_timings = _TechnologyTimings(tREFI=64e6/8192, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80)) trefi = {"1x": 64e6/8192, "2x": (64e6/8192)/2, "4x": (64e6/8192)/4}
trfc = {"1x": (None, 350), "2x": (None, 260), "4x": (None, 160)}
technology_timings = _TechnologyTimings(tREFI=trefi, tWTR=(4, 7.5), tCCD=(4, None), tRRD=(4, 4.9), tZQCS=(128, 80))
speedgrade_timings = { speedgrade_timings = {
"2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=(None, 350), tFAW=(20, 25), tRAS=32), "2400": _SpeedgradeTimings(tRP=13.32, tRCD=13.32, tWR=15, tRFC=trfc, tFAW=(20, 25), tRAS=32),
} }
speedgrade_timings["default"] = speedgrade_timings["2400"] speedgrade_timings["default"] = speedgrade_timings["2400"]