coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
memory.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <soc/gpio.h>
5 #include <soc/setup.h>
6 #include <soc/dmc.h>
7 #include <soc/clk.h>
8 
9 const struct mem_timings mem_timings[] = {
10  {
12  .mem_type = DDR_MODE_DDR3,
13  .frequency_mhz = 800,
14  .mpll_mdiv = 0x64,
15  .mpll_pdiv = 0x3,
16  .mpll_sdiv = 0x0,
17  .cpll_mdiv = 0xde,
18  .cpll_pdiv = 0x4,
19  .cpll_sdiv = 0x2,
20  .gpll_mdiv = 0x215,
21  .gpll_pdiv = 0xc,
22  .gpll_sdiv = 0x1,
23  .epll_mdiv = 0x60,
24  .epll_pdiv = 0x3,
25  .epll_sdiv = 0x3,
26  .vpll_mdiv = 0x96,
27  .vpll_pdiv = 0x3,
28  .vpll_sdiv = 0x2,
29 
30  .bpll_mdiv = 0x64,
31  .bpll_pdiv = 0x3,
32  .bpll_sdiv = 0x0,
33  .use_bpll = 0,
34  .pclk_cdrex_ratio = 0x5,
35  .direct_cmd_msr = {
36  0x00020018, 0x00030000, 0x00010042, 0x00000d70
37  },
38  .timing_ref = 0x000000bb,
39  .timing_row = 0x8c36660f,
40  .timing_data = 0x3630580b,
41  .timing_power = 0x41000a44,
42  .phy0_dqs = 0x08080808,
43  .phy1_dqs = 0x08080808,
44  .phy0_dq = 0x08080808,
45  .phy1_dq = 0x08080808,
46  .phy0_tFS = 0x4,
47  .phy1_tFS = 0x4,
48  .phy0_pulld_dqs = 0xf,
49  .phy1_pulld_dqs = 0xf,
50 
51  .lpddr3_ctrl_phy_reset = 0x1,
52  .ctrl_start_point = 0x10,
53  .ctrl_inc = 0x10,
54  .ctrl_start = 0x1,
55  .ctrl_dll_on = 0x1,
56  .ctrl_ref = 0x8,
57 
58  .ctrl_force = 0x1a,
59  .ctrl_rdlat = 0x0b,
60  .ctrl_bstlen = 0x08,
61 
62  .fp_resync = 0x8,
63  .iv_size = 0x7,
64  .dfi_init_start = 1,
65  .aref_en = 1,
66 
67  .rd_fetch = 0x3,
68 
69  .zq_mode_dds = 0x7,
70  .zq_mode_term = 0x1,
71  .zq_mode_noterm = 0,
72 
73  /*
74  * Dynamic Clock: Always Running
75  * Memory Burst length: 8
76  * Number of chips: 1
77  * Memory Bus width: 32 bit
78  * Memory Type: DDR3
79  * Additional Latancy for PLL: 0 Cycle
80  */
81  .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
97  .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
98  .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
99  .prechconfig_tp_cnt = 0xff,
100  .dpwrdn_cyc = 0xff,
101  .dsref_cyc = 0xffff,
108  .dmc_channels = 2,
109  .chips_per_channel = 2,
110  .chips_to_configure = 1,
111  .send_zq_init = 1,
112  .impedance = IMP_OUTPUT_DRV_30_OHM,
113  .gate_leveling_enable = 0,
114  }, {
115  .mem_manuf = MEM_MANUF_SAMSUNG,
116  .mem_type = DDR_MODE_DDR3,
117  .frequency_mhz = 800,
118  .mpll_mdiv = 0x64,
119  .mpll_pdiv = 0x3,
120  .mpll_sdiv = 0x0,
121  .cpll_mdiv = 0xde,
122  .cpll_pdiv = 0x4,
123  .cpll_sdiv = 0x2,
124  .gpll_mdiv = 0x215,
125  .gpll_pdiv = 0xc,
126  .gpll_sdiv = 0x1,
127  .epll_mdiv = 0x60,
128  .epll_pdiv = 0x3,
129  .epll_sdiv = 0x3,
130  .vpll_mdiv = 0x96,
131  .vpll_pdiv = 0x3,
132  .vpll_sdiv = 0x2,
133 
134  .bpll_mdiv = 0x64,
135  .bpll_pdiv = 0x3,
136  .bpll_sdiv = 0x0,
137  .use_bpll = 0,
138  .pclk_cdrex_ratio = 0x5,
139  .direct_cmd_msr = {
140  0x00020018, 0x00030000, 0x00010000, 0x00000d70
141  },
142  .timing_ref = 0x000000bb,
143  .timing_row = 0x8c36660f,
144  .timing_data = 0x3630580b,
145  .timing_power = 0x41000a44,
146  .phy0_dqs = 0x08080808,
147  .phy1_dqs = 0x08080808,
148  .phy0_dq = 0x08080808,
149  .phy1_dq = 0x08080808,
150  .phy0_tFS = 0x8,
151  .phy1_tFS = 0x8,
152  .phy0_pulld_dqs = 0xf,
153  .phy1_pulld_dqs = 0xf,
154 
155  .lpddr3_ctrl_phy_reset = 0x1,
156  .ctrl_start_point = 0x10,
157  .ctrl_inc = 0x10,
158  .ctrl_start = 0x1,
159  .ctrl_dll_on = 0x1,
160  .ctrl_ref = 0x8,
161 
162  .ctrl_force = 0x1a,
163  .ctrl_rdlat = 0x0b,
164  .ctrl_bstlen = 0x08,
165 
166  .fp_resync = 0x8,
167  .iv_size = 0x7,
168  .dfi_init_start = 1,
169  .aref_en = 1,
170 
171  .rd_fetch = 0x3,
172 
173  .zq_mode_dds = 0x5,
174  .zq_mode_term = 0x1,
175  .zq_mode_noterm = 1,
176 
177  /*
178  * Dynamic Clock: Always Running
179  * Memory Burst length: 8
180  * Number of chips: 1
181  * Memory Bus width: 32 bit
182  * Memory Type: DDR3
183  * Additional Latancy for PLL: 0 Cycle
184  */
185  .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
201  .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
202  .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
203  .prechconfig_tp_cnt = 0xff,
204  .dpwrdn_cyc = 0xff,
205  .dsref_cyc = 0xffff,
212  .dmc_channels = 2,
213  .chips_per_channel = 2,
214  .chips_to_configure = 1,
215  .send_zq_init = 1,
216  .impedance = IMP_OUTPUT_DRV_40_OHM,
217  .gate_leveling_enable = 1,
218  },
219  {
220  .mem_manuf = MEM_MANUF_ELPIDA,
221  .mem_type = DDR_MODE_DDR3,
222  .frequency_mhz = 780,
223  .mpll_mdiv = 0x64,
224  .mpll_pdiv = 0x3,
225  .mpll_sdiv = 0x0,
226  .cpll_mdiv = 0xde,
227  .cpll_pdiv = 0x4,
228  .cpll_sdiv = 0x2,
229  .gpll_mdiv = 0x215,
230  .gpll_pdiv = 0xc,
231  .gpll_sdiv = 0x1,
232  .epll_mdiv = 0x60,
233  .epll_pdiv = 0x3,
234  .epll_sdiv = 0x3,
235  .vpll_mdiv = 0x96,
236  .vpll_pdiv = 0x3,
237  .vpll_sdiv = 0x2,
238 
239  .bpll_mdiv = 0x82,
240  .bpll_pdiv = 0x4,
241  .bpll_sdiv = 0x0,
242  .use_bpll = 1,
243  .pclk_cdrex_ratio = 0x5,
244  .direct_cmd_msr = {
245  0x00020018, 0x00030000, 0x00010042, 0x00000d70
246  },
247  .timing_ref = 0x000000bb,
248  .timing_row = 0x8c36660f,
249  .timing_data = 0x3630580b,
250  .timing_power = 0x41000a44,
251  .phy0_dqs = 0x08080808,
252  .phy1_dqs = 0x08080808,
253  .phy0_dq = 0x08080808,
254  .phy1_dq = 0x08080808,
255  .phy0_tFS = 0x4,
256  .phy1_tFS = 0x4,
257  .phy0_pulld_dqs = 0xf,
258  .phy1_pulld_dqs = 0xf,
259 
260  .lpddr3_ctrl_phy_reset = 0x1,
261  .ctrl_start_point = 0x10,
262  .ctrl_inc = 0x10,
263  .ctrl_start = 0x1,
264  .ctrl_dll_on = 0x1,
265  .ctrl_ref = 0x8,
266 
267  .ctrl_force = 0x1a,
268  .ctrl_rdlat = 0x0b,
269  .ctrl_bstlen = 0x08,
270 
271  .fp_resync = 0x8,
272  .iv_size = 0x7,
273  .dfi_init_start = 1,
274  .aref_en = 1,
275 
276  .rd_fetch = 0x3,
277 
278  .zq_mode_dds = 0x7,
279  .zq_mode_term = 0x1,
280  .zq_mode_noterm = 0,
281 
282  /*
283  * Dynamic Clock: Always Running
284  * Memory Burst length: 8
285  * Number of chips: 1
286  * Memory Bus width: 32 bit
287  * Memory Type: DDR3
288  * Additional Latancy for PLL: 0 Cycle
289  */
290  .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
306  .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
307  .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
308  .prechconfig_tp_cnt = 0xff,
309  .dpwrdn_cyc = 0xff,
310  .dsref_cyc = 0xffff,
317  .dmc_channels = 2,
318  .chips_per_channel = 2,
319  .chips_to_configure = 1,
320  .send_zq_init = 1,
321  .impedance = IMP_OUTPUT_DRV_30_OHM,
322  .gate_leveling_enable = 0,
323  }, {
324  .mem_manuf = MEM_MANUF_SAMSUNG,
325  .mem_type = DDR_MODE_DDR3,
326  .frequency_mhz = 780,
327  .mpll_mdiv = 0x64,
328  .mpll_pdiv = 0x3,
329  .mpll_sdiv = 0x0,
330  .cpll_mdiv = 0xde,
331  .cpll_pdiv = 0x4,
332  .cpll_sdiv = 0x2,
333  .gpll_mdiv = 0x215,
334  .gpll_pdiv = 0xc,
335  .gpll_sdiv = 0x1,
336  .epll_mdiv = 0x60,
337  .epll_pdiv = 0x3,
338  .epll_sdiv = 0x3,
339  .vpll_mdiv = 0x96,
340  .vpll_pdiv = 0x3,
341  .vpll_sdiv = 0x2,
342 
343  .bpll_mdiv = 0x82,
344  .bpll_pdiv = 0x4,
345  .bpll_sdiv = 0x0,
346  .use_bpll = 1,
347  .pclk_cdrex_ratio = 0x5,
348  .direct_cmd_msr = {
349  0x00020018, 0x00030000, 0x00010000, 0x00000d70
350  },
351  .timing_ref = 0x000000bb,
352  .timing_row = 0x8c36660f,
353  .timing_data = 0x3630580b,
354  .timing_power = 0x41000a44,
355  .phy0_dqs = 0x08080808,
356  .phy1_dqs = 0x08080808,
357  .phy0_dq = 0x08080808,
358  .phy1_dq = 0x08080808,
359  .phy0_tFS = 0x8,
360  .phy1_tFS = 0x8,
361  .phy0_pulld_dqs = 0xf,
362  .phy1_pulld_dqs = 0xf,
363 
364  .lpddr3_ctrl_phy_reset = 0x1,
365  .ctrl_start_point = 0x10,
366  .ctrl_inc = 0x10,
367  .ctrl_start = 0x1,
368  .ctrl_dll_on = 0x1,
369  .ctrl_ref = 0x8,
370 
371  .ctrl_force = 0x1a,
372  .ctrl_rdlat = 0x0b,
373  .ctrl_bstlen = 0x08,
374 
375  .fp_resync = 0x8,
376  .iv_size = 0x7,
377  .dfi_init_start = 1,
378  .aref_en = 1,
379 
380  .rd_fetch = 0x3,
381 
382  .zq_mode_dds = 0x5,
383  .zq_mode_term = 0x1,
384  .zq_mode_noterm = 1,
385 
386  /*
387  * Dynamic Clock: Always Running
388  * Memory Burst length: 8
389  * Number of chips: 1
390  * Memory Bus width: 32 bit
391  * Memory Type: DDR3
392  * Additional Latancy for PLL: 0 Cycle
393  */
394  .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
410  .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
411  .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
412  .prechconfig_tp_cnt = 0xff,
413  .dpwrdn_cyc = 0xff,
414  .dsref_cyc = 0xffff,
421  .dmc_channels = 2,
422  .chips_per_channel = 2,
423  .chips_to_configure = 1,
424  .send_zq_init = 1,
425  .impedance = IMP_OUTPUT_DRV_40_OHM,
426  .gate_leveling_enable = 1,
427  }
428 };
429 
430 #define BOARD_ID0_GPIO 88 /* GPD0, pin 0 */
431 #define BOARD_ID1_GPIO 89 /* GPD0, pin 1 */
432 
444 };
445 
446 struct {
447  enum mvl3 id0, id1;
448  enum board_config config;
449 } id_map[] = {
450  /* ID0 ID1 config */
460 };
461 
462 static int board_get_config(void)
463 {
464  int i;
465  int id0, id1;
467 
470  if (id0 < 0 || id1 < 0)
471  return -1;
472 
473  for (i = 0; i < ARRAY_SIZE(id_map); i++) {
474  if (id0 == id_map[i].id0 && id1 == id_map[i].id1) {
475  config = id_map[i].config;
476  break;
477  }
478  }
479 
480  return config;
481 }
482 
484 {
485  int i;
486  enum board_config config;
487  enum ddr_mode mem_type;
488  unsigned int frequency_mhz;
489  enum mem_manuf mem_manuf;
490  const struct mem_timings *mem;
491 
493  switch (config) {
500  frequency_mhz = 800;
501  break;
508  frequency_mhz = 800;
509  break;
510  default:
511  printk(BIOS_CRIT, "Unknown board configuration.\n");
512  return NULL;
513  }
514 
515  for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings);
516  i++, mem++) {
517  if (mem->mem_type == mem_type &&
518  mem->frequency_mhz == frequency_mhz &&
519  mem->mem_manuf == mem_manuf)
520  return (struct mem_timings *)mem;
521  }
522 
523  return NULL;
524 }
mem_type
Definition: meminit.h:10
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
mem_manuf
Definition: dmc.h:184
@ MEM_MANUF_ELPIDA
Definition: dmc.h:186
@ MEM_MANUF_SAMSUNG
Definition: dmc.h:187
ddr_mode
Definition: dmc.h:160
@ DDR_MODE_DDR3
Definition: dmc.h:162
#define DMC_MEMCONTROL_MEM_TYPE_DDR3
Definition: setup.h:72
#define IMP_OUTPUT_DRV_30_OHM
Definition: setup.h:652
#define DMC_MEMCONTROL_NUM_CHIP_1
Definition: setup.h:77
#define DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(x)
Definition: setup.h:69
#define DMC_MEMCONTROL_BL_8
Definition: setup.h:80
#define DMC_MEMCONFIGx_CHIP_MAP_INTERLEAVED
Definition: setup.h:91
#define DMC_MEMCONTROL_MRR_BYTE_7_0
Definition: setup.h:85
#define DMC_CONCONTROL_EMPTY_DISABLE
Definition: setup.h:128
#define DMC_MEMCONTROL_TP_DISABLE
Definition: setup.h:66
#define DMC_MEMCONTROL_CLK_STOP_DISABLE
Definition: setup.h:63
#define DMC_MEMBASECONFIG_VAL(x)
Definition: setup.h:99
#define DMC_CONCONTROL_AREF_EN_DISABLE
Definition: setup.h:127
#define IMP_OUTPUT_DRV_40_OHM
Definition: setup.h:651
#define DMC_MEMCONFIGx_CHIP_ROW_15
Definition: setup.h:94
#define DMC_CONCONTROL_DFI_INIT_START_DISABLE
Definition: setup.h:132
#define DMC_MEMCONTROL_DSREF_ENABLE
Definition: setup.h:68
#define DMC_CONCONTROL_RD_FETCH_DISABLE
Definition: setup.h:130
#define DMC_MEMCONFIGx_CHIP_COL_10
Definition: setup.h:92
#define DMC_MEMCONTROL_DPWRDN_DISABLE
Definition: setup.h:64
#define DMC_MEMCONTROL_PZQ_DISABLE
Definition: setup.h:83
#define DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE
Definition: setup.h:65
#define DMC_MEMCONTROL_MEM_WIDTH_32BIT
Definition: setup.h:75
#define DMC_CONCONTROL_TIMEOUT_LEVEL0
Definition: setup.h:131
#define DMC_CONCONTROL_IO_PD_CON_DISABLE
Definition: setup.h:126
#define DMC_MEMCONFIGx_CHIP_BANK_8
Definition: setup.h:95
#define BIOS_CRIT
BIOS_CRIT - Recovery unlikely.
Definition: loglevel.h:56
#define BOARD_ID1_GPIO
Definition: memory.c:431
enum mvl3 id0 id1
Definition: memory.c:447
enum board_config config
Definition: memory.c:448
static int board_get_config(void)
Definition: memory.c:462
board_config
Definition: memory.c:433
@ DAISY_CONFIG_ELPIDA_EVT
Definition: memory.c:436
@ DAISY_CONFIG_SAMSUNG_DVT
Definition: memory.c:437
@ DAISY_CONFIG_ELPIDA_MP
Definition: memory.c:442
@ DAISY_CONFIG_RSVD
Definition: memory.c:443
@ DAISY_CONFIG_SAMSUNG_MP
Definition: memory.c:441
@ DAISY_CONFIG_ELPIDA_PVT
Definition: memory.c:440
@ DAISY_CONFIG_SAMSUNG_EVT
Definition: memory.c:435
@ DAISY_CONFIG_ELPIDA_DVT
Definition: memory.c:438
@ DAISY_CONFIG_SAMSUNG_PVT
Definition: memory.c:439
@ DAISY_CONFIG_UNKNOWN
Definition: memory.c:434
struct mem_timings * get_mem_timings(void)
Get the correct memory timings for our selected memory type and speed.
Definition: memory.c:483
#define BOARD_ID0_GPIO
Definition: memory.c:430
struct @270 id_map[]
int gpio_read_mvl3(unsigned int gpio)
Definition: gpio.c:197
mvl3
Definition: gpio.h:546
@ LOGIC_Z
Definition: gpio.h:549
@ LOGIC_0
Definition: gpio.h:547
@ LOGIC_1
Definition: gpio.h:548
#define NULL
Definition: stddef.h:19
unsigned int frequency_mhz
Definition: dmc.h:249
enum mem_manuf mem_manuf
Definition: dmc.h:247
enum ddr_mode mem_type
Definition: dmc.h:248