1 /* SPDX-License-Identifier: GPL-2.0-or-later */
11 /* ------------------------------------------------------------------------------------------ */
12 /* LP4x-defined types */
13 /* ------------------------------------------------------------------------------------------ */
18 type LP4xMemAttributes
struct {
19 /* Primary attributes - must be provided by JSON file for each part */
20 DensityPerChannelGb
int
24 BitWidthPerChannel
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 */
49 type LP4xSpeedParams
struct {
52 CASLatenciesx16Channel
string
53 CASLatenciesx8Channel
string
56 type LP4xRefreshTimings
struct {
61 type LP4xSPDAttribFunc
func(*LP4xMemAttributes
) byte
63 type LP4xSPDAttribTableEntry
struct {
65 getVal LP4xSPDAttribFunc
68 type LP4xSetFunc
func(*LP4xMemAttributes
) int
71 getMRCDensity LP4xSetFunc
72 getDiesPerPackage LP4xSetFunc
74 normalizeAttribs LP4xSetFunc
77 /* ------------------------------------------------------------------------------------------ */
79 /* ------------------------------------------------------------------------------------------ */
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
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
132 LP4xSPDValueRevision
= 0x11
134 /* LPDDR4x memory type = 0x11 */
135 LP4xSPDValueMemoryType
= 0x11
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.
147 LP4xSPDValueModuleType
= 0x0e
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.
157 LP4xSPDValueOptionalFeatures
= 0x08
161 * 3:2 (MTB) = 00 (0.125ns)
162 * 1:0 (FTB) = 00 (1ps)
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
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
{
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)
223 busWidthEncoding
: 0x01,
224 normalizeAttribs
: LP4xNormalizeAttribsSet0
,
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)
235 busWidthEncoding
: 0x22,
239 var LP4xPartAttributeMap
= map[string]LP4xMemAttributes
{}
242 /* This encodes the density in Gb to SPD values as per JESD 21-C */
243 var LP4xDensityGbToSPDEncoding
= map[int]byte{
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
285 var LP4xDensityGbPhysicalChannelToRefreshEncoding
= map[int]LP4xRefreshTimings
{
312 var LP4xBankEncoding
= map[int]byte{
317 var LP4xSpeedMbpsToSPDEncoding
= map[int]LP4xSpeedParams
{
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",
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",
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 /* ------------------------------------------------------------------------------------------ */
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 {
400 return f
.getMRCDensity(memAttribs
)
403 func LP4xEncodeDensityBanks(memAttribs
*LP4xMemAttributes
) byte {
406 b
= LP4xDensityGbToSPDEncoding
[LP4xGetMRCDensity(memAttribs
)]
407 b |
= LP4xBankEncoding
[memAttribs
.Banks
]
412 func LP4xEncodeSdramAddressing(memAttribs
*LP4xMemAttributes
) byte {
413 densityPerChannelGb
:= memAttribs
.DensityPerChannelGb
414 if memAttribs
.BitWidthPerChannel
== 8 {
415 return LP4xDensityGbx8ChannelToRowColumnEncoding
[densityPerChannelGb
]
417 return LP4xDensityGbx16ChannelToRowColumnEncoding
[densityPerChannelGb
]
422 func LP4xEncodePackage(dies
int) byte {
426 /* If more than one die, then this is a non-monolithic device. */
429 /* If only single die, then this is a monolithic device. */
436 func LP4xEncodeChannelsPerDie(channels
int) byte {
439 temp
= byte(channels
>> 1)
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 {
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
471 func LP4xEncodePackageType(memAttribs
*LP4xMemAttributes
) byte {
474 b |
= LP4xEncodeChannelsPerDie(memAttribs
.ChannelsPerDie
)
475 b |
= LP4xEncodeDiesPerPackage(memAttribs
)
480 func LP4xEncodeDataWidth(bitWidthPerChannel
int) byte {
481 return byte(bitWidthPerChannel
/ 8)
484 func LP4xEncodeRanks(ranks
int) byte {
490 func LP4xEncodeModuleOrganization(memAttribs
*LP4xMemAttributes
) byte {
493 b
= LP4xEncodeDataWidth(memAttribs
.BitWidthPerChannel
)
494 b |
= LP4xEncodeRanks(memAttribs
.RanksPerChannel
)
499 func LP4xEncodeBusWidth(memAttribs
*LP4xMemAttributes
) byte {
500 f
, ok
:= LP4xSetInfo
[LP4xCurrSet
]
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
{
588 memAttribs
.CASFirstByte |
= LP4xCAS6
590 memAttribs
.CASFirstByte |
= LP4xCAS10
592 memAttribs
.CASFirstByte |
= LP4xCAS14
594 memAttribs
.CASSecondByte |
= LP4xCAS16
596 memAttribs
.CASSecondByte |
= LP4xCAS20
598 memAttribs
.CASSecondByte |
= LP4xCAS22
600 memAttribs
.CASSecondByte |
= LP4xCAS24
602 memAttribs
.CASSecondByte |
= LP4xCAS26
604 memAttribs
.CASSecondByte |
= LP4xCAS28
606 memAttribs
.CASThirdByte |
= LP4xCAS32
608 memAttribs
.CASThirdByte |
= LP4xCAS36
610 memAttribs
.CASThirdByte |
= LP4xCAS40
612 fmt
.Errorf("Incorrect CAS Latency: ", latency
)
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
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
])
646 return fmt
.Errorf("Unable to convert latency ", latencies
[i
])
648 if err
:= LP4xEncodeLatencies(latency
, memAttribs
); err
!= nil {
655 func LP4xGetMinCAS(memAttribs
*LP4xMemAttributes
) (int, error
) {
656 if (memAttribs
.CASThirdByte
& LP4xCAS40
) != 0 {
659 if (memAttribs
.CASThirdByte
& LP4xCAS36
) != 0 {
662 if (memAttribs
.CASThirdByte
& LP4xCAS32
) != 0 {
665 if (memAttribs
.CASSecondByte
& LP4xCAS28
) != 0 {
669 return 0, fmt
.Errorf("Unexpected min CAS")
672 func LP4xUpdateTAAMin(memAttribs
*LP4xMemAttributes
) error
{
673 if memAttribs
.TAAMinPs
== 0 {
674 minCAS
, err
:= LP4xGetMinCAS(memAttribs
)
678 memAttribs
.TAAMinPs
= memAttribs
.TCKMinPs
* minCAS
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
723 memAttribs
.DiesPerPackage
= 0
728 func LP4xNormalizeMemoryAttributes(memAttribs
*LP4xMemAttributes
) {
729 f
, ok
:= LP4xSetInfo
[LP4xCurrSet
]
731 if ok
== false || f
.normalizeAttribs
== nil {
735 f
.normalizeAttribs(memAttribs
)
738 func Lp4xUpdateMemoryAttributes(memAttribs
*LP4xMemAttributes
) error
{
739 LP4xUpdateTCK(memAttribs
)
740 if err
:= LP4xUpdateCAS(memAttribs
); err
!= nil {
743 if err
:= LP4xUpdateTAAMin(memAttribs
); err
!= nil {
746 LP4xUpdateTRFCAB(memAttribs
)
747 LP4xUpdateTRFCPB(memAttribs
)
748 LP4xUpdateTRCD(memAttribs
)
749 LP4xUpdateTRPAB(memAttribs
)
750 LP4xUpdateTRPPB(memAttribs
)
752 LP4xNormalizeMemoryAttributes(memAttribs
)
757 func LP4xValidateDensityx8Channel(densityPerChannelGb
int) error
{
758 if _
, ok
:= LP4xDensityGbx8ChannelToRowColumnEncoding
[densityPerChannelGb
]; ok
== false {
759 return fmt
.Errorf("Incorrect x8 density: %d Gb", densityPerChannelGb
)
764 func LP4xValidateDensityx16Channel(densityPerChannelGb
int) error
{
765 if _
, ok
:= LP4xDensityGbx16ChannelToRowColumnEncoding
[densityPerChannelGb
]; ok
== false {
766 return fmt
.Errorf("Incorrect x16 density: %d Gb", densityPerChannelGb
)
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
)
788 func LP4xValidateChannels(channels
int) error
{
789 if channels
!= 1 && channels
!= 2 && channels
!= 4 {
790 return fmt
.Errorf("Incorrect channels per die: %d ", channels
)
795 func LP4xValidateDataWidth(width
int) error
{
796 if width
!= 8 && width
!= 16 {
797 return fmt
.Errorf("Incorrect bit width: %d", width
)
802 func LP4xValidateRanks(ranks
int) error
{
803 if ranks
!= 1 && ranks
!= 2 {
804 return fmt
.Errorf("Incorrect ranks: %d", ranks
)
809 func LP4xValidateSpeed(speed
int) error
{
810 if _
, ok
:= LP4xSpeedMbpsToSPDEncoding
[speed
]; ok
== false {
811 return fmt
.Errorf("Incorrect speed: %d Mbps", speed
)
816 func Lp4xValidateMemPartAttributes(memAttribs
*LP4xMemAttributes
) error
{
817 if err
:= LP4xValidateBanks(memAttribs
.Banks
); err
!= nil {
820 if err
:= LP4xValidateChannels(memAttribs
.ChannelsPerDie
); err
!= nil {
823 if err
:= LP4xValidateDataWidth(memAttribs
.BitWidthPerChannel
); err
!= nil {
826 if err
:= LP4xValidateDensity(memAttribs
); err
!= nil {
829 if err
:= LP4xValidateRanks(memAttribs
.RanksPerChannel
); err
!= nil {
832 if err
:= LP4xValidateSpeed(memAttribs
.SpeedMbps
); err
!= nil {
839 func LP4xIsManufacturerPartNumberByte(index
int) bool {
840 if index
>= LP4xSPDIndexManufacturerPartNumberStartByte
&&
841 index
<= LP4xSPDIndexManufacturerPartNumberEndByte
{
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
)
862 if err
:= json
.Unmarshal(eByte
, &lp4xAttributes
); err
!= nil {
866 if err
:= Lp4xValidateMemPartAttributes(&lp4xAttributes
); err
!= nil {
870 LP4xPartAttributeMap
[name
] = lp4xAttributes
874 func (lp4x
) getSPDAttribs(name
string, set
int) (interface{}, error
) {
875 lp4xAttributes
:= LP4xPartAttributeMap
[name
]
879 if err
:= Lp4xUpdateMemoryAttributes(&lp4xAttributes
); err
!= nil {
880 return lp4xAttributes
, err
883 return lp4xAttributes
, nil
886 func (lp4x
) getSPDLen() int {
890 func (lp4x
) getSPDByte(index
int, attribs
interface{}) byte {
891 e
, ok
:= LP4xSPDAttribTable
[index
]
893 if LP4xIsManufacturerPartNumberByte(index
) {
894 return LP4xSPDValueManufacturerPartNumberBlank
900 var lp4xAttribs LP4xMemAttributes
901 lp4xAttribs
= attribs
.(LP4xMemAttributes
)
902 return e
.getVal(&lp4xAttribs
)