blob: 17910ff4bd99afe380ebb65cbc0e66cde0929485 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -05002
Elyes HAOUASaa8e7e72016-06-19 12:38:47 +02003/*
4 * JEDEC Standard No. 21-C
5 * Annex K: Serial Presence Detect (SPD) for DDR3 SDRAM Modules 2014
6 * http://www.jedec.org/sites/default/files/docs/4_01_02_11R24.pdf
7 */
8
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -05009#ifndef DEVICE_DRAM_DDR3L_H
10#define DEVICE_DRAM_DDR3L_H
11
12/**
13 * @file ddr3.h
14 *
15 * \brief Utilities for decoding DDR3 SPDs
16 */
17
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050018#include <spd.h>
Arthur Heymansfc31e442018-02-12 15:12:34 +010019#include <device/dram/common.h>
Patrick Rudolph24efe732018-08-19 11:06:06 +020020#include <types.h>
Arthur Heymansfc31e442018-02-12 15:12:34 +010021
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050022/**
Matt DeVillier5aaa8ce2016-09-02 13:29:17 -050023 * Convenience definitions for SPD offsets
24 *
25 * @{
26 */
27#define SPD_DIMM_MOD_ID1 117
28#define SPD_DIMM_MOD_ID2 118
29#define SPD_DIMM_SERIAL_NUM 122
30#define SPD_DIMM_SERIAL_LEN 4
31#define SPD_DIMM_PART_NUM 128
32#define SPD_DIMM_PART_LEN 18
33/** @} */
34
35/**
Martin Rothf48acbd2020-07-24 12:24:27 -060036 * \brief Convenience macro for enabling printk with CONFIG(DEBUG_RAM_SETUP)
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050037 *
38 * Use this macro instead of printk(); for verbose RAM initialization messages.
Martin Rothf48acbd2020-07-24 12:24:27 -060039 * When CONFIG(DEBUG_RAM_SETUP) is not selected, these messages are automatically
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050040 * disabled.
41 * @{
42 */
Julius Wernercd49cce2019-03-05 16:53:33 -080043#if CONFIG(DEBUG_RAM_SETUP)
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050044#define printram(x, ...) printk(BIOS_DEBUG, x, ##__VA_ARGS__)
45#else
46#define printram(x, ...)
47#endif
48/** @} */
49
50/*
51 * Module type (byte 3, bits 3:0) of SPD
Martin Roth0cb07e32013-07-09 21:46:01 -060052 * This definition is specific to DDR3. DDR2 SPDs have a different structure.
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050053 */
Angel Pons18571382021-03-28 13:49:39 +020054enum spd_dimm_type_ddr3 {
55 SPD_DDR3_DIMM_TYPE_UNDEFINED = 0x00,
56 SPD_DDR3_DIMM_TYPE_RDIMM = 0x01,
57 SPD_DDR3_DIMM_TYPE_UDIMM = 0x02,
58 SPD_DDR3_DIMM_TYPE_SO_DIMM = 0x03,
59 SPD_DDR3_DIMM_TYPE_MICRO_DIMM = 0x04,
60 SPD_DDR3_DIMM_TYPE_MINI_RDIMM = 0x05,
61 SPD_DDR3_DIMM_TYPE_MINI_UDIMM = 0x06,
62 SPD_DDR3_DIMM_TYPE_MINI_CDIMM = 0x07,
63 SPD_DDR3_DIMM_TYPE_72B_SO_UDIMM = 0x08,
64 SPD_DDR3_DIMM_TYPE_72B_SO_RDIMM = 0x09,
65 SPD_DDR3_DIMM_TYPE_72B_SO_CDIMM = 0x0a,
66 SPD_DDR3_DIMM_TYPE_LRDIMM = 0x0b,
67 SPD_DDR3_DIMM_TYPE_16B_SO_DIMM = 0x0c,
68 SPD_DDR3_DIMM_TYPE_32B_SO_DIMM = 0x0d,
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050069 /* Masks to bits 3:0 to give the dimm type */
Angel Pons18571382021-03-28 13:49:39 +020070 SPD_DDR3_DIMM_TYPE_MASK = 0x0f,
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050071};
72
73/**
74 * \brief DIMM flags
75 *
76 * Characteristic flags for the DIMM, as presented by the SPD
77 */
Angel Ponsafb3d7e2021-03-28 13:43:13 +020078union dimm_flags_ddr3_st {
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050079 /* The whole point of the union/struct construct is to allow us to clear
80 * all the bits with one line: flags.raw = 0.
81 * We do not care how these bits are ordered */
82 struct {
83 /* Indicates if rank 1 of DIMM uses a mirrored pin mapping. See:
84 * Annex K: Serial Presence Detect (SPD) for DDR3 SDRAM */
Lee Leahy0ca2a062017-03-06 18:01:04 -080085 unsigned int pins_mirrored:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050086 /* Module can work at 1.50V - All DIMMS must be 1.5V operable */
Lee Leahy0ca2a062017-03-06 18:01:04 -080087 unsigned int operable_1_50V:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050088 /* Module can work at 1.35V */
Lee Leahy0ca2a062017-03-06 18:01:04 -080089 unsigned int operable_1_35V:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050090 /* Module can work at 1.20V */
Lee Leahy0ca2a062017-03-06 18:01:04 -080091 unsigned int operable_1_25V:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050092 /* Has an 8-bit bus extension, meaning the DIMM supports ECC */
Lee Leahy0ca2a062017-03-06 18:01:04 -080093 unsigned int is_ecc:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050094 /* DLL-Off Mode Support */
Lee Leahy0ca2a062017-03-06 18:01:04 -080095 unsigned int dll_off_mode:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050096 /* Indicates a drive strength of RZQ/6 (40 Ohm) is supported */
Lee Leahy0ca2a062017-03-06 18:01:04 -080097 unsigned int rzq6_supported:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -050098 /* Indicates a drive strength of RZQ/7 (35 Ohm) is supported */
Lee Leahy0ca2a062017-03-06 18:01:04 -080099 unsigned int rzq7_supported:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500100 /* Partial Array Self Refresh */
Lee Leahy0ca2a062017-03-06 18:01:04 -0800101 unsigned int pasr:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500102 /* On-die Thermal Sensor Readout */
Lee Leahy0ca2a062017-03-06 18:01:04 -0800103 unsigned int odts:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500104 /* Auto Self Refresh */
Lee Leahy0ca2a062017-03-06 18:01:04 -0800105 unsigned int asr:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500106 /* Extended temperature range supported */
Lee Leahy0ca2a062017-03-06 18:01:04 -0800107 unsigned int ext_temp_range:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500108 /* Operating at extended temperature requires 2X refresh rate */
Lee Leahy0ca2a062017-03-06 18:01:04 -0800109 unsigned int ext_temp_refresh:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500110 /* Thermal sensor incorporated */
Lee Leahy0ca2a062017-03-06 18:01:04 -0800111 unsigned int therm_sensor:1;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500112 };
Lee Leahy0ca2a062017-03-06 18:01:04 -0800113 unsigned int raw;
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200114};
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500115
116/**
117 * \brief DIMM characteristics
118 *
119 * The characteristics of each DIMM, as presented by the SPD
120 */
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200121struct dimm_attr_ddr3_st {
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500122 enum spd_memory_type dram_type;
Angel Pons18571382021-03-28 13:49:39 +0200123 enum spd_dimm_type_ddr3 dimm_type;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500124 u16 cas_supported;
125 /* Flags extracted from SPD */
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200126 union dimm_flags_ddr3_st flags;
Vladimir Serbinenko7686a562014-05-18 11:05:56 +0200127 /* SDRAM width */
128 u8 width;
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500129 /* Number of ranks */
130 u8 ranks;
131 /* Number or row address bits */
132 u8 row_bits;
133 /* Number or column address bits */
134 u8 col_bits;
135 /* Size of module in MiB */
136 u32 size_mb;
137 /* Latencies are in units of 1/256 ns */
138 u32 tCK;
139 u32 tAA;
140 u32 tWR;
141 u32 tRCD;
142 u32 tRRD;
143 u32 tRP;
144 u32 tRAS;
145 u32 tRC;
146 u32 tRFC;
147 u32 tWTR;
148 u32 tRTP;
149 u32 tFAW;
Dan Elkouby0c024202018-04-13 18:45:02 +0300150 u32 tCWL;
151 u16 tCMD;
Vladimir Serbinenko7686a562014-05-18 11:05:56 +0200152
153 u8 reference_card;
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100154 /* XMP: Module voltage in mV */
155 u16 voltage;
156 /* XMP: max DIMMs per channel supported (1-4) */
157 u8 dimms_per_channel;
Patrick Rudolph07691592016-02-29 18:21:00 +0100158 /* Manufacturer ID */
159 u16 manufacturer_id;
160 /* ASCII part number - NULL terminated */
161 u8 part_number[17];
Patrick Rudolph15e64692018-08-17 15:24:56 +0200162 /* Serial number */
163 u8 serial[SPD_DIMM_SERIAL_LEN];
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200164};
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500165
Patrick Rudolphbd1fdc62016-01-26 08:45:21 +0100166enum ddr3_xmp_profile {
167 DDR3_XMP_PROFILE_1 = 0,
168 DDR3_XMP_PROFILE_2 = 1,
169};
170
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500171typedef u8 spd_raw_data[256];
172
Alexandru Gagniuc4c37e582013-12-17 13:08:01 -0500173u16 spd_ddr3_calc_crc(u8 *spd, int len);
Kyösti Mälkki7dc4b842016-11-18 18:41:17 +0200174u16 spd_ddr3_calc_unique_crc(u8 *spd, int len);
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200175int spd_decode_ddr3(struct dimm_attr_ddr3_st *dimm, spd_raw_data spd_data);
Angel Pons18571382021-03-28 13:49:39 +0200176int spd_dimm_is_registered_ddr3(enum spd_dimm_type_ddr3 type);
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200177void dram_print_spd_ddr3(const struct dimm_attr_ddr3_st *dimm);
178int spd_xmp_decode_ddr3(struct dimm_attr_ddr3_st *dimm,
Lee Leahy708fc272017-03-07 12:18:53 -0800179 spd_raw_data spd,
180 enum ddr3_xmp_profile profile);
Patrick Rudolph24efe732018-08-19 11:06:06 +0200181enum cb_err spd_add_smbios17(const u8 channel, const u8 slot,
182 const u16 selected_freq,
Angel Ponsafb3d7e2021-03-28 13:43:13 +0200183 const struct dimm_attr_ddr3_st *info);
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500184/**
185 * \brief Read double word from specified address
186 *
187 * Should be useful when doing an MRS to the DIMM
188 */
Stefan Reinauer1e2500e2015-06-19 14:59:06 -0700189static inline u32 volatile_read(volatile uintptr_t addr)
Alexandru Gagniucf97ff3f2013-05-21 14:43:45 -0500190{
191 volatile u32 result;
192 result = *(volatile u32 *)addr;
193 return result;
194}
195
Alexandru Gagniuc78706fd2013-06-03 13:58:10 -0500196/**
197 * \brief Representation of an MRS command
198 *
199 * This represents an MRS command as seen by the DIMM. This is not a memory
200 * address that can be read to generate an MRS command. The mapping of CPU
201 * to memory pins is hardware-dependent.
202 * \n
203 * The idea is to generalize the MRS code, and only need a hardware-specific
204 * function to map the MRS bits to CPU address bits. An MRS command can be
205 * sent like:
206 * @code{.c}
207 * u32 addr;
208 * mrs_cmd_t mrs;
209 * chipset_enable_mrs_command_mode();
210 * mrs = ddr3_get_mr2(rtt_wr, srt, asr, cwl)
211 * if (rank_has_mirrorred_pins)
212 * mrs = ddr3_mrs_mirror_pins(mrs);
213 * addr = chipset_specific_get_mrs_addr(mrs);
214 * volatile_read(addr);
215 * @endcode
216 *
217 * The MRS representation has the following structure:
218 * - cmd[15:0] = Address pins MA[15:0]
219 * - cmd[18:16] = Bank address BA[2:0]
220 */
221typedef u32 mrs_cmd_t;
222
223enum ddr3_mr0_precharge {
224 DDR3_MR0_PRECHARGE_SLOW = 0,
225 DDR3_MR0_PRECHARGE_FAST = 1,
226};
227enum ddr3_mr0_mode {
228 DDR3_MR0_MODE_NORMAL = 0,
229 DDR3_MR0_MODE_TEST = 1,
230};
231enum ddr3_mr0_dll_reset {
232 DDR3_MR0_DLL_RESET_NO = 0,
233 DDR3_MR0_DLL_RESET_YES = 1,
234};
235enum ddr3_mr0_burst_type {
236 DDR3_MR0_BURST_TYPE_SEQUENTIAL = 0,
237 DDR3_MR0_BURST_TYPE_INTERLEAVED = 1,
238};
239enum ddr3_mr0_burst_length {
240 DDR3_MR0_BURST_LENGTH_8 = 0,
241 DDR3_MR0_BURST_LENGTH_CHOP = 1,
242 DDR3_MR0_BURST_LENGTH_4 = 2,
243};
244mrs_cmd_t ddr3_get_mr0(enum ddr3_mr0_precharge precharge_pd,
245 u8 write_recovery,
246 enum ddr3_mr0_dll_reset dll_reset,
247 enum ddr3_mr0_mode mode,
248 u8 cas,
249 enum ddr3_mr0_burst_type interleaved_burst,
250 enum ddr3_mr0_burst_length burst_length);
251
252enum ddr3_mr1_qoff {
253 DDR3_MR1_QOFF_ENABLE = 0,
254 DDR3_MR1_QOFF_DISABLE = 1,
255};
256enum ddr3_mr1_tqds {
257 DDR3_MR1_TQDS_DISABLE = 0,
258 DDR3_MR1_TQDS_ENABLE = 1,
259};
260enum ddr3_mr1_write_leveling {
261 DDR3_MR1_WRLVL_DISABLE = 0,
262 DDR3_MR1_WRLVL_ENABLE = 1,
263};
264enum ddr3_mr1_rtt_nom {
265 DDR3_MR1_RTT_NOM_OFF = 0,
266 DDR3_MR1_RTT_NOM_RZQ4 = 1,
267 DDR3_MR1_RTT_NOM_RZQ2 = 2,
268 DDR3_MR1_RTT_NOM_RZQ6 = 3,
269 DDR3_MR1_RTT_NOM_RZQ12 = 4,
270 DDR3_MR1_RTT_NOM_RZQ8 = 5,
271};
272enum ddr3_mr1_additive_latency {
273 DDR3_MR1_AL_DISABLE = 0,
274 DDR3_MR1_AL_CL_MINUS_1 = 1,
275 DDR3_MR1_AL_CL_MINUS_2 = 2,
276};
277enum ddr3_mr1_ods {
278 DDR3_MR1_ODS_RZQ6 = 0,
279 DDR3_MR1_ODS_RZQ7 = 1,
280};
281enum ddr3_mr1_dll {
282 DDR3_MR1_DLL_ENABLE = 0,
283 DDR3_MR1_DLL_DISABLE = 1,
284};
285
286mrs_cmd_t ddr3_get_mr1(enum ddr3_mr1_qoff qoff,
287 enum ddr3_mr1_tqds tqds,
288 enum ddr3_mr1_rtt_nom rtt_nom,
289 enum ddr3_mr1_write_leveling write_leveling,
290 enum ddr3_mr1_ods output_drive_strenght,
291 enum ddr3_mr1_additive_latency additive_latency,
292 enum ddr3_mr1_dll dll_disable);
293
294enum ddr3_mr2_rttwr {
295 DDR3_MR2_RTTWR_OFF = 0,
296 DDR3_MR2_RTTWR_RZQ4 = 1,
297 DDR3_MR2_RTTWR_RZQ2 = 2,
298};
299enum ddr3_mr2_srt_range {
300 DDR3_MR2_SRT_NORMAL = 0,
301 DDR3_MR2_SRT_EXTENDED = 1,
302};
303enum ddr3_mr2_asr {
304 DDR3_MR2_ASR_MANUAL = 0,
305 DDR3_MR2_ASR_AUTO = 1,
306};
307
308mrs_cmd_t ddr3_get_mr2(enum ddr3_mr2_rttwr rtt_wr,
309 enum ddr3_mr2_srt_range extended_temp,
310 enum ddr3_mr2_asr self_refresh, u8 cas_cwl);
311
312mrs_cmd_t ddr3_get_mr3(char dataflow_from_mpr);
313mrs_cmd_t ddr3_mrs_mirror_pins(mrs_cmd_t cmd);
314
Martin Rothfd277d82016-01-11 12:47:30 -0700315#endif /* DEVICE_DRAM_DDR3L_H */