blob: bb51c60fd852ce7937ee990794cbe12239573952 [file] [log] [blame]
Angel Pons4b429832020-04-02 23:48:50 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Damien Zammit43a1f782015-08-19 15:16:59 +10002
3#ifndef __NORTHBRIDGE_INTEL_X4X_H__
4#define __NORTHBRIDGE_INTEL_X4X_H__
5
Arthur Heymansdc972e12019-11-12 08:35:05 +01006#include <stdint.h>
Arthur Heymans6190d0b2019-11-01 18:34:45 +01007#include "iomap.h"
8
Damien Zammit43a1f782015-08-19 15:16:59 +10009/*
10 * D0:F0
11 */
Angel Pons38965762020-07-22 11:15:17 +020012#include "hostbridge_regs.h"
Damien Zammit43a1f782015-08-19 15:16:59 +100013
14/*
15 * D1:F0 PEG
16 */
17#define PEG_CAP 0xa2
18#define SLOTCAP 0xb4
19#define PEGLC 0xec
20#define D1F0_VCCAP 0x104
21#define D1F0_VC0RCTL 0x114
22
23/*
24 * Graphics frequencies
25 */
26#define GCFGC_PCIDEV PCI_DEV(0, 2, 0)
27#define GCFGC_OFFSET 0xf0
28#define GCFGC_CR_SHIFT 0
29#define GCFGC_CR_MASK (0xf << GCFGC_CR_SHIFT)
30#define GCFGC_CS_SHIFT 8
31#define GCFGC_CS_MASK (0xf << GCFGC_CS_SHIFT)
32#define GCFGC_CD_SHIFT 12
33#define GCFGC_CD_MASK (0x1 << GCFGC_CD_SHIFT)
34#define GCFGC_UPDATE_SHIFT 5
35#define GCFGC_UPDATE (0x1 << GCFGC_UPDATE_SHIFT)
36
37/*
38 * MCHBAR
39 */
40
Arthur Heymans70a1dda2017-03-09 01:58:24 +010041#define MCHBAR8(x) (*((volatile u8 *)(DEFAULT_MCHBAR + (x))))
42#define MCHBAR16(x) (*((volatile u16 *)(DEFAULT_MCHBAR + (x))))
43#define MCHBAR32(x) (*((volatile u32 *)(DEFAULT_MCHBAR + (x))))
Felix Held6cd2c2f2018-07-29 18:04:14 +020044#define MCHBAR8_AND(x, and) (MCHBAR8(x) = MCHBAR8(x) & (and))
45#define MCHBAR8_OR(x, or) (MCHBAR8(x) = MCHBAR8(x) | (or))
46#define MCHBAR8_AND_OR(x, and, or) \
47 (MCHBAR8(x) = (MCHBAR8(x) & (and)) | (or))
48#define MCHBAR16_AND(x, and) (MCHBAR16(x) = MCHBAR16(x) & (and))
49#define MCHBAR16_OR(x, or) (MCHBAR16(x) = MCHBAR16(x) | (or))
50#define MCHBAR16_AND_OR(x, and, or) \
51 (MCHBAR16(x) = (MCHBAR16(x) & (and)) | (or))
52#define MCHBAR32_AND(x, and) (MCHBAR32(x) = MCHBAR32(x) & (and))
53#define MCHBAR32_OR(x, or) (MCHBAR32(x) = MCHBAR32(x) | (or))
54#define MCHBAR32_AND_OR(x, and, or) \
55 (MCHBAR32(x) = (MCHBAR32(x) & (and)) | (or))
Damien Zammit43a1f782015-08-19 15:16:59 +100056
Arthur Heymans1994e4482017-11-04 07:52:23 +010057#define CHDECMISC 0x111
58#define STACKED_MEM (1 << 1)
59
60#define C0DRB0 0x200
61#define C0DRB1 0x202
62#define C0DRB2 0x204
63#define C0DRB3 0x206
64#define C0DRA01 0x208
65#define C0DRA23 0x20a
66#define C0CKECTRL 0x260
67
68#define C1DRB0 0x600
69#define C1DRB1 0x602
70#define C1DRB2 0x604
71#define C1DRB3 0x606
72#define C1DRA01 0x608
73#define C1DRA23 0x60a
74#define C1CKECTRL 0x660
75
Damien Zammit43a1f782015-08-19 15:16:59 +100076#define PMSTS_MCHBAR 0x0f14 /* Self refresh channel status */
Arthur Heymans97e13d82016-11-30 18:40:38 +010077#define PMSTS_WARM_RESET (1 << 8)
78#define PMSTS_BOTH_SELFREFRESH (3 << 0)
Damien Zammit43a1f782015-08-19 15:16:59 +100079
80#define CLKCFG_MCHBAR 0x0c00
81#define CLKCFG_FSBCLK_SHIFT 0
82#define CLKCFG_FSBCLK_MASK (7 << CLKCFG_FSBCLK_SHIFT)
83#define CLKCFG_MEMCLK_SHIFT 4
84#define CLKCFG_MEMCLK_MASK (7 << CLKCFG_MEMCLK_SHIFT)
85#define CLKCFG_UPDATE (1 << 12)
86
Arthur Heymans5b30b822016-12-01 18:41:50 +010087#define SSKPD_MCHBAR 0x0c20 /* 64 bit */
Damien Zammit43a1f782015-08-19 15:16:59 +100088
89/*
90 * DMIBAR
91 */
92
Arthur Heymans70a1dda2017-03-09 01:58:24 +010093#define DMIBAR8(x) (*((volatile u8 *)(DEFAULT_DMIBAR + (x))))
94#define DMIBAR16(x) (*((volatile u16 *)(DEFAULT_DMIBAR + (x))))
95#define DMIBAR32(x) (*((volatile u32 *)(DEFAULT_DMIBAR + (x))))
Damien Zammit43a1f782015-08-19 15:16:59 +100096
97#define DMIVC0RCTL 0x14
98#define DMIVC1RCTL 0x20
99#define DMIVC1RSTS 0x26
100#define DMIESD 0x44
101#define DMILE1D 0x50
102#define DMILE1A 0x58
103#define DMILE2D 0x60
104#define DMILE2A 0x68
105
106/*
107 * EPBAR
108 */
109
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100110#define EPBAR8(x) (*((volatile u8 *)(DEFAULT_EPBAR + (x))))
111#define EPBAR16(x) (*((volatile u16 *)(DEFAULT_EPBAR + (x))))
112#define EPBAR32(x) (*((volatile u32 *)(DEFAULT_EPBAR + (x))))
Damien Zammit43a1f782015-08-19 15:16:59 +1000113
114#define EPESD 0x44
115#define EPLE1D 0x50
116#define EPLE1A 0x58
117#define EPLE2D 0x60
118
119#define NOP_CMD 0x2
120#define PRECHARGE_CMD 0x4
121#define MRS_CMD 0x6
122#define EMRS_CMD 0x8
123#define EMRS1_CMD (EMRS_CMD | 0x10)
124#define EMRS2_CMD (EMRS_CMD | 0x20)
125#define EMRS3_CMD (EMRS_CMD | 0x30)
126#define ZQCAL_CMD 0xa
127#define CBR_CMD 0xc
128#define NORMALOP_CMD 0xe
129
130#define TOTAL_CHANNELS 2
131#define TOTAL_DIMMS 4
Arthur Heymans276049f2017-11-05 05:56:34 +0100132#define TOTAL_BYTELANES 8
Nico Huber3c209062016-11-26 02:03:25 +0100133#define DIMMS_PER_CHANNEL (TOTAL_DIMMS / TOTAL_CHANNELS)
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000134#define RAW_CARD_UNPOPULATED 0xff
Arthur Heymans3cf94032017-04-05 16:17:26 +0200135#define RAW_CARD_POPULATED 0
Damien Zammit43a1f782015-08-19 15:16:59 +1000136
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000137#define DIMM_IS_POPULATED(dimms, idx) (dimms[idx].card_type != RAW_CARD_UNPOPULATED)
138#define IF_DIMM_POPULATED(dimms, idx) if (dimms[idx].card_type != RAW_CARD_UNPOPULATED)
Damien Zammit43a1f782015-08-19 15:16:59 +1000139#define ONLY_DIMMA_IS_POPULATED(dimms, ch) ( \
140 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
141 !DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3)))
142#define ONLY_DIMMB_IS_POPULATED(dimms, ch) ( \
143 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3) && \
144 !DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2)))
145#define BOTH_DIMMS_ARE_POPULATED(dimms, ch) ( \
146 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
147 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3))))
148#define FOR_EACH_DIMM(idx) \
149 for (idx = 0; idx < TOTAL_DIMMS; ++idx)
150#define FOR_EACH_POPULATED_DIMM(dimms, idx) \
151 FOR_EACH_DIMM(idx) IF_DIMM_POPULATED(dimms, idx)
Nico Huber696abfc2016-11-23 23:56:53 +0100152#define FOR_EACH_DIMM_IN_CHANNEL(ch, idx) \
Nico Huber3c209062016-11-26 02:03:25 +0100153 for (idx = (ch) << 1; idx < ((ch) << 1) + DIMMS_PER_CHANNEL; ++idx)
Nico Huber696abfc2016-11-23 23:56:53 +0100154#define FOR_EACH_POPULATED_DIMM_IN_CHANNEL(dimms, ch, idx) \
155 FOR_EACH_DIMM_IN_CHANNEL(ch, idx) IF_DIMM_POPULATED(dimms, idx)
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100156#define CHANNEL_IS_POPULATED(dimms, idx) \
157 ((dimms[idx<<1].card_type != RAW_CARD_UNPOPULATED) \
158 || (dimms[(idx<<1) + 1].card_type != RAW_CARD_UNPOPULATED))
159#define CHANNEL_IS_CARDF(dimms, idx) \
160 ((dimms[idx<<1].card_type == 0xf) \
161 || (dimms[(idx<<1) + 1].card_type == 0xf))
162#define IF_CHANNEL_POPULATED(dimms, idx) \
163 if ((dimms[idx<<1].card_type != RAW_CARD_UNPOPULATED) \
164 || (dimms[(idx<<1) + 1].card_type != RAW_CARD_UNPOPULATED))
Damien Zammit43a1f782015-08-19 15:16:59 +1000165#define FOR_EACH_CHANNEL(idx) \
166 for (idx = 0; idx < TOTAL_CHANNELS; ++idx)
167#define FOR_EACH_POPULATED_CHANNEL(dimms, idx) \
168 FOR_EACH_CHANNEL(idx) IF_CHANNEL_POPULATED(dimms, idx)
169
170#define RANKS_PER_CHANNEL 4
171#define RANK_IS_POPULATED(dimms, ch, r) \
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000172 (((dimms[ch<<1].card_type != RAW_CARD_UNPOPULATED) && ((r) < dimms[ch<<1].ranks)) || \
173 ((dimms[(ch<<1) + 1].card_type != RAW_CARD_UNPOPULATED) && ((r) >= 2) && ((r) < (dimms[(ch<<1) + 1].ranks + 2))))
Damien Zammit43a1f782015-08-19 15:16:59 +1000174#define IF_RANK_POPULATED(dimms, ch, r) \
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100175 if (((dimms[ch<<1].card_type != RAW_CARD_UNPOPULATED) \
176 && ((r) < dimms[ch<<1].ranks)) \
177 || ((dimms[(ch<<1) + 1].card_type != RAW_CARD_UNPOPULATED) \
178 && ((r) >= 2) && ((r) < (dimms[(ch<<1) + 1].ranks + 2))))
Damien Zammit43a1f782015-08-19 15:16:59 +1000179#define FOR_EACH_RANK_IN_CHANNEL(r) \
180 for (r = 0; r < RANKS_PER_CHANNEL; ++r)
181#define FOR_EACH_POPULATED_RANK_IN_CHANNEL(dimms, ch, r) \
182 FOR_EACH_RANK_IN_CHANNEL(r) IF_RANK_POPULATED(dimms, ch, r)
183#define FOR_EACH_RANK(ch, r) \
184 FOR_EACH_CHANNEL(ch) FOR_EACH_RANK_IN_CHANNEL(r)
185#define FOR_EACH_POPULATED_RANK(dimms, ch, r) \
186 FOR_EACH_RANK(ch, r) IF_RANK_POPULATED(dimms, ch, r)
Arthur Heymans276049f2017-11-05 05:56:34 +0100187#define FOR_EACH_BYTELANE(l) \
188 for (l = 0; l < TOTAL_BYTELANES; l++)
189#define FOR_EACH_POPULATED_CHANNEL_AND_BYTELANE(dimms, ch, l) \
190 FOR_EACH_POPULATED_CHANNEL (dimms, ch) FOR_EACH_BYTELANE(l)
Damien Zammit43a1f782015-08-19 15:16:59 +1000191
192#define DDR3_MAX_CAS 18
193
194enum fsb_clock {
195 FSB_CLOCK_800MHz = 0,
196 FSB_CLOCK_1066MHz = 1,
197 FSB_CLOCK_1333MHz = 2,
198};
199
200enum mem_clock {
201 MEM_CLOCK_400MHz = 0,
202 MEM_CLOCK_533MHz = 1,
203 MEM_CLOCK_667MHz = 2,
204 MEM_CLOCK_800MHz = 3,
205 MEM_CLOCK_1066MHz = 4,
206 MEM_CLOCK_1333MHz = 5,
207};
208
209enum ddr {
210 DDR2 = 2,
211 DDR3 = 3,
212};
213
214enum ddrxspd {
215 DDR2SPD = 0x8,
216 DDR3SPD = 0xb,
217};
218
219enum chip_width { /* as in DDR3 spd */
220 CHIP_WIDTH_x4 = 0,
221 CHIP_WIDTH_x8 = 1,
222 CHIP_WIDTH_x16 = 2,
223 CHIP_WIDTH_x32 = 3,
224};
225
226enum chip_cap { /* as in DDR3 spd */
227 CHIP_CAP_256M = 0,
228 CHIP_CAP_512M = 1,
229 CHIP_CAP_1G = 2,
230 CHIP_CAP_2G = 3,
231 CHIP_CAP_4G = 4,
232 CHIP_CAP_8G = 5,
233 CHIP_CAP_16G = 6,
234};
235
Arthur Heymans27f0ca12017-05-09 18:38:14 +0200236struct dll_setting {
237 u8 tap;
238 u8 pi;
239 u8 db_en;
240 u8 db_sel;
241 u8 clk_delay;
242 u8 coarse;
243};
244
Arthur Heymans0bf87de2017-11-04 06:15:05 +0100245struct rt_dqs_setting {
246 u8 tap;
247 u8 pi;
248};
249
Arthur Heymans3cf94032017-04-05 16:17:26 +0200250enum n_banks {
251 N_BANKS_4 = 0,
252 N_BANKS_8 = 1,
253};
254
Damien Zammit43a1f782015-08-19 15:16:59 +1000255struct timings {
256 unsigned int CAS;
Arthur Heymans3cf94032017-04-05 16:17:26 +0200257 unsigned int tclk;
Damien Zammit43a1f782015-08-19 15:16:59 +1000258 enum fsb_clock fsb_clk;
259 enum mem_clock mem_clk;
260 unsigned int tRAS;
261 unsigned int tRP;
262 unsigned int tRCD;
263 unsigned int tWR;
264 unsigned int tRFC;
265 unsigned int tWTR;
266 unsigned int tRRD;
267 unsigned int tRTP;
268};
269
270struct dimminfo {
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000271 unsigned int card_type; /* 0xff: unpopulated,
Damien Zammit43a1f782015-08-19 15:16:59 +1000272 0xa - 0xf: raw card type A - F */
273 enum chip_width width;
Damien Zammit43a1f782015-08-19 15:16:59 +1000274 unsigned int page_size; /* of whole DIMM in Bytes (4096 or 8192) */
Arthur Heymans3cf94032017-04-05 16:17:26 +0200275 enum n_banks n_banks;
Damien Zammit43a1f782015-08-19 15:16:59 +1000276 unsigned int ranks;
277 unsigned int rows;
278 unsigned int cols;
Arthur Heymansadc571a2017-09-25 09:40:54 +0200279 u16 spd_crc;
Arthur Heymansf1287262017-12-25 18:30:01 +0100280 u8 mirrored;
Arthur Heymansadc571a2017-09-25 09:40:54 +0200281};
282
283struct rcven_timings {
284 u8 min_common_coarse;
Arthur Heymans276049f2017-11-05 05:56:34 +0100285 u8 coarse_offset[TOTAL_BYTELANES];
286 u8 medium[TOTAL_BYTELANES];
287 u8 tap[TOTAL_BYTELANES];
288 u8 pi[TOTAL_BYTELANES];
Damien Zammit43a1f782015-08-19 15:16:59 +1000289};
290
291/* The setup is up to two DIMMs per channel */
292struct sysinfo {
Damien Zammit43a1f782015-08-19 15:16:59 +1000293 int boot_path;
Damien Zammit43a1f782015-08-19 15:16:59 +1000294 enum fsb_clock max_fsb;
Damien Zammit43a1f782015-08-19 15:16:59 +1000295
296 int dimm_config[2];
Damien Zammit43a1f782015-08-19 15:16:59 +1000297 int spd_type;
298 int channel_capacity[2];
299 struct timings selected_timings;
300 struct dimminfo dimms[4];
301 u8 spd_map[4];
Arthur Heymansadc571a2017-09-25 09:40:54 +0200302 struct rcven_timings rcven_t[TOTAL_CHANNELS];
Arthur Heymans0bf87de2017-11-04 06:15:05 +0100303 /*
304 * The rt_dqs delay register for rank 0 seems to be used
305 * for all other ranks on the channel, so only save that
306 */
Arthur Heymans276049f2017-11-05 05:56:34 +0100307 struct rt_dqs_setting rt_dqs[TOTAL_CHANNELS][TOTAL_BYTELANES];
308 struct dll_setting dqs_settings[TOTAL_CHANNELS][TOTAL_BYTELANES];
309 struct dll_setting dq_settings[TOTAL_CHANNELS][TOTAL_BYTELANES];
Arthur Heymans7a3a3192017-05-15 10:26:29 +0200310 u8 nmode;
Arthur Heymans0602ce62018-05-26 14:44:42 +0200311 u8 stacked_mode;
Damien Zammit43a1f782015-08-19 15:16:59 +1000312};
Arthur Heymans97e13d82016-11-30 18:40:38 +0100313#define BOOT_PATH_NORMAL 0
314#define BOOT_PATH_WARM_RESET 1
315#define BOOT_PATH_RESUME 2
Damien Zammit43a1f782015-08-19 15:16:59 +1000316
317enum ddr2_signals {
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200318 CLKSET0 = 0,
319 CTRL0,
320 CLKSET1,
321 CMD,
322 CTRL1,
323 CTRL2,
324 CTRL3,
Damien Zammit43a1f782015-08-19 15:16:59 +1000325};
326
327void x4x_early_init(void);
Arthur Heymansef7e98a2016-12-30 21:07:18 +0100328void x4x_late_init(int s3resume);
Arthur Heymansbf53acc2019-11-11 21:14:39 +0100329void mb_get_spd_map(u8 spd_map[4]);
330void mb_pre_raminit_setup(int s3_resume);
Damien Zammit43a1f782015-08-19 15:16:59 +1000331u32 decode_igd_memory_size(u32 gms);
332u32 decode_igd_gtt_size(u32 gsm);
Arthur Heymans4c65bfc2018-04-10 13:34:24 +0200333u32 decode_tseg_size(const u32 esmramc);
Angel Ponsecec9472020-08-03 15:44:27 +0200334int decode_pcie_bar(u32 *const base, u32 *const len);
Damien Zammit43a1f782015-08-19 15:16:59 +1000335void sdram_initialize(int boot_path, const u8 *spd_map);
Arthur Heymansa2cc2312017-05-15 10:13:36 +0200336void do_raminit(struct sysinfo *, int fast_boot);
Arthur Heymansadc571a2017-09-25 09:40:54 +0200337void rcven(struct sysinfo *s);
Elyes HAOUASe951e8e2019-06-15 11:03:00 +0200338u32 fsb_to_mhz(u32 speed);
339u32 ddr_to_mhz(u32 speed);
Arthur Heymans1994e4482017-11-04 07:52:23 +0100340u32 test_address(int channel, int rank);
Arthur Heymans95c48cb2017-11-04 08:07:06 +0100341void dqsset(u8 ch, u8 lane, const struct dll_setting *setting);
342void dqset(u8 ch, u8 lane, const struct dll_setting *setting);
343void rt_set_dqs(u8 channel, u8 lane, u8 rank,
344 struct rt_dqs_setting *dqs_setting);
345int do_write_training(struct sysinfo *s);
346int do_read_training(struct sysinfo *s);
Arthur Heymansb5170c32017-12-25 20:13:28 +0100347void search_write_leveling(struct sysinfo *s);
348void send_jedec_cmd(const struct sysinfo *s, u8 r, u8 ch, u8 cmd, u32 val);
Damien Zammit43a1f782015-08-19 15:16:59 +1000349
Arthur Heymans0bf87de2017-11-04 06:15:05 +0100350extern const struct dll_setting default_ddr2_667_ctrl[7];
351extern const struct dll_setting default_ddr2_800_ctrl[7];
352extern const struct dll_setting default_ddr3_800_ctrl[2][7];
353extern const struct dll_setting default_ddr3_1067_ctrl[2][7];
354extern const struct dll_setting default_ddr3_1333_ctrl[2][7];
Arthur Heymans276049f2017-11-05 05:56:34 +0100355extern const struct dll_setting default_ddr2_667_dqs[TOTAL_BYTELANES];
356extern const struct dll_setting default_ddr2_800_dqs[TOTAL_BYTELANES];
357extern const struct dll_setting default_ddr3_800_dqs[2][TOTAL_BYTELANES];
358extern const struct dll_setting default_ddr3_1067_dqs[2][TOTAL_BYTELANES];
359extern const struct dll_setting default_ddr3_1333_dqs[2][TOTAL_BYTELANES];
360extern const struct dll_setting default_ddr2_667_dq[TOTAL_BYTELANES];
361extern const struct dll_setting default_ddr2_800_dq[TOTAL_BYTELANES];
362extern const struct dll_setting default_ddr3_800_dq[2][TOTAL_BYTELANES];
363extern const struct dll_setting default_ddr3_1067_dq[2][TOTAL_BYTELANES];
364extern const struct dll_setting default_ddr3_1333_dq[2][TOTAL_BYTELANES];
Arthur Heymansf1287262017-12-25 18:30:01 +0100365extern const u8 ddr3_emrs1_rtt_nom_config[16][4];
Arthur Heymans0d284952017-05-25 19:55:52 +0200366extern const u8 post_jedec_tab[3][4][2];
Arthur Heymans3fa103a2017-05-25 19:54:49 +0200367extern const u32 ddr3_c2_tab[2][3][6][2];
368extern const u8 ddr3_c2_x264[3][6];
369extern const u16 ddr3_c2_x23c[3][6];
Arthur Heymans0bf87de2017-11-04 06:15:05 +0100370
Kyösti Mälkkid7205be2019-09-27 07:24:17 +0300371#include <device/device.h>
Damien Zammit43a1f782015-08-19 15:16:59 +1000372struct acpi_rsdp;
Furquan Shaikh0f007d82020-04-24 06:41:18 -0700373unsigned long northbridge_write_acpi_tables(const struct device *device,
Elyes HAOUASfea02e12018-02-08 14:59:03 +0100374 unsigned long start, struct acpi_rsdp *rsdp);
Kyösti Mälkkid7205be2019-09-27 07:24:17 +0300375
Damien Zammit43a1f782015-08-19 15:16:59 +1000376#endif /* __NORTHBRIDGE_INTEL_X4X_H__ */