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