Name Date Size #Lines LOC

..--

src/H25-Apr-2025-3,8462,715

.gitignoreH A D25-Apr-202528 43

MakefileH A D25-Apr-2025265 1710

README.mdH A D25-Apr-202523.4 KiB659512

README.md

1# SPD tools
2
3A set of tools to generate SPD files for platforms with memory down
4configurations.
5
6The memory technologies currently supported are:
7
8*   LPDDR4x - based on the JESD209-4C spec and Intel recommendations
9    (docs #616599, #610202, #634730).
10*   DDR4 - based on the JESD79-4C and Jedec 4.1.2.L-5 R29 v103 specs.
11*   LPDDR5/5X - based on the LPDDR5 spec JESD209-5B, the SPD spec SPD4.1.2.M-2
12    (the LPDDR3/4 spec is used since JEDEC has not released an SPD spec for
13    LPDDR5), and Intel recommendations in advisory #616599.
14
15There are two tools provided to assist with generating SPDs and Makefiles to
16integrate into the coreboot build. These tools can also be used to allocate DRAM
17IDs (configure DRAM hardware straps) for any memory part used by a board.
18
19*   `spd_gen`: This tool generates de-duplicated SPD files using a global memory
20    part list. It also generates a CSV manifest file which maps each memory part
21    in the global list to one of the generated SPD files. For each supported
22    memory technology, multiple sets of SPDs are generated. Each set corresponds
23    to a set of SoC platforms with different SPD requirements, e.g. due to
24    different expectations in the memory training code. Another CSV manifest
25    maps each supported platform to one of these sets.
26*   `part_id_gen`: This tool allocates DRAM strap IDs for the different memory
27    parts used by a board. It takes as input a CSV file of the memory parts used
28    with optional fixed IDs. It generates a Makefile.mk which is used to
29    integrate the SPD files generated by `spd_gen` into the coreboot build.
30
31## Tool 1 - `spd_gen`
32
33This program takes the following inputs:
34
35*   Path to a JSON file containing a global list of memory parts with their
36    attributes as per the datasheet. This is the list of all known memory parts
37    for the given memory technology.
38
39*   The memory technology for which to generate the SPDs,
40    One of:
41        ddr4,
42        lp4x,
43        lp5
44
45The input JSON file requires the following two fields for every memory part:
46
47*   `name`: The name of the memory part.
48*   `attribs`: A list of the memory part's attributes, as per its datasheet.
49    These attributes match the part specifications and are independent of any
50    SoC expectations. The tool takes care of translating the physical attributes
51    of the memory part to match JEDEC spec and memory traning code expectations.
52
53The `attribs` field further contains two types of sub-field:
54
55*   Mandatory: These attributes must be provided for each memory part.
56*   Optional: These attributes may be provided for a memory part in order to
57    override the defaults.
58
59The attributes are different for each memory technology.
60
61### LP4x attributes
62
63#### Mandatory
64
65*   `densityPerChannelGb`: Density in Gb of the physical channel.
66
67*   `banks`: Number of banks per physical channel. This is typically 8 for
68    LPDDR4x memory parts.
69
70*   `channelsPerDie`: Number of physical channels per die. Valid values: `1, 2,
71    4`. For a part with x16 bit width, number of channels per die is 1 or 2. For
72    a part with x8 bit width, number of channels can be 2 or 4 (4 is basically
73    when two dual-channel byte mode devices are combined as shown in Figure 3 in
74    JESD209-4C).
75
76*   `diesPerPackage`: Number of physical dies in each SDRAM package. As per
77    JESD209-4C, "Standard LPDDR4 package ballmaps allocate one ZQ ball per die."
78    Thus, number of diesPerPackage is the number of ZQ balls on the package.
79
80*   `bitWidthPerChannel`: Width of each physical channel. Valid values: `8, 16`
81    bits.
82
83*   `ranksPerChannel`: Number of ranks per physical channel. Valid values: `1,
84    2`. If the channels across multiple dies share the same DQ/DQS pins but use
85    a separate CS, then ranks is 2 else it is 1.
86
87*   `speedMbps`: Maximum data rate supported by the part in Mbps. Valid values:
88    `3200, 3733, 4267` Mbps.
89
90#### Optional
91
92*   `trfcabNs`: Minimum Refresh Recovery Delay Time (tRFCab) for all banks in
93    nanoseconds. As per JESD209-4C, this is dependent on the density per
94    channel. Default values used:
95
96    *   6Gb : 280ns
97    *   8Gb : 280ns
98    *   12Gb: 380ns
99    *   16Gb: 380ns
100
101*   `trfcpbNs`: Minimum Refresh Recovery Delay Time (tRFCab) per bank in
102    nanoseconds. As per JESD209-4C, this is dependent on the density per
103    channel. Default values used:
104
105    *   6Gb : 140ns
106    *   8Gb : 140ns
107    *   12Gb: 190ns
108    *   16Gb: 190ns
109
110*   `trpabMinNs`: Minimum Row Precharge Delay Time (tRPab) for all banks in
111    nanoseconds. As per JESD209-4C, this is max(21ns, 4nck) which defaults to
112    `21ns`.
113
114*   `trppbMinNs`: Minimum Row Precharge Delay Time (tRPpb) per bank in
115    nanoseconds. As per JESD209-4C, this is max(18ns, 4nck) which defaults to
116    `18ns`.
117
118*   `tckMinPs`: SDRAM minimum cycle time (tckMin) value in picoseconds. This is
119    typically calculated based on the `speedMbps` attribute. `(1 / speedMbps) *
120    2`. Default values used(taken from JESD209-4C):
121
122    *   4267 Mbps: 468ps
123    *   3733 Mbps: 535ps
124    *   3200 Mbps: 625ps
125
126*   `tckMaxPs`: SDRAM maximum cycle time (tckMax) value in picoseconds. Default
127    value used: `31875ps`. As per JESD209-4C, TCKmax should be 100ns (100000ps)
128    for all speed grades. But the SPD byte to encode this field is only 1 byte.
129    Hence, the maximum value that can be encoded is 31875ps.
130
131*   `taaMinPs`: Minimum CAS Latency Time(taaMin) in picoseconds. This value
132    defaults to nck * tckMin, where nck is minimum CAS latency.
133
134*   `trcdMinNs`: Minimum RAS# to CAS# Delay Time (tRCDmin) in nanoseconds. As
135    per JESD209-4C, this is max(18ns, 4nck) which defaults to `18ns`.
136
137*   `casLatencies`: List of CAS latencies supported by the part. This is
138    dependent on the attrib `speedMbps`. Default values used:
139
140    *   4267: `"6 10 14 20 24 28 32 36"`.
141    *   3733: `"6 10 14 20 24 28 32"`.
142    *   3200: `"6 10 14 20 24 28"`.
143
144#### Example `memory_parts.json`
145
146```
147{
148    "parts": [
149        {
150            "name": "MT53D512M64D4NW-046 WT:F",
151            "attribs": {
152                "densityPerChannelGb": 8,
153                "banks": 8,
154                "channelsPerDie": 2,
155                "diesPerPackage": 2,
156                "bitWidthPerChannel": 16,
157                "ranksPerChannel": 1,
158                "speedMbps": 4267
159            }
160        },
161        {
162            "name": "NT6AP256T32AV-J1",
163            "attribs": {
164                "densityPerChannelGb": 4,
165                "banks": 8,
166                "channelsPerDie": 2,
167                "diesPerPackage": 1,
168                "bitWidthPerChannel": 16,
169                "ranksPerChannel": 1,
170                "speedMbps": 4267,
171                "tckMaxPs": 1250,
172                "casLatencies": "14 20 24 28 32 36"
173            }
174        },
175    ]
176}
177```
178
179### DDR4 attributes
180
181#### Mandatory
182
183*   `speedMTps`: Maximum rate supported by the part in MT/s. Valid values:
184    `1600, 1866, 2133, 2400, 2666, 2933, 3200` MT/s.
185
186*   `CL_nRCD_nRP`: Refers to CAS Latency specified for the part (find
187    "CL-nRCD-nRP" in the vendor spec for the DDR4 part).
188
189*   `capacityPerDieGb`: Capacity per die in gigabits. Valid values: `2, 4, 8,
190    16` Gb part.
191
192*   `diesPerPackage`: Number of dies on the part. Valid values: `1, 2` dies per
193    package.
194
195*   `packageBusWidth`: Number of bits of the device's address bus. Valid values:
196    `8, 16` bit-wide bus. NOTE: Width of x4 is not supported by this tool.
197
198*   `ranksPerPackage`: From Jedec doc 4_01_02_AnnexL-1R23: “Package ranks per
199    DIMM” refers to the collections of devices on the module sharing common chip
200    select signals (across the data width of the DIMM), either from the edge
201    connector for unbuffered modules or from the outputs of a registering clock
202    driver for RDIMMs and LRDIMMs.Number of bits of the device's address bus.
203    Valid values: `1, 2` package ranks.
204
205#### Optional
206
207The following options are calculated by the tool based on the mandatory
208attributes described for the part, but there may be cases where a default value
209must be overridden, such as when a device appears to be 3200AA, but does not
210support all of the CAS latencies typically supported by a speed bin 3200AA part.
211To deal with such a case, the variable can be overridden here and the tool will
212use this value instead of calculating one. All values must be defined in
213picosecond units, except for "CASLatencies", which would be represented as a
214string like "9 10 11 12 14".
215
216*   `TAAMinPs`: Defines the minimum CAS Latency. Table 48 of Jedec doc
217    4_01_02_AnnexL-5R29 lists tAAmin for each speed grade.
218
219*   `TRASMinPs`: Refers to the minimum active to precharge delay time. Table 55
220    of Jedec doc 4_01_02_AnnexL-5R29 lists tRPmin for each speed grade.
221
222*   `TCKMinPs`: Refers to the minimum clock cycle time. Table 42 of Jedec doc
223    4_01_02_AnnexL-5R29 lists tCKmin for each speed grade.
224
225*   `TCKMaxPs`:Refers to the minimum clock cycle time. Table 44 of Jedec doc
226    4_01_02_AnnexL-5R29 lists tCKmin for each speed grade.
227
228*   `TRFC1MinPs`: Refers to the minimum refresh recovery delay time. Table 59 of
229    Jedec doc 4_01_02_AnnexL-5R29 lists tRFC1min for each page size.
230
231*   `TRFC2MinPs`: Refers to the minimum refresh recovery delay time. Table 61 of
232    Jedec doc 4_01_02_AnnexL-5R29 lists tRFC2min for each page size.
233
234*   `TRFC4MinPs`: Refers to the minimum refresh recovery delay time. Table 63 of
235    Jedec doc 4_01_02_AnnexL-5R29 lists tRFC4min for each page size.
236
237*   `TFAWMinPs`:: Refers to the minimum four activate window delay time. Table
238    66 of Jedec doc 4_01_02_AnnexL-5R29 lists tFAWmin for each speed grade and
239    page size combination.
240
241*   `TRRDSMinPs`: Refers to the minimum activate to activate delay time to
242    different bank groups. Table 68 of Jedec doc 4_01_02_AnnexL-5R29 lists
243    tRRD_Smin for each speed grade and page size combination.
244
245*   `TRRDLMinPs`: Refers to the minimum activate to activate delay time to the
246    same bank group. Table 70 of Jedec doc 4_01_02_AnnexL-5R29 lists tRRD_Lmin
247    for each speed grade and page size combination.
248
249*   `TCCDLMinPs`: Refers to the minimum CAS to CAS delay time to same bank
250    group. Table 72 of Jedec doc 4_01_02_AnnexL-5R29 lists tCCD_Lmin for each
251    speed grade.
252
253*   `TWRMinPs`: Refers to the minimum write recovery time. Table 75 of Jedec doc
254    4_01_02_AnnexL-5R29 lists tWRmin for each ddr4 type.
255
256*   `TWTRSMinPs`: Refers to minimum write to read time to different bank group.
257    Table 78 of Jedec doc 4_01_02_AnnexL-5R29 lists tWTR_Smin for each ddr4
258    type.
259
260*   `TWTRLMinPs`: Refers to minimum write to read time to same bank group. Table
261    80 of Jedec doc 4_01_02_AnnexL-5R29 lists tWTR_Lmin for each ddr4 type.
262
263*   `CASLatencies`: Refers to the CAS latencies supported by the part. The speed
264    bin tables in the back of Jedec doc 4_01_02_AnnexL-5R29 define the standard
265    CAS latencies that a speed bin part is supposed to support. In cases where a
266    part does not support all of the CAS latencies listed in the speed bin
267    tables, this entry should be used to override the default settings.
268
269#### Example `memory_parts.json`
270
271```
272{
273    "parts": [
274        {
275            "name": "K4A8G165WC-BCWE",
276            "attribs": {
277                "speedMTps": 3200,
278                "CL_nRCD_nRP": 22,
279                "capacityPerDieGb": 8,
280                "diesPerPackage": 1,
281                "packageBusWidth": 16,
282                "ranksPerPackage": 1
283            }
284        },
285        {
286            "name": "MT40A1G16KD-062E:E",
287            "attribs": {
288                "speedMTps": 3200,
289                "CL_nRCD_nRP": 22,
290                "capacityPerDieGb": 16,
291                "diesPerPackage": 1,
292                "packageBusWidth": 16,
293                "ranksPerPackage": 1,
294                "TRFC1MinPs": 350000,
295                "TRFC2MinPs": 260000,
296                "TRFC4MinPs": 160000
297            }
298        },
299    ]
300}
301```
302
303### LP5 attributes
304
305#### Mandatory
306
307*   `densityPerDieGb`: Density per die in Gb. Valid values: `4, 6, 8, 12, 16,
308    24, 32` Gb per die.
309
310*   `diesPerPackage`: Number of physical dies in each SDRAM package. Valid
311    values: `2, 4, 8` dies per package.
312
313*   `bitWidthPerChannel`: Width of each physical channel. Valid values: `8, 16`
314    bits.
315
316*   `ranksPerChannel`: Number of ranks per physical channel. Valid values: `1,
317    2`. If the channels across multiple dies share the same DQ/DQS pins but use
318    a separate CS, then ranks is 2 else it is 1.
319
320*   `speedMbps`: Maximum data rate supported by the part in Mbps. Valid values:
321    `5500, 6400` Mbps.
322
323#### Optional
324
325*   `lp5x`: If this is an LP5X part. SPD format is identical for LP5/5X aside
326    from the memory type byte.
327
328*   `trfcabNs`: Minimum Refresh Recovery Delay Time (tRFCab) for all banks in
329    nanoseconds. As per JESD209-5B, this is dependent on the density per die.
330    Default values used:
331
332    *   4 Gb : 180 ns
333    *   6 Gb : 210 ns
334    *   8 Gb : 210 ns
335    *   12 Gb: 280 ns
336    *   16 Gb: 280 ns
337    *   24 Gb: 380 ns
338    *   32 Gb: 380 ns
339
340*   `trfcpbNs`: Minimum Refresh Recovery Delay Time (tRFCpb) per bank in
341    nanoseconds. As per JESD209-5B, this is dependent on the density per die.
342    Default values used:
343
344    *   4 Gb : 90 ns
345    *   6 Gb : 120 ns
346    *   8 Gb : 120 ns
347    *   12 Gb: 140 ns
348    *   16 Gb: 140 ns
349    *   24 Gb: 190 ns
350    *   32 Gb: 190 ns
351
352*   `trpabMinNs`: Minimum Row Precharge Delay Time (tRPab) for all banks in
353    nanoseconds. As per JESD209-5B, this is max(21ns, 2nCK), which defaults to
354    `21 ns`.
355
356*   `trppbMinNs`: Minimum Row Precharge Delay Time (tRPpb) per bank in
357    nanoseconds. As per JESD209-5B, this is max(18ns, 2nCK) which defaults to
358    `18 ns`.
359
360*   `tckMinPs`: SDRAM minimum cycle time (tCKmin) value in picoseconds. LPDDR5
361    has two clocks: the command/addrees clock (CK) and the data clock (WCK).
362    They are related by the WCK:CK ratio, which can be either 4:1 or 2:1. For
363    LPDDR5, tCKmin is the CK period, which can be calculated from the
364    `speedMbps` attribute and the WCK:CK ratio as follows: `tCKmin = 1 /
365    (speedMbps / 2 / WCK:CK)`. The default values used are for a 4:1 WCK:CK
366    ratio:
367
368    *   6400 Mbps: 1250 ps
369    *   5500 Mbps: 1455 ps
370
371*   `taaMinPs`: Minimum CAS Latency Time(tAAmin) in picoseconds. This value
372    defaults to nck * tCKmin, where nck is maximum CAS latency, and is
373    determined from the `speedMbps` attribute as per JESD209-5B:
374
375    *   6400 Mbps: 17
376    *   5500 Mbps: 15
377
378*   `trcdMinNs`: Minimum RAS# to CAS# Delay Time (tRCDmin) in nanoseconds. As
379    per JESD209-5B, this is max(18ns, 2nCK) which defaults to `18 ns`.
380
381#### Example `memory_parts.json`
382
383```
384{
385    "parts": [
386        {
387            "name": "MT62F1G32D4DR-031 WT:B",
388            "attribs": {
389                "densityPerDieGb": 8,
390                "diesPerPackage": 4,
391                "bitWidthPerChannel": 16,
392                "ranksPerChannel": 2,
393                "speedMbps": 6400
394            }
395        },
396    ]
397}
398```
399
400### Output
401
402The `spd_gen` tool generates the directory structure shown below. The inputs to
403the tool are the `memory_parts.json` files, and all other files are generated.
404
405```
406    spd
407      |
408      |_ lp4x
409           |
410           |_ memory_parts.json
411           |_ platforms_manifest.generated.txt
412           |_ set-0
413                |_parts_spd_manifest.generated.txt
414                |_spd-1.hex
415                |_spd-2.hex
416                |_...
417           |_ set-1
418                |_...
419           |_...
420      |
421      |_ ddr4
422           |
423           |_ memory_parts.json
424           |_ platforms_manifest.generated.txt
425           |_ set-0
426                |_parts_spd_manifest.generated.txt
427                |_spd-1.hex
428                |_spd-2.hex
429                |_...
430           |_ set-1
431                |_...
432           |_...
433      |_...
434```
435
436The files generated are:
437
438*   `spd-X.hex`: Deduplicated SPDs for all the memory parts in the input JSON
439    file.
440
441*   `parts_spd_manifest.generated.txt`: A CSV file mapping each memory part to
442    one of the deduplicated SPD files. E.g.
443
444    ```
445    H9HCNNNBKMMLXR-NEE,spd-1.hex
446    H9HCNNNFAMMLXR-NEE,spd-2.hex
447    K4U6E3S4AA-MGCL,spd-1.hex
448    K4UBE3D4AA-MGCL,spd-3.hex
449    MT53E1G32D2NP-046 WT:A,spd-4.hex
450    ```
451
452*   `platforms_manifest.generated.txt`: A CSV file mapping each platform to the
453    SPD set used by that platform. E.g.
454
455    ```
456    TGL,set-0
457    ADL,set-0
458    JSL,set-1
459    CZN,set-1
460    ```
461
462## Tool 2 - `part_id_gen`
463
464This program takes the following 4 inputs:
465
466*   1) The SoC platform which the board is based on, e.g. ADL.
467*   2) The memory technology used by the board, One of ddr4, lp4x, or lp5.
468*   3) The path to the directory where the generated Makefile.mk should be placed.
469*   4) A CSV file containing a list of the memory parts used by the board, with an
470        optional fixed or exclusive ID for each part and an optional SPD override file.
471        A fixed ID is simply an integer and it ensure that part (and any that share the
472        same SPD) will be assigned that ID. An exclusive ID is prefixed with `*` and ensures
473        that only parts with the same exclusive ID will be assigned that ID, even if they would
474        otherwise share the same ID. When using an SPD override file, the file will be searched
475        for in the directory where mem_parts_used is located, if it is not found there then it
476        will be searched for in the appropriate default spd directory.
477
478        NOTE: Only assign a fixed/exclusive ID if required for legacy reasons.
479
480Example of a CSV file using fixed and exclusive IDs, and SPD file overrides:
481
482```
483K4AAG165WA-BCWE,1
484MT40A512M16TB-062E:J
485MT40A1G16KD-062E:E
486K4A8G165WC-BCWE
487H5AN8G6NDJR-XNC,8
488H5ANAG6NCMR-XNC,*9
489H9HCNNNCPMMLXR-NEE,,H9HCNNNCPMMLXR-NEE.hex
490H54G56CYRBX247,4,H54G56CYRBX247.hex
491```
492
493Explanation: This will ensure that the SPDs for K4AAG165WA-BCWE and
494H5AN8G6NDJR-XNC are assigned to IDs 1 and 8 respectively. H5ANAG6NCMR-XNC
495will be assigned ID 9 and no other part will be assigned ID 9 even if it
496shares the same SPD. The SPDs for all other memory parts will be assigned to
497the first compatible ID. Assigning fixed/exclusive IDs may result in duplicate
498SPD entries or gaps in the ID mapping.
499
500### Output
501
502The `part_id_gen` tool outputs the following:
503
504*   It prints the DRAM hardware strap ID which should be allocated to each
505    memory part in the input file.
506*   It generates a `Makefile.mk` in the given directory. This is used to
507    integrate the SPD files generated by `spd_gen` with the coreboot build for
508    the board.
509*   It generates a `dram_id.generated.txt` in the same directory as the
510    `Makefile.mk`. This lists the part IDs assigned to each memory part, and is
511    useful for itegration with the board schematics.
512
513Sample `Makefile.mk`:
514
515```
516# SPDX-License-Identifier: GPL-2.0-or-later
517# This is an auto-generated file. Do not edit!!
518# Generated by:
519# util/spd_tools/bin/part_id_gen ADL lp4x src/mainboard/google/brya/variants/felwinter/memory src/mainboard/google/brya/variants/felwinter/memory/mem_parts_used.txt
520
521SPD_SOURCES =
522SPD_SOURCES += spd/lp4x/set-0/spd-1.hex      # ID = 0(0b0000)  Parts = K4U6E3S4AA-MGCR, H9HCNNNBKMMLXR-NEE
523SPD_SOURCES += spd/lp4x/set-0/spd-3.hex      # ID = 1(0b0001)  Parts = K4UBE3D4AA-MGCR
524SPD_SOURCES += spd/lp4x/set-0/spd-4.hex      # ID = 2(0b0010)  Parts = MT53E1G32D2NP-046 WT:A
525```
526
527NOTE: Empty entries may be required if there is a gap created by a memory part
528with a fixed ID.
529
530Sample `dram_id.generated.txt`:
531
532```
533# SPDX-License-Identifier: GPL-2.0-or-later
534# This is an auto-generated file. Do not edit!!
535# Generated by:
536# util/spd_tools/bin/part_id_gen ADL lp4x src/mainboard/google/brya/variants/felwinter/memory src/mainboard/google/brya/variants/felwinter/memory/mem_parts_used.txt
537
538DRAM Part Name                 ID to assign
539K4U6E3S4AA-MGCR                0 (0000)
540K4UBE3D4AA-MGCR                1 (0001)
541H9HCNNNBKMMLXR-NEE             0 (0000)
542MT53E1G32D2NP-046 WT:A         2 (0010)
543```
544
545### Note of caution
546
547The `part_id_gen` tool assigns DRAM IDs based on the order of the part names in
548the input file. Thus, when adding a new memory part to the list, it should
549always go at the end of the file. This guarantees that the memory parts that
550were already assigned IDs do not change.
551
552## How to build the tools?
553
554```
555make clean -C util/spd_tools
556make -C util/spd_tools
557```
558
559## How to use the tools?
560
561### `spd_gen`
562
563Usage:
564
565```
566util/spd_tools/bin/spd_gen <mem_parts_list_json> <mem_technology>
567```
568
569Usage Examples:
570
571```
572util/spd_tools/bin/spd_gen spd/ddr4/memory_parts.json ddr4
573util/spd_tools/bin/spd_gen spd/lp4x/memory_parts.json lp4x
574util/spd_tools/bin/spd_gen spd/lp5/memory_parts.json lp5
575```
576
577### `part_id_gen`
578
579Usage:
580
581```
582util/spd_tools/bin/part_id_gen <platform> <mem_technology> <makefile_dir> <mem_parts_used_file>
583```
584
585Usage Example:
586
587```
588util/spd_tools/bin/part_id_gen \
589  ADL \
590  lp4x \
591  src/mainboard/google/brya/variants/felwinter/memory \
592  src/mainboard/google/brya/variants/felwinter/memory/mem_parts_used.txt
593```
594
595### Need to add a new memory part for a board?
596
597*   If the memory part is not present in the global list of memory parts for
598    that memory technology (e.g. `spd/lp4x/memory_parts.json`), then add the
599    memory part name and attributes as per the datasheet.
600
601    *   Use `spd_gen` to regenerate all the SPD files and manifests for that
602        memory technology. Either a new SPD file will be generated for the new
603        part, or an existing one will be reused.
604    *   Upload the new SPD (if one is created) and the manifest changes for
605        review.
606
607*   Update the file containing the memory parts used by board (variant), by
608    adding the new memory part name at the end of the file.
609
610    *   Use `part_id_gen` to update the variant's `Makefile.mk` and
611        `dram_id.generated.txt` with the new part.
612    *   Upload the changes to `Makefile.mk` and `dram_id.generated.txt` for
613        review.
614
615## How to add support for a new memory technology
616
617### 1. Gather the SPD requirements
618
619To generate SPDs for the new memory technology, information is needed about the
620list of bytes in the SPD and how the value of each byte should be determined.
621This information usually comes from a combination of:
622
623*   The JEDEC spec for the memory technology, e.g. JESD209-5B for LPDDR5.
624*   The JEDEC SPD spec for the memory technology, e.g. SPD4.1.2.M-2 for LPDDR3/4
625    (also used for LP4x and LP5).
626*   Platform-specific requirements. SoC vendors often don't follow the JEDEC
627    specs exactly. E.g. the memory training code may expect certain SPD bytes to
628    encode a different value to what is stated in the spec. So for each SoC
629    platform using the new memory technology, any platform-specific requirements
630    need to be gathered.
631
632### 2. Implement support in spd_tools
633
634Support for the new memory technology needs to be added to both the `spd_gen`
635and `part_id_gen` tools.
636
637#### `spd_gen`
638
639Adding support to `spd_gen` requires implementing the logic to generate SPDs for
640the new memory technology. The changes required are:
641
642*   Add the new memory technology to the `memTechMap` in `spd_gen/spd_gen.go`.
643*   Add a new file `spd_gen/<mem_tech>.go`. This file will contain all the logic
644    for generating SPDs for the new memory technology. It needs to implement the
645    `memTech` interface defined in `spd_gen/spd_gen.go`. The interface functions
646    are documented inline. Examples of how the interface is implemented for
647    existing memory technologies can be found in the `spd_gen/` directory, e.g.
648    `lp4x.go`, `ddr4.go`, `lp5.go`. While not strictly necessary, it is
649    recommended to follow the overall structure of these existing files when
650    adding a new memory technology.
651
652#### `part_id_gen`
653
654The `part_id_gen` tool is memory technology-agnostic, so the only change
655required is:
656
657*   Add the new memory technology to the `supportedMemTechs` list in
658    `part_id_gen/part_id_gen.go`.
659