Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41612 )
Change subject: util/mb/google: Add spd_tools to generate SPDs for TGL boards
......................................................................
util/mb/google: Add spd_tools to generate SPDs for TGL boards
This change adds tools for generating SPD files for LPDDR4x memory
used in memory down configurations on Intel Tiger Lake(TGL) based
Chrome OS platforms. These tools generate SPDs following JESD209-4C
specification and Intel recommendations(doc #616599) for LPDDR4x SPD.
Two tools are provided:
* 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.
BUG=b:155239397,b:147321551
Change-Id: Ia9b64d1d48371ccea1c01630a33a245d90f45214
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
A util/mainboard/google/spd_tools/lp4x/README.md
A util/mainboard/google/spd_tools/lp4x/gen_part_id.go
A util/mainboard/google/spd_tools/lp4x/gen_spd.go
3 files changed, 1,247 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/12/41612/1
diff --git a/util/mainboard/google/spd_tools/lp4x/README.md b/util/mainboard/google/spd_tools/lp4x/README.md
new file mode 100644
index 0000000..1a2cdd0
--- /dev/null
+++ b/util/mainboard/google/spd_tools/lp4x/README.md
@@ -0,0 +1,232 @@
+# LPDDR4x SPD tools README
+
+Tools for generating SPD files for LPDDR4x memory used in memory down
+configurations on Intel Tiger Lake(TGL) based Chrome OS
+platforms. These tools generate SPDs following JESD209-4C
+specification and Intel recommendations(doc #616599) for LPDDR4x SPD.
+
+There are two tools provided that assist TGL-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:
+* JSON file containing a global list of memory parts with their
+ attributes as per the datasheet (Argument: `--mem_list`). This is
+ the list of all known LPDDR4x memory parts irrespective of their
+ usage on the board.
+* Pointer to directory where the generated SPD files and manifest will
+ be placed (Argument: `--spd_dir`).
+
+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.
+
+`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 logical channel. Logical
+ channel is considered as a 16-bit wide channel. Thus, this attribute
+ is expected to provide the density of a 16-wide logical
+ channel. Valid values: `6, 8, 12, 16` Gb.
+
+* `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`
+
+* `diesPerPackage`: Number of dies in the package: `SDP = 1`, `DDP =
+ 2`, `QDP = 4`, `ODP = 8`.
+
+* `bitWidthPerChannel`: Width of each physical channel. Valid values:
+ `8, 16` bits.
+
+* `ranksPerChannel`: Number of ranks per physical channel. Valid
+ values: `1, 2`.
+
+* `speedMbps`: Maximum data rate supported by the part in Mbps. Valid
+ values: `3200, 3733, 4267` Mbps.
+
+### Optional `attribs`
+
+* `tckPs`: 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
+
+* `trfcabNs`: Minimum Refresh Recovery Delay Time (tRFCab) for all
+ banks in nanoseconds. As per JESD209-4C, this is dependent on the
+ density per channel (in this case density per logical
+ 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 (in this case density per logical
+ 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`.
+
+* `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": "EXAMPLE-MEMORY",
+ "attribs": {
+ "densityPerChannelGb": 8,
+ "banks": 8,
+ "channelsPerDie": 2,
+ "diesPerPackage": 2,
+ "bitWidthPerChannel": 16,
+ "ranksPerChannel": 1,
+ "speedMbps": 4267
+ }
+ }
+}
+```
+
+### 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 diretory 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.
+
+Sample output:
+```
+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
+
+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 <Path to store SPD files> --mem_list <Global list of memory parts>
+# ./gen_part_id --spd_dir <Path where SPD files are stored> --mem_pars_used <List of parts used by board> -- makefile_dir <Path where Makefile.inc should be generated>
+```
+
+### Need to add a new memory part for a board?
+
+* If the memory part is not present in the global list of memory parts
+ as maintained by the reference board, 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` with updated changes and push a
+ CL for review.
diff --git a/util/mainboard/google/spd_tools/lp4x/gen_part_id.go b/util/mainboard/google/spd_tools/lp4x/gen_part_id.go
new file mode 100644
index 0000000..4e91b38
--- /dev/null
+++ b/util/mainboard/google/spd_tools/lp4x/gen_part_id.go
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+package main
+
+import "encoding/csv"
+import "flag"
+import "fmt"
+import "io"
+import "io/ioutil"
+import "log"
+import "os"
+import "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.
+ * 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.
+ * Pointer to Makefile directory. Makefile.inc generated by this program is placed in this
+ * location.
+ */
+var spdDirPtr = flag.String("spd_dir", "", "Directory containing SPD files and manifest")
+var memPartListPtr = flag.String("mem_parts_used", "",
+ "File containing list of memory parts used by the board")
+var makefileDirPtr = flag.String("makefile_dir", "",
+ "Directory where the generated Makefile.inc file should be placed")
+
+var spdManifestFileName = "spd_manifest.generated.txt"
+var makefileName = "Makefile.inc"
+
+func checkArgs() {
+ if *spdDirPtr == "" {
+ log.Fatal("SPD directory not provided!\n")
+ }
+
+ if *makefileDirPtr == "" {
+ log.Fatal("Makefile.inc directory not provided!\n")
+ }
+
+ if *memPartListPtr == "" {
+ log.Fatal("List of memory parts not provided!\n")
+ }
+
+ if _, err := os.Stat(*spdDirPtr); err != nil {
+ log.Fatal(err)
+ }
+
+ if _, err := os.Stat(*makefileDirPtr); err != nil {
+ log.Fatal(err)
+ }
+
+ if _,err := os.Stat(*memPartListPtr); err != nil {
+ log.Fatal(err)
+ }
+}
+
+/*
+ * 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() []string {
+ lines, err := ioutil.ReadFile(*memPartListPtr)
+ if err != nil {
+ log.Fatal(err)
+ }
+ str := string(lines)
+ parts := strings.Split(str, "\n")
+
+ return parts
+}
+
+/*
+ * 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() (map[string]string, map[string]int) {
+ filePath := *spdDirPtr + "/" + spdManifestFileName
+ f, err := os.Open(filePath)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer f.Close()
+ r := csv.NewReader(f)
+
+ partToSpdMap := make(map[string]string)
+ spdToIndexMap := make(map[string]int)
+
+ for true {
+ fields, err := r.Read()
+
+ if err == io.EOF {
+ break
+ }
+
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if len(fields) != 2 {
+ log.Fatal("CSV file is incorrectly formatted!\n")
+ }
+
+ partToSpdMap[fields[0]] = fields[1]
+
+ if _, ok := spdToIndexMap[fields[1]]; ok == false {
+ spdToIndexMap[fields[1]] = -1
+ }
+ }
+
+ return partToSpdMap, spdToIndexMap
+}
+
+/* Print information about memory part used by variant and ID assigned to it. */
+func printPartIdInfo(partName string, index int) {
+ fmt.Printf("%-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) []partIds {
+ partIdList := []partIds{}
+ curId := 0
+
+ fmt.Printf("%-30s %s\n", "DRAM Part Name", "ID to assign")
+ for i := 0; i < len(parts); i++ {
+ if parts[i] == "" {
+ continue
+ }
+
+ spdFileName,ok := partToSpdMap[parts[i]]
+ if ok == false {
+ log.Fatal("Failed to find part ", parts[i], " in SPD Manifest! Please add the part to global part list and regenerate SPD Manifest!\n")
+ }
+
+ index := spdToIndexMap[spdFileName]
+ if index != -1 {
+ partIdList[index].memParts += ", " + parts[i]
+ printPartIdInfo(parts[i], index)
+ continue
+ }
+
+ spdToIndexMap[spdFileName] = curId
+
+ printPartIdInfo(parts[i], curId)
+ entry := partIds{spdFileName: spdFileName, memParts: parts[i]}
+ partIdList = append(partIdList, entry)
+
+ curId++
+ }
+
+ return partIdList
+}
+
+var generatedCodeLicense string = "## SPDX-License-Identifier: GPL-2.0-or-later"
+
+/*
+ * This function generates Makefile.inc under the variant directory path and adds assigned SPDs
+ * to SPD_SOURCES.
+ */
+func genMakefile(partIdList []partIds) {
+ filePath := *makefileDirPtr + "/" + makefileName
+ f, err := os.Create(filePath)
+
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer f.Close()
+ fmt.Fprintf(f, "%s\n\n", generatedCodeLicense)
+ fmt.Fprintf(f, "SPD_SOURCES =\n")
+
+ for i := 0; i < len(partIdList); i++ {
+ fmt.Fprintf(f, "SPD_SOURCES += %s ", partIdList[i].spdFileName)
+ fmt.Fprintf(f, " # ID = %d(0b%04b) ", i, int64(i))
+ fmt.Fprintf(f, " Parts = %04s\n", partIdList[i].memParts)
+ }
+}
+
+func main() {
+ flag.Parse()
+ checkArgs()
+
+ partToSpdMap, spdToIndexMap := readSpdManifest()
+ parts := readParts()
+
+ partIdList := genPartIdInfo(parts, partToSpdMap, spdToIndexMap)
+
+ genMakefile(partIdList)
+}
diff --git a/util/mainboard/google/spd_tools/lp4x/gen_spd.go b/util/mainboard/google/spd_tools/lp4x/gen_spd.go
new file mode 100644
index 0000000..ac5603f
--- /dev/null
+++ b/util/mainboard/google/spd_tools/lp4x/gen_spd.go
@@ -0,0 +1,807 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+package main
+
+import "bufio"
+import "bytes"
+import "encoding/csv"
+import "encoding/json"
+import "flag"
+import "fmt"
+import "io/ioutil"
+import "log"
+import "os"
+import "reflect"
+import "strconv"
+import "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.
+ */
+var spdDirPtr = flag.String("spd_dir", "", "Directory to store SPD files and manifest")
+var memPartListPtr = flag.String("mem_list", "", "File containing global list of memory parts with attributes")
+
+var spdManifestFileName = "spd_manifest.generated.txt"
+
+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
+ TckPs int
+ TaaPs int
+ TrcdMinNs int
+
+ /* CAS */
+ CasLatencies string
+ casFirstByte byte
+ casSecondByte byte
+ casThirdByte byte
+}
+
+func encodeSpdSize(memAttribs *memAttributes) byte {
+ /*
+ * From JEDEC spec:
+ * 6:4 (Bytes total) = 2 (512 bytes)
+ * 3:0 (Bytes used) = 3 (384 bytes)
+ * Set to 0x23 for LPDDR4x.
+ */
+ return 0x23
+}
+
+func encodeSpdRevision(memAttribs *memAttributes) byte {
+ /*
+ * From JEDEC spec: Revision 1.1
+ * Set to 0x11.
+ */
+ return 0x11
+}
+
+func encodeMemoryType(memAttribs *memAttributes) byte {
+ /* LPDDR4x memory type = 0x11 */
+ return 0x11
+}
+
+func encodeModuleType(memAttribs *memAttributes) byte {
+ /*
+ * 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.
+ */
+ return 0x0e
+}
+
+type densityParams struct {
+ densityEncoding byte
+ rowColumnEncoding byte
+ trfcabNs int
+ trfcpbNs int
+}
+
+var densityGbToSPDEncoding = map[int]densityParams {
+ 6: {
+ densityEncoding: 0xb,
+ rowColumnEncoding: 0x21, /* 16 rows, 10 columns */
+ trfcabNs: 280,
+ trfcpbNs: 140,
+ },
+ 8: {
+ densityEncoding: 0x5,
+ rowColumnEncoding: 0x21, /* 16 rows, 10 columns */
+ trfcabNs: 280,
+ trfcpbNs: 140,
+ },
+ 12: {
+ densityEncoding: 0x8,
+ rowColumnEncoding: 0x29, /* 17 rows, 10 columns */
+ trfcabNs: 380,
+ trfcpbNs: 190,
+ },
+ 16: {
+ densityEncoding: 0x6,
+ rowColumnEncoding: 0x29, /* 17 rows, 10 columns */
+ trfcabNs: 380,
+ trfcpbNs: 190,
+ },
+}
+
+type speedParams struct {
+ tckPs int
+ casFirstByte byte
+ casSecondByte byte
+ casThirdByte byte
+}
+
+const (
+ CAS_6 = 1 << 1 /* 10 - 266 MHz */
+ CAS_10 = 1 << 4 /* 266 - 533 MHz */
+ CAS_14 = 1 << 7 /* 533 - 800 MHz */
+ CAS_20 = 1 << 2 /* 800 - 1066 MHz */
+ CAS_24 = 1 << 4 /* 1066 - 1333 MHz */
+ CAS_28 = 1 << 6 /* 1333 - 1600 MHz */
+ CAS_32 = 1 << 0 /* 1600 - 1866 MHz */
+ CAS_36 = 1 << 2 /* 1866 - 2133 MHz */
+)
+
+var speedMbpsToSpdEncoding = map[int]speedParams {
+ 4267: {
+ tckPs: 468, /* 1/4267 * 2 */
+ casFirstByte: CAS_6 | CAS_10 | CAS_14,
+ casSecondByte: CAS_20 | CAS_24 | CAS_28,
+ casThirdByte: CAS_32 | CAS_36,
+ },
+ 3733: {
+ tckPs: 535, /* 1/3733 * 2 */
+ casFirstByte: CAS_6 | CAS_10 | CAS_14,
+ casSecondByte: CAS_20 | CAS_24 | CAS_28,
+ casThirdByte: CAS_32,
+ },
+ 3200: {
+ tckPs: 625, /* 1/3200 * 2 */
+ casFirstByte: CAS_6 | CAS_10 | CAS_14,
+ casSecondByte: CAS_20 | CAS_24 | CAS_28,
+ casThirdByte: 0,
+ },
+}
+
+func encodeDensity(densityPerChannelGb int) byte {
+ return densityGbToSPDEncoding[densityPerChannelGb].densityEncoding
+}
+
+func encodeBanks(banks int) byte {
+ var temp byte
+
+ if banks == 4 {
+ temp = 0
+ } else if banks == 8 {
+ temp = 1
+ }
+
+ return temp << 4
+}
+
+func encodeDensityBanks(memAttribs *memAttributes) byte {
+ var b byte
+
+ b = encodeDensity(memAttribs.DensityPerChannelGb)
+ b |= encodeBanks(memAttribs.Banks)
+
+ return b
+}
+
+func encodeSdramAddressing(memAttribs *memAttributes) byte {
+ return densityGbToSPDEncoding[memAttribs.DensityPerChannelGb].rowColumnEncoding
+}
+
+func encodeChannelsPerDie(channels int) byte {
+ var temp byte
+
+ temp = byte(channels >> 1)
+
+ return temp << 2
+}
+
+func encodeDiesPerPackage(dies int) byte {
+ return (byte(dies) - 1) << 4
+}
+
+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
+}
+
+func encodePackageType(memAttribs *memAttributes) byte {
+ var b byte
+
+ b = encodePackage(memAttribs.DiesPerPackage) /* Non-monolithic device */
+ b |= 0x1 /* Signal Loading Matrix 1 */
+
+ b |= encodeChannelsPerDie(memAttribs.ChannelsPerDie)
+ b |= encodeDiesPerPackage(memAttribs.DiesPerPackage)
+
+ return b
+}
+
+func encodeOptionalFeatures(memAttribs *memAttributes) byte {
+ /*
+ * 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
+ */
+ return 0x08
+}
+
+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
+}
+
+func encodeBusWidth(memAttribs *memAttributes) byte {
+ /*
+ * As per advisory 616599:
+ * 7:5 (Number of system channels) = 000 (1 channel always)
+ * 2:0 (Bus width) = 001 (x16 always)
+ * Set to 0x01.
+ */
+ return 0x01
+}
+
+func encodeSignalLoading(memAttribs *memAttributes) byte {
+ /* Unsure about this ??? Check with Intel!!! */
+ return 0x48
+}
+
+func encodeTimebases(memAttribs *memAttributes) byte {
+ /*
+ * From JEDEC spec:
+ * 3:2 (MTB) = 00 (0.125ns)
+ * 1:0 (FTB) = 00 (1ps)
+ * Set to 0x00.
+ */
+ return 0x00
+}
+
+func encodeTckMin(memAttribs *memAttributes) byte {
+ return convPsToMtbByte(memAttribs.TckPs)
+}
+
+func encodeTckMinFineOffset(memAttribs *memAttributes) byte {
+ return convPsToFtbByte(memAttribs.TckPs)
+}
+
+func encodeTckMax(memAttribs *memAttributes) byte {
+ /*
+ * 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.
+ */
+ return 0xff
+}
+
+func encodeTckMaxFineOffset(memAttribs *memAttributes) byte {
+ /* No fine offset for TckMax */
+ return 0x00
+}
+
+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 {
+ /* All bits are reserved */
+ return 0x00
+}
+
+func encodeReadWriteLatency(memAttribs *memAttributes) byte {
+ /* Write Latency Set A and Read Latency DBI-RD disabled. */
+ return 0
+}
+
+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.TaaPs)
+}
+
+func encodeTaaMinFineOffset(memAttribs *memAttributes) byte {
+ return convPsToFtbByte(memAttribs.TaaPs)
+}
+
+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
+
+const (
+ SPD_INDEX_SIZE = 0
+ SPD_INDEX_REVISION = 1
+ SPD_INDEX_MEMORY_TYPE = 2
+ SPD_INDEX_MODULE_TYPE = 3
+ SPD_INDEX_DENSITY_BANKS = 4
+ SPD_INDEX_ADDRESSING = 5
+ SPD_INDEX_PACKAGE_TYPE = 6
+ SPD_INDEX_OPTIONAL_FEATURES = 7
+ SPD_INDEX_MODULE_ORGANIZATION = 12
+ SPD_INDEX_BUS_WIDTH = 13
+ SPD_INDEX_SIGNAL_LOADING = 16
+ SPD_INDEX_TIMEBASES = 17
+ SPD_INDEX_TCK_MIN = 18
+ SPD_INDEX_TCK_MAX = 19
+ SPD_INDEX_CAS_FIRST_BYTE = 20
+ SPD_INDEX_CAS_SECOND_BYTE = 21
+ SPD_INDEX_CAS_THIRD_BYTE = 22
+ SPD_INDEX_CAS_FOURTH_BYTE = 23
+ SPD_INDEX_TAA_MIN = 24
+ SPD_INDEX_READ_WRITE_LATENCY = 25
+ SPD_INDEX_TRCD_MIN = 26
+ SPD_INDEX_TRPAB_MIN = 27
+ SPD_INDEX_TRPPB_MIN = 28
+ SPD_INDEX_TRFCAB_MIN_LSB = 29
+ SPD_INDEX_TRFCAB_MIN_MSB = 30
+ SPD_INDEX_TRFCPB_MIN_LSB = 31
+ SPD_INDEX_TRFCPB_MIN_MSB = 32
+ SPD_INDEX_TRPPB_MIN_FINE_OFFSET = 120
+ SPD_INDEX_TRPAB_MIN_FINE_OFFSET = 121
+ SPD_INDEX_TRCD_MIN_FINE_OFFSET = 122
+ SPD_INDEX_TAA_MIN_FINE_OFFSET = 123
+ SPD_INDEX_TCK_MAX_FINE_OFFSET = 124
+ SPD_INDEX_TCK_MIN_FINE_OFFSET = 125
+)
+
+var spdAttribFuncTable = map[int]spdAttribFunc {
+ SPD_INDEX_SIZE: encodeSpdSize,
+ SPD_INDEX_REVISION: encodeSpdRevision,
+ SPD_INDEX_MEMORY_TYPE: encodeMemoryType,
+ SPD_INDEX_MODULE_TYPE: encodeModuleType,
+ SPD_INDEX_DENSITY_BANKS: encodeDensityBanks,
+ SPD_INDEX_ADDRESSING: encodeSdramAddressing,
+ SPD_INDEX_PACKAGE_TYPE: encodePackageType,
+ SPD_INDEX_OPTIONAL_FEATURES: encodeOptionalFeatures,
+ SPD_INDEX_MODULE_ORGANIZATION: encodeModuleOrganization,
+ SPD_INDEX_BUS_WIDTH: encodeBusWidth,
+ SPD_INDEX_SIGNAL_LOADING: encodeSignalLoading,
+ SPD_INDEX_TIMEBASES: encodeTimebases,
+ SPD_INDEX_TCK_MIN: encodeTckMin,
+ SPD_INDEX_TCK_MAX: encodeTckMax,
+ SPD_INDEX_TCK_MAX_FINE_OFFSET: encodeTckMaxFineOffset,
+ SPD_INDEX_TCK_MIN_FINE_OFFSET: encodeTckMinFineOffset,
+ SPD_INDEX_CAS_FIRST_BYTE: encodeCasFirstByte,
+ SPD_INDEX_CAS_SECOND_BYTE: encodeCasSecondByte,
+ SPD_INDEX_CAS_THIRD_BYTE: encodeCasThirdByte,
+ SPD_INDEX_CAS_FOURTH_BYTE: encodeCasFourthByte,
+ SPD_INDEX_TAA_MIN: encodeTaaMin,
+ SPD_INDEX_TAA_MIN_FINE_OFFSET: encodeTaaMinFineOffset,
+ SPD_INDEX_READ_WRITE_LATENCY: encodeReadWriteLatency,
+ SPD_INDEX_TRCD_MIN: encodeTrcdMin,
+ SPD_INDEX_TRCD_MIN_FINE_OFFSET: encodeTrcdMinFineOffset,
+ SPD_INDEX_TRPAB_MIN: encodeTrpabMin,
+ SPD_INDEX_TRPAB_MIN_FINE_OFFSET: encodeTrpabMinFineOffset,
+ SPD_INDEX_TRPPB_MIN: encodeTrppbMin,
+ SPD_INDEX_TRPPB_MIN_FINE_OFFSET: encodeTrppbMinFineOffset,
+ SPD_INDEX_TRFCAB_MIN_LSB: encodeTrfcabMinLsb,
+ SPD_INDEX_TRFCAB_MIN_MSB: encodeTrfcabMinMsb,
+ SPD_INDEX_TRFCPB_MIN_LSB: encodeTrfcpbMinLsb,
+ SPD_INDEX_TRFCPB_MIN_MSB: encodeTrfcpbMinMsb,
+}
+
+type memParts struct {
+ MemParts []memPart `json:"parts"`
+}
+
+type memPart struct {
+ Name string
+ Attribs memAttributes
+ spdFileName string
+}
+
+func writeSpdManifest(memParts *memParts) {
+ filePath := *spdDirPtr + "/" + spdManifestFileName
+ f, err := os.Create(filePath)
+
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer f.Close()
+ w := csv.NewWriter(f)
+
+ records := [][]string{}
+
+ fmt.Printf("Generating SPD Manifest with following entries:\n")
+
+ for i := 0; i < len(memParts.MemParts); i++ {
+ entry := []string{memParts.MemParts[i].Name, memParts.MemParts[i].spdFileName}
+
+ records = append(records, entry)
+ fmt.Printf("%-40s %s\n", memParts.MemParts[i].Name, memParts.MemParts[i].spdFileName)
+ }
+ w.WriteAll(records)
+}
+
+func getSpdByte(index int, memAttribs *memAttributes) byte {
+ f, ok := spdAttribFuncTable[index]
+ if ok == false {
+ return 0x00
+ }
+ return f(memAttribs)
+}
+
+func writeByteToFile(w *bufio.Writer, b *bytes.Buffer, c byte) {
+ temp, _ := b.ReadByte()
+ fmt.Fprintf(w, "%02X%c", temp, c)
+}
+
+func writeSpd(fileName string, b bytes.Buffer) {
+ filePath := *spdDirPtr + "/" + fileName
+ f, err := os.Create(filePath)
+
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer f.Close()
+ w := bufio.NewWriter(f)
+
+ for i := 0; i < 512; i += 16 {
+ for j := 0; j < 15; j++ {
+ writeByteToFile(w, &b, ' ')
+ }
+ writeByteToFile(w, &b, '\n')
+ }
+
+ w.Flush()
+}
+
+func createSpd(memAttribs *memAttributes) bytes.Buffer {
+ var b bytes.Buffer
+
+ for i := 0; i < 512; i++ {
+ b.WriteByte(getSpdByte(i, memAttribs))
+ }
+
+ return b
+}
+
+func generateSpd(dedupedParts []*memPart, memPart *memPart, spdId *int) bool {
+ for i := 0; i < len(dedupedParts); i++ {
+ if reflect.DeepEqual(dedupedParts[i].Attribs, memPart.Attribs) {
+ memPart.spdFileName = dedupedParts[i].spdFileName
+ return false
+ }
+ }
+
+ b := createSpd(&memPart.Attribs)
+ memPart.spdFileName = fmt.Sprintf("spd-%d.hex", *spdId)
+ writeSpd(memPart.spdFileName, b)
+
+ *spdId++
+ return true
+}
+
+func readMemoryParts(memParts *memParts) {
+ partsFile, err := os.Open(*memPartListPtr)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer partsFile.Close()
+
+ databytes, _ := ioutil.ReadAll(partsFile)
+
+ if err := json.Unmarshal(databytes, memParts); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func validateDensity(densityPerChannelGb int) {
+ if _, ok := densityGbToSPDEncoding[densityPerChannelGb]; ok == false {
+ log.Fatal("Incorrect density: ", densityPerChannelGb, "Gb!\n")
+ }
+}
+
+func validateBanks(banks int) {
+ if banks != 4 && banks != 8 {
+ log.Fatal("Incorrect banks: ", banks, "!\n")
+ }
+}
+
+func validateChannels(channels int) {
+ if channels != 1 && channels != 2 && channels != 4 {
+ log.Fatal("Incorrect channels per die: ", channels, "!\n")
+ }
+}
+
+func validateDies(dies int) {
+ if dies > 8 || dies < 1 {
+ log.Fatal("Incorrect dies per package: ", dies, "!\n")
+ }
+}
+
+func validateDataWidth(width int) {
+ if width != 8 && width != 16 {
+ log.Fatal("Incorrect bit width: ", width, "!\n")
+ }
+}
+
+func validateRanks(ranks int) {
+ if ranks != 1 && ranks != 2 {
+ log.Fatal("Incorrect ranks: ", ranks, "!\n")
+ }
+}
+
+func validateSpeed(speed int) {
+ if _, ok := speedMbpsToSpdEncoding[speed]; ok == false {
+ log.Fatal("Incorrect speed: ", speed, " Mbps!\n")
+ }
+}
+
+func validateMemoryParts(memParts *memParts) {
+ for i := 0; i < len(memParts.MemParts); i++ {
+ validateDensity(memParts.MemParts[i].Attribs.DensityPerChannelGb)
+ validateBanks(memParts.MemParts[i].Attribs.Banks)
+ validateChannels(memParts.MemParts[i].Attribs.ChannelsPerDie)
+ validateDies(memParts.MemParts[i].Attribs.DiesPerPackage)
+ validateDataWidth(memParts.MemParts[i].Attribs.BitWidthPerChannel)
+ validateRanks(memParts.MemParts[i].Attribs.RanksPerChannel)
+ validateSpeed(memParts.MemParts[i].Attribs.SpeedMbps)
+ }
+}
+
+func encodeLatencies(latency int, firstByte *byte, secondByte *byte, thirdByte *byte) {
+ switch latency {
+ case 6:
+ *firstByte |= CAS_6
+ case 10:
+ *firstByte |= CAS_10
+ case 14:
+ *firstByte |= CAS_14
+ case 20:
+ *secondByte |= CAS_20
+ case 24:
+ *secondByte |= CAS_24
+ case 28:
+ *secondByte |= CAS_28
+ case 32:
+ *thirdByte |= CAS_32
+ case 36:
+ *thirdByte |= CAS_36
+ default:
+ log.Fatal("Incorrect CAS Latency: ", latency, "!\n")
+ }
+}
+
+func updateTck(memAttribs *memAttributes) {
+ if memAttribs.TckPs == 0 {
+ memAttribs.TckPs = speedMbpsToSpdEncoding[memAttribs.SpeedMbps].tckPs
+ }
+}
+
+func updateCas(memAttribs *memAttributes) {
+ if len(memAttribs.CasLatencies) == 0 {
+ memAttribs.casFirstByte = speedMbpsToSpdEncoding[memAttribs.SpeedMbps].casFirstByte
+ memAttribs.casSecondByte = speedMbpsToSpdEncoding[memAttribs.SpeedMbps].casSecondByte
+ memAttribs.casThirdByte = speedMbpsToSpdEncoding[memAttribs.SpeedMbps].casThirdByte
+ } else {
+ latencies := strings.Fields(memAttribs.CasLatencies)
+ for i := 0; i < len(latencies); i++ {
+ latency,err := strconv.Atoi(latencies[i])
+ if err != nil {
+ log.Fatal("Unable to convert latency ", latencies[i], "!\n")
+ }
+ encodeLatencies(latency, &memAttribs.casFirstByte, &memAttribs.casSecondByte, &memAttribs.casThirdByte)
+ }
+ }
+}
+
+func getMinCas(memAttribs *memAttributes) int {
+ if (memAttribs.casThirdByte & CAS_36) != 0 {
+ return 36
+ }
+ if (memAttribs.casThirdByte & CAS_32) != 0 {
+ return 32
+ }
+ if (memAttribs.casSecondByte & CAS_28) != 0 {
+ return 28
+ }
+ log.Fatal("Unexpected min CAS!\n")
+ return 0
+}
+
+func updateTaa(memAttribs *memAttributes) {
+ if memAttribs.TaaPs == 0 {
+ memAttribs.TaaPs = memAttribs.TckPs * getMinCas(memAttribs)
+ }
+}
+
+func updateTrfcab(memAttribs *memAttributes) {
+ if memAttribs.TrfcabNs == 0 {
+ memAttribs.TrfcabNs = densityGbToSPDEncoding[memAttribs.DensityPerChannelGb].trfcabNs
+ }
+}
+
+func updateTrfcpb(memAttribs *memAttributes) {
+ if memAttribs.TrfcpbNs == 0 {
+ memAttribs.TrfcpbNs = densityGbToSPDEncoding[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 updateMemoryAttributes(memAttribs *memAttributes) {
+ updateTck(memAttribs)
+ updateCas(memAttribs)
+ updateTaa(memAttribs)
+ updateTrfcab(memAttribs)
+ updateTrfcpb(memAttribs)
+ updateTrcd(memAttribs)
+ updateTrpab(memAttribs)
+ updateTrppb(memAttribs)
+}
+
+func checkArgs() {
+ if *spdDirPtr == "" {
+ log.Fatal("SPD directory not provided!\n");
+ }
+
+ if *memPartListPtr == "" {
+ log.Fatal("Global memory part list not provided!\n");
+ }
+
+ if _, err := os.Stat(*spdDirPtr); err != nil {
+ log.Fatal(err)
+ }
+
+ if _, err := os.Stat(*memPartListPtr); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func main() {
+ flag.Parse()
+ checkArgs()
+
+ var memParts memParts
+ var dedupedParts []*memPart
+
+ readMemoryParts(&memParts)
+ validateMemoryParts(&memParts)
+
+ spdId := 1
+
+ for i := 0; i < len(memParts.MemParts); i++ {
+ updateMemoryAttributes(&memParts.MemParts[i].Attribs)
+ if generateSpd(dedupedParts, &memParts.MemParts[i], &spdId) == true {
+ dedupedParts = append(dedupedParts, &memParts.MemParts[i])
+ }
+ }
+
+ writeSpdManifest(&memParts)
+}
--
To view, visit https://review.coreboot.org/c/coreboot/+/41612
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ia9b64d1d48371ccea1c01630a33a245d90f45214
Gerrit-Change-Number: 41612
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-MessageType: newchange
Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41614 )
Change subject: mb/google/volteer/var/ripto: Use auto-generated Makefile.inc using gen_part_id.go
......................................................................
mb/google/volteer/var/ripto: Use auto-generated Makefile.inc using gen_part_id.go
This change adds mem_list_variant.txt that contains the list of
memory parts used by ripto and Makefile.inc generated by
gen_part_id.go using mem_list_variant.txt.
In the final change of the series, all volteer variants will be
switched from using the current SPDs to new auto-generated SPDs.
Differences in auto-generated SPD from current SPD are as follows:
Part: K4U6E3S4AA-MGCL
Byte# Current New Explanation
6 0x95 0x05 As per datasheet, this is a single
die device. So, value should be
0x05.
19 0x00 0xFF As per JEDEC spec, tckMax should be
100ns. So, value should be 0xff as
per datasheet.
21,22 0x55,0x00 0x54,0x05 As per datasheet, part supports CAS
latencies 20,24,28,32,36. So value
should be 0x54, 0x05.
24 0x8C 0x87 taa is .468ns * CAS-36 which results
in byte 24 being 0x87 as per datasheet.
123 0x00 0xE5 Fine offset for taa. Expected value
is 0xE5 as per datasheet.
124 0x7F 0x00 Fine offset for tckMax. Expected
value is 0x00 as per datasheet.
125 0xE1 0xE0 Fine offset for tckMin. As per
datasheet tckMin is 0.468ns. So, this
comes out to be 0xE0.
BUG=b:155239397,b:147321551
Change-Id: Ibb06443a5c7fd80915f66b806cdd7c3ae1275b05
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
A src/mainboard/google/volteer/variants/ripto/memory/Makefile.inc
A src/mainboard/google/volteer/variants/ripto/memory/mem_list_variant.txt
2 files changed, 5 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/14/41614/1
diff --git a/src/mainboard/google/volteer/variants/ripto/memory/Makefile.inc b/src/mainboard/google/volteer/variants/ripto/memory/Makefile.inc
new file mode 100644
index 0000000..ac644a1
--- /dev/null
+++ b/src/mainboard/google/volteer/variants/ripto/memory/Makefile.inc
@@ -0,0 +1,4 @@
+## SPDX-License-Identifier: GPL-2.0-or-later
+
+SPD_SOURCES =
+SPD_SOURCES += spd-3.hex # ID = 0(0b0000) Parts = K4U6E3S4AA-MGCL
diff --git a/src/mainboard/google/volteer/variants/ripto/memory/mem_list_variant.txt b/src/mainboard/google/volteer/variants/ripto/memory/mem_list_variant.txt
new file mode 100644
index 0000000..a226d2f
--- /dev/null
+++ b/src/mainboard/google/volteer/variants/ripto/memory/mem_list_variant.txt
@@ -0,0 +1 @@
+K4U6E3S4AA-MGCL
--
To view, visit https://review.coreboot.org/c/coreboot/+/41614
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ibb06443a5c7fd80915f66b806cdd7c3ae1275b05
Gerrit-Change-Number: 41614
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-MessageType: newchange
Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41616 )
Change subject: mb/google/volteer/var/halvor: Use auto-generated Makefile.inc using gen_part_id.go
......................................................................
mb/google/volteer/var/halvor: Use auto-generated Makefile.inc using gen_part_id.go
This change adds mem_list_variant.txt that contains the list of
memory parts used by halvor and Makefile.inc generated by
gen_part_id.go using mem_list_variant.txt.
In the final change of the series, all volteer variants will be
switched from using the current SPDs to new auto-generated SPDs.
Differences in auto-generated SPD from current SPD are as follows:
Part: H9HKNNNCRMBVAR-NEH
Byte# Current New Explanation
4 0x16 0x15 As per datasheet, density is 8Gb per
logical channel. So value should be 0x15.
16 0x00 0x48 Unsure about this byte. All other
SPDs set this to 0x48. So, keeping it
consistent.
19 0x0F 0xFF As per JEDEC spec, tckMax should be
100ns. So, value should be 0xff as
per datasheet.
29,30 0xE0,0x0B 0xC0,0x08 As per datasheet, this corresponds to
280ns in MTB units which is 0x08C0.
31,32 0xF0,0x05 0x60,0x04 As per datasheet, this corresponds to
140ns in MTB units which is 0x0460.
125 0xE1 0xE0 Fine offset for tckMin. tckMin is
calculated as (1/4267)*2 which comes
out to be 0.46871. Some datasheets
round this down to 0.468 and others
round it up to 0.469. JEDEC spec uses
0.468. As per that, this value comes
out to be 0xE0.
Part: MT53E1G64D4SQ-046 WT:A
Byte# Current New Explanation
5 0x21 0x29 As per datasheet, this part has 17row
address bits and 10column address
bits. This results in 0x29.
16 0x00 0x48 Unsure about this byte. All other
SPDs set this to 0x48. So, keeping it
consistent.
19 0x0F 0xFF As per JEDEC spec, tckMax should be
100ns. So, value should be 0xff as
per datasheet.
125 0xE1 0xE0 Fine offset for tckMin. As per
datasheet tckMin is 0.468ns. So, this
comes out to be 0xE0.
BUG=b:147321551,b:155423877
Change-Id: I28b065a00380516d8686279a92ef68b9f17e2f65
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
A src/mainboard/google/volteer/variants/halvor/memory/Makefile.inc
A src/mainboard/google/volteer/variants/halvor/memory/mem_list_variant.txt
2 files changed, 7 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/41616/1
diff --git a/src/mainboard/google/volteer/variants/halvor/memory/Makefile.inc b/src/mainboard/google/volteer/variants/halvor/memory/Makefile.inc
new file mode 100644
index 0000000..8990e85
--- /dev/null
+++ b/src/mainboard/google/volteer/variants/halvor/memory/Makefile.inc
@@ -0,0 +1,5 @@
+## SPDX-License-Identifier: GPL-2.0-or-later
+
+SPD_SOURCES =
+SPD_SOURCES += spd-6.hex # ID = 0(0b0000) Parts = H9HKNNNCRMBVAR-NEH
+SPD_SOURCES += spd-7.hex # ID = 1(0b0001) Parts = MT53E1G64D4SQ-046 WT:A
diff --git a/src/mainboard/google/volteer/variants/halvor/memory/mem_list_variant.txt b/src/mainboard/google/volteer/variants/halvor/memory/mem_list_variant.txt
new file mode 100644
index 0000000..8fdcce6
--- /dev/null
+++ b/src/mainboard/google/volteer/variants/halvor/memory/mem_list_variant.txt
@@ -0,0 +1,2 @@
+H9HKNNNCRMBVAR-NEH
+MT53E1G64D4SQ-046 WT:A
--
To view, visit https://review.coreboot.org/c/coreboot/+/41616
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I28b065a00380516d8686279a92ef68b9f17e2f65
Gerrit-Change-Number: 41616
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-MessageType: newchange
Furquan Shaikh has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41615 )
Change subject: mb/google/volteer/var/malefor: Use auto-generated Makefile.inc using gen_part_id.go
......................................................................
mb/google/volteer/var/malefor: Use auto-generated Makefile.inc using gen_part_id.go
This change adds mem_list_variant.txt that contains the list of
memory parts used by malefor and Makefile.inc generated by
gen_part_id.go using mem_list_variant.txt.
In the final change of the series, all volteer variants will be
switched from using the current SPDs to new auto-generated SPDs.
Differences in auto-generated SPD from current SPD are as follows:
Part: K4U6E3S4AA-MGCL
Byte# Current New Explanation
6 0x95 0x05 As per datasheet, this is a single
die device. So, value should be
0x05.
19 0x00 0xFF As per JEDEC spec, tckMax should be
100ns. So, value should be 0xff as
per datasheet.
21,22 0x55,0x00 0x54,0x05 As per datasheet, part supports CAS
latencies 20,24,28,32,36. So value
should be 0x54, 0x05.
24 0x8C 0x87 taa is .468ns * CAS-36 which results
in byte 24 being 0x87 as per datasheet.
123 0x00 0xE5 Fine offset for taa. Expected value
is 0xE5 as per datasheet.
124 0x7F 0x00 Fine offset for tckMax. Expected
value is 0x00 as per datasheet.
125 0xE1 0xE0 Fine offset for tckMin. As per
datasheet tckMin is 0.468ns. So, this
comes out to be 0xE0.
BUG=b:155239397,b:147321551
Change-Id: I8b8bdc55314f538aff4dd1944a0b745357744d8c
Signed-off-by: Furquan Shaikh <furquan(a)google.com>
---
A src/mainboard/google/volteer/variants/malefor/memory/Makefile.inc
A src/mainboard/google/volteer/variants/malefor/memory/mem_list_variant.txt
2 files changed, 5 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/15/41615/1
diff --git a/src/mainboard/google/volteer/variants/malefor/memory/Makefile.inc b/src/mainboard/google/volteer/variants/malefor/memory/Makefile.inc
new file mode 100644
index 0000000..ac644a1
--- /dev/null
+++ b/src/mainboard/google/volteer/variants/malefor/memory/Makefile.inc
@@ -0,0 +1,4 @@
+## SPDX-License-Identifier: GPL-2.0-or-later
+
+SPD_SOURCES =
+SPD_SOURCES += spd-3.hex # ID = 0(0b0000) Parts = K4U6E3S4AA-MGCL
diff --git a/src/mainboard/google/volteer/variants/malefor/memory/mem_list_variant.txt b/src/mainboard/google/volteer/variants/malefor/memory/mem_list_variant.txt
new file mode 100644
index 0000000..a226d2f
--- /dev/null
+++ b/src/mainboard/google/volteer/variants/malefor/memory/mem_list_variant.txt
@@ -0,0 +1 @@
+K4U6E3S4AA-MGCL
--
To view, visit https://review.coreboot.org/c/coreboot/+/41615
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I8b8bdc55314f538aff4dd1944a0b745357744d8c
Gerrit-Change-Number: 41615
Gerrit-PatchSet: 1
Gerrit-Owner: Furquan Shaikh <furquan(a)google.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-MessageType: newchange
Usha P has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/41853 )
Change subject: mb/google/dedede: config spk_en gpio to low by default
......................................................................
Patch Set 3:
(2 comments)
https://review.coreboot.org/c/coreboot/+/41853/3//COMMIT_MSG
Commit Message:
https://review.coreboot.org/c/coreboot/+/41853/3//COMMIT_MSG@10
PS3, Line 10: based on use, so configure it low to save power.
> Yes, we are seeing a power saving of ~10mW.
Done
https://review.coreboot.org/c/coreboot/+/41853/2/src/mainboard/google/deded…
File src/mainboard/google/dedede/variants/baseboard/gpio.c:
https://review.coreboot.org/c/coreboot/+/41853/2/src/mainboard/google/deded…
PS2, Line 178: GPP_D17
> As mentioned by Usha, audio support for waddledee is yet to be added. […]
Done
--
To view, visit https://review.coreboot.org/c/coreboot/+/41853
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I070679457b06cb82633c1197b893a5d89c8b2cf0
Gerrit-Change-Number: 41853
Gerrit-PatchSet: 3
Gerrit-Owner: Usha P <usha.p(a)intel.com>
Gerrit-Reviewer: Aamir Bohra <aamir.bohra(a)intel.com>
Gerrit-Reviewer: Divagar Mohandass <divagar.mohandass(a)intel.com>
Gerrit-Reviewer: Furquan Shaikh <furquan(a)google.com>
Gerrit-Reviewer: Karthik Ramasubramanian <kramasub(a)google.com>
Gerrit-Reviewer: Maulik V Vaghela <maulik.v.vaghela(a)intel.com>
Gerrit-Reviewer: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-Comment-Date: Mon, 08 Jun 2020 05:14:17 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Furquan Shaikh <furquan(a)google.com>
Comment-In-Reply-To: Paul Menzel <paulepanter(a)users.sourceforge.net>
Comment-In-Reply-To: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Comment-In-Reply-To: Usha P <usha.p(a)intel.com>
Comment-In-Reply-To: Karthik Ramasubramanian <kramasub(a)google.com>
Gerrit-MessageType: comment
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/37441 )
Change subject: src/mainboard/supermicro/x11-lga1151v2-series: Add Support for X11SCH-F
......................................................................
Patch Set 51:
(2 comments)
https://review.coreboot.org/c/coreboot/+/37441/51//COMMIT_MSG
Commit Message:
https://review.coreboot.org/c/coreboot/+/37441/51//COMMIT_MSG@23
PS51, Line 23: 84
In decimal?
https://review.coreboot.org/c/coreboot/+/37441/51//COMMIT_MSG@26
PS51, Line 26:
> Please mention, why the code can’t be shared with the x11-lga1151 series code.
It's a different platform (Coffee Lake vs Skylake/Kaby Lake), so sharing code is just not worth the hassle. We don't use variants in coreboot when the boards use different chipset code anyway.
--
To view, visit https://review.coreboot.org/c/coreboot/+/37441
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I0ab1cb9462607b9af068bc2374508d99c60d0a30
Gerrit-Change-Number: 37441
Gerrit-PatchSet: 51
Gerrit-Owner: Christian Walter <christian.walter(a)9elements.com>
Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Reviewer: Christian Walter <christian.walter(a)9elements.com>
Gerrit-Reviewer: Guido Beyer @ Prodrive Technologies <guido.beyer(a)prodrive-technologies.com>
Gerrit-Reviewer: Justin van Son <justin.van.son(a)prodrive-technologies.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-Reviewer: Patrick Rudolph <patrick.rudolph(a)9elements.com>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki(a)gmail.com>
Gerrit-Reviewer: Stef van Os <stef.van.os(a)prodrive-technologies.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-Reviewer: wouter.eckhardt(a)prodrive-technologies.com
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-Comment-Date: Sun, 07 Jun 2020 22:49:31 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-MessageType: comment