blob: 1fed02f5c6e95cab2d4c1713b930d271cb65252b [file] [log] [blame]
Furquan Shaikh859ca182021-01-15 17:12:12 -08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#ifndef __SOC_INTEL_COMMON_BLOCK_MEMINIT_H__
4#define __SOC_INTEL_COMMON_BLOCK_MEMINIT_H__
5
Furquan Shaikh859ca182021-01-15 17:12:12 -08006#include <types.h>
7
8/*
9 * Calculates the number of channels depending upon the data bus width of the
10 * platform and the channel width.
11 */
12#define CHANNEL_COUNT(ch_width) (CONFIG_DATA_BUS_WIDTH / (ch_width))
13
14/*
15 * UPDs for FSP-M are organized depending upon the MRC's view of channel. Thus,
16 * the number of channels as seen by the MRC are dependent on the channel width
17 * assumption in the UPDs. These channels might not necessarily be the same as
18 * the physical channels supported by the platform.
19 */
20#define MRC_CHANNELS CHANNEL_COUNT(CONFIG_MRC_CHANNEL_WIDTH)
21
22/* Different memory topologies supported by the platform. */
23enum mem_topology {
24 MEM_TOPO_MEMORY_DOWN = BIT(0),
25 MEM_TOPO_DIMM_MODULE = BIT(1),
26 MEM_TOPO_MIXED = MEM_TOPO_MEMORY_DOWN | MEM_TOPO_DIMM_MODULE,
27};
28
29/*
30 * SPD provides information about the memory module. Depending upon the memory
31 * topology, the SPD data can be obtained from different sources. Example: for
32 * memory down topology, SPD is read from CBFS using cbfs_index. For DIMM
33 * modules, SPD is read from EEPROM using the DIMM addresses provided by the
34 * mainboard.
35 */
36struct mem_spd {
37 enum mem_topology topo;
38 /*
39 * SPD data is read from CBFS spd.bin file using cbfs_index to locate
40 * the entry. This is used in case of MEM_TOPO_MEMORY_DOWN and
41 * MEM_TOPO_MIXED topologies.
42 */
43 size_t cbfs_index;
44
45 /*
46 * SPD data is read from on-module EEPROM using the DIMM addresses
47 * provided by the mainboard. This is used in case of
48 * MEM_TOPO_DIMM_MODULE and MEM_TOPO_MIXED topologies.
49 *
50 * Up to a maximum of MRC_CHANNELS * CONFIG_DIMMS_PER_CHANNEL addresses
51 * can be provided by mainboard. However, depending upon the memory
52 * technology being used and the number of physical channels supported
53 * by that technology, the actual channels might be less than
54 * MRC_CHANNELS.
55 */
56 struct {
57 uint8_t addr_dimm[CONFIG_DIMMS_PER_CHANNEL];
58 } smbus[MRC_CHANNELS];
59};
60
61/* Information about memory technology supported by SoC */
62struct soc_mem_cfg {
63 /*
64 * Number of physical channels that are supported by the memory
65 * technology.
66 */
67 size_t num_phys_channels;
68
69 /*
70 * Map of physical channel numbers to MRC channel numbers. This is
71 * helpful in identifying what SPD entries need to be filled for a
72 * physical channel.
73 *
74 * Example: MRC supports 8 channels 0 - 7, but a memory technology
75 * supports only 2 physical channels 0 - 1. In this case, the map could
76 * be:
77 * [0] = 0,
78 * [1] = 4,
79 * indicating that physical channel 0 is mapped to MRC channel 0 and
80 * physical channel 1 is mapped to MRC channel 4.
81 */
82 size_t phys_to_mrc_map[MRC_CHANNELS];
83
84 /*
85 * Masks to be applied in case of memory down topology. For memory down
86 * topology, there is no separate EEPROM. Thus, the masks need to be
87 * hard-coded by the SoC to indicate what combinations are supported.
88 * This is a mask of physical channels for the memory technology.
89 *
90 * Example: For the memory technology supporting 2 physical channels,
91 * where the population rules restrict use of channel 0 for
92 * half-channel, half_channel mask would be set to 0x1 indicating
93 * channel 0 is always populated.
94 */
95 struct {
96 /*
97 * Mask of physical channels that are populated in case of
98 * half-channel configuration.
99 */
100 uint32_t half_channel;
101 /*
102 * Mask of physical channels that are populated with memory
103 * down parts in case of mixed topology.
104 */
105 uint32_t mixed_topo;
106 } md_phy_masks;
107};
108
109/* Flags indicating how the channels are populated. */
110enum channel_population {
111 NO_CHANNEL_POPULATED = 0,
112 TOP_HALF_POPULATED = BIT(0),
113 BOTTOM_HALF_POPULATED = BIT(1),
114 FULLY_POPULATED = TOP_HALF_POPULATED | BOTTOM_HALF_POPULATED,
115};
116
117/*
118 * Data for the memory channels that can be used by SoC code to populate FSP
119 * UPDs.
120 */
121struct mem_channel_data {
122 /* Pointer to SPD data for each DIMM of each channel */
123 uintptr_t spd[MRC_CHANNELS][CONFIG_DIMMS_PER_CHANNEL];
124 /* Length of SPD data */
125 size_t spd_len;
126 /* Flags indicating how channels are populated */
127 enum channel_population ch_population_flags;
128};
129
130/*
131 * This change populates data regarding memory channels in `struct
132 * mem_channel_data` using the following inputs from SoC code:
133 * soc_mem_cfg : SoC-specific information about the memory technology used by
134 * the mainboard.
135 * spd_info : Information about the memory topology.
136 * half_populated: Hint from mainboard if channels are half populated.
137 */
138void mem_populate_channel_data(const struct soc_mem_cfg *soc_mem_cfg,
139 const struct mem_spd *spd_info,
140 bool half_populated,
141 struct mem_channel_data *data);
142
143/*
144 * Given a channel number and the maximum number of supported channels, this
145 * function returns if a channel is populated. This is useful for populating
146 * DQ/DQS UPDs by the SoC code.
147 */
148static inline bool channel_is_populated(size_t curr_ch, size_t max_ch,
149 enum channel_population flags)
150{
151 if ((curr_ch * 2) < max_ch)
152 return !!(flags & BOTTOM_HALF_POPULATED);
153
154 return !!(flags & TOP_HALF_POPULATED);
155}
156
157#endif /* __SOC_INTEL_COMMON_BLOCK_MEMINIT_H__ */