util/spd_tools: Remove old lp4x and ddr4 versions of spd_tools

The migration to the new unified version of spd_tools is complete, so
the old lp4x and ddr4 versions can be removed.

BUG=b:191776301
TEST=None

Signed-off-by: Reka Norman <rekanorman@google.com>
Change-Id: I6b1fc297739efc8dc7d7eec64956bf3343984604
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57822
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
diff --git a/util/spd_tools/ddr4/README.md b/util/spd_tools/ddr4/README.md
deleted file mode 100644
index 7527544..0000000
--- a/util/spd_tools/ddr4/README.md
+++ /dev/null
@@ -1,294 +0,0 @@
-# DDR4 SPD tools README
-
-Tools for generating SPD files for DDR4 memory used in platforms with
-memory down configuration. These tools generate SPDs following JESD79-4C
-and Jedec 4.1.2.L-5 R29 v103 specifications.
-
-There are two tools provided that assist with generating SPDs and Makefiles
-to integrate in coreboot build. These tools can also be used to allocate
-DRAM IDs (configure DRAM hardware straps) for any DDR4 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 DDR4
-  memory parts used by the board. Takes as input a list of memory parts
-  used (in CSV format) by the board with optional fixed ids and the SPD
-  manifest file generated by gen_spd.go. Generates Makefile.inc for
-  integrating the generated SPD files in the coreboot build.
-
-## Tool 1 - gen_spd.go
-
-This program takes as input:
-* Pointer to directory where the generated SPD files and manifest will
-  be placed.
-* JSON file containing a global list of memory parts with their
-  attributes as per the datasheet. This is the list of all known
-  DDR4 memory parts irrespective of their usage on the board.
-* SoC platform name for which the SPDs are being generated. Currently
-  supported platform names are `TGL`, `PCO` and `PLK`.
-
-Input JSON file requires the following two fields for every memory part:
-* `name`: Name of the memory part
-* `attribs`: 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:
-* Mandatory: These attributes have to be provided for a memory part.
-* Optional: These attributes can be provided by memory part if it wants
-  to override the defaults.
-
-### Mandatory `attribs`
-
-* `speedMTps`: Maximum rate supported by the part in MT/s. Valid values:
-  `1600, 1866, 2133, 2400, 2666, 2933, 3200` MT/s.
-
-* `CL_nRCD_nRP`: Refers to CAS Latency specified for the part (find
-  "CL-nRCD-nRP" in the vendor spec for the DDR4 part).
-
-* `capacityPerDieGb`: Capacity per die in gigabits.  Valid values:
-  `2, 4, 8, 16` Gb part.
-
-* `diesPerPackage`: Number of dies on the part.  Valid values:
-  `1, 2` dies per package.
-
-* `packageBusWidth`: Number of bits of the device's address bus.  Valid values:
-  `8, 16` bit-wide bus. NOTE: Width of x4 is not supported by this tool.
-
-* `ranksPerPackage`: From Jedec doc 4_01_02_AnnexL-1R23:
-  “Package ranks per DIMM” refers to the collections of devices on the module
-  sharing common chip select signals (across the data width of the DIMM),
-  either from the edge connector for unbuffered modules or from the outputs of
-  a registering clock driver for RDIMMs and LRDIMMs.Number of bits of the
-  device's address bus.  Valid values:
-  `1, 2` package ranks.
-
-### Optional `attribs`
-
-The following options are calculated by the tool based on the mandatory
-attributes described for the part, but there may be cases where a default value
-must be overridden, such as when a device appears to be 3200AA, but does not
-support all of the CAS latencies typically supported by a speed bin 3200AA part.
-Do deal with such a case, the variable can be overridden here and the tool will
-use this value instead of calculating one.  All values must be defined in
-picosecond units, except for "CASLatencies", which would be represented as a
-string like "9 10 11 12 14".
-
- * `TAAMinPs`: Defines the minimum CAS Latency.
-   Table 48 of Jedec doc 4_01_02_AnnexL-5R29 lists tAAmin for each speed grade.
-
- * `TRASMinPs`: Refers to the minimum active to precharge delay time.
-   Table 55 of Jedec doc 4_01_02_AnnexL-5R29 lists tRPmin for each speed grade.
-
- * `TCKMinPs`: Refers to the minimum clock cycle time.
-   Table 42 of Jedec doc 4_01_02_AnnexL-5R29 lists tCKmin for each speed grade.
-
- * `TCKMaxPs`:Refers to the minimum clock cycle time.
-   Table 44 of Jedec doc 4_01_02_AnnexL-5R29 lists tCKmin for each speed grade.
-
- * `TRFC1MinPs`: Refers to the minimum refresh recovery delay time.
-   Table 59 of Jedec doc 4_01_02_AnnexL-5R29 lists tRFC1min for each page size.
-
- * `TRFC2MinPs`: Refers to the minimum refresh recovery delay time.
-   Table 61 of Jedec doc 4_01_02_AnnexL-5R29 lists tRFC2min for each page size.
-
- * `TRFC4MinPs`: Refers to the minimum refresh recovery delay time.
-   Table 63 of Jedec doc 4_01_02_AnnexL-5R29 lists tRFC4min for each page size.
-
- * `TFAWMinPs`:: Refers to the minimum four activate window delay time.
-   Table 66 of Jedec doc 4_01_02_AnnexL-5R29 lists tFAWmin for each speed grade
-   and page size combination.
-
- * `TRRDSMinPs`: Refers to the minimum activate to activate delay time to
-   different bank groups.
-   Table 68 of Jedec doc 4_01_02_AnnexL-5R29 lists tRRD_Smin for each speed grade
-   and page size combination.
-
- * `TRRDLMinPs`: Refers to the minimum activate to activate delay time to the
-   same bank group.
-   Table 70 of Jedec doc 4_01_02_AnnexL-5R29 lists tRRD_Lmin for each speed grade
-   and page size combination.
-
- * `TCCDLMinPs`: Refers to the minimum CAS to CAS delay time to same bank group.
-   Table 72 of Jedec doc 4_01_02_AnnexL-5R29 lists tCCD_Lmin for each speed grade.
-
- * `TWRMinPs`: Refers to the minimum write recovery time.
-   Table 75 of Jedec doc 4_01_02_AnnexL-5R29 lists tWRmin for each ddr4 type.
-
- * `TWTRSMinPs`: Refers to minimum write to read time to different bank group.
-   Table 78 of Jedec doc 4_01_02_AnnexL-5R29 lists tWTR_Smin for each ddr4 type.
-
- * `TWTRLMinPs`: Refers to minimum write to read time to same bank group.
-   Table 80 of Jedec doc 4_01_02_AnnexL-5R29 lists tWTR_Lmin for each ddr4 type.
-
- * `CASLatencies`: Refers to the CAS latencies supported by the part.
-   The speed bin tables in the back of Jedec doc 4_01_02_AnnexL-5R29 define the
-   standard CAS latencies that a speed bin part is supposed to support.
-   In cases where a part does not support all of the CAS latencies listed in the
-   speed bin tables, this entry should be used to override the default settings.
-
-### Example JSON file
-```
-{
-    "parts": [
-        {
-            "name": "MEMORY_PART_A",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 2,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1,
-            }
-        },
-        {
-            "name": "MEMORY_PART_B",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 2,
-                "casLatencies": "9 10 11 12 13 14 15 16 17 18 19 20",
-                "tCKMaxPs": "1250"
-            }
-        }
-    ]
-}
-```
-
-### Output
-
-This tool generates the following files using the global list of
-memory parts in JSON format as described above:
-  * De-duplicated SPDs required for the different memory parts. These
-    SPD files are named (ddr4-spd-1.hex, ddr4-spd-2.hex, and so on)
-    and placed in the directory provided as an input to the tool.
-  * CSV file representing which of the deduplicated SPD files is used
-    by which memory part. This file is named as
-    `ddr4_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, ddr4-spd-1.hex
-    MEMORY_PART_B, ddr4-spd-2.hex
-    MEMORY_PART_C, ddr4-spd-3.hex
-    MEMORY_PART_D, ddr4-spd-2.hex
-    MEMORY_PART_E, ddr4-spd-2.hex
-    ```
-
-## Tool 2 - gen_part_id.go
-
-This program takes as input:
-* Pointer to directory where the SPD files and the manifest file
-  `ddr4_spd_manifest.generated.txt` (in CSV format) are placed by
-  gen_spd.go
-* CSV file containing list of memory parts used by the board and optional
-  fixed id. Each line of the file is supposed to contain one memory part `name`
-  as present in the global list of memory parts provided to gen_spd.go.
-  Optionally a fixed id may also be assigned to the part if required.
-  NOTE: Only assign a fixed ID if required for legacy reasons.
-
-* Pointer to directory where the generated Makefile.inc should be
-  placed by the tool.
-
-Sample input (mem_parts_used_file.txt):
-```
-K4AAG165WA-BCWE,1
-MT40A512M16TB-062E:J
-MT40A1G16KD-062E:E
-K4A8G165WC-BCWE
-H5AN8G6NDJR-XNC,8
-H5ANAG6NCMR-XNC
-```
-NOTE: This will ensure SPDs compatible with K4AAG165WA-BCWE and H5AN8G6NDJR-XNC
-are assigned to ID 1 and 8 respectively. All other memory parts will be
-assigned to the first compatible ID. Assigning fixed IDs may result in
-duplicate SPD entries or gaps in the ID mapping.
-
-### Output
-
-This program provides the following:
-
-* Prints out the list of DRAM hardware strap IDs that should be
-  allocated to each memory part listed in the input file.
-* Makefile.inc is generated in the provided directory to integrate
-  SPDs generated by gen_spd.go with the coreboot build for the board.
-* dram_id.generated.txt is generated in the same directory as
-  Makefile. This contains the part IDs assigned to the different
-  memory parts. (Useful to integrate in board schematics).
-
-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 += ddr4-spd-1.hex      # ID = 0(0b0000)  Parts = MEMORY_PART_A
-SPD_SOURCES += ddr4-spd-2.hex      # ID = 1(0b0001)  Parts = MEMORY_PART_B, MEMORY_PART_D
-SPD_SOURCES += ddr4-spd-empty.hex  # ID = 2(0b0010)
-SPD_SOURCES += ddr4-spd-3.hex      # ID = 2(0b0010)  Parts = MEMORY_PART_C
-```
-NOTE: Empty entries may be required if there is a gap created by a memory part
-with a fixed id.
-
-### Note of caution
-
-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.
-
-## How to build the tools?
-```
-# go build gen_spd.go
-# go build gen_part_id.go
-```
-
-## How to use the tools?
-```
-# ./gen_spd <spd_dir> <mem_parts_list_json> <platform>
-# ./gen_part_id <spd_dir> <makefile_dir> <mem_parts_used_file>
-```
-
-## Example Usage
-```
-# ./gen_spd ../../../../src/soc/intel/tigerlake/spd/ddr4 ./global_ddr4_mem_parts.json.txt 'TGL'
-
-```
-
-### Need to add a new memory part for a board?
-
-* If the memory part is not present in the global list of memory
-  parts, then add the memory part name and attributes as per the
-  datasheet to the file containing the global list.
-  * Use `gen_spd.go` with input as the file containing the global list
-    of memory parts to generate de-duplicated SPDs.
-  * If a new SPD file is generated, use `git add` to add it to the
-    tree and push a CL for review.
-* Update the file containing memory parts used by board (variant) to
-  add the new memory part name at the end of the file.
-  * Use gen_part_id.go providing it pointer to the location where SPD
-    files are stored and file containing the list of memory parts used
-    by the board(variant).
-  * Use `git add` to add `Makefile.inc` and `dram_id.generated.txt`
-    with updated changes and push a CL for review.
diff --git a/util/spd_tools/ddr4/gen_part_id.go b/util/spd_tools/ddr4/gen_part_id.go
deleted file mode 100644
index 110b9b2..0000000
--- a/util/spd_tools/ddr4/gen_part_id.go
+++ /dev/null
@@ -1,308 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-package main
-
-import (
-	"encoding/csv"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"path/filepath"
-	"strconv"
-)
-
-/*
- * This program allocates DRAM strap IDs for different parts that are being used by the variant.
- *
- * It expects the following inputs:
- *  Pointer to SPD directory. This is the location where SPD files and SPD Manifest generated by
- *  gen_spd.go are placed.
- *  Pointer to Makefile directory. Makefile.inc generated by this program is placed in this
- *  location.
- *  Text file containing a list of memory parts names used by the board. Each line in the file
- *  is expected to have one memory part name.
- */
-const (
-	SPDManifestFileName = "ddr4_spd_manifest.generated.txt"
-	MakefileName        = "Makefile.inc"
-	DRAMIdFileName      = "dram_id.generated.txt"
-	MaxMemoryId         = 15
-)
-
-func usage() {
-	fmt.Printf("\nUsage: %s <spd_dir> <makefile_dir> <mem_parts_used_file>\n\n", os.Args[0])
-	fmt.Printf("   where,\n")
-	fmt.Printf("   spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n")
-	fmt.Printf("   makefile_dir = Directory path where generated Makefile.inc should be placed\n")
-	fmt.Printf("   mem_parts_used_file = CSV file containing list of memory parts used by the board and optional fixed ids\n\n\n")
-}
-
-func checkArgs() error {
-
-	for _, arg := range os.Args[1:] {
-		if _, err := os.Stat(arg); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-type usedPart struct {
-	partName string
-	index    int
-}
-
-/*
- * Read input file CSV that contains list of memory part names used by the variant
- * and an optional assigned id.
- */
-func readParts(memPartsUsedFileName string) ([]usedPart, error) {
-
-	f, err := os.Open(memPartsUsedFileName)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	r := csv.NewReader(f)
-	r.FieldsPerRecord = -1 // Allow variable length records
-	r.TrimLeadingSpace = true
-	r.Comment = '#'
-
-	parts := []usedPart{}
-
-	for {
-		fields, err := r.Read()
-
-		if err == io.EOF {
-			break
-		}
-
-		if err != nil {
-			return nil, err
-		}
-
-		if len(fields) == 1 {
-			parts = append(parts, usedPart{fields[0], -1})
-		} else if len(fields) == 2 {
-			assignedId, err := strconv.Atoi(fields[1])
-			if err != nil {
-				return nil, err
-			}
-			if assignedId > MaxMemoryId || assignedId < 0 {
-				return nil, fmt.Errorf("Out of bounds assigned id %d for part %s", assignedId, fields[0])
-			}
-			parts = append(parts, usedPart{fields[0], assignedId})
-		} else {
-			return nil, fmt.Errorf("mem_parts_used_file file is incorrectly formatted")
-		}
-	}
-
-	return parts, nil
-}
-
-/*
- * Read SPD manifest file(CSV) generated by gen_spd program and generate two maps:
- * 1. Part to SPD Map : This maps global memory part name to generated SPD file name
- * 2. SPD to Index Map: This generates a map of deduplicated SPD file names to index assigned to
- *                      that SPD. This function sets index for all SPDs to -1. This index gets
- *                      updated as part of genPartIdInfo() depending upon the SPDs actually used
- *                      by the variant.
- */
-func readSPDManifest(SPDDirName string) (map[string]string, map[string]int, error) {
-	f, err := os.Open(filepath.Join(SPDDirName, SPDManifestFileName))
-	if err != nil {
-		return nil, nil, err
-	}
-	defer f.Close()
-	r := csv.NewReader(f)
-
-	partToSPDMap := make(map[string]string)
-	SPDToIndexMap := make(map[string]int)
-
-	for {
-		fields, err := r.Read()
-
-		if err == io.EOF {
-			break
-		}
-
-		if err != nil {
-			return nil, nil, err
-		}
-
-		if len(fields) != 2 {
-			return nil, nil, fmt.Errorf("CSV file is incorrectly formatted")
-		}
-
-		partToSPDMap[fields[0]] = fields[1]
-		SPDToIndexMap[fields[1]] = -1
-	}
-
-	return partToSPDMap, SPDToIndexMap, nil
-}
-
-/* Print information about memory part used by variant and ID assigned to it. */
-func appendPartIdInfo(s *string, partName string, index int) {
-	*s += fmt.Sprintf("%-30s %d (%04b)\n", partName, index, int64(index))
-}
-
-type partIds struct {
-	SPDFileName string
-	memParts    string
-}
-
-/*
- * For each part used by variant, check if the SPD (as per the manifest) already has an ID
- * assigned to it. If yes, then add the part name to the list of memory parts supported by the
- * SPD entry. If not, then assign the next ID to the SPD file and add the part name to the
- * list of memory parts supported by the SPD entry.
- *
- * Returns list of partIds that contains spdFileName and supported memory parts for each
- * assigned ID.
- */
-func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexMap map[string]int, makefileDirName string) ([]partIds, error) {
-
-	partIdList := []partIds{}
-	var s string
-
-	// Assign parts with fixed ids first
-	for _, p := range parts {
-
-		if p.index == -1 {
-			continue
-		}
-
-		if p.partName == "" {
-			return nil, fmt.Errorf("Invalid part entry")
-		}
-
-		SPDFileName, ok := partToSPDMap[p.partName]
-		if !ok {
-			return nil, fmt.Errorf("Failed to find part ", p.partName, " in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest")
-		}
-
-		// Extend partIdList with empty entries if needed
-		for i := len(partIdList) - 1; i < p.index; i++ {
-			partIdList = append(partIdList, partIds{})
-		}
-
-		if partIdList[p.index].SPDFileName != "" {
-			return nil, fmt.Errorf("Part ", p.partName, " is assigned to an already assigned ID ", p.index)
-		}
-
-		partIdList[p.index] = partIds{SPDFileName: SPDFileName, memParts: p.partName}
-
-		// SPDToIndexMap should point to first assigned index in the used part list
-		if SPDToIndexMap[SPDFileName] < 0 {
-			SPDToIndexMap[SPDFileName] = p.index
-		}
-	}
-
-	s += fmt.Sprintf("%-30s %s\n", "DRAM Part Name", "ID to assign")
-
-	// Assign parts with no fixed id
-	for _, p := range parts {
-		if p.partName == "" {
-			return nil, fmt.Errorf("Invalid part entry")
-		}
-
-		// Add assigned parts to dram id file in the order they appear
-		if p.index != -1 {
-			appendPartIdInfo(&s, p.partName, p.index)
-			continue
-		}
-
-		SPDFileName, ok := partToSPDMap[p.partName]
-		if !ok {
-			return nil, fmt.Errorf("Failed to find part ", p.partName, " in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest")
-		}
-
-		index := SPDToIndexMap[SPDFileName]
-		if index != -1 {
-			partIdList[index].memParts += ", " + p.partName
-			appendPartIdInfo(&s, p.partName, index)
-			continue
-		}
-
-		// Find first empty index
-		for i, partId := range partIdList {
-			if partId.SPDFileName == "" {
-				index = i
-				break
-			}
-		}
-
-		// Append new entry
-		if index == -1 {
-			index = len(partIdList)
-			partIdList = append(partIdList, partIds{})
-		}
-
-		SPDToIndexMap[SPDFileName] = index
-		appendPartIdInfo(&s, p.partName, index)
-		partIdList[index] = partIds{SPDFileName: SPDFileName, memParts: p.partName}
-	}
-
-	fmt.Printf("%s", s)
-	err := ioutil.WriteFile(filepath.Join(makefileDirName, DRAMIdFileName), []byte(s), 0644)
-
-	return partIdList, err
-}
-
-var generatedCodeLicense string = "## SPDX-License-Identifier: GPL-2.0-or-later"
-var autoGeneratedInfo string = "## This is an auto-generated file. Do not edit!!"
-
-/*
- * This function generates Makefile.inc under the variant directory path and adds assigned SPDs
- * to SPD_SOURCES.
- */
-func genMakefile(partIdList []partIds, makefileDirName string) error {
-	var s string
-
-	s += fmt.Sprintf("%s\n%s\n\n", generatedCodeLicense, autoGeneratedInfo)
-	s += fmt.Sprintf("SPD_SOURCES =\n")
-
-	for i := 0; i < len(partIdList); i++ {
-		if partIdList[i].SPDFileName == "" {
-			s += fmt.Sprintf("SPD_SOURCES += %s ", "ddr4-spd-empty.hex")
-			s += fmt.Sprintf("     # ID = %d(0b%04b)\n", i, int64(i))
-		} else {
-			s += fmt.Sprintf("SPD_SOURCES += %s ", partIdList[i].SPDFileName)
-			s += fmt.Sprintf("     # ID = %d(0b%04b) ", i, int64(i))
-			s += fmt.Sprintf(" Parts = %04s\n", partIdList[i].memParts)
-		}
-	}
-
-	return ioutil.WriteFile(filepath.Join(makefileDirName, MakefileName), []byte(s), 0644)
-}
-
-func main() {
-	if len(os.Args) != 4 {
-		usage()
-		log.Fatal("Incorrect number of arguments")
-	}
-
-	SPDDir, MakefileDir, MemPartsUsedFile := os.Args[1], os.Args[2], os.Args[3]
-
-	partToSPDMap, SPDToIndexMap, err := readSPDManifest(SPDDir)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	parts, err := readParts(MemPartsUsedFile)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	partIdList, err := genPartIdInfo(parts, partToSPDMap, SPDToIndexMap, MakefileDir)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	if err := genMakefile(partIdList, MakefileDir); err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/util/spd_tools/ddr4/gen_spd.go b/util/spd_tools/ddr4/gen_spd.go
deleted file mode 100644
index eaa56a7..0000000
--- a/util/spd_tools/ddr4/gen_spd.go
+++ /dev/null
@@ -1,1428 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os"
-	"path/filepath"
-	"reflect"
-	"regexp"
-	"strconv"
-	"strings"
-)
-
-/*
- * This program generates de-duplicated SPD files for DDR4 memory using the global memory
- * part list provided in CSV format. In addition to that, it also generates SPD manifest in CSV
- * format that contains entries of type (DRAM part name, SPD file name) which provides the SPD
- * file name used by a given DRAM part.
- *
- * It takes as input:
- * Pointer to directory where the generated SPD files will be placed.
- * JSON file containing a list of memory parts with their attributes as per datasheet.
- */
-const (
-	SPDManifestFileName = "ddr4_spd_manifest.generated.txt"
-
-	PlatformTGL = 0
-	PlatformPCO = 1
-	PlatformPLK = 2
-)
-
-var platformMap = map[string]int{
-	"TGL": PlatformTGL,
-	"PCO": PlatformPCO,
-	"PLK": PlatformPLK,
-}
-
-var currPlatform int
-
-type memAttributes struct {
-	/* Primary attributes - must be provided by JSON file for each part */
-	SpeedMTps        int
-	CL_nRCD_nRP      int
-	CapacityPerDieGb int
-	DiesPerPackage   int
-	PackageBusWidth  int
-	RanksPerPackage  int
-
-	/*
-	 * All the following parameters are optional and required only if the part requires
-	 * special parameters as per the datasheet.
-	 */
-	/* Timing parameters */
-	TAAMinPs   int
-	TRCDMinPs  int
-	TRPMinPs   int
-	TRASMinPs  int
-	TRCMinPs   int
-	TCKMinPs   int
-	TCKMaxPs   int
-	TRFC1MinPs int
-	TRFC2MinPs int
-	TRFC4MinPs int
-	TFAWMinPs  int
-	TRRDLMinPs int
-	TRRDSMinPs int
-	TCCDLMinPs int
-	TWRMinPs   int
-	TWTRLMinPs int
-	TWTRSMinPs int
-
-	/* CAS */
-	CASLatencies  string
-	CASFirstByte  byte
-	CASSecondByte byte
-	CASThirdByte  byte
-	CASFourthByte byte
-
-	/* The following is for internal-use only and is not overridable */
-	dieBusWidth int
-}
-
-/* This encodes the density in Gb to SPD low nibble value as per JESD 4.1.2.L-5 R29 */
-var densityGbToSPDEncoding = map[int]byte{
-	2:  0x3,
-	4:  0x4,
-	8:  0x5,
-	16: 0x6,
-}
-
-/*
- * Tables 4 thru Table 7 from JESD79-4C.
- * Maps density per die to row-column encoding for a device with x8/x16
- * physical channel.
- */
-var densityGbx8x16DieCapacityToRowColumnEncoding = map[int]byte{
-	2:  0x11, /* 14 rows, 10 columns */
-	4:  0x19, /* 15 rows, 10 columns */
-	8:  0x21, /* 16 rows, 10 columns */
-	16: 0x29, /* 17 rows, 10 columns */
-}
-
-/*
- * Tables 169 & 170 in the JESD79-4C spec
- * Maps die density to refresh timings. This is the same for x8 and x16
- * devices.
- */
-
-/* maps die density to rcf1 timing in pico seconds */
-var tRFC1Encoding = map[int]int{
-	2:  160000,
-	4:  260000,
-	8:  350000,
-	16: 550000,
-}
-
-/* maps die density to rcf2 timing in pico seconds */
-var tRFC2Encoding = map[int]int{
-	2:  110000,
-	4:  160000,
-	8:  260000,
-	16: 350000,
-}
-
-/* maps die density to rcf4 timing in pico seconds */
-var tRFC4Encoding = map[int]int{
-	2:  90000,
-	4:  110000,
-	8:  160000,
-	16: 260000,
-}
-
-func getTRCMinPs(memAttribs *memAttributes) int {
-	return memAttribs.TAAMinPs + memAttribs.TRASMinPs
-}
-
-func getDefaultTCKMinPs(memAttribs *memAttributes) int {
-	/* value 2000000 = 2 * 1000000, where 1000000 is to convert mS to pS */
-	return 2000000 / memAttribs.SpeedMTps
-}
-
-type speedBinAttributes struct {
-	TRASMinPs int
-	TCKMaxPs  int
-}
-
-var speedBinToSPDEncoding = map[int]speedBinAttributes{
-	1600: {
-		TRASMinPs: 35000,
-		TCKMaxPs:  1500,
-	},
-	1866: {
-		TRASMinPs: 34000,
-		TCKMaxPs:  1250,
-	},
-	2133: {
-		TRASMinPs: 33000,
-		TCKMaxPs:  1071,
-	},
-	2400: {
-		TRASMinPs: 32000,
-		TCKMaxPs:  937,
-	},
-	2666: {
-		TRASMinPs: 32000,
-		TCKMaxPs:  833,
-	},
-	2933: {
-		TRASMinPs: 32000,
-		TCKMaxPs:  750,
-	},
-	3200: {
-		TRASMinPs: 32000,
-		TCKMaxPs:  682,
-	},
-}
-
-func getBankGroups(memAttribs *memAttributes) byte {
-	var bg byte
-
-	switch memAttribs.PackageBusWidth {
-	case 8:
-		bg = 4
-	case 16:
-		if memAttribs.DiesPerPackage == 1 {
-			bg = 2 /* x16 SDP has 2 bank groups */
-		} else {
-			bg = 4 /* x16 DDP has 4 bank groups */
-		}
-	}
-
-	return bg
-}
-
-func encodeBankGroups(bg byte) byte {
-	var val byte
-
-	switch bg {
-	case 2:
-		val = 1
-	case 4:
-		val = 2
-	}
-
-	return val << 6
-}
-
-func encodeDensityBanks(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = densityGbToSPDEncoding[memAttribs.CapacityPerDieGb]
-	b |= encodeBankGroups(getBankGroups(memAttribs))
-	/* No need to encode banksPerGroup.it's always 4 ([4:5] = 0) */
-
-	return b
-}
-
-func encodeSdramAddressing(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = densityGbx8x16DieCapacityToRowColumnEncoding[memAttribs.CapacityPerDieGb]
-
-	return b
-}
-
-func encodePackageDeviceType(dies int) byte {
-	var b byte
-
-	if dies > 1 {
-		/* If more than one die, then this is a non-monolithic device. */
-		b = 1
-	} else {
-		/* If only single die, then this is a monolithic device. */
-		b = 0
-	}
-
-	return b << 7
-}
-
-func encodeSignalLoadingFromDieCount(dies int) byte {
-	var loading byte
-
-	/*
-	 * If die count = 1, signal loading = "not specified" = 0
-	 * If die count > 1, signal loading = "multi" = 2
-	 */
-	if dies == 1 {
-		loading = 0
-	} else {
-		loading = 1
-	}
-
-	return loading
-}
-
-func encodeDiesPerPackage(dies int) byte {
-	var b byte
-
-	b = encodePackageDeviceType(dies) /* Monolithic / Non-monolithic device */
-	b |= (byte(dies) - 1) << 4
-
-	return b
-}
-
-func encodePackageType(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = encodeDiesPerPackage(memAttribs.DiesPerPackage)
-	b |= encodeSignalLoadingFromDieCount(memAttribs.DiesPerPackage)
-
-	return b
-}
-
-func encodeDataWidth(bitWidthPerDevice int) byte {
-	var width byte
-
-	switch bitWidthPerDevice {
-	case 8:
-		width = 1
-	case 16:
-		width = 2
-	}
-
-	return width
-}
-
-func encodeRanks(ranks int) byte {
-	var b byte
-
-	b = byte(ranks - 1)
-
-	return b << 3
-}
-
-func encodeModuleOrganization(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = encodeDataWidth(memAttribs.dieBusWidth)
-	b |= encodeRanks(memAttribs.RanksPerPackage)
-
-	return b
-}
-
-func encodeTCKMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TCKMinPs)
-}
-
-func encodeTCKMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TCKMinPs)
-}
-
-func encodeTCKMax(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TCKMaxPs)
-}
-
-func encodeTCKMaxFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TCKMaxPs)
-}
-
-func divRoundUp(dividend int, divisor int) int {
-	return (dividend + divisor - 1) / divisor
-}
-
-func convNsToPs(timeNs int) int {
-	return timeNs * 1000
-}
-
-func convMtbToPs(mtb int) int {
-	return mtb * 125
-}
-
-func convPsToMtb(timePs int) int {
-	return divRoundUp(timePs, 125)
-}
-
-func convPsToMtbByte(timePs int) byte {
-	return byte(convPsToMtb(timePs) & 0xff)
-}
-
-func convPsToFtbByte(timePs int) byte {
-	mtb := convPsToMtb(timePs)
-	ftb := timePs - convMtbToPs(mtb)
-
-	return byte(ftb)
-}
-
-func encodeTAAMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TAAMinPs)
-}
-
-func encodeTAAMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TAAMinPs)
-}
-
-func encodeTRCDMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TRCDMinPs)
-}
-
-func encodeTRCDMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TRCDMinPs)
-}
-
-func encodeTRPMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TRPMinPs)
-}
-
-func encodeTRCMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TRCMinPs)
-}
-
-func encodeTRPMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TRPMinPs)
-}
-
-func encodeTRASRCMinMSNs(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = byte((convPsToMtb(memAttribs.TRASMinPs) >> 4) & 0xf0)
-	b |= byte((convPsToMtb(memAttribs.TRCMinPs) >> 8) & 0x0f)
-
-	return b
-}
-
-func encodeTRASMinLsb(memAttribs *memAttributes) byte {
-	return byte(convPsToMtb(memAttribs.TRASMinPs) & 0xff)
-}
-
-func encodeTRCMinLsb(memAttribs *memAttributes) byte {
-	return byte(convPsToMtb(memAttribs.TRCMinPs) & 0xff)
-}
-
-/* This takes memAttribs.PackageBusWidth as an index */
-var pageSizefromBusWidthEncoding = map[int]int{
-	8:  1,
-	16: 2,
-}
-
-/*
- * Per Table 169 & Table 170 of Jedec JESD79-4C
- * tFAW timing is based on :
- *  Speed bin and page size
- */
-func getTFAWMinPs(memAttribs *memAttributes) int {
-	var tFAWFixed int
-
-	if pageSizefromBusWidthEncoding[memAttribs.PackageBusWidth] == 1 {
-		switch memAttribs.SpeedMTps {
-		case 1600:
-			tFAWFixed = 25000
-		case 1866:
-			tFAWFixed = 23000
-		default:
-			tFAWFixed = 21000
-		}
-	} else if pageSizefromBusWidthEncoding[memAttribs.PackageBusWidth] == 2 {
-		switch memAttribs.SpeedMTps {
-		case 1600:
-			tFAWFixed = 35000
-		default:
-			tFAWFixed = 30000
-		}
-	}
-
-	return tFAWFixed
-}
-
-/* Update settings based on data sheet (json) supplied memory attributes */
-
-func updateTFAWMin(memAttribs *memAttributes) {
-	var tFAWFromTck int
-
-	if memAttribs.TFAWMinPs == 0 {
-		memAttribs.TFAWMinPs = getTFAWMinPs(memAttribs)
-	}
-
-	switch pageSizefromBusWidthEncoding[memAttribs.PackageBusWidth] {
-	case 1:
-		tFAWFromTck = 20 * memAttribs.TCKMinPs
-	case 2:
-		tFAWFromTck = 28 * memAttribs.TCKMinPs
-	}
-
-	if memAttribs.TFAWMinPs < tFAWFromTck {
-		memAttribs.TFAWMinPs = tFAWFromTck
-	}
-}
-
-func updateTRFC1Min(memAttribs *memAttributes) {
-	if memAttribs.TRFC1MinPs == 0 {
-		memAttribs.TRFC1MinPs = tRFC1Encoding[memAttribs.CapacityPerDieGb]
-	}
-}
-
-func updateTRFC2Min(memAttribs *memAttributes) {
-	if memAttribs.TRFC2MinPs == 0 {
-		memAttribs.TRFC2MinPs = tRFC2Encoding[memAttribs.CapacityPerDieGb]
-	}
-}
-
-func updateTRFC4Min(memAttribs *memAttributes) {
-	if memAttribs.TRFC4MinPs == 0 {
-		memAttribs.TRFC4MinPs = tRFC4Encoding[memAttribs.CapacityPerDieGb]
-	}
-}
-
-func getTRRDLMinPs(memAttribs *memAttributes) int {
-	var tRRDLFixed int
-
-	/*
-	 * Per JESD79-4C Tables 169 & 170, tRRD_L is based on :
-	 *  Speed bin and page size
-	 */
-	switch pageSizefromBusWidthEncoding[memAttribs.PackageBusWidth] {
-	case 1:
-		switch memAttribs.SpeedMTps {
-		case 1600:
-			tRRDLFixed = 6000
-		default:
-			tRRDLFixed = 5300
-		}
-	case 2:
-		switch memAttribs.SpeedMTps {
-		case 1600:
-			tRRDLFixed = 7500
-		default:
-			tRRDLFixed = 6400
-		}
-	}
-
-	return tRRDLFixed
-}
-
-func updateTRRDLMin(memAttribs *memAttributes) {
-	var tRRDLFromTck int
-
-	if memAttribs.TRRDLMinPs == 0 {
-		memAttribs.TRRDLMinPs = getTRRDLMinPs(memAttribs)
-	}
-
-	tRRDLFromTck = 4 * memAttribs.TCKMinPs
-
-	if memAttribs.TRRDLMinPs < tRRDLFromTck {
-		memAttribs.TRRDLMinPs = tRRDLFromTck
-	}
-}
-
-var speedToTRRDSMinPsOneKPageSize = map[int]int{
-	1600: 5000,
-	1866: 4200,
-	2133: 3700,
-	2400: 3300,
-	2666: 3000,
-	2933: 2700,
-	3200: 2500,
-}
-
-var speedToTRRDSMinPsTwoKPageSize = map[int]int{
-	1600: 6000,
-	1866: 5300,
-	2133: 5300,
-	2400: 5300,
-	2666: 5300,
-	2933: 5300,
-	3200: 5300,
-}
-
-func getTRRDSMinPs(memAttribs *memAttributes) int {
-	var tRRDFixed int
-
-	switch pageSizefromBusWidthEncoding[memAttribs.PackageBusWidth] {
-	case 1:
-		tRRDFixed = speedToTRRDSMinPsOneKPageSize[memAttribs.SpeedMTps]
-	case 2:
-		tRRDFixed = speedToTRRDSMinPsTwoKPageSize[memAttribs.SpeedMTps]
-	}
-
-	return tRRDFixed
-}
-
-func updateTRRDSMin(memAttribs *memAttributes) {
-	var tRRDFromTck int
-
-	if memAttribs.TRRDSMinPs == 0 {
-		memAttribs.TRRDSMinPs = getTRRDSMinPs(memAttribs)
-	}
-
-	tRRDFromTck = 4 * memAttribs.TCKMinPs
-
-	if memAttribs.TRRDSMinPs < tRRDFromTck {
-		memAttribs.TRRDSMinPs = tRRDFromTck
-	}
-}
-
-/*
- * Per JESD79-4C Tables 169 and 170,
- * tCCD_L is based on :
- *  Speed Bin
- */
-func getTCCDLMinPs(memAttribs *memAttributes) int {
-	var tCCDLFixed int
-
-	switch memAttribs.SpeedMTps {
-	case 1600:
-		tCCDLFixed = 6250
-	case 1866:
-		tCCDLFixed = 5355
-	case 2133:
-		tCCDLFixed = 5355
-	default:
-		tCCDLFixed = 5000
-	}
-
-	return tCCDLFixed
-}
-
-func updateTCCDLMin(memAttribs *memAttributes) {
-	var tCCDLFromTck int
-
-	if memAttribs.TCCDLMinPs == 0 {
-		memAttribs.TCCDLMinPs = getTCCDLMinPs(memAttribs)
-	}
-
-	tCCDLFromTck = 5 * memAttribs.TCKMinPs
-
-	if memAttribs.TCCDLMinPs < tCCDLFromTck {
-		memAttribs.TCCDLMinPs = tCCDLFromTck
-	}
-}
-
-func encodeTRFC1MinLsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TRFC1MinPs)
-
-	return byte(mtb & 0xff)
-}
-
-func encodeTRFC1MinMsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TRFC1MinPs)
-
-	return byte((mtb >> 8) & 0xff)
-}
-
-func encodeTRFC2MinLsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TRFC2MinPs)
-
-	return byte(mtb & 0xff)
-}
-
-func encodeTRFC2MinMsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TRFC2MinPs)
-
-	return byte((mtb >> 8) & 0xff)
-}
-
-func encodeTRFC4MinLsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TRFC4MinPs)
-
-	return byte(mtb & 0xff)
-}
-
-func encodeTRFC4MinMsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TRFC4MinPs)
-
-	return byte((mtb >> 8) & 0xff)
-}
-
-func encodeTFAWMinMSN(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TFAWMinPs)
-
-	return byte((mtb >> 8) & 0x0f)
-}
-
-func encodeTFAWMinLsb(memAttribs *memAttributes) byte {
-	var mtb int
-
-	mtb = convPsToMtb(memAttribs.TFAWMinPs)
-
-	return byte(mtb & 0xff)
-}
-
-func encodeCASFirstByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASFirstByte
-}
-
-func encodeCASSecondByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASSecondByte
-}
-
-func encodeCASThirdByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASThirdByte
-}
-
-func encodeCASFourthByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASFourthByte
-}
-
-func encodeTRRDSMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TRRDSMinPs)
-}
-
-func encodeTRRDSMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TRRDSMinPs)
-}
-
-func encodeTRRDLMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TRRDLMinPs)
-}
-
-func encodeTRRDLMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TRRDLMinPs)
-}
-
-func encodeTCCDLMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TCCDLMinPs)
-}
-
-func encodeTCCDLMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TCCDLMinPs)
-}
-
-func encodeTWRMinMSN(memAttribs *memAttributes) byte {
-	return byte((convPsToMtb(TimingValueTWRMinPs) >> 8) & 0x0f)
-}
-
-func encodeTWRMinLsb(memAttribs *memAttributes) byte {
-	return byte(convPsToMtb(TimingValueTWRMinPs) & 0xff)
-}
-
-func encodeTWTRMinMSNs(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = byte((convPsToMtb(memAttribs.TWTRLMinPs) >> 4) & 0xf0)
-	b |= byte((convPsToMtb(memAttribs.TWTRSMinPs) >> 8) & 0x0f)
-
-	return b
-}
-
-func encodeTWTRSMinLsb(memAttribs *memAttributes) byte {
-	return byte(convPsToMtb(memAttribs.TWTRSMinPs) & 0xff)
-}
-
-func encodeTWTRLMinLsb(memAttribs *memAttributes) byte {
-	return byte(convPsToMtb(memAttribs.TWTRLMinPs) & 0xff)
-}
-
-type SPDMemAttribFunc func(*memAttributes) byte
-type SPDConvConstFunc func() byte
-
-type SPDAttribTableEntry struct {
-	constVal byte
-	getVal   SPDMemAttribFunc
-}
-
-const (
-	/* SPD Byte Index */
-	SPDIndexSize                            = 0
-	SPDIndexRevision                        = 1
-	SPDIndexMemoryType                      = 2
-	SPDIndexModuleType                      = 3
-	SPDIndexDensityBanks                    = 4
-	SPDIndexAddressing                      = 5
-	SPDIndexPackageType                     = 6
-	SPDIndexOptionalFeatures                = 7
-	SPDIndexModuleOrganization              = 12
-	SPDIndexBusWidth                        = 13
-	SPDIndexTimebases                       = 17
-	SPDIndexTCKMin                          = 18
-	SPDIndexTCKMax                          = 19
-	SPDIndexCASFirstByte                    = 20
-	SPDIndexCASSecondByte                   = 21
-	SPDIndexCASThirdByte                    = 22
-	SPDIndexCASFourthByte                   = 23
-	SPDIndexTAAMin                          = 24
-	SPDIndexTRCDMin                         = 25
-	SPDIndexTRPMin                          = 26
-	SPDIndexTRASRCMinMSNs                   = 27
-	SPDIndexTRASMinLsb                      = 28
-	SPDIndexTRCMinLsb                       = 29
-	SPDIndexTRFC1MinLsb                     = 30
-	SPDIndexTRFC1MinMsb                     = 31
-	SPDIndexTRFC2MinLsb                     = 32
-	SPDIndexTRFC2MinMsb                     = 33
-	SPDIndexTRFC4MinLsb                     = 34
-	SPDIndexTRFC4MinMsb                     = 35
-	SPDIndexTFAWMinMSN                      = 36
-	SPDIndexTFAWMinLsb                      = 37
-	SPDIndexTRRDSMin                        = 38
-	SPDIndexTRRDLMin                        = 39
-	SPDIndexTCCDLMin                        = 40
-	SPDIndexTWRMinMSN                       = 41
-	SPDIndexTWRMinLsb                       = 42
-	SPDIndexTWTRMinMSNs                     = 43
-	SPDIndexWTRSMinLsb                      = 44
-	SPDIndexWTRLMinLsb                      = 45
-	SPDIndexTCCDLMinFineOffset              = 117
-	SPDIndexTRRDLMinFineOffset              = 118
-	SPDIndexTRRDSMinFineOffset              = 119
-	SPDIndexTRCMinFineOffset                = 120
-	SPDIndexTRPMinFineOffset                = 121
-	SPDIndexTRCDMinFineOffset               = 122
-	SPDIndexTAAMinFineOffset                = 123
-	SPDIndexTCKMaxFineOffset                = 124
-	SPDIndexTCKMinFineOffset                = 125
-	SPDIndexManufacturerPartNumberStartByte = 329
-	SPDIndexManufacturerPartNumberEndByte   = 348
-
-	/* SPD Byte Value */
-
-	/*
-	 * From JEDEC spec:
-	 * 6:4 (Bytes total) = 2 (512 bytes)
-	 * 3:0 (Bytes used) = 3 (384 bytes)
-	 * Set to 0x23 for DDR4.
-	 */
-	SPDValueSize = 0x23
-
-	/*
-	 * From JEDEC spec: Revision 1.1
-	 * Set to 0x11.
-	 */
-	SPDValueRevision = 0x11
-
-	/* DDR4 memory type = 0x0C */
-	SPDValueMemoryType = 0x0C
-
-	/*
-		 * From JEDEC spec:
-	 	 * Module Type [0:3] :
-		 *  0 = Undefined
-		 *  1 = RDIMM (width = 133.35 mm nom)
-		 *  2 = UDIMM (width = 133.35 mm nom)
-		 *  3 = SO-DIMM (width = 68.60 mm nom)
-		 *  4 = LRDIMM (width = 133.35 mm nom)
-		 *
-		 * DDR4 on TGL uses SO-DIMM type for for both memory down and DIMM config.
-		 * Set to 0x03.
-	*/
-	SPDValueModuleType = 0x03
-
-	/*
-	 * From JEDEC spec:
-	 * 5:4 (Maximum Activate Window) = 00 (8192 * tREFI)
-	 * 3:0 (Maximum Activate Count) = 1000 (Unlimited MAC)
-	 *
-	 * Needs to come from datasheet, but most parts seem to support unlimited MAC.
-	 * MR#24 OP3
-	 */
-	SPDValueOptionalFeatures = 0x08
-
-	/*
-	 * From JEDEC spec:
-	 * 2:0 Primary Bus Width in Bits = 011 (x64 always)
-	 * Set to 0x03.
-	 */
-	SPDValueModuleBusWidth = 0x03
-
-	/*
-	 * From JEDEC spec:
-	 * 3:2 (MTB) = 00 (0.125ns)
-	 * 1:0 (FTB) = 00 (1ps)
-	 * Set to 0x00.
-	 */
-	SPDValueTimebases = 0x00
-
-	/* CAS fourth byte: All bits are reserved */
-	SPDValueCASFourthByte = 0x00
-
-	/* As per JEDEC spec, unused digits of manufacturer part number are left as blank. */
-	SPDValueManufacturerPartNumberBlank = 0x20
-)
-
-const (
-	/*
-	 * As per Table 75 of Jedec spec 4.1.20-L-5 R29 v103:
-	 * tWRMin = 15nS for all DDR4 Speed Bins
-	 * Set to 15000 pS
-	 */
-	TimingValueTWRMinPs = 15000
-
-	/*
-	 * As per Table 78 of Jedec spec 4.1.20-L-5 R29 v103:
-	 * tWTR_SMin = 2.5nS for all DDR4 Speed Bins
-	 * Set to 2500 pS
-	 */
-	TimingValueTWTRSMinPs = 2500
-
-	/*
-	 * As per Table 80 of Jedec spec 4.1.20-L-5 R29 v103:
-	 * tWTR_LMin = 7.5 nS for all DDR4 Speed Bins
-	 * Set to 7500 pS
-	 */
-	TimingValueTWTRLMinPs = 7500
-)
-
-var SPDAttribTable = map[int]SPDAttribTableEntry{
-	SPDIndexSize:               {constVal: SPDValueSize},
-	SPDIndexRevision:           {constVal: SPDValueRevision},
-	SPDIndexMemoryType:         {constVal: SPDValueMemoryType},
-	SPDIndexModuleType:         {constVal: SPDValueModuleType},
-	SPDIndexDensityBanks:       {getVal: encodeDensityBanks},
-	SPDIndexAddressing:         {getVal: encodeSdramAddressing},
-	SPDIndexPackageType:        {getVal: encodePackageType},
-	SPDIndexOptionalFeatures:   {constVal: SPDValueOptionalFeatures},
-	SPDIndexModuleOrganization: {getVal: encodeModuleOrganization},
-	SPDIndexBusWidth:           {constVal: SPDValueModuleBusWidth},
-	SPDIndexTimebases:          {constVal: SPDValueTimebases},
-	SPDIndexTCKMin:             {getVal: encodeTCKMin},
-	SPDIndexTCKMinFineOffset:   {getVal: encodeTCKMinFineOffset},
-	SPDIndexTCKMax:             {getVal: encodeTCKMax},
-	SPDIndexTCKMaxFineOffset:   {getVal: encodeTCKMaxFineOffset},
-	SPDIndexCASFirstByte:       {getVal: encodeCASFirstByte},
-	SPDIndexCASSecondByte:      {getVal: encodeCASSecondByte},
-	SPDIndexCASThirdByte:       {getVal: encodeCASThirdByte},
-	SPDIndexCASFourthByte:      {getVal: encodeCASFourthByte},
-	SPDIndexTAAMin:             {getVal: encodeTAAMin},
-	SPDIndexTAAMinFineOffset:   {getVal: encodeTAAMinFineOffset},
-	SPDIndexTRCDMin:            {getVal: encodeTRCDMin},
-	SPDIndexTRCDMinFineOffset:  {getVal: encodeTRCDMinFineOffset},
-	SPDIndexTRPMin:             {getVal: encodeTRPMin},
-	SPDIndexTRPMinFineOffset:   {getVal: encodeTRPMinFineOffset},
-	SPDIndexTRASRCMinMSNs:      {getVal: encodeTRASRCMinMSNs},
-	SPDIndexTRASMinLsb:         {getVal: encodeTRASMinLsb},
-	SPDIndexTRCMinLsb:          {getVal: encodeTRCMinLsb},
-	SPDIndexTRCMinFineOffset:   {getVal: encodeTRCMinFineOffset},
-	SPDIndexTRFC1MinLsb:        {getVal: encodeTRFC1MinLsb},
-	SPDIndexTRFC1MinMsb:        {getVal: encodeTRFC1MinMsb},
-	SPDIndexTRFC2MinLsb:        {getVal: encodeTRFC2MinLsb},
-	SPDIndexTRFC2MinMsb:        {getVal: encodeTRFC2MinMsb},
-	SPDIndexTRFC4MinLsb:        {getVal: encodeTRFC4MinLsb},
-	SPDIndexTRFC4MinMsb:        {getVal: encodeTRFC4MinMsb},
-	SPDIndexTFAWMinMSN:         {getVal: encodeTFAWMinMSN},
-	SPDIndexTFAWMinLsb:         {getVal: encodeTFAWMinLsb},
-	SPDIndexTRRDSMin:           {getVal: encodeTRRDSMin},
-	SPDIndexTRRDSMinFineOffset: {getVal: encodeTRRDSMinFineOffset},
-	SPDIndexTRRDLMin:           {getVal: encodeTRRDLMin},
-	SPDIndexTRRDLMinFineOffset: {getVal: encodeTRRDLMinFineOffset},
-	SPDIndexTCCDLMin:           {getVal: encodeTCCDLMin},
-	SPDIndexTCCDLMinFineOffset: {getVal: encodeTCCDLMinFineOffset},
-	SPDIndexTWRMinMSN:          {getVal: encodeTWRMinMSN},
-	SPDIndexTWRMinLsb:          {getVal: encodeTWRMinLsb},
-	SPDIndexTWTRMinMSNs:        {getVal: encodeTWTRMinMSNs},
-	SPDIndexWTRSMinLsb:         {getVal: encodeTWTRSMinLsb},
-	SPDIndexWTRLMinLsb:         {getVal: encodeTWTRLMinLsb},
-}
-
-type memParts struct {
-	MemParts []memPart `json:"parts"`
-}
-
-type memPart struct {
-	Name        string
-	Attribs     memAttributes
-	SPDFileName string
-}
-
-func writeSPDManifest(memParts *memParts, SPDDirName string) error {
-	var s string
-
-	fmt.Printf("Generating SPD Manifest with following entries:\n")
-
-	for i := 0; i < len(memParts.MemParts); i++ {
-		fmt.Printf("%-40s %s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName)
-		s += fmt.Sprintf("%s,%s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName)
-	}
-
-	return ioutil.WriteFile(filepath.Join(SPDDirName, SPDManifestFileName), []byte(s), 0644)
-}
-
-func isManufacturerPartNumberByte(index int) bool {
-	if index >= SPDIndexManufacturerPartNumberStartByte && index <= SPDIndexManufacturerPartNumberEndByte {
-		return true
-	}
-	return false
-}
-
-func getSPDByte(index int, memAttribs *memAttributes) byte {
-	e, ok := SPDAttribTable[index]
-	if ok == false {
-		if isManufacturerPartNumberByte(index) {
-			return SPDValueManufacturerPartNumberBlank
-		}
-		return 0x00
-	}
-
-	if e.getVal != nil {
-		return e.getVal(memAttribs)
-	}
-
-	return e.constVal
-}
-
-func createSPD(memAttribs *memAttributes) string {
-	var s string
-
-	for i := 0; i < 512; i++ {
-		var b byte = 0
-		if memAttribs != nil {
-			b = getSPDByte(i, memAttribs)
-		}
-
-		if (i+1)%16 == 0 {
-			s += fmt.Sprintf("%02X\n", b)
-		} else {
-			s += fmt.Sprintf("%02X ", b)
-		}
-	}
-
-	return s
-}
-
-func dedupeMemoryPart(dedupedParts []*memPart, memPart *memPart) bool {
-	for i := 0; i < len(dedupedParts); i++ {
-		if reflect.DeepEqual(dedupedParts[i].Attribs, memPart.Attribs) {
-			memPart.SPDFileName = dedupedParts[i].SPDFileName
-			return true
-		}
-	}
-
-	return false
-}
-
-func generateSPD(memPart *memPart, SPDId int, SPDDirName string) {
-	s := createSPD(&memPart.Attribs)
-	memPart.SPDFileName = fmt.Sprintf("ddr4-spd-%d.hex", SPDId)
-	ioutil.WriteFile(filepath.Join(SPDDirName, memPart.SPDFileName), []byte(s), 0644)
-}
-
-func generateEmptySPD(SPDDirName string) {
-
-	s := createSPD(nil)
-	SPDFileName := "ddr4-spd-empty.hex"
-	ioutil.WriteFile(filepath.Join(SPDDirName, SPDFileName), []byte(s), 0644)
-}
-
-func readMemoryParts(memParts *memParts, memPartsFileName string) error {
-	databytes, err := ioutil.ReadFile(memPartsFileName)
-	if err != nil {
-		return err
-	}
-
-	// Strip comments from json file
-	re := regexp.MustCompile(`(?m)^\s*//.*`)
-	databytes = re.ReplaceAll(databytes, []byte(""))
-
-	return json.Unmarshal(databytes, memParts)
-}
-
-func validateSpeedMTps(speedBin int) error {
-	if _, ok := speedBinToSPDEncoding[speedBin]; ok == false {
-		return fmt.Errorf("Incorrect speed bin: DDR4-", speedBin)
-	}
-	return nil
-}
-
-func validateCapacityPerDie(capacityPerDieGb int) error {
-	if _, ok := densityGbToSPDEncoding[capacityPerDieGb]; ok == false {
-		return fmt.Errorf("Incorrect capacity per die: ", capacityPerDieGb)
-	}
-	return nil
-}
-
-func validateDiesPerPackage(dieCount int) error {
-	if dieCount >= 1 && dieCount <= 2 {
-		return nil
-	}
-	return fmt.Errorf("Incorrect dies per package count: ", dieCount)
-}
-
-func validatePackageBusWidth(width int) error {
-	if width != 8 && width != 16 {
-		return fmt.Errorf("Incorrect device bus width: ", width)
-	}
-	return nil
-}
-
-func validateRanksPerPackage(ranks int) error {
-	if ranks >= 1 && ranks <= 2 {
-		return nil
-	}
-	return fmt.Errorf("Incorrect package ranks: ", ranks)
-}
-
-func validateCASLatency(CL int) error {
-	if CL >= 10 && CL <= 24 && CL != 23 {
-		return nil
-	}
-	return fmt.Errorf("Incorrect CAS latency: ", CL)
-}
-
-/*
-1) validate memory parts
-2) remove any fields that Intel does not care about
-*/
-
-/* verify the supplied CAS Latencies supported does not match default */
-func verifySupportedCASLatencies(part *memPart) error {
-	if part.Attribs.CASLatencies == getDefaultCASLatencies(&part.Attribs) {
-		return fmt.Errorf("CASLatencies for %s already matches default,\nPlease remove CASLatencies override line from the %s part attributes in the global part list and regenerate SPD Manifest", part.Name, part.Name)
-	}
-
-	return nil
-}
-
-func validateMemoryParts(memParts *memParts) error {
-	memPartExists := make(map[string]bool)
-
-	for i := 0; i < len(memParts.MemParts); i++ {
-		if memPartExists[memParts.MemParts[i].Name] {
-			return fmt.Errorf(memParts.MemParts[i].Name + " is duplicated in mem_parts_list_json")
-		}
-		memPartExists[memParts.MemParts[i].Name] = true
-
-		if err := validateSpeedMTps(memParts.MemParts[i].Attribs.SpeedMTps); err != nil {
-			return err
-		}
-		if err := validateCapacityPerDie(memParts.MemParts[i].Attribs.CapacityPerDieGb); err != nil {
-			return err
-		}
-		if err := validateDiesPerPackage(memParts.MemParts[i].Attribs.DiesPerPackage); err != nil {
-			return err
-		}
-		if err := validatePackageBusWidth(memParts.MemParts[i].Attribs.PackageBusWidth); err != nil {
-			return err
-		}
-		if err := validateRanksPerPackage(memParts.MemParts[i].Attribs.RanksPerPackage); err != nil {
-			return err
-		}
-		if err := validateCASLatency(memParts.MemParts[i].Attribs.CL_nRCD_nRP); err != nil {
-			return err
-		}
-		/* If CAS Latency was supplied, make sure it doesn't match default value */
-		if len(memParts.MemParts[i].Attribs.CASLatencies) != 0 {
-			if err := verifySupportedCASLatencies(&memParts.MemParts[i]); err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
-
-const (
-	/* First Byte */
-	CAS9  = 1 << 2
-	CAS10 = 1 << 3
-	CAS11 = 1 << 4
-	CAS12 = 1 << 5
-	CAS13 = 1 << 6
-	CAS14 = 1 << 7
-	/* Second Byte */
-	CAS15 = 1 << 0
-	CAS16 = 1 << 1
-	CAS17 = 1 << 2
-	CAS18 = 1 << 3
-	CAS19 = 1 << 4
-	CAS20 = 1 << 5
-	CAS21 = 1 << 6
-	CAS22 = 1 << 7
-	/* Third Byte */
-	CAS24 = 1 << 1
-)
-
-func encodeLatencies(latency int, memAttribs *memAttributes) error {
-	switch latency {
-	case 9:
-		memAttribs.CASFirstByte |= CAS9
-	case 10:
-		memAttribs.CASFirstByte |= CAS10
-	case 11:
-		memAttribs.CASFirstByte |= CAS11
-	case 12:
-		memAttribs.CASFirstByte |= CAS12
-	case 13:
-		memAttribs.CASFirstByte |= CAS13
-	case 14:
-		memAttribs.CASFirstByte |= CAS14
-	case 15:
-		memAttribs.CASSecondByte |= CAS15
-	case 16:
-		memAttribs.CASSecondByte |= CAS16
-	case 17:
-		memAttribs.CASSecondByte |= CAS17
-	case 18:
-		memAttribs.CASSecondByte |= CAS18
-	case 19:
-		memAttribs.CASSecondByte |= CAS19
-	case 20:
-		memAttribs.CASSecondByte |= CAS20
-	case 21:
-		memAttribs.CASSecondByte |= CAS21
-	case 22:
-		memAttribs.CASSecondByte |= CAS22
-	case 24:
-		memAttribs.CASThirdByte |= CAS24
-	default:
-		fmt.Errorf("Incorrect CAS Latency: ", latency)
-	}
-
-	return nil
-}
-
-/* Default CAS Latencies from Speed Bin tables in JEDS79-4C */
-func getDefaultCASLatencies(memAttribs *memAttributes) string {
-	var str string
-
-	switch memAttribs.SpeedMTps {
-	case 1600:
-		switch memAttribs.CL_nRCD_nRP {
-		case 10:
-			str = "9 10 11 12"
-		case 11:
-			str = "9 11 12"
-		case 12:
-			str = "10 12"
-		}
-	case 1866:
-		switch memAttribs.CL_nRCD_nRP {
-		case 12:
-			str = "9 10 12 13 14"
-		case 13:
-			str = "9 11 12 13 14"
-		case 14:
-			str = "10 12 14"
-		}
-	case 2133:
-		switch memAttribs.CL_nRCD_nRP {
-		case 14:
-			str = "9 10 12 14 15 16"
-		case 15:
-			str = "9 11 12 13 14 15 16"
-		case 16:
-			str = "10 12 14 16"
-		}
-	case 2400:
-		switch memAttribs.CL_nRCD_nRP {
-		case 15:
-			str = "9 10 12 14 15 16 17 18"
-		case 16:
-			str = "9 11 12 13 14 15 16 17 18"
-		case 17:
-			str = "10 11 12 13 14 15 16 17 18"
-		case 18:
-			str = "10 12 14 16 18"
-		}
-	case 2666:
-		switch memAttribs.CL_nRCD_nRP {
-		case 17:
-			str = "9 10 11 12 13 14 15 16 17 18 19 20"
-		case 18:
-			str = "9 10 11 12 13 14 15 16 17 18 19 20"
-		case 19:
-			str = "10 11 12 13 14 15 16 17 18 19 20"
-		case 20:
-			str = "10 12 14 16 18 20"
-		}
-	case 2933:
-		switch memAttribs.CL_nRCD_nRP {
-		case 19:
-			str = "9 10 11 12 13 14 15 16 17 18 19 20 21 22"
-		case 20:
-			str = "10 11 12 13 14 15 16 17 18 19 20 21 22"
-		case 21:
-			str = "10 11 12 13 14 15 16 17 18 19 20 21 22"
-		case 22:
-			str = "10 12 14 16 18 20 22"
-		}
-	case 3200:
-		switch memAttribs.CL_nRCD_nRP {
-		case 20:
-			str = "9 10 11 12 13 14 15 16 17 18 19 20 21 22 24"
-		case 22:
-			str = "10 11 12 13 14 15 16 17 18 19 20 21 22 24"
-		case 24:
-			str = "10 12 14 16 18 20 22 24"
-		}
-	}
-
-	return str
-}
-
-func updateDieBusWidth(memAttribs *memAttributes) {
-	if memAttribs.PackageBusWidth == 16 && memAttribs.RanksPerPackage == 1 &&
-		memAttribs.DiesPerPackage == 2 {
-		/*
-		 * If a x16 part has 2 die with single rank, PackageBusWidth
-		 * needs to be converted to match die bus width.
-		 */
-		memAttribs.dieBusWidth = 8
-	} else {
-		memAttribs.dieBusWidth = memAttribs.PackageBusWidth
-	}
-}
-
-func updateCAS(memAttribs *memAttributes) error {
-	if len(memAttribs.CASLatencies) == 0 {
-		memAttribs.CASLatencies = getDefaultCASLatencies(memAttribs)
-	}
-
-	latencies := strings.Fields(memAttribs.CASLatencies)
-	for i := 0; i < len(latencies); i++ {
-		latency, err := strconv.Atoi(latencies[i])
-		if err != nil {
-			return fmt.Errorf("Unable to convert latency ", latencies[i])
-		}
-		if err := encodeLatencies(latency, memAttribs); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func getTAAMinPs(memAttribs *memAttributes) int {
-	return (memAttribs.CL_nRCD_nRP * 2000000) / memAttribs.SpeedMTps
-}
-
-func updateTAAMin(memAttribs *memAttributes) {
-	if memAttribs.TAAMinPs == 0 {
-		memAttribs.TAAMinPs = getTAAMinPs(memAttribs)
-	}
-}
-
-func updateTRCDMin(memAttribs *memAttributes) {
-	/* tRCDmin is same as tAAmin for all cases */
-	if memAttribs.TRCDMinPs == 0 {
-		memAttribs.TRCDMinPs = getTAAMinPs(memAttribs)
-	}
-}
-
-func updateTRPMin(memAttribs *memAttributes) {
-	/* tRPmin is same as tAAmin for all cases */
-	if memAttribs.TRPMinPs == 0 {
-		memAttribs.TRPMinPs = getTAAMinPs(memAttribs)
-	}
-}
-
-func updateTRASMin(memAttribs *memAttributes) {
-	if memAttribs.TRASMinPs == 0 {
-		memAttribs.TRASMinPs = speedBinToSPDEncoding[memAttribs.SpeedMTps].TRASMinPs
-	}
-}
-
-func updateTRCMin(memAttribs *memAttributes) {
-	if memAttribs.TRCMinPs == 0 {
-		memAttribs.TRCMinPs = getTRCMinPs(memAttribs)
-	}
-}
-
-func updateTCK(memAttribs *memAttributes) {
-	if memAttribs.TCKMinPs == 0 {
-		memAttribs.TCKMinPs = getDefaultTCKMinPs(memAttribs)
-	}
-	if memAttribs.TCKMaxPs == 0 {
-		memAttribs.TCKMaxPs = speedBinToSPDEncoding[memAttribs.SpeedMTps].TCKMaxPs
-	}
-}
-
-func updateTWRMin(memAttribs *memAttributes) {
-	if memAttribs.TWRMinPs == 0 {
-		memAttribs.TWRMinPs = TimingValueTWRMinPs
-	}
-}
-
-func updateTWTRMin(memAttribs *memAttributes) {
-	if memAttribs.TWTRLMinPs == 0 {
-		memAttribs.TWTRLMinPs = TimingValueTWTRLMinPs
-	}
-	if memAttribs.TWTRSMinPs == 0 {
-		memAttribs.TWTRSMinPs = TimingValueTWTRSMinPs
-	}
-}
-
-func updateMemoryAttributes(memAttribs *memAttributes) {
-	updateDieBusWidth(memAttribs)
-	updateTCK(memAttribs)
-	updateTAAMin(memAttribs)
-	updateTRCDMin(memAttribs)
-	updateTRPMin(memAttribs)
-	updateTRASMin(memAttribs)
-	updateTRCMin(memAttribs)
-	updateTWRMin(memAttribs)
-	updateTWTRMin(memAttribs)
-	updateCAS(memAttribs)
-	updateTRFC1Min(memAttribs)
-	updateTRFC2Min(memAttribs)
-	updateTRFC4Min(memAttribs)
-	updateTCCDLMin(memAttribs)
-	updateTRRDSMin(memAttribs)
-	updateTRRDLMin(memAttribs)
-	updateTFAWMin(memAttribs)
-}
-
-func isPlatformSupported(platform string) error {
-	var ok bool
-
-	currPlatform, ok = platformMap[platform]
-	if ok == false {
-		return fmt.Errorf("Unsupported platform: ", platform)
-	}
-
-	return nil
-}
-
-func usage() {
-	fmt.Printf("\nUsage: %s <spd_dir> <mem_parts_list_json> <platform>\n\n", os.Args[0])
-	fmt.Printf("   where,\n")
-	fmt.Printf("   spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n")
-	fmt.Printf("   mem_parts_list_json = JSON File containing list of memory parts and attributes\n")
-	fmt.Printf("   platform = SoC Platform for which the SPDs are being generated\n\n\n")
-}
-
-func main() {
-	if len(os.Args) != 4 {
-		usage()
-		log.Fatal("Incorrect number of arguments")
-	}
-
-	var memParts memParts
-	var dedupedParts []*memPart
-
-	SPDDir, GlobalMemPartsFile, Platform := os.Args[1], os.Args[2], strings.ToUpper(os.Args[3])
-
-	if err := isPlatformSupported(Platform); err != nil {
-		log.Fatal(err)
-	}
-
-	if err := readMemoryParts(&memParts, GlobalMemPartsFile); err != nil {
-		log.Fatal(err)
-	}
-
-	if err := validateMemoryParts(&memParts); err != nil {
-		log.Fatal(err)
-	}
-
-	SPDId := 1
-
-	for i := 0; i < len(memParts.MemParts); i++ {
-		updateMemoryAttributes(&memParts.MemParts[i].Attribs)
-		if dedupeMemoryPart(dedupedParts, &memParts.MemParts[i]) == false {
-			generateSPD(&memParts.MemParts[i], SPDId, SPDDir)
-			SPDId++
-			dedupedParts = append(dedupedParts, &memParts.MemParts[i])
-		}
-	}
-
-	generateEmptySPD(SPDDir)
-
-	if err := writeSPDManifest(&memParts, SPDDir); err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/util/spd_tools/ddr4/global_ddr4_mem_parts.json.txt b/util/spd_tools/ddr4/global_ddr4_mem_parts.json.txt
deleted file mode 100644
index 66be6a9..0000000
--- a/util/spd_tools/ddr4/global_ddr4_mem_parts.json.txt
+++ /dev/null
@@ -1,254 +0,0 @@
-// Global list of ddr4 memory part attributes.
-// These attributes match the part specifications and are independent
-// of any SoC expectations.
-{
-    "parts": [
-        {
-            "name": "H5AN8G6NDJR-XNC",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            "name": "MT40A512M16TB-062E:J",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            "name": "H5ANAG6NCMR-XNC",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 2,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.1 / Sep.2017
-            "name": "HMA851S6CJR6N-VK",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 19,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.5, Apr. 2017
-            "name": "K4A8G165WC-BCTD",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 19,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.3 / Jun.2018
-            "name": "H5AN8G6NCJR-VKC",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 19,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision:  Rev. F 10/17 EN
-            "name": "MT40A1G16KNR-075:E",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 18,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 2,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.4, Jul. 2017
-            "name": "K4AAG165WB-MCTD",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 19,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 8,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.0 / Aug.2018
-            "name": "H5ANAG6NCMR-VKC",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 19,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 2,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 0.5, Jun. 2019
-            "name": "K4A8G165WC-BCWE",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. G 08/2020 EN
-            "name": "MT40A1G16KD-062E:E",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 16,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1,
-                // Table 158 - Refersh Timing - 16Gb
-                "TRFC1MinPs": 350000,
-                "TRFC2MinPs": 260000,
-                "TRFC4MinPs": 160000
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 0.5, Feb. 2019
-            "name": "K4AAG165WA-BCWE",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 16,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1,
-                // Table 57 - 16Gb
-                "TRFC1MinPs": 350000,
-                "TRFC2MinPs": 260000,
-                "TRFC4MinPs": 160000
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.5 / Mar.2019
-            "name": "H5AN8G6NCJR-XNC",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.0, Dec. 2019
-            "name": "K4AAG165WA-BCTD",
-            "attribs": {
-                "speedMTps": 2666,
-                "CL_nRCD_nRP": 19,
-                "capacityPerDieGb": 16,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1,
-                // Table 41 - Note: Both 550ns and 350ns tRFC1 is supported
-                "TRFC1MinPs": 350000,
-                "TRFC2MinPs": 260000,
-                "TRFC4MinPs": 160000
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.0, Feb. 2020
-            "name": "H5ANAG6NDMR-XNC",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 2,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 1.4, May. 2020
-            "name": "H5ANAG6NCJR-XNC",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 16,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. 0.0, Apr. 2020
-            "name": "K4AAG165WB-BCWE",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 16,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            // Datasheet Revision: Rev. A 03/2021 EN
-            "name": "MT40A1G16RC-062E:B",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 16,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            "name": "MT40A512M16TB-062E:R",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        },
-        {
-            "name": "4JQA-0622AD",
-            "attribs": {
-                "speedMTps": 3200,
-                "CL_nRCD_nRP": 22,
-                "capacityPerDieGb": 8,
-                "diesPerPackage": 1,
-                "packageBusWidth": 16,
-                "ranksPerPackage": 1
-            }
-        }
-    ]
-}
diff --git a/util/spd_tools/description.md b/util/spd_tools/description.md
deleted file mode 100644
index aa12781..0000000
--- a/util/spd_tools/description.md
+++ /dev/null
@@ -1,11 +0,0 @@
-Tools for generating SPD files for DDR4 memory used in platforms with
-memory down configuration.
-
-
-
-* _gen_spd.go_ - Generates de-duplicated SPD files using a
-                 global memory part list provided by the
-                 mainboard in JSON format. `Go`
-
-* _gen_part_id.go_ - Allocates DRAM strap IDs for different
-                     DDR4 memory parts used by the board. `Go`
diff --git a/util/spd_tools/lp4x/README.md b/util/spd_tools/lp4x/README.md
deleted file mode 100644
index d74ed6b..0000000
--- a/util/spd_tools/lp4x/README.md
+++ /dev/null
@@ -1,266 +0,0 @@
-# LPDDR4x SPD tools README
-
-Tools for generating SPD files for LPDDR4x memory used in memory down
-configurations on Intel Tiger Lake (TGL), Jasper Lake (JSL), and Alder
-Lake (ADL) based platforms. These tools generate SPDs following
-JESD209-4C specification and Intel recommendations (doc #616599,
-#610202, #634730) for LPDDR4x SPD.
-
-There are two tools provided that assist TGL, JSL and ADL 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.
-
-## Tool 1 - gen_spd.go
-
-This program takes as input:
-* Pointer to directory where the generated SPD files and manifest will
-  be placed.
-* JSON file containing a global list of memory parts with their
-  attributes as per the datasheet. This is the list of all known
-  LPDDR4x memory parts irrespective of their usage on the board.
-* SoC platform name for which the SPDs are being generated. Currently
-  supported platform names are `TGL`, `JSL` and `ADL`.
-
-Input JSON file requires the following two fields for every memory part:
-* `name`: Name of the memory part
-* `attribs`: 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:
-* Mandatory: These attributes have to be provided for a memory part.
-* Optional: These attributes can be provided by memory part if it wants
-  to override the defaults.
-
-### Mandatory `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.
-
-### Optional `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:
-    * 6Gb : 280ns
-    * 8Gb : 280ns
-    * 12Gb: 380ns
-    * 16Gb: 380ns
-
-* `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:
-    * 6Gb : 140ns
-    * 8Gb : 140ns
-    * 12Gb: 190ns
-    * 16Gb: 190ns
-
-* `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):
-    * 4267 Mbps: 468ps
-    * 3733 Mbps: 535ps
-    * 3200 Mbps: 625ps
-
-* `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:
-    * 4267: `"6 10 14 20 24 28 32 36"`.
-    * 3733: `"6 10 14 20 24 28 32"`.
-    * 3200: `"6 10 14 20 24 28"`.
-
-### Example JSON file
-```
-{
-    "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"
-            }
-        }
-    ]
-}
-```
-
-### Output
-
-This tool generates the following files using the global list of
-memory parts in JSON format as described above:
-  * De-duplicated SPDs required for the different memory parts. These
-    SPD files are named (spd_1.hex, spd_2.hex, spd_3.hex and so on)
-    and placed in the directory provided as an input to the tool.
-  * CSV file representing which of the deduplicated SPD files is used
-    by which memory part. This file is named as
-    `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
-    ```
-
-## Tool 2 - gen_part_id.go
-
-This program takes as input:
-* Pointer to directory where the SPD files and the manifest file
-  `spd_manifest.generated.txt` (in CSV format) are placed by
-  gen_spd.go
-* File containing list of memory parts used by the board. Each line of
-  the file is supposed to contain one memory part `name` as present in
-  the global list of memory parts provided to gen_spd.go
-* Pointer to directory where the generated Makefile.inc should be
-  placed by the tool.
-
-### Output
-
-This program provides the following:
-
-* Prints out the list of DRAM hardware strap IDs that should be
-  allocated to each memory part listed in the input file.
-* Makefile.inc is generated in the provided directory to integrate
-  SPDs generated by gen_spd.go with the coreboot build for the board.
-* dram_id.generated.txt is generated in the same directory as
-  Makefile. This contains the part IDs assigned to the different
-  memory parts. (Useful to integrate in board schematics).
-
-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
-```
-
-### Note of caution
-
-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.
-
-## How to build the tools?
-```
-# go build gen_spd.go
-# go build gen_part_id.go
-```
-
-## How to use the tools?
-```
-# ./gen_spd <spd_dir> <mem_parts_list_json> <platform>
-# ./gen_part_id <spd_dir> <makefile_dir> <mem_parts_used_file>
-```
-
-### Need to add a new memory part for a board?
-
-* If the memory part is not present in the global list of memory
-  parts, then add the memory part name and attributes as per the
-  datasheet to the file containing the global list.
-  * Use `gen_spd.go` with input as the file containing the global list
-    of memory parts to generate de-duplicated SPDs.
-  * If a new SPD file is generated, use `git add` to add it to the
-    tree and push a CL for review.
-* Update the file containing memory parts used by board (variant) to
-  add the new memory part name at the end of the file.
-  * Use gen_part_id.go providing it pointer to the location where SPD
-    files are stored and file containing the list of memory parts used
-    by the board(variant).
-  * Use `git add` to add `Makefile.inc` and `dram_id.generated.txt`
-    with updated changes and push a CL for review.
diff --git a/util/spd_tools/lp4x/gen_part_id.go b/util/spd_tools/lp4x/gen_part_id.go
deleted file mode 100644
index 71ef3ec..0000000
--- a/util/spd_tools/lp4x/gen_part_id.go
+++ /dev/null
@@ -1,214 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-package main
-
-import (
-	"encoding/csv"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"path/filepath"
-	"strings"
-)
-
-/*
- * This program allocates DRAM strap IDs for different parts that are being used by the variant.
- *
- * It expects the following inputs:
- *  Pointer to SPD directory. This is the location where SPD files and SPD Manifest generated by
- *  gen_spd.go are placed.
- *  Pointer to Makefile directory. Makefile.inc generated by this program is placed in this
- *  location.
- *  Text file containing a list of memory parts names used by the board. Each line in the file
- *  is expected to have one memory part name.
- */
-const (
-	SPDManifestFileName = "lp4x_spd_manifest.generated.txt"
-	MakefileName        = "Makefile.inc"
-	DRAMIdFileName      = "dram_id.generated.txt"
-)
-
-func usage() {
-	fmt.Printf("\nUsage: %s <spd_dir> <makefile_dir> <mem_parts_used_file>\n\n", os.Args[0])
-	fmt.Printf("   where,\n")
-	fmt.Printf("   spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n")
-	fmt.Printf("   makefile_dir = Directory path where generated Makefile.inc should be placed\n")
-	fmt.Printf("   mem_parts_used_file = File containing list of memory parts used by the board\n\n\n")
-}
-
-func checkArgs() error {
-
-	for _, arg := range os.Args[1:] {
-		if _, err := os.Stat(arg); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-/*
- * Read input file that contains list of memory part names used by the variant (one on a line)
- * and split into separate strings for each part name.
- */
-func readParts(memPartsUsedFileName string) ([]string, error) {
-	lines, err := ioutil.ReadFile(memPartsUsedFileName)
-	if err != nil {
-		return nil, err
-	}
-	str := string(lines)
-	parts := strings.Split(str, "\n")
-
-	return parts, nil
-}
-
-/*
- * Read SPD manifest file(CSV) generated by gen_spd program and generate two maps:
- * 1. Part to SPD Map : This maps global memory part name to generated SPD file name
- * 2. SPD to Index Map: This generates a map of deduplicated SPD file names to index assigned to
- *                      that SPD. This function sets index for all SPDs to -1. This index gets
- *                      updated as part of genPartIdInfo() depending upon the SPDs actually used
- *                      by the variant.
- */
-func readSPDManifest(SPDDirName string) (map[string]string, map[string]int, error) {
-	f, err := os.Open(filepath.Join(SPDDirName, SPDManifestFileName))
-	if err != nil {
-		return nil, nil, err
-	}
-	defer f.Close()
-	r := csv.NewReader(f)
-
-	partToSPDMap := make(map[string]string)
-	SPDToIndexMap := make(map[string]int)
-
-	for {
-		fields, err := r.Read()
-
-		if err == io.EOF {
-			break
-		}
-
-		if err != nil {
-			return nil, nil, err
-		}
-
-		if len(fields) != 2 {
-			return nil, nil, fmt.Errorf("CSV file is incorrectly formatted")
-		}
-
-		partToSPDMap[fields[0]] = fields[1]
-		SPDToIndexMap[fields[1]] = -1
-	}
-
-	return partToSPDMap, SPDToIndexMap, nil
-}
-
-/* Print information about memory part used by variant and ID assigned to it. */
-func appendPartIdInfo(s *string, partName string, index int) {
-	*s += fmt.Sprintf("%-30s %d (%04b)\n", partName, index, int64(index))
-}
-
-type partIds struct {
-	SPDFileName string
-	memParts    string
-}
-
-/*
- * For each part used by variant, check if the SPD (as per the manifest) already has an ID
- * assigned to it. If yes, then add the part name to the list of memory parts supported by the
- * SPD entry. If not, then assign the next ID to the SPD file and add the part name to the
- * list of memory parts supported by the SPD entry.
- *
- * Returns list of partIds that contains spdFileName and supported memory parts for each
- * assigned ID.
- */
-func genPartIdInfo(parts []string, partToSPDMap map[string]string, SPDToIndexMap map[string]int, makefileDirName string) ([]partIds, error) {
-	partIdList := []partIds{}
-	curId := 0
-	var s string
-
-	s += fmt.Sprintf("%-30s %s\n", "DRAM Part Name", "ID to assign")
-
-	for _, p := range parts {
-		if p == "" {
-			continue
-		}
-
-		SPDFileName, ok := partToSPDMap[p]
-		if !ok {
-			return nil, fmt.Errorf("Failed to find part ", p, " in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest")
-		}
-
-		index := SPDToIndexMap[SPDFileName]
-		if index != -1 {
-			partIdList[index].memParts += ", " + p
-			appendPartIdInfo(&s, p, index)
-			continue
-		}
-
-		SPDToIndexMap[SPDFileName] = curId
-
-		appendPartIdInfo(&s, p, curId)
-		entry := partIds{SPDFileName: SPDFileName, memParts: p}
-		partIdList = append(partIdList, entry)
-
-		curId++
-	}
-
-	fmt.Printf("%s", s)
-	err := ioutil.WriteFile(filepath.Join(makefileDirName, DRAMIdFileName), []byte(s), 0644)
-
-	return partIdList, err
-}
-
-var generatedCodeLicense string = "## SPDX-License-Identifier: GPL-2.0-or-later"
-var autoGeneratedInfo string = "## This is an auto-generated file. Do not edit!!"
-
-/*
- * This function generates Makefile.inc under the variant directory path and adds assigned SPDs
- * to SPD_SOURCES.
- */
-func genMakefile(partIdList []partIds, makefileDirName string) error {
-	var s string
-
-	s += fmt.Sprintf("%s\n%s\n\n", generatedCodeLicense, autoGeneratedInfo)
-	s += fmt.Sprintf("SPD_SOURCES =\n")
-
-	for i := 0; i < len(partIdList); i++ {
-		s += fmt.Sprintf("SPD_SOURCES += %s ", partIdList[i].SPDFileName)
-		s += fmt.Sprintf("     # ID = %d(0b%04b) ", i, int64(i))
-		s += fmt.Sprintf(" Parts = %04s\n", partIdList[i].memParts)
-	}
-
-	return ioutil.WriteFile(filepath.Join(makefileDirName, MakefileName), []byte(s), 0644)
-}
-
-func main() {
-	if len(os.Args) != 4 {
-		usage()
-		log.Fatal("Incorrect number of arguments")
-	}
-
-	SPDDir, MakefileDir, MemPartsUsedFile := os.Args[1], os.Args[2], os.Args[3]
-
-	partToSPDMap, SPDToIndexMap, err := readSPDManifest(SPDDir)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	parts, err := readParts(MemPartsUsedFile)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	partIdList, err := genPartIdInfo(parts, partToSPDMap, SPDToIndexMap, MakefileDir)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	if err := genMakefile(partIdList, MakefileDir); err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/util/spd_tools/lp4x/gen_spd.go b/util/spd_tools/lp4x/gen_spd.go
deleted file mode 100644
index aeb5e19..0000000
--- a/util/spd_tools/lp4x/gen_spd.go
+++ /dev/null
@@ -1,996 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os"
-	"path/filepath"
-	"reflect"
-	"strconv"
-	"strings"
-)
-
-/*
- * This program generates de-duplicated SPD files for LPDDR4x memory using the global memory
- * part list provided in CSV format. In addition to that, it also generates SPD manifest in CSV
- * format that contains entries of type (DRAM part name, SPD file name) which provides the SPD
- * file name used by a given DRAM part.
- *
- * It takes as input:
- * Pointer to directory where the generated SPD files will be placed.
- * JSON file containing a list of memory parts with their attributes as per datasheet.
- */
-const (
-	SPDManifestFileName = "lp4x_spd_manifest.generated.txt"
-
-	PlatformTGLADL = 0
-	PlatformJSL    = 1
-	PlatformCZN    = 2
-)
-
-var platformMap = map[string]int{
-	"TGL": PlatformTGLADL,
-	"JSL": PlatformJSL,
-	"ADL": PlatformTGLADL,
-	"CZN": PlatformCZN,
-}
-
-var currPlatform int
-
-type memAttributes struct {
-	/* Primary attributes - must be provided by JSON file for each part */
-	DensityPerChannelGb int
-	Banks               int
-	ChannelsPerDie      int
-	DiesPerPackage      int
-	BitWidthPerChannel  int
-	RanksPerChannel     int
-	SpeedMbps           int
-
-	/*
-	 * All the following parameters are optional and required only if the part requires
-	 * special parameters as per the datasheet.
-	 */
-	/* Timing parameters */
-	TRFCABNs   int
-	TRFCPBNs   int
-	TRPABMinNs int
-	TRPPBMinNs int
-	TCKMinPs   int
-	TCKMaxPs   int
-	TAAMinPs   int
-	TRCDMinNs  int
-
-	/* CAS */
-	CASLatencies  string
-	CASFirstByte  byte
-	CASSecondByte byte
-	CASThirdByte  byte
-}
-
-/* This encodes the density in Gb to SPD values as per JESD 21-C */
-var densityGbToSPDEncoding = map[int]byte{
-	4:  0x4,
-	6:  0xb,
-	8:  0x5,
-	12: 0x8,
-	16: 0x6,
-	24: 0x9,
-	32: 0x7,
-}
-
-/*
- * Table 3 from JESD209-4C.
- * Maps density per physical channel to row-column encoding as per JESD 21-C for a device with
- * x16 physical channel.
- */
-var densityGbx16ChannelToRowColumnEncoding = map[int]byte{
-	4:  0x19, /* 15 rows, 10 columns */
-	6:  0x21, /* 16 rows, 10 columns */
-	8:  0x21, /* 16 rows, 10 columns */
-	12: 0x29, /* 17 rows, 10 columns */
-	16: 0x29, /* 17 rows, 10 columns */
-}
-
-/*
- * Table 5 from JESD209-4C.
- * Maps density per physical channel to row-column encoding as per JESD 21-C for a device with
- * x8 physical channel.
- */
-var densityGbx8ChannelToRowColumnEncoding = map[int]byte{
-	3:  0x21, /* 16 rows, 10 columns */
-	4:  0x21, /* 16 rows, 10 columns */
-	6:  0x29, /* 17 rows, 10 columns */
-	8:  0x29, /* 17 rows, 10 columns */
-	12: 0x31, /* 18 rows, 10 columns */
-	16: 0x31, /* 18 rows, 10 columns */
-}
-
-type refreshTimings struct {
-	TRFCABNs int
-	TRFCPBNs int
-}
-
-/*
- * Table 112 from JESD209-4C
- * Maps density per physical channel to refresh timings. This is the same for x8 and x16
- * devices.
- */
-var densityGbPhysicalChannelToRefreshEncoding = map[int]refreshTimings{
-	3: {
-		TRFCABNs: 180,
-		TRFCPBNs: 90,
-	},
-	4: {
-		TRFCABNs: 180,
-		TRFCPBNs: 90,
-	},
-	6: {
-		TRFCABNs: 280,
-		TRFCPBNs: 140,
-	},
-	8: {
-		TRFCABNs: 280,
-		TRFCPBNs: 140,
-	},
-	12: {
-		TRFCABNs: 380,
-		TRFCPBNs: 190,
-	},
-	16: {
-		TRFCABNs: 380,
-		TRFCPBNs: 190,
-	},
-}
-
-type speedParams struct {
-	TCKMinPs               int
-	TCKMaxPs               int
-	CASLatenciesx16Channel string
-	CASLatenciesx8Channel  string
-}
-
-const (
-	/* First Byte */
-	CAS6  = 1 << 1
-	CAS10 = 1 << 4
-	CAS14 = 1 << 7
-	/* Second Byte */
-	CAS16 = 1 << 0
-	CAS20 = 1 << 2
-	CAS22 = 1 << 3
-	CAS24 = 1 << 4
-	CAS26 = 1 << 5
-	CAS28 = 1 << 6
-	/* Third Byte */
-	CAS32 = 1 << 0
-	CAS36 = 1 << 2
-	CAS40 = 1 << 4
-)
-
-const (
-	/*
-	 * JEDEC spec says that TCKmax should be 100ns for all speed grades.
-	 * 100ns in MTB units comes out to be 0x320. But since this is a byte field, set it to
-	 * 0xFF i.e. 31.875ns.
-	 */
-	TCKMaxPsDefault = 31875
-)
-
-var speedMbpsToSPDEncoding = map[int]speedParams{
-	4267: {
-		TCKMinPs:               468, /* 1/4267 * 2 */
-		TCKMaxPs:               TCKMaxPsDefault,
-		CASLatenciesx16Channel: "6 10 14 20 24 28 32 36",
-		CASLatenciesx8Channel:  "6 10 16 22 26 32 36 40",
-	},
-	3733: {
-		TCKMinPs:               535, /* 1/3733 * 2 */
-		TCKMaxPs:               TCKMaxPsDefault,
-		CASLatenciesx16Channel: "6 10 14 20 24 28 32",
-		CASLatenciesx8Channel:  "6 10 16 22 26 32 36",
-	},
-	3200: {
-		TCKMinPs:               625, /* 1/3200 * 2 */
-		TCKMaxPs:               TCKMaxPsDefault,
-		CASLatenciesx16Channel: "6 10 14 20 24 28",
-		CASLatenciesx8Channel:  "6 10 16 22 26 32",
-	},
-}
-
-var bankEncoding = map[int]byte{
-	4: 0 << 4,
-	8: 1 << 4,
-}
-
-const (
-	TGLLogicalChannelWidth = 16
-)
-
-/* Returns density to encode as per Intel MRC expectations. */
-func getMRCDensity(memAttribs *memAttributes) int {
-	if currPlatform == PlatformTGLADL {
-		/*
-		 * Intel MRC on TGL expects density per logical channel to be encoded in
-		 * SPDIndexDensityBanks. Logical channel on TGL is an x16 channel.
-		 */
-		return memAttribs.DensityPerChannelGb * TGLLogicalChannelWidth / memAttribs.BitWidthPerChannel
-	} else if currPlatform == PlatformJSL || currPlatform == PlatformCZN {
-		/*
-		 * Intel MRC on JSL expects density per die to be encoded in
-		 * SPDIndexDensityBanks.
-		 */
-		return memAttribs.DensityPerChannelGb * memAttribs.ChannelsPerDie
-	}
-
-	return 0
-}
-
-func encodeDensityBanks(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = densityGbToSPDEncoding[getMRCDensity(memAttribs)]
-	b |= bankEncoding[memAttribs.Banks]
-
-	return b
-}
-
-func encodeSdramAddressing(memAttribs *memAttributes) byte {
-	densityPerChannelGb := memAttribs.DensityPerChannelGb
-	if memAttribs.BitWidthPerChannel == 8 {
-		return densityGbx8ChannelToRowColumnEncoding[densityPerChannelGb]
-	} else {
-		return densityGbx16ChannelToRowColumnEncoding[densityPerChannelGb]
-	}
-	return 0
-}
-
-func encodeChannelsPerDie(channels int) byte {
-	var temp byte
-
-	temp = byte(channels >> 1)
-
-	return temp << 2
-}
-
-func encodePackage(dies int) byte {
-	var temp byte
-
-	if dies > 1 {
-		/* If more than one die, then this is a non-monolithic device. */
-		temp = 1
-	} else {
-		/* If only single die, then this is a monolithic device. */
-		temp = 0
-	}
-
-	return temp << 7
-}
-
-/* Per JESD209-4C Dies = ZQ balls on the package */
-/* Note that this can be different than the part's die count */
-func encodeDiesPerPackage(memAttribs *memAttributes) byte {
-	var dies int = 0
-	if currPlatform == PlatformTGLADL {
-		/* Intel MRC expects logical dies to be encoded for TGL. */
-		dies = memAttribs.ChannelsPerDie * memAttribs.RanksPerChannel * memAttribs.BitWidthPerChannel / 16
-	} else if currPlatform == PlatformJSL || currPlatform == PlatformCZN {
-		/* Intel MRC expects physical dies to be encoded for JSL. */
-		/* AMD PSP expects physical dies (ZQ balls) */
-		dies = memAttribs.DiesPerPackage
-	}
-
-	b := encodePackage(dies) /* Monolithic / Non-monolithic device */
-	b |= (byte(dies) - 1) << 4
-
-	return b
-}
-
-func encodePackageType(memAttribs *memAttributes) byte {
-	var b byte
-
-	b |= encodeChannelsPerDie(memAttribs.ChannelsPerDie)
-	b |= encodeDiesPerPackage(memAttribs)
-
-	return b
-}
-
-func encodeDataWidth(bitWidthPerChannel int) byte {
-	return byte(bitWidthPerChannel / 8)
-}
-
-func encodeRanks(ranks int) byte {
-	var b byte
-	b = byte(ranks - 1)
-	return b << 3
-}
-
-func encodeModuleOrganization(memAttribs *memAttributes) byte {
-	var b byte
-
-	b = encodeDataWidth(memAttribs.BitWidthPerChannel)
-	b |= encodeRanks(memAttribs.RanksPerChannel)
-
-	return b
-}
-
-const (
-	/*
-	 * As per advisory 616599:
-	 * 7:5 (Number of system channels) = 000 (1 channel always)
-	 * 2:0 (Bus width) = 001 (x16 always)
-	 * Set to 0x01.
-	 */
-	SPDValueBusWidthTGL = 0x01
-	/*
-	 * As per advisory 610202:
-	 * 7:5 (Number of system channels) = 001 (2 channel always)
-	 * 2:0 (Bus width) = 010 (x32 always)
-	 * Set to 0x01.
-	 */
-	SPDValueBusWidthJSL = 0x22
-)
-
-func encodeBusWidth(memAttribs *memAttributes) byte {
-	if currPlatform == PlatformTGLADL {
-		return SPDValueBusWidthTGL
-	} else if currPlatform == PlatformJSL || currPlatform == PlatformCZN {
-		return SPDValueBusWidthJSL
-	}
-	return 0
-}
-
-func encodeTCKMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TCKMinPs)
-}
-
-func encodeTCKMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TCKMinPs)
-}
-
-func encodeTCKMax(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TCKMaxPs)
-}
-
-func encodeTCKMaxFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TCKMaxPs)
-}
-
-func encodeCASFirstByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASFirstByte
-}
-
-func encodeCASSecondByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASSecondByte
-}
-
-func encodeCASThirdByte(memAttribs *memAttributes) byte {
-	return memAttribs.CASThirdByte
-}
-
-func divRoundUp(dividend int, divisor int) int {
-	return (dividend + divisor - 1) / divisor
-}
-
-func convNsToPs(timeNs int) int {
-	return timeNs * 1000
-}
-
-func convMtbToPs(mtb int) int {
-	return mtb * 125
-}
-
-func convPsToMtb(timePs int) int {
-	return divRoundUp(timePs, 125)
-}
-
-func convPsToMtbByte(timePs int) byte {
-	return byte(convPsToMtb(timePs) & 0xff)
-}
-
-func convPsToFtbByte(timePs int) byte {
-	mtb := convPsToMtb(timePs)
-	ftb := timePs - convMtbToPs(mtb)
-
-	return byte(ftb)
-}
-
-func convNsToMtb(timeNs int) int {
-	return convPsToMtb(convNsToPs(timeNs))
-}
-
-func convNsToMtbByte(timeNs int) byte {
-	return convPsToMtbByte(convNsToPs(timeNs))
-}
-
-func convNsToFtbByte(timeNs int) byte {
-	return convPsToFtbByte(convNsToPs(timeNs))
-}
-
-func encodeTAAMin(memAttribs *memAttributes) byte {
-	return convPsToMtbByte(memAttribs.TAAMinPs)
-}
-
-func encodeTAAMinFineOffset(memAttribs *memAttributes) byte {
-	return convPsToFtbByte(memAttribs.TAAMinPs)
-}
-
-func encodeTRCDMin(memAttribs *memAttributes) byte {
-	return convNsToMtbByte(memAttribs.TRCDMinNs)
-}
-
-func encodeTRCDMinFineOffset(memAttribs *memAttributes) byte {
-	return convNsToFtbByte(memAttribs.TRCDMinNs)
-}
-
-func encodeTRPABMin(memAttribs *memAttributes) byte {
-	return convNsToMtbByte(memAttribs.TRPABMinNs)
-}
-
-func encodeTRPABMinFineOffset(memAttribs *memAttributes) byte {
-	return convNsToFtbByte(memAttribs.TRPABMinNs)
-}
-
-func encodeTRPPBMin(memAttribs *memAttributes) byte {
-	return convNsToMtbByte(memAttribs.TRPPBMinNs)
-}
-
-func encodeTRPPBMinFineOffset(memAttribs *memAttributes) byte {
-	return convNsToFtbByte(memAttribs.TRPPBMinNs)
-}
-
-func encodeTRFCABMinMsb(memAttribs *memAttributes) byte {
-	return byte((convNsToMtb(memAttribs.TRFCABNs) >> 8) & 0xff)
-}
-
-func encodeTRFCABMinLsb(memAttribs *memAttributes) byte {
-	return byte(convNsToMtb(memAttribs.TRFCABNs) & 0xff)
-}
-
-func encodeTRFCPBMinMsb(memAttribs *memAttributes) byte {
-	return byte((convNsToMtb(memAttribs.TRFCPBNs) >> 8) & 0xff)
-}
-
-func encodeTRFCPBMinLsb(memAttribs *memAttributes) byte {
-	return byte(convNsToMtb(memAttribs.TRFCPBNs) & 0xff)
-}
-
-type SPDAttribFunc func(*memAttributes) byte
-
-type SPDAttribTableEntry struct {
-	constVal byte
-	getVal   SPDAttribFunc
-}
-
-const (
-	/* SPD Byte Index */
-	SPDIndexSize                            = 0
-	SPDIndexRevision                        = 1
-	SPDIndexMemoryType                      = 2
-	SPDIndexModuleType                      = 3
-	SPDIndexDensityBanks                    = 4
-	SPDIndexAddressing                      = 5
-	SPDIndexPackageType                     = 6
-	SPDIndexOptionalFeatures                = 7
-	SPDIndexModuleOrganization              = 12
-	SPDIndexBusWidth                        = 13
-	SPDIndexTimebases                       = 17
-	SPDIndexTCKMin                          = 18
-	SPDIndexTCKMax                          = 19
-	SPDIndexCASFirstByte                    = 20
-	SPDIndexCASSecondByte                   = 21
-	SPDIndexCASThirdByte                    = 22
-	SPDIndexCASFourthByte                   = 23
-	SPDIndexTAAMin                          = 24
-	SPDIndexReadWriteLatency                = 25
-	SPDIndexTRCDMin                         = 26
-	SPDIndexTRPABMin                        = 27
-	SPDIndexTRPPBMin                        = 28
-	SPDIndexTRFCABMinLSB                    = 29
-	SPDIndexTRFCABMinMSB                    = 30
-	SPDIndexTRFCPBMinLSB                    = 31
-	SPDIndexTRFCPBMinMSB                    = 32
-	SPDIndexTRPPBMinFineOffset              = 120
-	SPDIndexTRPABMinFineOffset              = 121
-	SPDIndexTRCDMinFineOffset               = 122
-	SPDIndexTAAMinFineOffset                = 123
-	SPDIndexTCKMaxFineOffset                = 124
-	SPDIndexTCKMinFineOffset                = 125
-	SPDIndexManufacturerPartNumberStartByte = 329
-	SPDIndexManufacturerPartNumberEndByte   = 348
-
-	/* SPD Byte Value */
-
-	/*
-	 * From JEDEC spec:
-	 * 6:4 (Bytes total) = 2 (512 bytes)
-	 * 3:0 (Bytes used) = 3 (384 bytes)
-	 * Set to 0x23 for LPDDR4x.
-	 */
-	SPDValueSize = 0x23
-
-	/*
-	 * From JEDEC spec: Revision 1.1
-	 * Set to 0x11.
-	 */
-	SPDValueRevision = 0x11
-
-	/* LPDDR4x memory type = 0x11 */
-	SPDValueMemoryType = 0x11
-
-	/*
-	 * From JEDEC spec:
-	 * 7:7 (Hybrid) = 0 (Not hybrid)
-	 * 6:4 (Hybrid media) = 000 (Not hybrid)
-	 * 3:0 (Base Module Type) = 1110 (Non-DIMM solution)
-	 *
-	 * This is dependent on hardware design. LPDDR4x only has memory down solution.
-	 * Hence this is not hybrid non-DIMM solution.
-	 * Set to 0x0E.
-	 */
-	SPDValueModuleType = 0x0e
-
-	/*
-	 * From JEDEC spec:
-	 * 5:4 (Maximum Activate Window) = 00 (8192 * tREFI)
-	 * 3:0 (Maximum Activate Count) = 1000 (Unlimited MAC)
-	 *
-	 * Needs to come from datasheet, but most parts seem to support unlimited MAC.
-	 * MR#24 OP3
-	 */
-	SPDValueOptionalFeatures = 0x08
-
-	/*
-	 * From JEDEC spec:
-	 * 3:2 (MTB) = 00 (0.125ns)
-	 * 1:0 (FTB) = 00 (1ps)
-	 * Set to 0x00.
-	 */
-	SPDValueTimebases = 0x00
-
-	/* CAS fourth byte: All bits are reserved */
-	SPDValueCASFourthByte = 0x00
-
-	/* Write Latency Set A and Read Latency DBI-RD disabled. */
-	SPDValueReadWriteLatency = 0x00
-
-	/* As per JEDEC spec, unused digits of manufacturer part number are left as blank. */
-	SPDValueManufacturerPartNumberBlank = 0x20
-)
-
-var SPDAttribTable = map[int]SPDAttribTableEntry{
-	SPDIndexSize:               {constVal: SPDValueSize},
-	SPDIndexRevision:           {constVal: SPDValueRevision},
-	SPDIndexMemoryType:         {constVal: SPDValueMemoryType},
-	SPDIndexModuleType:         {constVal: SPDValueModuleType},
-	SPDIndexDensityBanks:       {getVal: encodeDensityBanks},
-	SPDIndexAddressing:         {getVal: encodeSdramAddressing},
-	SPDIndexPackageType:        {getVal: encodePackageType},
-	SPDIndexOptionalFeatures:   {constVal: SPDValueOptionalFeatures},
-	SPDIndexModuleOrganization: {getVal: encodeModuleOrganization},
-	SPDIndexBusWidth:           {getVal: encodeBusWidth},
-	SPDIndexTimebases:          {constVal: SPDValueTimebases},
-	SPDIndexTCKMin:             {getVal: encodeTCKMin},
-	SPDIndexTCKMax:             {getVal: encodeTCKMax},
-	SPDIndexTCKMaxFineOffset:   {getVal: encodeTCKMaxFineOffset},
-	SPDIndexTCKMinFineOffset:   {getVal: encodeTCKMinFineOffset},
-	SPDIndexCASFirstByte:       {getVal: encodeCASFirstByte},
-	SPDIndexCASSecondByte:      {getVal: encodeCASSecondByte},
-	SPDIndexCASThirdByte:       {getVal: encodeCASThirdByte},
-	SPDIndexCASFourthByte:      {constVal: SPDValueCASFourthByte},
-	SPDIndexTAAMin:             {getVal: encodeTAAMin},
-	SPDIndexTAAMinFineOffset:   {getVal: encodeTAAMinFineOffset},
-	SPDIndexReadWriteLatency:   {constVal: SPDValueReadWriteLatency},
-	SPDIndexTRCDMin:            {getVal: encodeTRCDMin},
-	SPDIndexTRCDMinFineOffset:  {getVal: encodeTRCDMinFineOffset},
-	SPDIndexTRPABMin:           {getVal: encodeTRPABMin},
-	SPDIndexTRPABMinFineOffset: {getVal: encodeTRPABMinFineOffset},
-	SPDIndexTRPPBMin:           {getVal: encodeTRPPBMin},
-	SPDIndexTRPPBMinFineOffset: {getVal: encodeTRPPBMinFineOffset},
-	SPDIndexTRFCABMinLSB:       {getVal: encodeTRFCABMinLsb},
-	SPDIndexTRFCABMinMSB:       {getVal: encodeTRFCABMinMsb},
-	SPDIndexTRFCPBMinLSB:       {getVal: encodeTRFCPBMinLsb},
-	SPDIndexTRFCPBMinMSB:       {getVal: encodeTRFCPBMinMsb},
-}
-
-type memParts struct {
-	MemParts []memPart `json:"parts"`
-}
-
-type memPart struct {
-	Name        string
-	Attribs     memAttributes
-	SPDFileName string
-}
-
-func writeSPDManifest(memParts *memParts, SPDDirName string) error {
-	var s string
-
-	fmt.Printf("Generating SPD Manifest with following entries:\n")
-
-	for i := 0; i < len(memParts.MemParts); i++ {
-		fmt.Printf("%-40s %s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName)
-		s += fmt.Sprintf("%s,%s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName)
-	}
-
-	return ioutil.WriteFile(filepath.Join(SPDDirName, SPDManifestFileName), []byte(s), 0644)
-}
-
-func isManufacturerPartNumberByte(index int) bool {
-	if index >= SPDIndexManufacturerPartNumberStartByte && index <= SPDIndexManufacturerPartNumberEndByte {
-		return true
-	}
-	return false
-}
-
-func getSPDByte(index int, memAttribs *memAttributes) byte {
-	e, ok := SPDAttribTable[index]
-	if ok == false {
-		if isManufacturerPartNumberByte(index) {
-			return SPDValueManufacturerPartNumberBlank
-		}
-		return 0x00
-	}
-
-	if e.getVal != nil {
-		return e.getVal(memAttribs)
-	}
-
-	return e.constVal
-}
-
-func createSPD(memAttribs *memAttributes) string {
-	var s string
-
-	for i := 0; i < 512; i++ {
-		b := getSPDByte(i, memAttribs)
-
-		if (i+1)%16 == 0 {
-			s += fmt.Sprintf("%02X\n", b)
-		} else {
-			s += fmt.Sprintf("%02X ", b)
-		}
-	}
-
-	return s
-}
-
-func dedupeMemoryPart(dedupedParts []*memPart, memPart *memPart) bool {
-	for i := 0; i < len(dedupedParts); i++ {
-		if reflect.DeepEqual(dedupedParts[i].Attribs, memPart.Attribs) {
-			memPart.SPDFileName = dedupedParts[i].SPDFileName
-			return true
-		}
-	}
-
-	return false
-}
-
-func generateSPD(memPart *memPart, SPDId int, SPDDirName string) {
-	s := createSPD(&memPart.Attribs)
-	memPart.SPDFileName = fmt.Sprintf("lp4x-spd-%d.hex", SPDId)
-	ioutil.WriteFile(filepath.Join(SPDDirName, memPart.SPDFileName), []byte(s), 0644)
-}
-
-func readMemoryParts(memParts *memParts, memPartsFileName string) error {
-	databytes, err := ioutil.ReadFile(memPartsFileName)
-	if err != nil {
-		return err
-	}
-
-	return json.Unmarshal(databytes, memParts)
-}
-
-func validateDensityx8Channel(densityPerChannelGb int) error {
-	if _, ok := densityGbx8ChannelToRowColumnEncoding[densityPerChannelGb]; ok == false {
-		return fmt.Errorf("Incorrect x8 density: ", densityPerChannelGb, "Gb")
-	}
-	return nil
-}
-
-func validateDensityx16Channel(densityPerChannelGb int) error {
-	if _, ok := densityGbx16ChannelToRowColumnEncoding[densityPerChannelGb]; ok == false {
-		return fmt.Errorf("Incorrect x16 density: ", densityPerChannelGb, "Gb")
-	}
-	return nil
-}
-
-func validateDensity(memAttribs *memAttributes) error {
-	if memAttribs.BitWidthPerChannel == 8 {
-		return validateDensityx8Channel(memAttribs.DensityPerChannelGb)
-	} else if memAttribs.BitWidthPerChannel == 16 {
-		return validateDensityx16Channel(memAttribs.DensityPerChannelGb)
-	}
-
-	return fmt.Errorf("No density table for this bit width: ", memAttribs.BitWidthPerChannel)
-}
-
-func validateBanks(banks int) error {
-	if banks != 4 && banks != 8 {
-		return fmt.Errorf("Incorrect banks: ", banks)
-	}
-	return nil
-}
-
-func validateChannels(channels int) error {
-	if channels != 1 && channels != 2 && channels != 4 {
-		return fmt.Errorf("Incorrect channels per die: ", channels)
-	}
-	return nil
-}
-
-func validateDataWidth(width int) error {
-	if width != 8 && width != 16 {
-		return fmt.Errorf("Incorrect bit width: ", width)
-	}
-	return nil
-}
-
-func validateRanks(ranks int) error {
-	if ranks != 1 && ranks != 2 {
-		return fmt.Errorf("Incorrect ranks: ", ranks)
-	}
-	return nil
-}
-
-func validateSpeed(speed int) error {
-	if _, ok := speedMbpsToSPDEncoding[speed]; ok == false {
-		return fmt.Errorf("Incorrect speed: ", speed, " Mbps")
-	}
-	return nil
-}
-
-func validateMemoryParts(memParts *memParts) error {
-	for i := 0; i < len(memParts.MemParts); i++ {
-		if err := validateBanks(memParts.MemParts[i].Attribs.Banks); err != nil {
-			return err
-		}
-		if err := validateChannels(memParts.MemParts[i].Attribs.ChannelsPerDie); err != nil {
-			return err
-		}
-		if err := validateDataWidth(memParts.MemParts[i].Attribs.BitWidthPerChannel); err != nil {
-			return err
-		}
-		if err := validateDensity(&memParts.MemParts[i].Attribs); err != nil {
-			return err
-		}
-		if err := validateRanks(memParts.MemParts[i].Attribs.RanksPerChannel); err != nil {
-			return err
-		}
-		if err := validateSpeed(memParts.MemParts[i].Attribs.SpeedMbps); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func encodeLatencies(latency int, memAttribs *memAttributes) error {
-	switch latency {
-	case 6:
-		memAttribs.CASFirstByte |= CAS6
-	case 10:
-		memAttribs.CASFirstByte |= CAS10
-	case 14:
-		memAttribs.CASFirstByte |= CAS14
-	case 16:
-		memAttribs.CASSecondByte |= CAS16
-	case 20:
-		memAttribs.CASSecondByte |= CAS20
-	case 22:
-		memAttribs.CASSecondByte |= CAS22
-	case 24:
-		memAttribs.CASSecondByte |= CAS24
-	case 26:
-		memAttribs.CASSecondByte |= CAS26
-	case 28:
-		memAttribs.CASSecondByte |= CAS28
-	case 32:
-		memAttribs.CASThirdByte |= CAS32
-	case 36:
-		memAttribs.CASThirdByte |= CAS36
-	case 40:
-		memAttribs.CASThirdByte |= CAS40
-	default:
-		fmt.Errorf("Incorrect CAS Latency: ", latency)
-	}
-
-	return nil
-}
-
-func updateTCK(memAttribs *memAttributes) {
-	if memAttribs.TCKMinPs == 0 {
-		memAttribs.TCKMinPs = speedMbpsToSPDEncoding[memAttribs.SpeedMbps].TCKMinPs
-	}
-	if memAttribs.TCKMaxPs == 0 {
-		memAttribs.TCKMaxPs = speedMbpsToSPDEncoding[memAttribs.SpeedMbps].TCKMaxPs
-	}
-}
-
-func getCASLatencies(memAttribs *memAttributes) string {
-	if memAttribs.BitWidthPerChannel == 16 {
-		return speedMbpsToSPDEncoding[memAttribs.SpeedMbps].CASLatenciesx16Channel
-	} else if memAttribs.BitWidthPerChannel == 8 {
-		return speedMbpsToSPDEncoding[memAttribs.SpeedMbps].CASLatenciesx8Channel
-	}
-
-	return ""
-}
-
-func updateCAS(memAttribs *memAttributes) error {
-	if len(memAttribs.CASLatencies) == 0 {
-		memAttribs.CASLatencies = getCASLatencies(memAttribs)
-	}
-
-	latencies := strings.Fields(memAttribs.CASLatencies)
-	for i := 0; i < len(latencies); i++ {
-		latency, err := strconv.Atoi(latencies[i])
-		if err != nil {
-			return fmt.Errorf("Unable to convert latency ", latencies[i])
-		}
-		if err := encodeLatencies(latency, memAttribs); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func getMinCAS(memAttribs *memAttributes) (int, error) {
-	if (memAttribs.CASThirdByte & CAS40) != 0 {
-		return 40, nil
-	}
-	if (memAttribs.CASThirdByte & CAS36) != 0 {
-		return 36, nil
-	}
-	if (memAttribs.CASThirdByte & CAS32) != 0 {
-		return 32, nil
-	}
-	if (memAttribs.CASSecondByte & CAS28) != 0 {
-		return 28, nil
-	}
-
-	return 0, fmt.Errorf("Unexpected min CAS")
-}
-
-func updateTAAMin(memAttribs *memAttributes) error {
-	if memAttribs.TAAMinPs == 0 {
-		minCAS, err := getMinCAS(memAttribs)
-		if err != nil {
-			return err
-		}
-		memAttribs.TAAMinPs = memAttribs.TCKMinPs * minCAS
-	}
-
-	return nil
-}
-
-func updateTRFCAB(memAttribs *memAttributes) {
-	if memAttribs.TRFCABNs == 0 {
-		memAttribs.TRFCABNs = densityGbPhysicalChannelToRefreshEncoding[memAttribs.DensityPerChannelGb].TRFCABNs
-	}
-}
-
-func updateTRFCPB(memAttribs *memAttributes) {
-	if memAttribs.TRFCPBNs == 0 {
-		memAttribs.TRFCPBNs = densityGbPhysicalChannelToRefreshEncoding[memAttribs.DensityPerChannelGb].TRFCPBNs
-	}
-}
-
-func updateTRCD(memAttribs *memAttributes) {
-	if memAttribs.TRCDMinNs == 0 {
-		/* JEDEC spec says max of 18ns */
-		memAttribs.TRCDMinNs = 18
-	}
-}
-
-func updateTRPAB(memAttribs *memAttributes) {
-	if memAttribs.TRPABMinNs == 0 {
-		/* JEDEC spec says max of 21ns */
-		memAttribs.TRPABMinNs = 21
-	}
-}
-
-func updateTRPPB(memAttribs *memAttributes) {
-	if memAttribs.TRPPBMinNs == 0 {
-		/* JEDEC spec says max of 18ns */
-		memAttribs.TRPPBMinNs = 18
-	}
-}
-
-func normalizeMemoryAttributes(memAttribs *memAttributes) {
-	if currPlatform == PlatformTGLADL {
-		/*
-		 * TGL does not really use physical organization of dies per package when
-		 * generating the SPD. So, set it to 0 here so that deduplication ignores
-		 * that field.
-		 */
-		memAttribs.DiesPerPackage = 0
-	}
-}
-
-func updateMemoryAttributes(memAttribs *memAttributes) error {
-	updateTCK(memAttribs)
-	if err := updateCAS(memAttribs); err != nil {
-		return err
-	}
-	if err := updateTAAMin(memAttribs); err != nil {
-		return err
-	}
-	updateTRFCAB(memAttribs)
-	updateTRFCPB(memAttribs)
-	updateTRCD(memAttribs)
-	updateTRPAB(memAttribs)
-	updateTRPPB(memAttribs)
-
-	normalizeMemoryAttributes(memAttribs)
-
-	return nil
-}
-
-func isPlatformSupported(platform string) error {
-	var ok bool
-
-	currPlatform, ok = platformMap[platform]
-	if ok == false {
-		return fmt.Errorf("Unsupported platform: ", platform)
-	}
-
-	return nil
-}
-
-func usage() {
-	fmt.Printf("\nUsage: %s <spd_dir> <mem_parts_list_json> <platform>\n\n", os.Args[0])
-	fmt.Printf("   where,\n")
-	fmt.Printf("   spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n")
-	fmt.Printf("   mem_parts_list_json = JSON File containing list of memory parts and attributes\n")
-	fmt.Printf("   platform = SoC Platform for which the SPDs are being generated\n")
-	fmt.Printf("              supported platforms: ")
-	keys := reflect.ValueOf(platformMap).MapKeys()
-	fmt.Println(keys)
-	fmt.Printf("\n\n\n")
-}
-
-func main() {
-	if len(os.Args) != 4 {
-		usage()
-		log.Fatal("Incorrect number of arguments")
-	}
-
-	var memParts memParts
-	var dedupedParts []*memPart
-
-	SPDDir, GlobalMemPartsFile, Platform := os.Args[1], os.Args[2], strings.ToUpper(os.Args[3])
-
-	if err := isPlatformSupported(Platform); err != nil {
-		log.Fatal(err)
-	}
-
-	if err := readMemoryParts(&memParts, GlobalMemPartsFile); err != nil {
-		log.Fatal(err)
-	}
-
-	if err := validateMemoryParts(&memParts); err != nil {
-		log.Fatal(err)
-	}
-
-	SPDId := 1
-
-	for i := 0; i < len(memParts.MemParts); i++ {
-		if err := updateMemoryAttributes(&memParts.MemParts[i].Attribs); err != nil {
-			log.Fatal(err)
-		}
-
-		if dedupeMemoryPart(dedupedParts, &memParts.MemParts[i]) == false {
-			generateSPD(&memParts.MemParts[i], SPDId, SPDDir)
-			SPDId++
-			dedupedParts = append(dedupedParts, &memParts.MemParts[i])
-		}
-	}
-
-	if err := writeSPDManifest(&memParts, SPDDir); err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/util/spd_tools/lp4x/global_lp4x_mem_parts.json.txt b/util/spd_tools/lp4x/global_lp4x_mem_parts.json.txt
deleted file mode 100644
index 68e241a..0000000
--- a/util/spd_tools/lp4x/global_lp4x_mem_parts.json.txt
+++ /dev/null
@@ -1,344 +0,0 @@
-{
-    "parts": [
-        {
-            "name": "H9HCNNNBKMMLXR-NEE",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H9HCNNNFAMMLXR-NEE",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 4,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 8,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "K4U6E3S4AA-MGCL",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "K4UBE3D4AA-MGCL",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E1G32D2NP-046 WT:A",
-            "attribs": {
-                "densityPerChannelGb": 16,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E1G32D2NP-046 WT:B",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H9HKNNNCRMBVAR-NEH",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E1G64D4SQ-046 WT:A",
-            "attribs": {
-                "densityPerChannelGb": 16,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E512M32D2NP-046 WT:F",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "NT6AP256T32AV-J2",
-            "attribs": {
-                "densityPerChannelGb": 4,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 3733,
-                "tckMaxPs": 1250,
-                "casLatencies": "14 20 24 28 32"
-            }
-        },
-        {
-            "name": "K4U6E3S4AA-MGCR",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E512M32D2NP-046 WT:E",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H9HCNNNCPMMLXR-NEE",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "K4UBE3D4AA-MGCR",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E512M64D4NW-046 WT:E",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E1G64D8NW-046 WT:E",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 4,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H9HCNNNCRMBLPR-NEE",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H9HCNNNFBMBLPR-NEE",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 4,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53D1G64D4NW-046 WT:A",
-            "attribs": {
-                "densityPerChannelGb": 16,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53D512M64D4NW-046 WT:F",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "NT6AP256T32AV-J1",
-            "attribs": {
-                "densityPerChannelGb": 4,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267,
-                "tckMaxPs": 1250,
-                "casLatencies": "14 20 24 28 32 36"
-            }
-        },
-        {
-            "name": "MT53E1G32D4NQ-046 WT:E",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E2G32D4NQ-046 WT:A",
-            "attribs": {
-                "densityPerChannelGb": 16,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "MT53E512M32D1NP-046 WT:B",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H54G46CYRBX267",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "H54G56CYRBX247",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "K4U6E3S4AB-MGCL",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 1,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 1,
-                "speedMbps": 4267
-            }
-        },
-        {
-            "name": "K4UBE3D4AB-MGCL",
-            "attribs": {
-                "densityPerChannelGb": 8,
-                "banks": 8,
-                "channelsPerDie": 2,
-                "diesPerPackage": 2,
-                "bitWidthPerChannel": 16,
-                "ranksPerChannel": 2,
-                "speedMbps": 4267
-            }
-        }
-    ]
-}