xref: /rk3399_ARM-atf/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c (revision 16662dc40dd2578d3000528ece090ed39ed18b9c)
1*16662dc4SJiafei Pan /*
2*16662dc4SJiafei Pan  * Copyright 2018-2022 NXP
3*16662dc4SJiafei Pan  *
4*16662dc4SJiafei Pan  * SPDX-License-Identifier: BSD-3-Clause
5*16662dc4SJiafei Pan  */
6*16662dc4SJiafei Pan 
7*16662dc4SJiafei Pan #include <assert.h>
8*16662dc4SJiafei Pan #include <errno.h>
9*16662dc4SJiafei Pan 
10*16662dc4SJiafei Pan #include <common/debug.h>
11*16662dc4SJiafei Pan #include <ddr.h>
12*16662dc4SJiafei Pan #include <lib/utils.h>
13*16662dc4SJiafei Pan 
14*16662dc4SJiafei Pan #include <errata.h>
15*16662dc4SJiafei Pan 
16*16662dc4SJiafei Pan static const struct rc_timing rce[] = {
17*16662dc4SJiafei Pan 	{U(1600), U(8), U(7)},
18*16662dc4SJiafei Pan 	{U(1867), U(8), U(7)},
19*16662dc4SJiafei Pan 	{U(2134), U(8), U(9)},
20*16662dc4SJiafei Pan 	{}
21*16662dc4SJiafei Pan };
22*16662dc4SJiafei Pan 
23*16662dc4SJiafei Pan static const struct board_timing udimm[] = {
24*16662dc4SJiafei Pan 	{U(0x04), rce, U(0x01020304), U(0x06070805)},
25*16662dc4SJiafei Pan };
26*16662dc4SJiafei Pan 
27*16662dc4SJiafei Pan int ddr_board_options(struct ddr_info *priv)
28*16662dc4SJiafei Pan {
29*16662dc4SJiafei Pan 	int ret;
30*16662dc4SJiafei Pan 	struct memctl_opt *popts = &priv->opt;
31*16662dc4SJiafei Pan 
32*16662dc4SJiafei Pan 	if (popts->rdimm) {
33*16662dc4SJiafei Pan 		debug("RDIMM parameters not set.\n");
34*16662dc4SJiafei Pan 		return -EINVAL;
35*16662dc4SJiafei Pan 	}
36*16662dc4SJiafei Pan 
37*16662dc4SJiafei Pan 	ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
38*16662dc4SJiafei Pan 	if (ret != 0) {
39*16662dc4SJiafei Pan 		return ret;
40*16662dc4SJiafei Pan 	}
41*16662dc4SJiafei Pan 
42*16662dc4SJiafei Pan 	popts->wrlvl_override = U(1);
43*16662dc4SJiafei Pan 	popts->wrlvl_sample = U(0x0);	/* 32 clocks */
44*16662dc4SJiafei Pan 	popts->ddr_cdr1 = DDR_CDR1_DHC_EN	|
45*16662dc4SJiafei Pan 			  DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
46*16662dc4SJiafei Pan 	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm)	|
47*16662dc4SJiafei Pan 			  DDR_CDR2_VREF_TRAIN_EN		|
48*16662dc4SJiafei Pan 			  DDR_CDR2_VREF_RANGE_2;
49*16662dc4SJiafei Pan 
50*16662dc4SJiafei Pan 	/* optimize cpo for erratum A-009942 */
51*16662dc4SJiafei Pan 	popts->cpo_sample = U(0x70);
52*16662dc4SJiafei Pan 
53*16662dc4SJiafei Pan 	return 0;
54*16662dc4SJiafei Pan }
55*16662dc4SJiafei Pan 
56*16662dc4SJiafei Pan long long init_ddr(void)
57*16662dc4SJiafei Pan {
58*16662dc4SJiafei Pan 	int spd_addr[] = { NXP_SPD_EEPROM0 };
59*16662dc4SJiafei Pan 	struct ddr_info info;
60*16662dc4SJiafei Pan 	struct sysinfo sys;
61*16662dc4SJiafei Pan 	long long dram_size;
62*16662dc4SJiafei Pan 
63*16662dc4SJiafei Pan 	zeromem(&sys, sizeof(sys));
64*16662dc4SJiafei Pan 	if (get_clocks(&sys)) {
65*16662dc4SJiafei Pan 		ERROR("System clocks are not set\n");
66*16662dc4SJiafei Pan 		assert(0);
67*16662dc4SJiafei Pan 	}
68*16662dc4SJiafei Pan 	debug("platform clock %lu\n", sys.freq_platform);
69*16662dc4SJiafei Pan 	debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
70*16662dc4SJiafei Pan 	debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
71*16662dc4SJiafei Pan 
72*16662dc4SJiafei Pan 	zeromem(&info, sizeof(struct ddr_info));
73*16662dc4SJiafei Pan 	info.num_ctlrs = 1;
74*16662dc4SJiafei Pan 	info.dimm_on_ctlr = 1;
75*16662dc4SJiafei Pan 	info.clk = get_ddr_freq(&sys, 0);
76*16662dc4SJiafei Pan 	info.spd_addr = spd_addr;
77*16662dc4SJiafei Pan 	info.ddr[0] = (void *)NXP_DDR_ADDR;
78*16662dc4SJiafei Pan 
79*16662dc4SJiafei Pan 	dram_size = dram_init(&info);
80*16662dc4SJiafei Pan 
81*16662dc4SJiafei Pan 	if (dram_size < 0) {
82*16662dc4SJiafei Pan 		ERROR("DDR init failed.\n");
83*16662dc4SJiafei Pan 	}
84*16662dc4SJiafei Pan 
85*16662dc4SJiafei Pan #ifdef ERRATA_SOC_A008850
86*16662dc4SJiafei Pan 	erratum_a008850_post();
87*16662dc4SJiafei Pan #endif
88*16662dc4SJiafei Pan 
89*16662dc4SJiafei Pan 	return dram_size;
90*16662dc4SJiafei Pan }
91