summaryrefslogtreecommitdiffstats
path: root/src/soc/intel/tigerlake/include/soc/meminit.h
blob: 3c4c16b5c296384323c7c3a2714b02c31919c01d (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * 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;
};

/* Board-specific memory configuration information for DDR4 memory variant */
struct mb_ddr4_cfg {
	/*
	 * DQ CPU<>DRAM map:
	 * DDR4 memory interface has 8 DQs per channel. Each DQ consists of 8 bits(1
	 * byte). Thus, dq_map is represented as DDR[1-0]_DQ[7-0][7:0], where
	 * DDR[1-0] : DDR4 channel #
	 * DQ[7-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[DDR4_CHANNELS][DDR4_BYTES_PER_CHANNEL][BITS_PER_BYTE];
	/*
	 * DQS CPU<>DRAM map:
	 * DDR4 memory interface has 8 DQS pairs per channel. Thus, dqs_map is represented as
	 * DDR[1-0]_DQS[7-0], where
	 * DDR[1-0]  : DDR4 channel #
	 * DQS[7-0]  : DQS # within the channel
	 *
	 * Index of the array represents DQS pin# on the CPU, whereas value in
	 * the array represents DQS pin# on the memory part.
	 */
	uint8_t dqs_map[DDR4_CHANNELS][DDR4_BYTES_PER_CHANNEL];
	/*
	 * Indicates whether memory is interleaved.
	 * Set to 1 for an interleaved design,
	 * set to 0 for non-interleaved design.
	 */
	uint8_t dq_pins_interleaved;
	/*
	 * 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);
/* Initialize DDR4 memory configurations */
void meminit_ddr4(FSP_M_CONFIG *mem_cfg, const struct mb_ddr4_cfg *board_cfg,
			  const struct spd_info *spd, const bool half_populated);
#endif /* _SOC_TIGERLAKE_MEMINIT_H_ */