Tools for generating SPD files for LPDDR4x memory used in memory down configurations on Intel Tiger Lake (TGL) and Jasper Lake (JSL) based platforms. These tools generate SPDs following JESD209-4C specification and Intel recommendations (doc #616599, #610202) for LPDDR4x SPD.
There are two tools provided that assist TGL and JSL based mainboards to generate SPDs and Makefile to integrate these SPDs in coreboot build. These tools can also be used to allocate DRAM IDs (configure DRAM hardware straps) for any LPDDR4x memory part used by the board.
gen_spd.go: Generates de-duplicated SPD files using a global memory part list provided by the mainboard in JSON format. Additionally, generates a SPD manifest file(in CSV format) with information about what memory part from the global list uses which of the generated SPD files.
gen_part_id.go: Allocates DRAM strap IDs for different LPDDR4x memory parts used by the board. Takes as input list of memory parts used by the board (with one memory part on each line) and the SPD manifest file generated by gen_spd.go. Generates Makefile.inc for integrating the generated SPD files in the coreboot build.
This program takes as input:
TGL
and JSL
.Input JSON file requires the following two fields for every memory part:
name
: Name of the memory partattribs
: List of attributes of the memory part as per its datasheet. These attributes match the part specifications and are independent of any SoC expectations. Tool takes care of translating the physical attributes of the memory part to match JEDEC and Intel MRC expectations.attribs
field further contains two types of sub-fields:
attribs
densityPerChannelGb
: Density in Gb of the physical channel.
banks
: Number of banks per physical channel. This is typically 8 for LPDDR4x memory parts.
channelsPerDie
: Number of physical channels per die. Valid values: 1, 2, 4
. For a part with x16 bit width, number of channels per die is 1 or 2. For a part with x8 bit width, number of channels can be 2 or 4 (4 is basically when two dual-channel byte mode devices are combined as shown in Figure 3 in JESD209-4C).
diesPerPackage
: Number of physical dies in each SDRAM package. As per JESD209-4C, "Standard LPDDR4 package ballmaps allocate one ZQ ball per die." Thus, number of diesPerPackage is the number of ZQ balls on the package.
bitWidthPerChannel
: Width of each physical channel. Valid values: 8, 16
bits.
ranksPerChannel
: Number of ranks per physical channel. Valid values: 1, 2
. If the channels across multiple dies share the same DQ/DQS pins but use a separate CS, then ranks is 2 else it is 1.
speedMbps
: Maximum data rate supported by the part in Mbps. Valid values: 3200, 3733, 4267
Mbps.
attribs
trfcabNs
: Minimum Refresh Recovery Delay Time (tRFCab) for all banks in nanoseconds. As per JESD209-4C, this is dependent on the density per channel. Default values used:
trfcpbNs
: Minimum Refresh Recovery Delay Time (tRFCab) per bank in nanoseconds. As per JESD209-4C, this is dependent on the density per channel. Default values used:
trpabMinNs
: Minimum Row Precharge Delay Time (tRPab) for all banks in nanoseconds. As per JESD209-4C, this is max(21ns, 4nck) which defaults to 21ns
.
trppbMinNs
: Minimum Row Precharge Delay Time (tRPpb) per bank in nanoseconds. As per JESD209-4C, this is max(18ns, 4nck) which defaults to 18ns
.
tckMinPs
: SDRAM minimum cycle time (tckMin) value in picoseconds. This is typically calculated based on the speedMbps
attribute. (1 / speedMbps) * 2
. Default values used(taken from JESD209-4C):
tckMaxPs
: SDRAM maximum cycle time (tckMax) value in picoseconds. Default value used: 31875ps
. As per JESD209-4C, TCKmax should be 100ns (100000ps) for all speed grades. But the SPD byte to encode this field is only 1 byte. Hence, the maximum value that can be encoded is 31875ps.
taaMinPs
: Minimum CAS Latency Time(taaMin) in picoseconds. This value defaults to nck * tckMin, where nck is minimum CAS latency.
trcdMinNs
: Minimum RAS# to CAS# Delay Time (tRCDmin) in nanoseconds. As per JESD209-4C, this is max(18ns, 4nck) which defaults to 18ns
.
casLatencies
: List of CAS latencies supported by the part. This is dependent on the attrib speedMbps
. Default values used:
"6 10 14 20 24 28 32 36"
."6 10 14 20 24 28 32"
."6 10 14 20 24 28"
.{ "parts": [ { "name": "MEMORY_PART_A", "attribs": { "densityPerChannelGb": 8, "banks": 8, "channelsPerDie": 2, "diesPerPackage": 2, "bitWidthPerChannel": 16, "ranksPerChannel": 1, "speedMbps": 4267 } }, { "name": "MEMORY_PART_B", "attribs": { "densityPerChannelGb": 8, "banks": 8, "channelsPerDie": 1, "diesPerPackage": 2, "bitWidthPerChannel": 16, "ranksPerChannel": 1, "speedMbps": 3733, "casLatencies": "14 20 24 28 32", "tckMaxPs": "1250" } } ] }
This tool generates the following files using the global list of memory parts in JSON format as described above:
spd_manifest.generated.txt
and placed in the directory provided as an input to the tool along with the generated SPD files. Example CSV file:MEMORY_PART_A, spd_1.hex MEMORY_PART_B, spd_2.hex MEMORY_PART_C, spd_3.hex MEMORY_PART_D, spd_2.hex MEMORY_PART_E, spd_2.hex
This program takes as input:
spd_manifest.generated.txt
(in CSV format) are placed by gen_spd.goname
as present in the global list of memory parts provided to gen_spd.goThis program provides the following:
Sample output (dram_id.generated.txt):
DRAM Part Name ID to assign MEMORY_PART_A 0 (0000) MEMORY_PART_B 1 (0001) MEMORY_PART_C 2 (0010) MEMORY_PART_D 1 (0001)
Sample Makefile.inc:
## SPDX-License-Identifier: GPL-2.0-or-later ## This is an auto-generated file. Do not edit!! SPD_SOURCES = SPD_SOURCES += spd_1.hex # ID = 0(0b0000) Parts = MEMORY_PART_A SPD_SOURCES += spd_2.hex # ID = 1(0b0001) Parts = MEMORY_PART_B, MEMORY_PART_D SPD_SOURCES += spd_3.hex # ID = 2(0b0010) Parts = MEMORY_PART_C
This program assigns DRAM IDs using the order of DRAM part names provided in the input file. Thus, when adding a new memory part to the list, it should always go to the end of the input text file. This guarantees that the memory parts that were already assigned IDs do not change.
# go build gen_spd.go # go build gen_part_id.go
# ./gen_spd <spd_dir> <mem_parts_list_json> <platform> # ./gen_part_id <spd_dir> <makefile_dir> <mem_parts_used_file>
gen_spd.go
with input as the file containing the global list of memory parts to generate de-duplicated SPDs.git add
to add it to the tree and push a CL for review.git add
to add Makefile.inc
and dram_id.generated.txt
with updated changes and push a CL for review.