/** @file

 @copyright
  INTEL CONFIDENTIAL
  Copyright 2012 - 2017 Intel Corporation.

  The source code contained or described herein and all documents related to the
  source code ("Material") are owned by Intel Corporation or its suppliers or
  licensors. Title to the Material remains with Intel Corporation or its suppliers
  and licensors. The Material may contain trade secrets and proprietary and
  confidential information of Intel Corporation and its suppliers and licensors,
  and is protected by worldwide copyright and trade secret laws and treaty
  provisions. No part of the Material may be used, copied, reproduced, modified,
  published, uploaded, posted, transmitted, distributed, or disclosed in any way
  without Intel's prior express written permission.

  No license under any patent, copyright, trade secret or other intellectual
  property right is granted to or conferred upon you by disclosure or delivery
  of the Materials, either expressly, by implication, inducement, estoppel or
  otherwise. Any license under such intellectual property rights must be
  express and approved by Intel in writing.

  Unless otherwise agreed by Intel in writing, you may not remove or alter
  this notice or any other notice embedded in Materials by Intel or
  Intel's suppliers or licensors in any way.

  This file contains an 'Intel Peripheral Driver' and is uniquely identified as
  "Intel Reference Module" and is licensed for Intel CPUs and chipsets under
  the terms of your license agreement with Intel or your vendor. This file may
  be modified by the user, subject to additional terms of the license agreement.

@par Specification
**/

#ifndef _BL_PLATFORM_DATA_H
#define _BL_PLATFORM_DATA_H

//
// @note
// All lines between tag EXTERNAL_BOOTLOADER_STRUCT_BEGIN and
// EXTERNAL_BOOTLOADER_STRUCT_END will be exported to the generated
// FspUpdVpd.h file by the tool.
//

#pragma pack(1)

/* !EXPORT FSPM EXTERNAL_BOOTLOADER_STRUCT_BEGIN */

#define MAX_NODE_NUM     1
#define MAX_CHANNELS_NUM 4
#define MAX_DIMMS_NUM    1

#define MAX_PROFILE_NUM     4 // number of memory profiles supported
#define MAX_XMP_PROFILE_NUM 2 // number of XMP profiles supported

//
// Matches MAX_SPD_SAVE define in MRC
//
#ifndef MAX_SPD_SAVE
#define MAX_SPD_SAVE 29
#endif

#define MRC_DDR_TYPE_LPDDR4   6
#define MRC_DDR_TYPE_DDR4     7

//
// MRC version description.
//
typedef struct {
  UINT8  Major;     ///< Major version number
  UINT8  Minor;     ///< Minor version number
  UINT8  Rev;       ///< Revision number
  UINT8  Build;     ///< Build number
} SiMrcVersion;

//
// DIMM timings
//
typedef struct {
  UINT32 tCK;       ///< Memory cycle time, in femtoseconds.
  UINT16 NMode;     ///< Number of tCK cycles for the channel DIMM's command rate mode.
  UINT16 tCL;       ///< Number of tCK cycles for the channel DIMM's CAS latency.
  UINT16 tCWL;      ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
  UINT16 tFAW;      ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
  UINT16 tRAS;      ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
  UINT16 tRCDtRP;   ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time.
  UINT16 tREFI;     ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
  UINT16 tRFC;      ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
  UINT16 tRFCpb;    ///< Number of tCK cycles for the channel DIMM's minimum per bank refresh recovery delay time.
  UINT16 tRFC2;     ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
  UINT16 tRFC4;     ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
  UINT16 tRPab;     ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
  UINT16 tRRD;      ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
  UINT16 tRRD_L;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
  UINT16 tRRD_S;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
  UINT16 tRTP;      ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
  UINT16 tWR;       ///< Number of tCK cycles for the channel DIMM's minimum write recovery time.
  UINT16 tWTR;      ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
  UINT16 tWTR_L;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
  UINT16 tWTR_S;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
  UINT16 tCCD_L;  ///< Number of tCK cycles for the channel DIMM's minimum CAS-to-CAS delay for same bank group.
} MRC_CH_TIMING;

///
/// Memory SMBIOS & OC Memory Data Hob
///
typedef struct {
  UINT8             Status;                 ///< See MrcDimmStatus for the definition of this field.
  UINT8             DimmId;
  UINT32            DimmCapacity;           ///< DIMM size in MBytes.
  UINT16            MfgId;
  UINT8             ModulePartNum[20];      ///< Module part number for DDR3 is 18 bytes however for DRR4 20 bytes as per JEDEC Spec, so reserving 20 bytes
  UINT8             RankInDimm;             ///< The number of ranks in this DIMM.
  UINT8             SpdDramDeviceType;      ///< Save SPD DramDeviceType information needed for SMBIOS structure creation.
  UINT8             SpdModuleType;          ///< Save SPD ModuleType information needed for SMBIOS structure creation.
  UINT8             SpdModuleMemoryBusWidth;///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation.
  UINT8             SpdSave[MAX_SPD_SAVE];  ///< Save SPD Manufacturing information needed for SMBIOS structure creation.
} DIMM_INFO;

typedef struct {
  UINT8             Status;                  ///< Indicates whether this channel should be used.
  UINT8             ChannelId;
  UINT8             DimmCount;               ///< Number of valid DIMMs that exist in the channel.
  MRC_CH_TIMING     Timing[MAX_PROFILE_NUM]; ///< The channel timing values.
  DIMM_INFO         DimmInfo[MAX_DIMMS_NUM]; ///< Save the DIMM output characteristics.
} CHANNEL_INFO;

typedef struct {
  UINT8             Status;                  ///< Indicates whether this controller should be used.
  UINT16            DeviceId;                ///< The PCI device id of this memory controller.
  UINT8             RevisionId;              ///< The PCI revision id of this memory controller.
  UINT8             ChannelCount;            ///< Number of valid channels that exist on the controller.
  CHANNEL_INFO      ChannelInfo[MAX_CHANNELS_NUM];     ///< The following are channel level definitions.
} CONTROLLER_INFO;

typedef struct {
  UINT8             Revision;
  UINT16            DataWidth;              ///< Data width, in bits, of this memory device
  /** As defined in SMBIOS 3.0 spec
    Section 7.18.2 and Table 75
  **/
  UINT8             MemoryType;             ///< DDR type: DDR3, DDR4, or LPDDR3
  UINT16            MaximumMemoryClockSpeed;///< The maximum capable speed of the device, in megahertz (MHz)
  UINT16            ConfiguredMemoryClockSpeed; ///< The configured clock speed to the memory device, in megahertz (MHz)
  /** As defined in SMBIOS 3.0 spec
    Section 7.17.3 and Table 72
  **/
  UINT8             ErrorCorrectionType;

  SiMrcVersion      Version;
  BOOLEAN           EccSupport;
  UINT8             MemoryProfile;
  UINT32            TotalPhysicalMemorySize;
  UINT32            DefaultXmptCK[MAX_XMP_PROFILE_NUM];///< Stores the tCK value read from SPD XMP profiles if they exist.
  UINT8             XmpProfileEnable;                  ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
  UINT8             Ratio;
  UINT8             RefClk;
  UINT32            VddVoltage[MAX_PROFILE_NUM];
  CONTROLLER_INFO   Controller[MAX_NODE_NUM];
} FSP_SMBIOS_MEMORY_INFO;

typedef struct {
  UINT16     TotalNumberOfSockets;
  UINT16     CurrentSocketNumber;
  UINT8      ProcessorType;                 ///< ENUM defined in SMBIOS Spec v3.0 Section 7.5.1
  /** This info is used for both ProcessorFamily and ProcessorFamily2 fields
      See ENUM defined in SMBIOS Spec v3.0 Section 7.5.2
  **/
  UINT16     ProcessorFamily;
  UINT8      ProcessorManufacturerStrIndex; ///< Index of the String in the String Buffer
  UINT64     ProcessorId;                   ///< ENUM defined in SMBIOS Spec v3.0 Section 7.5.3
  UINT8      ProcessorVersionStrIndex;      ///< Index of the String in the String Buffer
  UINT8      Voltage;                       ///< Format defined in SMBIOS Spec v3.0 Section 7.5.4
  UINT16     ExternalClockInMHz;            ///< External Clock Frequency. Set to 0 if unknown.
  UINT16     CurrentSpeedInMHz;             ///< Snapshot of current processor speed during boot
  UINT8      Status;                        ///< Format defined in the SMBIOS Spec v3.0 Table 21
  UINT8      ProcessorUpgrade;              ///< ENUM defined in SMBIOS Spec v3.0 Section 7.5.5
  /** This info is used for both CoreCount & CoreCount2 fields
      See detailed description in SMBIOS Spec v3.0 Section 7.5.6
  **/
  UINT16     CoreCount;
  /** This info is used for both CoreEnabled & CoreEnabled2 fields
      See detailed description in SMBIOS Spec v3.0 Section 7.5.7
  **/
  UINT16     EnabledCoreCount;
  /** This info is used for both ThreadCount & ThreadCount2 fields
      See detailed description in SMBIOS Spec v3.0 Section 7.5.8
  **/
  UINT16     ThreadCount;
  UINT16     ProcessorCharacteristics;      ///< Format defined in SMBIOS Spec v3.0 Section 7.5.9
  /**
  String Buffer - each string terminated by NULL "0x00"
  String buffer terminated by double NULL "0x0000"
  **/
} FSP_SMBIOS_PROCESSOR_INFO;

typedef struct {
  UINT16     ProcessorSocketNumber;
  UINT16     NumberOfCacheLevels;         ///< Based on Number of Cache Types L1/L2/L3
  UINT8      SocketDesignationStrIndex;   ///< String Index in the string Buffer. Example "L1-CACHE"
  UINT16     CacheConfiguration;          ///< Format defined in SMBIOS Spec v3.0 Section7.8 Table36
  UINT16     MaxCacheSize;                ///< Format defined in SMBIOS Spec v3.0 Section7.8.1
  UINT16     InstalledSize;               ///< Format defined in SMBIOS Spec v3.0 Section7.8.1
  UINT16     SupportedSramType;           ///< Format defined in SMBIOS Spec v3.0 Section7.8.2
  UINT16     CurrentSramType;             ///< Format defined in SMBIOS Spec v3.0 Section7.8.2
  UINT8      CacheSpeed;                  ///< Cache Speed in nanoseconds. 0 if speed is unknown.
  UINT8      ErrorCorrectionType;         ///< ENUM Format defined in SMBIOS Spec v3.0 Section 7.8.3
  UINT8      SystemCacheType;             ///< ENUM Format defined in SMBIOS Spec v3.0 Section 7.8.4
  UINT8      Associativity;               ///< ENUM Format defined in SMBIOS Spec v3.0 Section 7.8.5
  /**
  String Buffer - each string terminated by NULL "0x00"
  String buffer terminated by double NULL "0x0000"
  **/
} FSP_SMBIOS_CACHE_INFO;

/* !EXPORT FSPM EXTERNAL_BOOTLOADER_STRUCT_END   */

#pragma pack()

#endif
