1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/*
* This file is part of the coreboot project.
*
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef _SOC_TIGERLAKE_MEMINIT_H_
#define _SOC_TIGERLAKE_MEMINIT_H_
#include <stddef.h>
#include <stdint.h>
#include <fsp/soc_binding.h>
#define BITS_PER_BYTE 8
#define LPDDR4X_CHANNELS 8
#define LPDDR4X_BYTES_PER_CHANNEL 2
#define DDR4_CHANNELS 2
#define DDR4_BYTES_PER_CHANNEL 8
enum mem_topology {
MEMORY_DOWN, /* Supports reading SPD from CBFS or in-memory pointer. */
SODIMM, /* Supports reading SPD using SMBus (only for DDR4). */
MIXED, /* CH0 = MD, CH1 = SODIMM (only for DDR4). */
};
enum md_spd_loc {
/* Read SPD from pointer provided to memory location. */
SPD_MEMPTR,
/* Read SPD using index into spd.bin in CBFS. */
SPD_CBFS,
};
struct spd_info {
enum mem_topology topology;
/* SPD info for Memory down topology */
enum md_spd_loc md_spd_loc;
union {
/* Used for SPD_CBFS */
uint8_t cbfs_index;
struct {
/* Used for SPD_MEMPTR */
uintptr_t data_ptr;
size_t data_len;
};
};
/*
* SPD info for SODIMM topology.
* Leave addr_dimmN as 0 for any DIMMs that are not populated.
*/
struct {
/* SMBus address for DIMM0 within the channel. */
uint8_t addr_dimm0;
/* SMBus address for DIMM1 within the channel. */
uint8_t addr_dimm1;
} smbus_info[DDR4_CHANNELS];
};
/* Board-specific memory configuration information */
struct lpddr4x_cfg {
/*
* DQ CPU<>DRAM map:
* LPDDR4x memory interface has 2 DQs per channel. Each DQ consists of 8 bits(1
* byte). Thus, dq_map is represented as DDR[7-0]_DQ[1-0][7:0], where
* DDR[7-0] : LPDDR4x channel #
* DQ[1-0] : DQ # within the channel
* [7:0] : Bits within the DQ
*
* Index of the array represents DQ pin# on the CPU, whereas value in
* the array represents DQ pin# on the memory part.
*/
uint8_t dq_map[LPDDR4X_CHANNELS][LPDDR4X_BYTES_PER_CHANNEL][BITS_PER_BYTE];
/*
* DQS CPU<>DRAM map:
* LPDDR4x memory interface has 2 DQS pairs(P/N) per channel. Thus, dqs_map is
* represented as DDR[7-0]_DQS[1:0], where
* DDR[7-0] : LPDDR4x channel #
* DQS[1-0] : DQS # within the channel
*
* Index of the array represents DQS pin# on the CPU, whereas value in
* the array represents DQ pin# on the memory part.
*/
uint8_t dqs_map[LPDDR4X_CHANNELS][LPDDR4X_BYTES_PER_CHANNEL];
/*
* Early Command Training Enable/Disable Control
* 1 = enable, 0 = disable
*/
uint8_t ect;
};
void meminit_lpddr4x(FSP_M_CONFIG *mem_cfg, const struct lpddr4x_cfg *board_cfg,
const struct spd_info *spd, bool half_populated);
#endif /* _SOC_TIGERLAKE_MEMINIT_H_ */
|