blob: 8669b1d68ad0ab63b4aa53fa16c4182b7a7c5e21 [file] [log] [blame]
Pankaj Gupta90ae1a02020-12-09 14:02:41 +05301/*
2 * Copyright 2021 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <assert.h>
9#include <errno.h>
10#include <stdbool.h>
11#include <stdint.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include <common/debug.h>
17#include <ddr.h>
18#include <lib/utils.h>
19#include <load_img.h>
20
21#include "plat_common.h"
22#include <platform_def.h>
23
24#ifdef CONFIG_STATIC_DDR
25const struct ddr_cfg_regs static_1600 = {
26 .cs[0].config = U(0xA8050322),
27 .cs[1].config = U(0x80000322),
28 .cs[0].bnds = U(0x3FF),
29 .cs[1].bnds = U(0x3FF),
30 .sdram_cfg[0] = U(0xE5044000),
31 .sdram_cfg[1] = U(0x401011),
32 .timing_cfg[0] = U(0xFF550018),
33 .timing_cfg[1] = U(0xBAB48C42),
34 .timing_cfg[2] = U(0x48C111),
35 .timing_cfg[3] = U(0x10C1000),
36 .timing_cfg[4] = U(0x2),
37 .timing_cfg[5] = U(0x3401400),
38 .timing_cfg[7] = U(0x13300000),
39 .timing_cfg[8] = U(0x2114600),
40 .sdram_mode[0] = U(0x6010210),
41 .sdram_mode[8] = U(0x500),
42 .sdram_mode[9] = U(0x4240000),
43 .interval = U(0x18600000),
44 .data_init = U(0xDEADBEEF),
45 .zq_cntl = U(0x8A090705),
46};
47
48const struct dimm_params static_dimm = {
49 .rdimm = U(0),
50 .primary_sdram_width = U(64),
51 .ec_sdram_width = U(8),
52 .n_ranks = U(2),
53 .device_width = U(8),
54 .mirrored_dimm = U(1),
55};
56
57/* Sample code using two UDIMM MT18ASF1G72AZ-2G6B1, on each DDR controller */
58unsigned long long board_static_ddr(struct ddr_info *priv)
59{
60 memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600));
61 memcpy(&priv->dimm, &static_dimm, sizeof(static_dimm));
62 priv->conf.cs_on_dimm[0] = 0x3;
63 ddr_board_options(priv);
64 compute_ddr_phy(priv);
65
66 return ULL(0x400000000);
67}
68
69#elif defined(CONFIG_DDR_NODIMM)
70/*
71 * Sample code to bypass reading SPD. This is a sample, not recommended
72 * for boards with slots. DDR model number: UDIMM MT18ASF1G72AZ-2G6B1.
73 */
74
75const struct dimm_params ddr_raw_timing = {
76 .n_ranks = U(2),
77 .rank_density = U(4294967296u),
78 .capacity = U(8589934592u),
79 .primary_sdram_width = U(64),
80 .ec_sdram_width = U(8),
81 .device_width = U(8),
82 .die_density = U(0x4),
83 .rdimm = U(0),
84 .mirrored_dimm = U(1),
85 .n_row_addr = U(15),
86 .n_col_addr = U(10),
87 .bank_addr_bits = U(0),
88 .bank_group_bits = U(2),
89 .edc_config = U(2),
90 .burst_lengths_bitmask = U(0x0c),
91 .tckmin_x_ps = 750,
92 .tckmax_ps = 1600,
93 .caslat_x = U(0x00FFFC00),
94 .taa_ps = 13750,
95 .trcd_ps = 13750,
96 .trp_ps = 13750,
97 .tras_ps = 32000,
98 .trc_ps = 457500,
99 .twr_ps = 15000,
100 .trfc1_ps = 260000,
101 .trfc2_ps = 160000,
102 .trfc4_ps = 110000,
103 .tfaw_ps = 21000,
104 .trrds_ps = 3000,
105 .trrdl_ps = 4900,
106 .tccdl_ps = 5000,
107 .refresh_rate_ps = U(7800000),
108};
109
110int ddr_get_ddr_params(struct dimm_params *pdimm,
111 struct ddr_conf *conf)
112{
113 static const char dimm_model[] = "Fixed DDR on board";
114
115 conf->dimm_in_use[0] = 1; /* Modify accordingly */
116 memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params));
117 memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
118
119 /* valid DIMM mask, change accordingly, together with dimm_on_ctlr. */
120 return 0x5;
121}
122#endif /* CONFIG_DDR_NODIMM */
123
124int ddr_board_options(struct ddr_info *priv)
125{
126 struct memctl_opt *popts = &priv->opt;
127 const struct ddr_conf *conf = &priv->conf;
128
129 popts->vref_dimm = U(0x24); /* range 1, 83.4% */
130 popts->rtt_override = 0;
131 popts->rtt_park = U(240);
132 popts->otf_burst_chop_en = 0;
133 popts->burst_length = U(DDR_BL8);
134 popts->trwt_override = U(1);
135 popts->bstopre = U(0); /* auto precharge */
136 popts->addr_hash = 1;
137
138 /* Set ODT impedance on PHY side */
139 switch (conf->cs_on_dimm[1]) {
140 case 0xc: /* Two slots dual rank */
141 case 0x4: /* Two slots single rank, not valid for interleaving */
142 popts->trwt = U(0xf);
143 popts->twrt = U(0x7);
144 popts->trrt = U(0x7);
145 popts->twwt = U(0x7);
146 popts->vref_phy = U(0x6B); /* 83.6% */
147 popts->odt = U(60);
148 popts->phy_tx_impedance = U(28);
149 break;
150 case 0: /* One slot used */
151 default:
152 popts->trwt = U(0x3);
153 popts->twrt = U(0x3);
154 popts->trrt = U(0x3);
155 popts->twwt = U(0x3);
156 popts->vref_phy = U(0x60); /* 75% */
157 popts->odt = U(48);
158 popts->phy_tx_impedance = U(28);
159 break;
160 }
161
162 return 0;
163}
164
165long long init_ddr(void)
166{
167 int spd_addr[] = { 0x51, 0x52, 0x53, 0x54 };
168 struct ddr_info info;
169 struct sysinfo sys;
170 long long dram_size;
171
172 zeromem(&sys, sizeof(sys));
173 if (get_clocks(&sys) != 0) {
174 ERROR("System clocks are not set\n");
175 panic();
176 }
177 debug("platform clock %lu\n", sys.freq_platform);
178 debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
179 debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
180
181 zeromem(&info, sizeof(info));
182
183 /* Set two DDRC. Unused DDRC will be removed automatically. */
184 info.num_ctlrs = NUM_OF_DDRC;
185 info.spd_addr = spd_addr;
186 info.ddr[0] = (void *)NXP_DDR_ADDR;
187 info.ddr[1] = (void *)NXP_DDR2_ADDR;
188 info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
189 info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
190 info.clk = get_ddr_freq(&sys, 0);
191 info.img_loadr = load_img;
192 info.phy_gen2_fw_img_buf = PHY_GEN2_FW_IMAGE_BUFFER;
193 if (info.clk == 0) {
194 info.clk = get_ddr_freq(&sys, 1);
195 }
196 info.dimm_on_ctlr = DDRC_NUM_DIMM;
197
198 info.warm_boot_flag = DDR_WRM_BOOT_NT_SUPPORTED;
199
200 dram_size = dram_init(&info
201#if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
202 , NXP_CCN_HN_F_0_ADDR
203#endif
204 );
205
206
207 if (dram_size < 0) {
208 ERROR("DDR init failed.\n");
209 }
210
211 return dram_size;
212}