mirror of https://github.com/acidanthera/audk.git
258 lines
10 KiB
C
258 lines
10 KiB
C
/** @file
|
|
Memory controller configuration.
|
|
|
|
Copyright (c) 2013-2015 Intel Corporation.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
#ifndef __DDR_MEMORY_CONTROLLER_H__
|
|
#define __DDR_MEMORY_CONTROLLER_H__
|
|
|
|
//
|
|
// DDR timing data definitions.
|
|
// These are used to create bitmaps of valid timing configurations.
|
|
//
|
|
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_FREQUENCY_UNKNOWN 0xFF
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_REFRESH_RATE_UNKNOWN 0xFF
|
|
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_20 0x01
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_25 0x00
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_30 0x02
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_ALL 0x03
|
|
|
|
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_02 0x02
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_03 0x01
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_04 0x00
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_ALL 0x03
|
|
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_02 0x02
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_03 0x01
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_04 0x00
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_ALL 0x03
|
|
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_05 0x05
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_06 0x04
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_07 0x03
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_08 0x02
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_09 0x01
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_10 0x00
|
|
#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_ALL 0x07
|
|
|
|
#define DUAL_CHANNEL_DDR_DATA_TYPE_REGISTERED 0x01
|
|
#define DUAL_CHANNEL_DDR_DATA_TYPE_UNREGISTERED 0x02
|
|
#define DUAL_CHANNEL_DDR_DATA_TYPE_BUFFERED 0x04
|
|
#define DUAL_CHANNEL_DDR_DATA_TYPE_UNBUFFERED 0x08
|
|
#define DUAL_CHANNEL_DDR_DATA_TYPE_SDR 0x10
|
|
#define DUAL_CHANNEL_DDR_DATA_TYPE_DDR 0x20
|
|
|
|
|
|
//
|
|
// Maximum number of SDRAM channels supported by the memory controller
|
|
//
|
|
#define MAX_CHANNELS 1
|
|
|
|
//
|
|
// Maximum number of DIMM sockets supported by the memory controller
|
|
//
|
|
#define MAX_SOCKETS 1
|
|
|
|
//
|
|
// Maximum number of sides supported per DIMM
|
|
//
|
|
#define MAX_SIDES 2
|
|
|
|
//
|
|
// Maximum number of "Socket Sets", where a "Socket Set is a set of matching
|
|
// DIMM's from the various channels
|
|
//
|
|
#define MAX_SOCKET_SETS 2
|
|
|
|
//
|
|
// Maximum number of rows supported by the memory controller
|
|
//
|
|
#define MAX_ROWS (MAX_SIDES * MAX_SOCKETS)
|
|
|
|
//
|
|
// Maximum number of memory ranges supported by the memory controller
|
|
//
|
|
#define MAX_RANGES (MAX_ROWS + 5)
|
|
|
|
//
|
|
// Maximum Number of Log entries
|
|
//
|
|
#define MEMORY_LOG_MAX_INDEX 16
|
|
|
|
|
|
typedef struct _MEMORY_LOG_ENTRY {
|
|
EFI_STATUS_CODE_VALUE Event;
|
|
EFI_STATUS_CODE_TYPE Severity;
|
|
UINT8 Data;
|
|
} MEMORY_LOG_ENTRY;
|
|
|
|
typedef struct _MEMORY_LOG {
|
|
UINT8 Index;
|
|
MEMORY_LOG_ENTRY Entry[MEMORY_LOG_MAX_INDEX];
|
|
} MEMORY_LOG;
|
|
|
|
|
|
|
|
//
|
|
// Defined ECC types
|
|
//
|
|
#define DUAL_CHANNEL_DDR_ECC_TYPE_NONE 0x01 // No error checking
|
|
#define DUAL_CHANNEL_DDR_ECC_TYPE_EC 0x02 // Error checking only
|
|
#define DUAL_CHANNEL_DDR_ECC_TYPE_SECC 0x04 // Software Scrubbing ECC
|
|
#define DUAL_CHANNEL_DDR_ECC_TYPE_HECC 0x08 // Hardware Scrubbing ECC
|
|
#define DUAL_CHANNEL_DDR_ECC_TYPE_CKECC 0x10 // Chip Kill ECC
|
|
|
|
//
|
|
// Row configuration status values
|
|
//
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_SUCCESS 0x00 // No error
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_UNKNOWN 0x01 // Pattern mismatch, no memory
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_UNSUPPORTED 0x02 // Memory type not supported
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_ADDRESS_ERROR 0x03 // Row/Col/Bnk mismatch
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_ECC_ERROR 0x04 // Received ECC error
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_NOT_PRESENT 0x05 // Row is not present
|
|
#define DUAL_CHANNEL_DDR_ROW_CONFIG_DISABLED 0x06 // Row is disabled
|
|
|
|
|
|
//
|
|
// Memory range types
|
|
//
|
|
typedef enum {
|
|
DualChannelDdrMainMemory,
|
|
DualChannelDdrSmramCacheable,
|
|
DualChannelDdrSmramNonCacheable,
|
|
DualChannelDdrGraphicsMemoryCacheable,
|
|
DualChannelDdrGraphicsMemoryNonCacheable,
|
|
DualChannelDdrReservedMemory,
|
|
DualChannelDdrMaxMemoryRangeType
|
|
} DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE;
|
|
|
|
//
|
|
// Memory map range information
|
|
//
|
|
typedef struct {
|
|
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
|
EFI_PHYSICAL_ADDRESS CpuAddress;
|
|
EFI_PHYSICAL_ADDRESS RangeLength;
|
|
DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE Type;
|
|
} DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE;
|
|
typedef struct {
|
|
unsigned dramType :1; /**< Type: 0 = RESERVED; 1 = DDR2 */
|
|
unsigned dramWidth :1; /**< Width: 0 = x8; 1 = x16 */
|
|
unsigned dramDensity :2; /**< Density: 00b = 2Gb; 01b = 1Gb; 10b = 512Mb; 11b = 256Mb */
|
|
unsigned dramSpeed :1; /**< Speed Grade: 0 = RESERVED; 1 = 800MT/s;*/
|
|
unsigned dramTimings :3; /**< Timings: 4-4-4, 5-5-5, 6-6-6 */
|
|
unsigned dramRanks :1; /**< Ranks: 0 = Single Rank; 1 = Dual Rank */
|
|
} DramGeometry; /**< DRAM Geometry Descriptor */
|
|
|
|
typedef union _RegDRP {
|
|
UINT32 raw;
|
|
struct {
|
|
unsigned rank0Enabled :1; /**< Rank 0 Enable */
|
|
unsigned rank0DevWidth :2; /**< DRAM Device Width (x8,x16) */
|
|
unsigned rank0DevDensity :2; /**< DRAM Device Density (256Mb,512Mb,1Gb,2Gb) */
|
|
unsigned reserved2 :1;
|
|
unsigned rank1Enabled :1; /**< Rank 1 Enable */
|
|
unsigned reserved3 :5;
|
|
unsigned dramType :1; /**< DRAM Type (0=DDR2) */
|
|
unsigned reserved4 :5;
|
|
unsigned reserved5 :14;
|
|
} field;
|
|
} RegDRP; /**< DRAM Rank Population and Interface Register */
|
|
|
|
|
|
typedef union {
|
|
UINT32 raw;
|
|
struct {
|
|
unsigned dramFrequency :3; /**< DRAM Frequency (000=RESERVED,010=667,011=800) */
|
|
unsigned tRP :2; /**< Precharge to Activate Delay (3,4,5,6) */
|
|
unsigned reserved1 :1;
|
|
unsigned tRCD :2; /**< Activate to CAS Delay (3,4,5,6) */
|
|
unsigned reserved2 :1;
|
|
unsigned tCL :2; /**< CAS Latency (3,4,5,6) */
|
|
unsigned reserved3 :21;
|
|
} field;
|
|
} RegDTR0; /**< DRAM Timing Register 0 */
|
|
|
|
typedef union {
|
|
UINT32 raw;
|
|
struct {
|
|
unsigned tWRRD_dly :2; /**< Additional Write to Read Delay (0,1,2,3) */
|
|
unsigned reserved1 :1;
|
|
unsigned tRDWR_dly :2; /**< Additional Read to Write Delay (0,1,2,3) */
|
|
unsigned reserved2 :1;
|
|
unsigned tRDRD_dr_dly :1; /**< Additional Read to Read Delay (1,2) */
|
|
unsigned reserved3 :1;
|
|
unsigned tRD_dly :3; /**< Additional Read Data Sampling Delay (0-7) */
|
|
unsigned reserved4 :1;
|
|
unsigned tRCVEN_halfclk_dly :4; /**< Additional RCVEN Half Clock Delay Control */
|
|
unsigned reserved5 :1;
|
|
unsigned readDqDelay :2; /**< Read DQ Delay */
|
|
unsigned reserved6 :13;
|
|
} field;
|
|
} RegDTR1; /**< DRAM Timing Register 1 */
|
|
|
|
typedef union {
|
|
UINT32 raw;
|
|
struct {
|
|
unsigned ckStaticDisable :1; /**< CK/CK# Static Disable */
|
|
unsigned reserved1 :3;
|
|
unsigned ckeStaticDisable :2; /**< CKE Static Disable */
|
|
unsigned reserved2 :8;
|
|
unsigned refreshPeriod :2; /**< Refresh Period (disabled,128clks,3.9us,7.8us) */
|
|
unsigned refreshQueueDepth :2; /**< Refresh Queue Depth (1,2,4,8) */
|
|
unsigned reserved5 :13;
|
|
unsigned initComplete :1; /**< Initialization Complete */
|
|
} field;
|
|
} RegDCO;
|
|
|
|
//
|
|
// MRC Data Structure
|
|
//
|
|
typedef struct {
|
|
RegDRP drp;
|
|
RegDTR0 dtr0;
|
|
RegDTR1 dtr1;
|
|
RegDCO dco;
|
|
UINT32 reg0104;
|
|
UINT32 reg0120;
|
|
UINT32 reg0121;
|
|
UINT32 reg0123;
|
|
UINT32 reg0111;
|
|
UINT32 reg0130;
|
|
UINT8 refreshPeriod; /**< Placeholder for the chosen refresh
|
|
* period. This value will NOT be
|
|
* programmed into DCO until all
|
|
* initialization is done.
|
|
*/
|
|
UINT8 ddr2Odt; /**< 0 = Disabled, 1 = 75 ohm, 2 = 150ohm, 3 = 50ohm */
|
|
UINT8 sku; /**< Detected QuarkNcSocId SKU */
|
|
UINT8 capabilities; /**< Capabilities Available on this part */
|
|
UINT8 state; /**< NORMAL_BOOT, S3_RESUME */
|
|
UINT32 memSize; /**< Memory size */
|
|
UINT16 pmBase; /**< PM Base */
|
|
UINT16 mrcVersion; /**< MRC Version */
|
|
UINT32 hecbase; /**< HECBASE shifted left 16 bits */
|
|
DramGeometry geometry; /**< DRAM Geometry */
|
|
} MRC_DATA_STRUCTURE; /**< QuarkNcSocId Memory Parameters for MRC */
|
|
|
|
typedef struct _EFI_MEMINIT_CONFIG_DATA {
|
|
MRC_DATA_STRUCTURE MrcData;
|
|
} EFI_MEMINIT_CONFIG_DATA;
|
|
|
|
|
|
|
|
#endif
|