Add Intel i5000 Memory Controller Hub
[coreboot.git] / src / northbridge / intel / i5000 / raminit.h
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; version 2 of
9  * the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  */
21
22 #ifndef NORTHBRIDGE_I5000_RAMINIT_H
23 #define NORTHBRIDGE_I5000_RAMINIT_H
24
25 #include <types.h>
26 #include <arch/io.h>
27 #include <arch/romcc_io.h>
28
29 #define I5000_MAX_BRANCH 2
30 #define I5000_MAX_CHANNEL 2
31 #define I5000_MAX_DIMM_PER_CHANNEL 4
32 #define I5000_MAX_DIMMS (I5000_MAX_BRANCH * I5000_MAX_CHANNEL * I5000_MAX_DIMM_PER_CHANNEL)
33
34 #define I5000_FBDRST 0x53
35
36 #define I5000_SPD_BUSY (1 << 12)
37 #define I5000_SPD_SBE (1 << 13)
38 #define I5000_SPD_WOD (1 << 14)
39 #define I5000_SPD_RDO (1 << 15)
40
41 #define I5000_SPD0 0x74
42 #define I5000_SPD1 0x76
43
44 #define I5000_SPDCMD0 0x78
45 #define I5000_SPDCMD1 0x7c
46
47 #define I5000_FBDHPC 0x4f
48 #define I5000_FBDST  0x4b
49
50 #define I5000_FBDHPC_STATE_RESET 0x00
51 #define I5000_FBDHPC_STATE_INIT 0x10
52 #define I5000_FBDHPC_STATE_READY 0x20
53 #define I5000_FBDHPC_STATE_ACTIVE 0x30
54
55 #define I5000_FBDISTS0 0x58
56 #define I5000_FBDISTS1 0x5a
57
58 #define I5000_FBDLVL0 0x44
59 #define I5000_FBDLVL1 0x45
60
61 #define I5000_FBDICMD0 0x46
62 #define I5000_FBDICMD1 0x47
63
64 #define I5000_FBDICMD_IDLE 0x00
65 #define I5000_FBDICMD_TS0  0x80
66 #define I5000_FBDICMD_TS1  0x90
67 #define I5000_FBDICMD_TS2  0xa0
68 #define I5000_FBDICMD_TS3  0xb0
69 #define I5000_FBDICMD_TS2_MERGE 0xd0
70 #define I5000_FBDICMD_TS2_NOMERGE 0xe0
71 #define I5000_FBDICMD_ALL_ONES 0xf0
72
73 #define I5000_AMBPRESENT0 0x64
74 #define I5000_AMBPRESENT1 0x66
75
76 #define I5000_FBDSBTXCFG0 0xc0
77 #define I5000_FBDSBTXCFG1 0xc1
78
79 #define I5000_PROCENABLE 0xf0
80 #define I5000_FBD0IBPORTCTL 0x180
81 #define I5000_FBD0IBTXPAT2EN 0x1a8
82 #define I5000_FBD0IBRXPAT2EN 0x1ac
83
84 #define I5000_FBD0IBTXMSK 0x18c
85 #define I5000_FBD0IBRXMSK 0x190
86
87 #define I5000_FBDPLLCTRL 0x1c0
88
89 /* dev 16, function 1 registers */
90 #define I5000_MC 0x40
91 #define I5000_DRTA 0x48
92 #define I5000_DRTB 0x4c
93 #define I5000_ERRPERR 0x50
94 #define I5000_MCA 0x58
95 #define I5000_TOLM 0x6c
96 #define I5000_MIR0 0x80
97 #define I5000_MIR1 0x84
98 #define I5000_MIR2 0x88
99 #define I5000_AMIR0 0x8c
100 #define I5000_AMIR1 0x90
101 #define I5000_AMIR2 0x94
102
103 #define I5000_FERR_FAT_FBD 0x98
104 #define I5000_NERR_FAT_FBD 0x9c
105 #define I5000_FERR_NF_FBD 0xa0
106 #define I5000_NERR_NF_FBD 0xa4
107 #define I5000_EMASK_FBD 0xa8
108 #define I5000_ERR0_FBD 0xac
109 #define I5000_ERR1_FBD 0xb0
110 #define I5000_ERR2_FBD 0xb4
111 #define I5000_MCERR_FBD 0xb8
112 #define I5000_NRECMEMA 0xbe
113 #define I5000_NRECMEMB 0xc0
114 #define I5000_NRECFGLOG 0xc4
115 #define I5000_NRECMEMA 0xbe
116 #define I5000_NRECFBDA 0xc8
117 #define I5000_NRECFBDB 0xcc
118 #define I5000_NRECFBDC 0xd0
119 #define I5000_NRECFBDD 0xd4
120 #define I5000_NRECFBDE 0xd8
121
122 #define I5000_REDMEMB 0x7c
123 #define I5000_RECMEMA 0xe2
124 #define I5000_RECMEMB 0xe4
125 #define I5000_RECFGLOG 0xe8
126 #define I5000_RECFBDA 0xec
127 #define I5000_RECFBDB 0xf0
128 #define I5000_RECFBDC 0xf4
129 #define I5000_RECFBDD 0xf8
130 #define I5000_RECFBDE 0xfc
131
132 #define I5000_FBDTOHOSTGRCFG0 0x160
133 #define I5000_FBDTOHOSTGRCFG1 0x164
134 #define I5000_HOSTTOFBDGRCFG 0x168
135 #define I5000_GRFBDLVLDCFG 0x16c
136 #define I5000_GRHOSTFULLCFG 0x16d
137 #define I5000_GRBUBBLECFG 0x16e
138 #define I5000_GRFBDTOHOSTDBLCFG 0x16f
139
140 /* dev 16, function 2 registers */
141 #define I5000_FERR_GLOBAL 0x40
142 #define I5000_NERR_GLOBAL 0x44
143
144 /* dev 21, function 0 registers */
145 #define I5000_MTR0 0x80
146 #define I5000_MTR1 0x84
147 #define I5000_MTR2 0x88
148 #define I5000_MTR3 0x8c
149 #define I5000_DMIR0 0x90
150 #define I5000_DMIR1 0x94
151 #define I5000_DMIR2 0x98
152 #define I5000_DMIR3 0x9c
153 #define I5000_DMIR4 0xa0
154
155 #define DEFAULT_AMBASE 0xfe000000
156
157 /* AMB function 1 registers */
158 #define AMB_FBDSBCFGNXT 0x54
159 #define AMB_FBDLOCKTO 0x68
160 #define AMB_EMASK 0x8c
161 #define AMB_FERR 0x90
162 #define AMB_NERR 0x94
163 #define AMB_CMD2DATANXT 0xe8
164
165 /* AMB function 3 registers */
166 #define AMB_DAREFTC 0x70
167 #define AMB_DSREFTC 0x74
168 #define AMB_DRT 0x78
169 #define AMB_DRC 0x7c
170
171 #define AMB_MBCSR 0x40
172 #define AMB_MBADDR 0x44
173 #define AMB_MBLFSRSED 0xa4
174
175 /* AMB function 4 registers */
176 #define AMB_DCALCSR  0x40
177 #define AMB_DCALADDR 0x44
178 #define AMB_DCALCSR_START (1 << 31)
179
180 #define AMB_DCALCSR_OPCODE_NOP                0x00
181 #define AMB_DCALCSR_OPCODE_REFRESH            0x01
182 #define AMB_DCALCSR_OPCODE_PRECHARGE          0x02
183 #define AMB_DCALCSR_OPCODE_MRS_EMRS           0x03
184 #define AMB_DCALCSR_OPCODE_DQS_DELAY_CAL      0x05
185 #define AMB_DCALCSR_OPCODE_RECV_ENABLE_CAL    0x0c
186 #define AMB_DCALCSR_OPCODE_SELF_REFRESH_ENTRY 0x0d
187
188 #define AMB_DDR2ODTC 0xfc
189
190 #define FBDIMM_SPD_SDRAM_ADDRESSING 0x04
191 #define FBDIMM_SPD_MODULE_ORGANIZATION 0x07
192 #define FBDIMM_SPD_FTB 0x08
193 #define FBDIMM_SPD_MTB_DIVIDEND 0x09
194 #define FBDIMM_SPD_MTB_DIVISOR 0x0a
195 #define FBDIMM_SPD_MIN_TCK 0x0b
196 #define FBDIMM_SPD_CAS_LATENCIES 0x0d
197 #define FBDIMM_SPD_CAS_MIN_LATENCY 0x0e
198 #define FBDIMM_SPD_T_WR 0x10
199 #define FBDIMM_SPD_T_RCD 0x13
200 #define FBDIMM_SPD_T_RRD 0x14
201 #define FBDIMM_SPD_T_RP 0x15
202 #define FBDIMM_SPD_T_RAS_RC_MSB 0x16
203 #define FBDIMM_SPD_T_RAS 0x17
204 #define FBDIMM_SPD_T_RC 0x18
205 #define FBDIMM_SPD_T_RFC 0x19
206 #define FBDIMM_SPD_T_WTR 0x1b
207 #define FBDIMM_SPD_T_RTP 0x1c
208 #define FBDIMM_SPD_BURST_LENGTHS_SUPPORTED 0x1d
209 #define FBDIMM_SPD_ODT 0x4f
210 #define FBDIMM_SPD_T_REFI 0x20
211 #define FBDIMM_SPD_T_BB 0x83
212 #define FBDIMM_SPD_CMD2DATA_800 0x54
213 #define FBDIMM_SPD_CMD2DATA_667 0x55
214 #define FBDIMM_SPD_CMD2DATA_533 0x56
215
216 void i5000_fbdimm_init(void);
217
218 #define I5000_BURST4 0x01
219 #define I5000_BURST8 0x02
220 #define I5000_BURST_CHOP 0x80
221
222 #define I5000_ODT_50 4
223 #define I5000_ODT_75 2
224 #define I5000_ODT_150 1
225
226 enum ddr_speeds {
227         DDR_533MHZ,
228         DDR_667MHZ,
229         DDR_MAX,
230 };
231
232 struct i5000_fbdimm {
233         struct i5000_fbd_branch *branch;
234         struct i5000_fbd_channel *channel;
235         struct i5000_fbd_setup *setup;
236         enum ddr_speeds speed;
237         int num;
238         int present:1;
239         u32 ambase;
240
241         /* SPD data */
242         u8 amb_personality_bytes[14];
243         u8 banks;
244         u8 rows;
245         u8 columns;
246         u8 ranks;
247         u8 odt;
248         u8 sdram_width;
249         u8 mtb_divisor;
250         u8 mtb_dividend;
251         u8 t_ck_min;
252         u8 min_cas_latency;
253         u8 t_rrd;
254         u16 t_rfc;
255         u8 t_wtr;
256         u8 t_refi;
257         u8 cmd2datanxt[DDR_MAX];
258
259         u16 vendor;
260         u16 device;
261
262         /* memory rank size in MB */
263         int ranksize;
264 };
265
266 struct i5000_fbd_channel {
267         struct i5000_fbdimm dimm[I5000_MAX_DIMM_PER_CHANNEL];
268         struct i5000_fbd_branch *branch;
269         struct i5000_fbd_setup *setup;
270         int num;
271         int used;
272         int highest_amb;
273         int columns;
274         int rows;
275         int ranks;
276         int banks;
277         int width;
278         /* memory size in MB on this channel */
279         int totalmem;
280 };
281
282 struct i5000_fbd_branch {
283         struct i5000_fbd_channel channel[I5000_MAX_CHANNEL];
284         struct i5000_fbd_setup *setup;
285         device_t branchdev;
286         int num;
287         int used;
288         /* memory size in MB on this branch */
289         int totalmem;
290 };
291
292 enum odt {
293         ODT_150OHM=1,
294         ODT_50OHM=4,
295         ODT_75OHM=2,
296 };
297
298 enum bl {
299         BL_BL4=1,
300         BL_BL8=2,
301 };
302
303 struct i5000_fbd_setup {
304         struct i5000_fbd_branch branch[I5000_MAX_BRANCH];
305         struct i5000_fbdimm *dimms[I5000_MAX_DIMMS];
306         enum bl bl;
307         enum ddr_speeds ddr_speed;
308
309         int single_channel:1;
310         u32 tolm;
311
312         /* global SDRAM timing parameters */
313         u8 t_al;
314         u8 t_cl;
315         u8 t_ras;
316         u8 t_wrc;
317         u8 t_rc;
318         u8 t_rfc;
319         u8 t_rrd;
320         u8 t_ref;
321         u8 t_w2rdr;
322         u8 t_r2w;
323         u8 t_w2r;
324         u8 t_r2r;
325         u8 t_w2w;
326         u8 t_wtr;
327         u8 t_rcd;
328         u8 t_rp;
329         u8 t_wr;
330         u8 t_rtp;
331         /* memory size in MB */
332         int totalmem;
333 };
334
335 int mainboard_set_fbd_clock(int);
336 #define AMB_ADDR(base, fn, reg) (base | ((fn & 7) << 8) | ((reg & 0xff)))
337 #endif