blob: 9db6c12122d3ba9a6afaa6e70dd94a73f0db7c5a [file] [log] [blame]
Damien Zammit43a1f782015-08-19 15:16:59 +10001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2008 coresystems GmbH
5 * 2012 secunet Security Networks AG
6 * Copyright (C) 2015 Damien Zammit <damien@zamaudio.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef __NORTHBRIDGE_INTEL_X4X_H__
19#define __NORTHBRIDGE_INTEL_X4X_H__
20
Damien Zammit43a1f782015-08-19 15:16:59 +100021/*
22 * D0:F0
23 */
24#define D0F0_EPBAR_LO 0x40
25#define D0F0_EPBAR_HI 0x44
26#define D0F0_MCHBAR_LO 0x48
27#define D0F0_MCHBAR_HI 0x4c
28#define D0F0_GGC 0x52
29#define D0F0_DEVEN 0x54
Damien Zammitfe9876a2016-01-22 19:11:05 +110030#define D0EN (1 << 0)
31#define D1EN (1 << 1)
32#define IGD0EN (1 << 3)
33#define IGD1EN (1 << 4)
34#define D3F0EN (1 << 6)
35#define D3F1EN (1 << 7)
36#define D3F2EN (1 << 8)
37#define D3F3EN (1 << 9)
38#define PEG1EN (1 << 13)
Damien Zammita99c64e2016-09-05 02:36:02 +100039#define BOARD_DEVEN (D0EN | D1EN | IGD0EN | IGD1EN | PEG1EN)
Damien Zammit43a1f782015-08-19 15:16:59 +100040#define D0F0_PCIEXBAR_LO 0x60
41#define D0F0_PCIEXBAR_HI 0x64
42#define D0F0_DMIBAR_LO 0x68
43#define D0F0_DMIBAR_HI 0x6c
Damien Zammit43a1f782015-08-19 15:16:59 +100044#define D0F0_PAM(x) (0x90+(x)) /* 0-6*/
45#define D0F0_REMAPBASE 0x98
46#define D0F0_REMAPLIMIT 0x9a
47#define D0F0_SMRAM 0x9d
48#define D0F0_ESMRAMC 0x9e
49#define D0F0_TOM 0xa0
50#define D0F0_TOUUD 0xa2
51#define D0F0_TOLUD 0xb0
52#define D0F0_GBSM 0xa4
53#define D0F0_BGSM 0xa8
54#define D0F0_TSEG 0xac
55#define D0F0_SKPD 0xdc /* Scratchpad Data */
56#define D0F0_CAPID0 0xe0
57
58/*
59 * D1:F0 PEG
60 */
61#define PEG_CAP 0xa2
62#define SLOTCAP 0xb4
63#define PEGLC 0xec
64#define D1F0_VCCAP 0x104
65#define D1F0_VC0RCTL 0x114
66
67/*
68 * Graphics frequencies
69 */
70#define GCFGC_PCIDEV PCI_DEV(0, 2, 0)
71#define GCFGC_OFFSET 0xf0
72#define GCFGC_CR_SHIFT 0
73#define GCFGC_CR_MASK (0xf << GCFGC_CR_SHIFT)
74#define GCFGC_CS_SHIFT 8
75#define GCFGC_CS_MASK (0xf << GCFGC_CS_SHIFT)
76#define GCFGC_CD_SHIFT 12
77#define GCFGC_CD_MASK (0x1 << GCFGC_CD_SHIFT)
78#define GCFGC_UPDATE_SHIFT 5
79#define GCFGC_UPDATE (0x1 << GCFGC_UPDATE_SHIFT)
80
81/*
82 * MCHBAR
83 */
84
Arthur Heymans70a1dda2017-03-09 01:58:24 +010085#define MCHBAR8(x) (*((volatile u8 *)(DEFAULT_MCHBAR + (x))))
86#define MCHBAR16(x) (*((volatile u16 *)(DEFAULT_MCHBAR + (x))))
87#define MCHBAR32(x) (*((volatile u32 *)(DEFAULT_MCHBAR + (x))))
Damien Zammit43a1f782015-08-19 15:16:59 +100088
89#define PMSTS_MCHBAR 0x0f14 /* Self refresh channel status */
Arthur Heymans97e13d82016-11-30 18:40:38 +010090#define PMSTS_WARM_RESET (1 << 8)
91#define PMSTS_BOTH_SELFREFRESH (3 << 0)
Damien Zammit43a1f782015-08-19 15:16:59 +100092
93#define CLKCFG_MCHBAR 0x0c00
94#define CLKCFG_FSBCLK_SHIFT 0
95#define CLKCFG_FSBCLK_MASK (7 << CLKCFG_FSBCLK_SHIFT)
96#define CLKCFG_MEMCLK_SHIFT 4
97#define CLKCFG_MEMCLK_MASK (7 << CLKCFG_MEMCLK_SHIFT)
98#define CLKCFG_UPDATE (1 << 12)
99
Arthur Heymans5b30b822016-12-01 18:41:50 +0100100#define SSKPD_MCHBAR 0x0c20 /* 64 bit */
Damien Zammit43a1f782015-08-19 15:16:59 +1000101
102/*
103 * DMIBAR
104 */
105
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100106#define DMIBAR8(x) (*((volatile u8 *)(DEFAULT_DMIBAR + (x))))
107#define DMIBAR16(x) (*((volatile u16 *)(DEFAULT_DMIBAR + (x))))
108#define DMIBAR32(x) (*((volatile u32 *)(DEFAULT_DMIBAR + (x))))
Damien Zammit43a1f782015-08-19 15:16:59 +1000109
110#define DMIVC0RCTL 0x14
111#define DMIVC1RCTL 0x20
112#define DMIVC1RSTS 0x26
113#define DMIESD 0x44
114#define DMILE1D 0x50
115#define DMILE1A 0x58
116#define DMILE2D 0x60
117#define DMILE2A 0x68
118
119/*
120 * EPBAR
121 */
122
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100123#define EPBAR8(x) (*((volatile u8 *)(DEFAULT_EPBAR + (x))))
124#define EPBAR16(x) (*((volatile u16 *)(DEFAULT_EPBAR + (x))))
125#define EPBAR32(x) (*((volatile u32 *)(DEFAULT_EPBAR + (x))))
Damien Zammit43a1f782015-08-19 15:16:59 +1000126
127#define EPESD 0x44
128#define EPLE1D 0x50
129#define EPLE1A 0x58
130#define EPLE2D 0x60
131
132#define NOP_CMD 0x2
133#define PRECHARGE_CMD 0x4
134#define MRS_CMD 0x6
135#define EMRS_CMD 0x8
136#define EMRS1_CMD (EMRS_CMD | 0x10)
137#define EMRS2_CMD (EMRS_CMD | 0x20)
138#define EMRS3_CMD (EMRS_CMD | 0x30)
139#define ZQCAL_CMD 0xa
140#define CBR_CMD 0xc
141#define NORMALOP_CMD 0xe
142
143#define TOTAL_CHANNELS 2
144#define TOTAL_DIMMS 4
Nico Huber3c209062016-11-26 02:03:25 +0100145#define DIMMS_PER_CHANNEL (TOTAL_DIMMS / TOTAL_CHANNELS)
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000146#define RAW_CARD_UNPOPULATED 0xff
Damien Zammit43a1f782015-08-19 15:16:59 +1000147
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000148#define DIMM_IS_POPULATED(dimms, idx) (dimms[idx].card_type != RAW_CARD_UNPOPULATED)
149#define IF_DIMM_POPULATED(dimms, idx) if (dimms[idx].card_type != RAW_CARD_UNPOPULATED)
Damien Zammit43a1f782015-08-19 15:16:59 +1000150#define ONLY_DIMMA_IS_POPULATED(dimms, ch) ( \
151 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
152 !DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3)))
153#define ONLY_DIMMB_IS_POPULATED(dimms, ch) ( \
154 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3) && \
155 !DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2)))
156#define BOTH_DIMMS_ARE_POPULATED(dimms, ch) ( \
157 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
158 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3))))
159#define FOR_EACH_DIMM(idx) \
160 for (idx = 0; idx < TOTAL_DIMMS; ++idx)
161#define FOR_EACH_POPULATED_DIMM(dimms, idx) \
162 FOR_EACH_DIMM(idx) IF_DIMM_POPULATED(dimms, idx)
Nico Huber696abfc2016-11-23 23:56:53 +0100163#define FOR_EACH_DIMM_IN_CHANNEL(ch, idx) \
Nico Huber3c209062016-11-26 02:03:25 +0100164 for (idx = (ch) << 1; idx < ((ch) << 1) + DIMMS_PER_CHANNEL; ++idx)
Nico Huber696abfc2016-11-23 23:56:53 +0100165#define FOR_EACH_POPULATED_DIMM_IN_CHANNEL(dimms, ch, idx) \
166 FOR_EACH_DIMM_IN_CHANNEL(ch, idx) IF_DIMM_POPULATED(dimms, idx)
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100167#define CHANNEL_IS_POPULATED(dimms, idx) \
168 ((dimms[idx<<1].card_type != RAW_CARD_UNPOPULATED) \
169 || (dimms[(idx<<1) + 1].card_type != RAW_CARD_UNPOPULATED))
170#define CHANNEL_IS_CARDF(dimms, idx) \
171 ((dimms[idx<<1].card_type == 0xf) \
172 || (dimms[(idx<<1) + 1].card_type == 0xf))
173#define IF_CHANNEL_POPULATED(dimms, idx) \
174 if ((dimms[idx<<1].card_type != RAW_CARD_UNPOPULATED) \
175 || (dimms[(idx<<1) + 1].card_type != RAW_CARD_UNPOPULATED))
Damien Zammit43a1f782015-08-19 15:16:59 +1000176#define FOR_EACH_CHANNEL(idx) \
177 for (idx = 0; idx < TOTAL_CHANNELS; ++idx)
178#define FOR_EACH_POPULATED_CHANNEL(dimms, idx) \
179 FOR_EACH_CHANNEL(idx) IF_CHANNEL_POPULATED(dimms, idx)
180
181#define RANKS_PER_CHANNEL 4
182#define RANK_IS_POPULATED(dimms, ch, r) \
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000183 (((dimms[ch<<1].card_type != RAW_CARD_UNPOPULATED) && ((r) < dimms[ch<<1].ranks)) || \
184 ((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 +1000185#define IF_RANK_POPULATED(dimms, ch, r) \
Arthur Heymans70a1dda2017-03-09 01:58:24 +0100186 if (((dimms[ch<<1].card_type != RAW_CARD_UNPOPULATED) \
187 && ((r) < dimms[ch<<1].ranks)) \
188 || ((dimms[(ch<<1) + 1].card_type != RAW_CARD_UNPOPULATED) \
189 && ((r) >= 2) && ((r) < (dimms[(ch<<1) + 1].ranks + 2))))
Damien Zammit43a1f782015-08-19 15:16:59 +1000190#define FOR_EACH_RANK_IN_CHANNEL(r) \
191 for (r = 0; r < RANKS_PER_CHANNEL; ++r)
192#define FOR_EACH_POPULATED_RANK_IN_CHANNEL(dimms, ch, r) \
193 FOR_EACH_RANK_IN_CHANNEL(r) IF_RANK_POPULATED(dimms, ch, r)
194#define FOR_EACH_RANK(ch, r) \
195 FOR_EACH_CHANNEL(ch) FOR_EACH_RANK_IN_CHANNEL(r)
196#define FOR_EACH_POPULATED_RANK(dimms, ch, r) \
197 FOR_EACH_RANK(ch, r) IF_RANK_POPULATED(dimms, ch, r)
198
199#define DDR3_MAX_CAS 18
200
201enum fsb_clock {
202 FSB_CLOCK_800MHz = 0,
203 FSB_CLOCK_1066MHz = 1,
204 FSB_CLOCK_1333MHz = 2,
205};
206
207enum mem_clock {
208 MEM_CLOCK_400MHz = 0,
209 MEM_CLOCK_533MHz = 1,
210 MEM_CLOCK_667MHz = 2,
211 MEM_CLOCK_800MHz = 3,
212 MEM_CLOCK_1066MHz = 4,
213 MEM_CLOCK_1333MHz = 5,
214};
215
216enum ddr {
217 DDR2 = 2,
218 DDR3 = 3,
219};
220
221enum ddrxspd {
222 DDR2SPD = 0x8,
223 DDR3SPD = 0xb,
224};
225
226enum chip_width { /* as in DDR3 spd */
227 CHIP_WIDTH_x4 = 0,
228 CHIP_WIDTH_x8 = 1,
229 CHIP_WIDTH_x16 = 2,
230 CHIP_WIDTH_x32 = 3,
231};
232
233enum chip_cap { /* as in DDR3 spd */
234 CHIP_CAP_256M = 0,
235 CHIP_CAP_512M = 1,
236 CHIP_CAP_1G = 2,
237 CHIP_CAP_2G = 3,
238 CHIP_CAP_4G = 4,
239 CHIP_CAP_8G = 5,
240 CHIP_CAP_16G = 6,
241};
242
Arthur Heymans27f0ca12017-05-09 18:38:14 +0200243struct dll_setting {
244 u8 tap;
245 u8 pi;
246 u8 db_en;
247 u8 db_sel;
248 u8 clk_delay;
249 u8 coarse;
250};
251
Damien Zammit43a1f782015-08-19 15:16:59 +1000252struct timings {
253 unsigned int CAS;
254 enum fsb_clock fsb_clk;
255 enum mem_clock mem_clk;
256 unsigned int tRAS;
257 unsigned int tRP;
258 unsigned int tRCD;
259 unsigned int tWR;
260 unsigned int tRFC;
261 unsigned int tWTR;
262 unsigned int tRRD;
263 unsigned int tRTP;
264};
265
266struct dimminfo {
Damien Zammit68e1dcf2016-06-03 15:39:30 +1000267 unsigned int card_type; /* 0xff: unpopulated,
Damien Zammit43a1f782015-08-19 15:16:59 +1000268 0xa - 0xf: raw card type A - F */
269 enum chip_width width;
270 enum chip_cap chip_capacity;
271 unsigned int page_size; /* of whole DIMM in Bytes (4096 or 8192) */
272 unsigned int sides;
273 unsigned int banks;
274 unsigned int ranks;
275 unsigned int rows;
276 unsigned int cols;
277 unsigned int cas_latencies;
278 unsigned int tAAmin;
279 unsigned int tCKmin;
280 unsigned int tWR;
281 unsigned int tRP;
282 unsigned int tRCD;
283 unsigned int tRAS;
Martin Roth128c1042016-11-18 09:29:03 -0700284 unsigned int rank_capacity_mb; /* per rank in Megabytes */
Damien Zammit43a1f782015-08-19 15:16:59 +1000285 u8 spd_data[256];
286};
287
288/* The setup is up to two DIMMs per channel */
289struct sysinfo {
290 int txt_enabled;
291 int cores;
292 int boot_path;
293 int max_ddr2_mhz;
294 int max_ddr3_mt;
295 enum fsb_clock max_fsb;
296 int max_fsb_mhz;
297 int max_render_mhz;
298 int enable_igd;
299 int enable_peg;
300 u16 ggc;
301
302 int dimm_config[2];
303 int dimms_per_ch;
304 int spd_type;
305 int channel_capacity[2];
306 struct timings selected_timings;
307 struct dimminfo dimms[4];
308 u8 spd_map[4];
309};
Arthur Heymans97e13d82016-11-30 18:40:38 +0100310#define BOOT_PATH_NORMAL 0
311#define BOOT_PATH_WARM_RESET 1
312#define BOOT_PATH_RESUME 2
Damien Zammit43a1f782015-08-19 15:16:59 +1000313
314enum ddr2_signals {
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200315 CLKSET0 = 0,
316 CTRL0,
317 CLKSET1,
318 CMD,
319 CTRL1,
320 CTRL2,
321 CTRL3,
322 DQS1,
323 DQS2,
324 DQS3,
325 DQS4,
326 DQS5,
327 DQS6,
328 DQS7,
329 DQS8,
330 DQ1,
331 DQ2,
332 DQ3,
333 DQ4,
334 DQ5,
335 DQ6,
336 DQ7,
337 DQ8
Damien Zammit43a1f782015-08-19 15:16:59 +1000338};
339
Martin Rothcbe38922016-01-05 19:40:41 -0700340#ifndef __BOOTBLOCK__
Damien Zammit43a1f782015-08-19 15:16:59 +1000341void x4x_early_init(void);
Arthur Heymansef7e98a2016-12-30 21:07:18 +0100342void x4x_late_init(int s3resume);
Damien Zammit43a1f782015-08-19 15:16:59 +1000343u32 decode_igd_memory_size(u32 gms);
344u32 decode_igd_gtt_size(u32 gsm);
345u8 decode_pciebar(u32 *const base, u32 *const len);
346void sdram_initialize(int boot_path, const u8 *spd_map);
347void raminit_ddr2(struct sysinfo *);
Arthur Heymans6d7a8c12017-03-07 20:48:14 +0100348void rcven(const struct sysinfo *);
Damien Zammit43a1f782015-08-19 15:16:59 +1000349
350struct acpi_rsdp;
Antonello Dettori60a6e152016-09-03 10:45:33 +0200351#ifndef __SIMPLE_DEVICE__
Damien Zammit43a1f782015-08-19 15:16:59 +1000352unsigned long northbridge_write_acpi_tables(device_t device, unsigned long start, struct acpi_rsdp *rsdp);
Antonello Dettori60a6e152016-09-03 10:45:33 +0200353#endif /* __SIMPLE_DEVICE__ */
Martin Rothcbe38922016-01-05 19:40:41 -0700354#endif
Damien Zammit43a1f782015-08-19 15:16:59 +1000355#endif /* __NORTHBRIDGE_INTEL_X4X_H__ */