soc/intel/ptl: Update ME specification version to 21
[coreboot.git] / util / spd_tools / src / spd_gen / lp4x.go
blob5257bcb92a9ee640ea993dde9502cf49e5095035
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 package main
4 import (
5 "encoding/json"
6 "fmt"
7 "strconv"
8 "strings"
11 /* ------------------------------------------------------------------------------------------ */
12 /* LP4x-defined types */
13 /* ------------------------------------------------------------------------------------------ */
15 type lp4x struct {
18 type LP4xMemAttributes struct {
19 /* Primary attributes - must be provided by JSON file for each part */
20 DensityPerChannelGb int
21 Banks int
22 ChannelsPerDie int
23 DiesPerPackage int
24 BitWidthPerChannel int
25 RanksPerChannel int
26 SpeedMbps int
29 * All the following parameters are optional and required only if the part requires
30 * special parameters as per the datasheet.
32 /* Timing parameters */
33 TRFCABNs int
34 TRFCPBNs int
35 TRPABMinNs int
36 TRPPBMinNs int
37 TCKMinPs int
38 TCKMaxPs int
39 TAAMinPs int
40 TRCDMinNs int
42 /* CAS */
43 CASLatencies string
44 CASFirstByte byte
45 CASSecondByte byte
46 CASThirdByte byte
49 type LP4xSpeedParams struct {
50 TCKMinPs int
51 TCKMaxPs int
52 CASLatenciesx16Channel string
53 CASLatenciesx8Channel string
56 type LP4xRefreshTimings struct {
57 TRFCABNs int
58 TRFCPBNs int
61 type LP4xSPDAttribFunc func(*LP4xMemAttributes) byte
63 type LP4xSPDAttribTableEntry struct {
64 constVal byte
65 getVal LP4xSPDAttribFunc
68 type LP4xSetFunc func(*LP4xMemAttributes) int
70 type LP4xSet struct {
71 getMRCDensity LP4xSetFunc
72 getDiesPerPackage LP4xSetFunc
73 busWidthEncoding byte
74 normalizeAttribs LP4xSetFunc
77 /* ------------------------------------------------------------------------------------------ */
78 /* Constants */
79 /* ------------------------------------------------------------------------------------------ */
81 const (
82 /* SPD Byte Index */
83 LP4xSPDIndexSize = 0
84 LP4xSPDIndexRevision = 1
85 LP4xSPDIndexMemoryType = 2
86 LP4xSPDIndexModuleType = 3
87 LP4xSPDIndexDensityBanks = 4
88 LP4xSPDIndexAddressing = 5
89 LP4xSPDIndexPackageType = 6
90 LP4xSPDIndexOptionalFeatures = 7
91 LP4xSPDIndexModuleOrganization = 12
92 LP4xSPDIndexBusWidth = 13
93 LP4xSPDIndexTimebases = 17
94 LP4xSPDIndexTCKMin = 18
95 LP4xSPDIndexTCKMax = 19
96 LP4xSPDIndexCASFirstByte = 20
97 LP4xSPDIndexCASSecondByte = 21
98 LP4xSPDIndexCASThirdByte = 22
99 LP4xSPDIndexCASFourthByte = 23
100 LP4xSPDIndexTAAMin = 24
101 LP4xSPDIndexReadWriteLatency = 25
102 LP4xSPDIndexTRCDMin = 26
103 LP4xSPDIndexTRPABMin = 27
104 LP4xSPDIndexTRPPBMin = 28
105 LP4xSPDIndexTRFCABMinLSB = 29
106 LP4xSPDIndexTRFCABMinMSB = 30
107 LP4xSPDIndexTRFCPBMinLSB = 31
108 LP4xSPDIndexTRFCPBMinMSB = 32
109 LP4xSPDIndexTRPPBMinFineOffset = 120
110 LP4xSPDIndexTRPABMinFineOffset = 121
111 LP4xSPDIndexTRCDMinFineOffset = 122
112 LP4xSPDIndexTAAMinFineOffset = 123
113 LP4xSPDIndexTCKMaxFineOffset = 124
114 LP4xSPDIndexTCKMinFineOffset = 125
115 LP4xSPDIndexManufacturerPartNumberStartByte = 329
116 LP4xSPDIndexManufacturerPartNumberEndByte = 348
118 /* SPD Byte Value */
121 * From JEDEC spec:
122 * 6:4 (Bytes total) = 2 (512 bytes)
123 * 3:0 (Bytes used) = 3 (384 bytes)
124 * Set to 0x23 for LPDDR4x.
126 LP4xSPDValueSize = 0x23
129 * From JEDEC spec: Revision 1.1
130 * Set to 0x11.
132 LP4xSPDValueRevision = 0x11
134 /* LPDDR4x memory type = 0x11 */
135 LP4xSPDValueMemoryType = 0x11
138 * From JEDEC spec:
139 * 7:7 (Hybrid) = 0 (Not hybrid)
140 * 6:4 (Hybrid media) = 000 (Not hybrid)
141 * 3:0 (Base Module Type) = 1110 (Non-DIMM solution)
143 * This is dependent on hardware design. LPDDR4x only has memory down solution.
144 * Hence this is not hybrid non-DIMM solution.
145 * Set to 0x0E.
147 LP4xSPDValueModuleType = 0x0e
150 * From JEDEC spec:
151 * 5:4 (Maximum Activate Window) = 00 (8192 * tREFI)
152 * 3:0 (Maximum Activate Count) = 1000 (Unlimited MAC)
154 * Needs to come from datasheet, but most parts seem to support unlimited MAC.
155 * MR#24 OP3
157 LP4xSPDValueOptionalFeatures = 0x08
160 * From JEDEC spec:
161 * 3:2 (MTB) = 00 (0.125ns)
162 * 1:0 (FTB) = 00 (1ps)
163 * Set to 0x00.
165 LP4xSPDValueTimebases = 0x00
167 /* CAS fourth byte: All bits are reserved */
168 LP4xSPDValueCASFourthByte = 0x00
170 /* Write Latency Set A and Read Latency DBI-RD disabled. */
171 LP4xSPDValueReadWriteLatency = 0x00
173 /* As per JEDEC spec, unused digits of manufacturer part number are left as blank. */
174 LP4xSPDValueManufacturerPartNumberBlank = 0x20
177 const (
178 /* First Byte */
179 LP4xCAS6 = 1 << 1
180 LP4xCAS10 = 1 << 4
181 LP4xCAS14 = 1 << 7
182 /* Second Byte */
183 LP4xCAS16 = 1 << 0
184 LP4xCAS20 = 1 << 2
185 LP4xCAS22 = 1 << 3
186 LP4xCAS24 = 1 << 4
187 LP4xCAS26 = 1 << 5
188 LP4xCAS28 = 1 << 6
189 /* Third Byte */
190 LP4xCAS32 = 1 << 0
191 LP4xCAS36 = 1 << 2
192 LP4xCAS40 = 1 << 4
195 const (
197 * JEDEC spec says that TCKmax should be 100ns for all speed grades.
198 * 100ns in MTB units comes out to be 0x320. But since this is a byte field, set it to
199 * 0xFF i.e. 31.875ns.
201 LP4xTCKMaxPsDefault = 31875
204 /* ------------------------------------------------------------------------------------------ */
205 /* Global variables */
206 /* ------------------------------------------------------------------------------------------ */
208 var LP4xPlatformSetMap = map[int][]int{
209 0: {PlatformTGL, PlatformADL},
210 1: {PlatformJSL, PlatformCZN},
213 var LP4xSetInfo = map[int]LP4xSet{
214 0: {
215 getMRCDensity: LP4xGetMRCDensitySet0,
216 getDiesPerPackage: LP4xGetDiesPerPackageSet0,
218 * As per advisory 616599:
219 * 7:5 (Number of system channels) = 000 (1 channel always)
220 * 2:0 (Bus width) = 001 (x16 always)
221 * Set to 0x01.
223 busWidthEncoding: 0x01,
224 normalizeAttribs: LP4xNormalizeAttribsSet0,
226 1: {
227 getMRCDensity: LP4xGetMRCDensitySet1,
228 getDiesPerPackage: LP4xGetDiesPerPackageSet1,
230 * As per advisory 610202:
231 * 7:5 (Number of system channels) = 001 (2 channel always)
232 * 2:0 (Bus width) = 010 (x32 always)
233 * Set to 0x22.
235 busWidthEncoding: 0x22,
239 var LP4xPartAttributeMap = map[string]LP4xMemAttributes{}
240 var LP4xCurrSet int
242 /* This encodes the density in Gb to SPD values as per JESD 21-C */
243 var LP4xDensityGbToSPDEncoding = map[int]byte{
244 4: 0x4,
245 6: 0xb,
246 8: 0x5,
247 12: 0x8,
248 16: 0x6,
249 24: 0x9,
250 32: 0x7,
254 * Table 5 from JESD209-4C.
255 * Maps density per physical channel to row-column encoding as per JESD 21-C for a device with
256 * x8 physical channel.
258 var LP4xDensityGbx8ChannelToRowColumnEncoding = map[int]byte{
259 3: 0x21, /* 16 rows, 10 columns */
260 4: 0x21, /* 16 rows, 10 columns */
261 6: 0x29, /* 17 rows, 10 columns */
262 8: 0x29, /* 17 rows, 10 columns */
263 12: 0x31, /* 18 rows, 10 columns */
264 16: 0x31, /* 18 rows, 10 columns */
268 * Table 3 from JESD209-4C.
269 * Maps density per physical channel to row-column encoding as per JESD 21-C for a device with
270 * x16 physical channel.
272 var LP4xDensityGbx16ChannelToRowColumnEncoding = map[int]byte{
273 4: 0x19, /* 15 rows, 10 columns */
274 6: 0x21, /* 16 rows, 10 columns */
275 8: 0x21, /* 16 rows, 10 columns */
276 12: 0x29, /* 17 rows, 10 columns */
277 16: 0x29, /* 17 rows, 10 columns */
281 * Table 112 from JESD209-4C
282 * Maps density per physical channel to refresh timings. This is the same for x8 and x16
283 * devices.
285 var LP4xDensityGbPhysicalChannelToRefreshEncoding = map[int]LP4xRefreshTimings{
286 3: {
287 TRFCABNs: 180,
288 TRFCPBNs: 90,
290 4: {
291 TRFCABNs: 180,
292 TRFCPBNs: 90,
294 6: {
295 TRFCABNs: 280,
296 TRFCPBNs: 140,
298 8: {
299 TRFCABNs: 280,
300 TRFCPBNs: 140,
302 12: {
303 TRFCABNs: 380,
304 TRFCPBNs: 190,
306 16: {
307 TRFCABNs: 380,
308 TRFCPBNs: 190,
312 var LP4xBankEncoding = map[int]byte{
313 4: 0 << 4,
314 8: 1 << 4,
317 var LP4xSpeedMbpsToSPDEncoding = map[int]LP4xSpeedParams{
318 4267: {
319 TCKMinPs: 468, /* 1/4267 * 2 */
320 TCKMaxPs: LP4xTCKMaxPsDefault,
321 CASLatenciesx16Channel: "6 10 14 20 24 28 32 36",
322 CASLatenciesx8Channel: "6 10 16 22 26 32 36 40",
324 3733: {
325 TCKMinPs: 535, /* 1/3733 * 2 */
326 TCKMaxPs: LP4xTCKMaxPsDefault,
327 CASLatenciesx16Channel: "6 10 14 20 24 28 32",
328 CASLatenciesx8Channel: "6 10 16 22 26 32 36",
330 3200: {
331 TCKMinPs: 625, /* 1/3200 * 2 */
332 TCKMaxPs: LP4xTCKMaxPsDefault,
333 CASLatenciesx16Channel: "6 10 14 20 24 28",
334 CASLatenciesx8Channel: "6 10 16 22 26 32",
338 var LP4xSPDAttribTable = map[int]LP4xSPDAttribTableEntry{
339 LP4xSPDIndexSize: {constVal: LP4xSPDValueSize},
340 LP4xSPDIndexRevision: {constVal: LP4xSPDValueRevision},
341 LP4xSPDIndexMemoryType: {constVal: LP4xSPDValueMemoryType},
342 LP4xSPDIndexModuleType: {constVal: LP4xSPDValueModuleType},
343 LP4xSPDIndexDensityBanks: {getVal: LP4xEncodeDensityBanks},
344 LP4xSPDIndexAddressing: {getVal: LP4xEncodeSdramAddressing},
345 LP4xSPDIndexPackageType: {getVal: LP4xEncodePackageType},
346 LP4xSPDIndexOptionalFeatures: {constVal: LP4xSPDValueOptionalFeatures},
347 LP4xSPDIndexModuleOrganization: {getVal: LP4xEncodeModuleOrganization},
348 LP4xSPDIndexBusWidth: {getVal: LP4xEncodeBusWidth},
349 LP4xSPDIndexTimebases: {constVal: LP4xSPDValueTimebases},
350 LP4xSPDIndexTCKMin: {getVal: LP4xEncodeTCKMin},
351 LP4xSPDIndexTCKMax: {getVal: LP4xEncodeTCKMax},
352 LP4xSPDIndexTCKMaxFineOffset: {getVal: LP4xEncodeTCKMaxFineOffset},
353 LP4xSPDIndexTCKMinFineOffset: {getVal: LP4xEncodeTCKMinFineOffset},
354 LP4xSPDIndexCASFirstByte: {getVal: LP4xEncodeCASFirstByte},
355 LP4xSPDIndexCASSecondByte: {getVal: LP4xEncodeCASSecondByte},
356 LP4xSPDIndexCASThirdByte: {getVal: LP4xEncodeCASThirdByte},
357 LP4xSPDIndexCASFourthByte: {constVal: LP4xSPDValueCASFourthByte},
358 LP4xSPDIndexTAAMin: {getVal: LP4xEncodeTAAMin},
359 LP4xSPDIndexTAAMinFineOffset: {getVal: LP4xEncodeTAAMinFineOffset},
360 LP4xSPDIndexReadWriteLatency: {constVal: LP4xSPDValueReadWriteLatency},
361 LP4xSPDIndexTRCDMin: {getVal: LP4xEncodeTRCDMin},
362 LP4xSPDIndexTRCDMinFineOffset: {getVal: LP4xEncodeTRCDMinFineOffset},
363 LP4xSPDIndexTRPABMin: {getVal: LP4xEncodeTRPABMin},
364 LP4xSPDIndexTRPABMinFineOffset: {getVal: LP4xEncodeTRPABMinFineOffset},
365 LP4xSPDIndexTRPPBMin: {getVal: LP4xEncodeTRPPBMin},
366 LP4xSPDIndexTRPPBMinFineOffset: {getVal: LP4xEncodeTRPPBMinFineOffset},
367 LP4xSPDIndexTRFCABMinLSB: {getVal: LP4xEncodeTRFCABMinLsb},
368 LP4xSPDIndexTRFCABMinMSB: {getVal: LP4xEncodeTRFCABMinMsb},
369 LP4xSPDIndexTRFCPBMinLSB: {getVal: LP4xEncodeTRFCPBMinLsb},
370 LP4xSPDIndexTRFCPBMinMSB: {getVal: LP4xEncodeTRFCPBMinMsb},
373 /* ------------------------------------------------------------------------------------------ */
374 /* Functions */
375 /* ------------------------------------------------------------------------------------------ */
377 func LP4xGetMRCDensitySet0(memAttribs *LP4xMemAttributes) int {
379 * Intel MRC on TGL/ADL expects density per logical channel to be encoded in
380 * SPDIndexDensityBanks. Logical channel on TGL/ADL is an x16 channel.
382 return memAttribs.DensityPerChannelGb * 16 / memAttribs.BitWidthPerChannel
385 func LP4xGetMRCDensitySet1(memAttribs *LP4xMemAttributes) int {
387 * Intel MRC on JSL expects density per die to be encoded in
388 * SPDIndexDensityBanks.
390 return memAttribs.DensityPerChannelGb * memAttribs.ChannelsPerDie
393 func LP4xGetMRCDensity(memAttribs *LP4xMemAttributes) int {
394 f, ok := LP4xSetInfo[LP4xCurrSet]
396 if ok == false || f.getMRCDensity == nil {
397 return 0
400 return f.getMRCDensity(memAttribs)
403 func LP4xEncodeDensityBanks(memAttribs *LP4xMemAttributes) byte {
404 var b byte
406 b = LP4xDensityGbToSPDEncoding[LP4xGetMRCDensity(memAttribs)]
407 b |= LP4xBankEncoding[memAttribs.Banks]
409 return b
412 func LP4xEncodeSdramAddressing(memAttribs *LP4xMemAttributes) byte {
413 densityPerChannelGb := memAttribs.DensityPerChannelGb
414 if memAttribs.BitWidthPerChannel == 8 {
415 return LP4xDensityGbx8ChannelToRowColumnEncoding[densityPerChannelGb]
416 } else {
417 return LP4xDensityGbx16ChannelToRowColumnEncoding[densityPerChannelGb]
419 return 0
422 func LP4xEncodePackage(dies int) byte {
423 var temp byte
425 if dies > 1 {
426 /* If more than one die, then this is a non-monolithic device. */
427 temp = 1
428 } else {
429 /* If only single die, then this is a monolithic device. */
430 temp = 0
433 return temp << 7
436 func LP4xEncodeChannelsPerDie(channels int) byte {
437 var temp byte
439 temp = byte(channels >> 1)
441 return temp << 2
444 func LP4xGetDiesPerPackageSet0(memAttribs *LP4xMemAttributes) int {
445 /* Intel MRC expects logical dies to be encoded for TGL/ADL. */
446 return memAttribs.ChannelsPerDie * memAttribs.RanksPerChannel * memAttribs.BitWidthPerChannel / 16
449 func LP4xGetDiesPerPackageSet1(memAttribs *LP4xMemAttributes) int {
450 /* Intel MRC expects physical dies to be encoded for JSL. */
451 /* AMD PSP expects physical dies (ZQ balls) */
452 return memAttribs.DiesPerPackage
455 /* Per JESD209-4C Dies = ZQ balls on the package */
456 /* Note that this can be different than the part's die count */
457 func LP4xEncodeDiesPerPackage(memAttribs *LP4xMemAttributes) byte {
458 var dies int = 0
460 f, ok := LP4xSetInfo[LP4xCurrSet]
461 if ok != false && f.getDiesPerPackage != nil {
462 dies = f.getDiesPerPackage(memAttribs)
465 b := LP4xEncodePackage(dies) /* Monolithic / Non-monolithic device */
466 b |= (byte(dies) - 1) << 4
468 return b
471 func LP4xEncodePackageType(memAttribs *LP4xMemAttributes) byte {
472 var b byte
474 b |= LP4xEncodeChannelsPerDie(memAttribs.ChannelsPerDie)
475 b |= LP4xEncodeDiesPerPackage(memAttribs)
477 return b
480 func LP4xEncodeDataWidth(bitWidthPerChannel int) byte {
481 return byte(bitWidthPerChannel / 8)
484 func LP4xEncodeRanks(ranks int) byte {
485 var b byte
486 b = byte(ranks - 1)
487 return b << 3
490 func LP4xEncodeModuleOrganization(memAttribs *LP4xMemAttributes) byte {
491 var b byte
493 b = LP4xEncodeDataWidth(memAttribs.BitWidthPerChannel)
494 b |= LP4xEncodeRanks(memAttribs.RanksPerChannel)
496 return b
499 func LP4xEncodeBusWidth(memAttribs *LP4xMemAttributes) byte {
500 f, ok := LP4xSetInfo[LP4xCurrSet]
502 if ok == false {
503 return 0
506 return f.busWidthEncoding
509 func LP4xEncodeTCKMin(memAttribs *LP4xMemAttributes) byte {
510 return convPsToMtbByte(memAttribs.TCKMinPs)
513 func LP4xEncodeTCKMinFineOffset(memAttribs *LP4xMemAttributes) byte {
514 return convPsToFtbByte(memAttribs.TCKMinPs)
517 func LP4xEncodeTCKMax(memAttribs *LP4xMemAttributes) byte {
518 return convPsToMtbByte(memAttribs.TCKMaxPs)
521 func LP4xEncodeTCKMaxFineOffset(memAttribs *LP4xMemAttributes) byte {
522 return convPsToFtbByte(memAttribs.TCKMaxPs)
525 func LP4xEncodeCASFirstByte(memAttribs *LP4xMemAttributes) byte {
526 return memAttribs.CASFirstByte
529 func LP4xEncodeCASSecondByte(memAttribs *LP4xMemAttributes) byte {
530 return memAttribs.CASSecondByte
533 func LP4xEncodeCASThirdByte(memAttribs *LP4xMemAttributes) byte {
534 return memAttribs.CASThirdByte
537 func LP4xEncodeTAAMin(memAttribs *LP4xMemAttributes) byte {
538 return convPsToMtbByte(memAttribs.TAAMinPs)
541 func LP4xEncodeTAAMinFineOffset(memAttribs *LP4xMemAttributes) byte {
542 return convPsToFtbByte(memAttribs.TAAMinPs)
545 func LP4xEncodeTRCDMin(memAttribs *LP4xMemAttributes) byte {
546 return convNsToMtbByte(memAttribs.TRCDMinNs)
549 func LP4xEncodeTRCDMinFineOffset(memAttribs *LP4xMemAttributes) byte {
550 return convNsToFtbByte(memAttribs.TRCDMinNs)
553 func LP4xEncodeTRPABMin(memAttribs *LP4xMemAttributes) byte {
554 return convNsToMtbByte(memAttribs.TRPABMinNs)
557 func LP4xEncodeTRPABMinFineOffset(memAttribs *LP4xMemAttributes) byte {
558 return convNsToFtbByte(memAttribs.TRPABMinNs)
561 func LP4xEncodeTRPPBMin(memAttribs *LP4xMemAttributes) byte {
562 return convNsToMtbByte(memAttribs.TRPPBMinNs)
565 func LP4xEncodeTRPPBMinFineOffset(memAttribs *LP4xMemAttributes) byte {
566 return convNsToFtbByte(memAttribs.TRPPBMinNs)
569 func LP4xEncodeTRFCABMinMsb(memAttribs *LP4xMemAttributes) byte {
570 return byte((convNsToMtb(memAttribs.TRFCABNs) >> 8) & 0xff)
573 func LP4xEncodeTRFCABMinLsb(memAttribs *LP4xMemAttributes) byte {
574 return byte(convNsToMtb(memAttribs.TRFCABNs) & 0xff)
577 func LP4xEncodeTRFCPBMinMsb(memAttribs *LP4xMemAttributes) byte {
578 return byte((convNsToMtb(memAttribs.TRFCPBNs) >> 8) & 0xff)
581 func LP4xEncodeTRFCPBMinLsb(memAttribs *LP4xMemAttributes) byte {
582 return byte(convNsToMtb(memAttribs.TRFCPBNs) & 0xff)
585 func LP4xEncodeLatencies(latency int, memAttribs *LP4xMemAttributes) error {
586 switch latency {
587 case 6:
588 memAttribs.CASFirstByte |= LP4xCAS6
589 case 10:
590 memAttribs.CASFirstByte |= LP4xCAS10
591 case 14:
592 memAttribs.CASFirstByte |= LP4xCAS14
593 case 16:
594 memAttribs.CASSecondByte |= LP4xCAS16
595 case 20:
596 memAttribs.CASSecondByte |= LP4xCAS20
597 case 22:
598 memAttribs.CASSecondByte |= LP4xCAS22
599 case 24:
600 memAttribs.CASSecondByte |= LP4xCAS24
601 case 26:
602 memAttribs.CASSecondByte |= LP4xCAS26
603 case 28:
604 memAttribs.CASSecondByte |= LP4xCAS28
605 case 32:
606 memAttribs.CASThirdByte |= LP4xCAS32
607 case 36:
608 memAttribs.CASThirdByte |= LP4xCAS36
609 case 40:
610 memAttribs.CASThirdByte |= LP4xCAS40
611 default:
612 fmt.Errorf("Incorrect CAS Latency: ", latency)
615 return nil
618 func LP4xUpdateTCK(memAttribs *LP4xMemAttributes) {
619 if memAttribs.TCKMinPs == 0 {
620 memAttribs.TCKMinPs = LP4xSpeedMbpsToSPDEncoding[memAttribs.SpeedMbps].TCKMinPs
622 if memAttribs.TCKMaxPs == 0 {
623 memAttribs.TCKMaxPs = LP4xSpeedMbpsToSPDEncoding[memAttribs.SpeedMbps].TCKMaxPs
627 func LP4xGetCASLatencies(memAttribs *LP4xMemAttributes) string {
628 if memAttribs.BitWidthPerChannel == 16 {
629 return LP4xSpeedMbpsToSPDEncoding[memAttribs.SpeedMbps].CASLatenciesx16Channel
630 } else if memAttribs.BitWidthPerChannel == 8 {
631 return LP4xSpeedMbpsToSPDEncoding[memAttribs.SpeedMbps].CASLatenciesx8Channel
634 return ""
637 func LP4xUpdateCAS(memAttribs *LP4xMemAttributes) error {
638 if len(memAttribs.CASLatencies) == 0 {
639 memAttribs.CASLatencies = LP4xGetCASLatencies(memAttribs)
642 latencies := strings.Fields(memAttribs.CASLatencies)
643 for i := 0; i < len(latencies); i++ {
644 latency, err := strconv.Atoi(latencies[i])
645 if err != nil {
646 return fmt.Errorf("Unable to convert latency ", latencies[i])
648 if err := LP4xEncodeLatencies(latency, memAttribs); err != nil {
649 return err
652 return nil
655 func LP4xGetMinCAS(memAttribs *LP4xMemAttributes) (int, error) {
656 if (memAttribs.CASThirdByte & LP4xCAS40) != 0 {
657 return 40, nil
659 if (memAttribs.CASThirdByte & LP4xCAS36) != 0 {
660 return 36, nil
662 if (memAttribs.CASThirdByte & LP4xCAS32) != 0 {
663 return 32, nil
665 if (memAttribs.CASSecondByte & LP4xCAS28) != 0 {
666 return 28, nil
669 return 0, fmt.Errorf("Unexpected min CAS")
672 func LP4xUpdateTAAMin(memAttribs *LP4xMemAttributes) error {
673 if memAttribs.TAAMinPs == 0 {
674 minCAS, err := LP4xGetMinCAS(memAttribs)
675 if err != nil {
676 return err
678 memAttribs.TAAMinPs = memAttribs.TCKMinPs * minCAS
681 return nil
684 func LP4xUpdateTRFCAB(memAttribs *LP4xMemAttributes) {
685 if memAttribs.TRFCABNs == 0 {
686 memAttribs.TRFCABNs = LP4xDensityGbPhysicalChannelToRefreshEncoding[memAttribs.DensityPerChannelGb].TRFCABNs
690 func LP4xUpdateTRFCPB(memAttribs *LP4xMemAttributes) {
691 if memAttribs.TRFCPBNs == 0 {
692 memAttribs.TRFCPBNs = LP4xDensityGbPhysicalChannelToRefreshEncoding[memAttribs.DensityPerChannelGb].TRFCPBNs
696 func LP4xUpdateTRCD(memAttribs *LP4xMemAttributes) {
697 if memAttribs.TRCDMinNs == 0 {
698 /* JEDEC spec says max of 18ns */
699 memAttribs.TRCDMinNs = 18
703 func LP4xUpdateTRPAB(memAttribs *LP4xMemAttributes) {
704 if memAttribs.TRPABMinNs == 0 {
705 /* JEDEC spec says max of 21ns */
706 memAttribs.TRPABMinNs = 21
710 func LP4xUpdateTRPPB(memAttribs *LP4xMemAttributes) {
711 if memAttribs.TRPPBMinNs == 0 {
712 /* JEDEC spec says max of 18ns */
713 memAttribs.TRPPBMinNs = 18
717 func LP4xNormalizeAttribsSet0(memAttribs *LP4xMemAttributes) int {
719 * TGL does not really use physical organization of dies per package when
720 * generating the SPD. So, set it to 0 here so that deduplication ignores
721 * that field.
723 memAttribs.DiesPerPackage = 0
725 return 0
728 func LP4xNormalizeMemoryAttributes(memAttribs *LP4xMemAttributes) {
729 f, ok := LP4xSetInfo[LP4xCurrSet]
731 if ok == false || f.normalizeAttribs == nil {
732 return
735 f.normalizeAttribs(memAttribs)
738 func Lp4xUpdateMemoryAttributes(memAttribs *LP4xMemAttributes) error {
739 LP4xUpdateTCK(memAttribs)
740 if err := LP4xUpdateCAS(memAttribs); err != nil {
741 return err
743 if err := LP4xUpdateTAAMin(memAttribs); err != nil {
744 return err
746 LP4xUpdateTRFCAB(memAttribs)
747 LP4xUpdateTRFCPB(memAttribs)
748 LP4xUpdateTRCD(memAttribs)
749 LP4xUpdateTRPAB(memAttribs)
750 LP4xUpdateTRPPB(memAttribs)
752 LP4xNormalizeMemoryAttributes(memAttribs)
754 return nil
757 func LP4xValidateDensityx8Channel(densityPerChannelGb int) error {
758 if _, ok := LP4xDensityGbx8ChannelToRowColumnEncoding[densityPerChannelGb]; ok == false {
759 return fmt.Errorf("Incorrect x8 density: %d Gb", densityPerChannelGb)
761 return nil
764 func LP4xValidateDensityx16Channel(densityPerChannelGb int) error {
765 if _, ok := LP4xDensityGbx16ChannelToRowColumnEncoding[densityPerChannelGb]; ok == false {
766 return fmt.Errorf("Incorrect x16 density: %d Gb", densityPerChannelGb)
768 return nil
771 func LP4xValidateDensity(memAttribs *LP4xMemAttributes) error {
772 if memAttribs.BitWidthPerChannel == 8 {
773 return LP4xValidateDensityx8Channel(memAttribs.DensityPerChannelGb)
774 } else if memAttribs.BitWidthPerChannel == 16 {
775 return LP4xValidateDensityx16Channel(memAttribs.DensityPerChannelGb)
778 return fmt.Errorf("No density table for this bit width: %d", memAttribs.BitWidthPerChannel)
781 func LP4xValidateBanks(banks int) error {
782 if banks != 4 && banks != 8 {
783 return fmt.Errorf("Incorrect banks: %d", banks)
785 return nil
788 func LP4xValidateChannels(channels int) error {
789 if channels != 1 && channels != 2 && channels != 4 {
790 return fmt.Errorf("Incorrect channels per die: %d ", channels)
792 return nil
795 func LP4xValidateDataWidth(width int) error {
796 if width != 8 && width != 16 {
797 return fmt.Errorf("Incorrect bit width: %d", width)
799 return nil
802 func LP4xValidateRanks(ranks int) error {
803 if ranks != 1 && ranks != 2 {
804 return fmt.Errorf("Incorrect ranks: %d", ranks)
806 return nil
809 func LP4xValidateSpeed(speed int) error {
810 if _, ok := LP4xSpeedMbpsToSPDEncoding[speed]; ok == false {
811 return fmt.Errorf("Incorrect speed: %d Mbps", speed)
813 return nil
816 func Lp4xValidateMemPartAttributes(memAttribs *LP4xMemAttributes) error {
817 if err := LP4xValidateBanks(memAttribs.Banks); err != nil {
818 return err
820 if err := LP4xValidateChannels(memAttribs.ChannelsPerDie); err != nil {
821 return err
823 if err := LP4xValidateDataWidth(memAttribs.BitWidthPerChannel); err != nil {
824 return err
826 if err := LP4xValidateDensity(memAttribs); err != nil {
827 return err
829 if err := LP4xValidateRanks(memAttribs.RanksPerChannel); err != nil {
830 return err
832 if err := LP4xValidateSpeed(memAttribs.SpeedMbps); err != nil {
833 return err
836 return nil
839 func LP4xIsManufacturerPartNumberByte(index int) bool {
840 if index >= LP4xSPDIndexManufacturerPartNumberStartByte &&
841 index <= LP4xSPDIndexManufacturerPartNumberEndByte {
842 return true
844 return false
847 /* ------------------------------------------------------------------------------------------ */
848 /* Interface Functions */
849 /* ------------------------------------------------------------------------------------------ */
851 func (lp4x) getSetMap() map[int][]int {
852 return LP4xPlatformSetMap
855 func (lp4x) addNewPart(name string, attribs interface{}) error {
856 var lp4xAttributes LP4xMemAttributes
857 eByte, err := json.Marshal(attribs)
858 if err != nil {
859 return err
862 if err := json.Unmarshal(eByte, &lp4xAttributes); err != nil {
863 return err
866 if err := Lp4xValidateMemPartAttributes(&lp4xAttributes); err != nil {
867 return err
870 LP4xPartAttributeMap[name] = lp4xAttributes
871 return nil
874 func (lp4x) getSPDAttribs(name string, set int) (interface{}, error) {
875 lp4xAttributes := LP4xPartAttributeMap[name]
877 LP4xCurrSet = set
879 if err := Lp4xUpdateMemoryAttributes(&lp4xAttributes); err != nil {
880 return lp4xAttributes, err
883 return lp4xAttributes, nil
886 func (lp4x) getSPDLen() int {
887 return 512
890 func (lp4x) getSPDByte(index int, attribs interface{}) byte {
891 e, ok := LP4xSPDAttribTable[index]
892 if ok == false {
893 if LP4xIsManufacturerPartNumberByte(index) {
894 return LP4xSPDValueManufacturerPartNumberBlank
896 return 0x00
899 if e.getVal != nil {
900 var lp4xAttribs LP4xMemAttributes
901 lp4xAttribs = attribs.(LP4xMemAttributes)
902 return e.getVal(&lp4xAttribs)
905 return e.constVal