]>
Commit | Line | Data |
---|---|---|
9bbd2132 DN |
1 | /* |
2 | * Copyright Altera Corporation (C) 2014-2015 | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | #include <common.h> | |
7 | #include <div64.h> | |
8 | #include <watchdog.h> | |
9 | #include <asm/arch/fpga_manager.h> | |
10 | #include <asm/arch/sdram.h> | |
9bbd2132 DN |
11 | #include <asm/arch/system_manager.h> |
12 | #include <asm/io.h> | |
13 | ||
d04941cf MV |
14 | /* |
15 | * FIXME: This path is temporary until the SDRAM driver gets | |
16 | * a proper thorough cleanup. | |
17 | */ | |
18 | #include "../../../board/altera/socfpga/qts/sdram_config.h" | |
19 | ||
9bbd2132 DN |
20 | /* define constant for 4G memory - used for SDRAM errata workaround */ |
21 | #define MEMSIZE_4G (4ULL * 1024ULL * 1024ULL * 1024ULL) | |
22 | ||
23 | DECLARE_GLOBAL_DATA_PTR; | |
24 | ||
42f7ebb8 MV |
25 | struct sdram_prot_rule { |
26 | u64 sdram_start; /* SDRAM start address */ | |
27 | u64 sdram_end; /* SDRAM end address */ | |
28 | u32 rule; /* SDRAM protection rule number: 0-19 */ | |
29 | int valid; /* Rule valid or not? 1 - valid, 0 not*/ | |
30 | ||
31 | u32 security; | |
32 | u32 portmask; | |
33 | u32 result; | |
34 | u32 lo_prot_id; | |
35 | u32 hi_prot_id; | |
36 | }; | |
37 | ||
9bbd2132 DN |
38 | static struct socfpga_system_manager *sysmgr_regs = |
39 | (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; | |
40 | static struct socfpga_sdr_ctrl *sdr_ctrl = | |
41 | (struct socfpga_sdr_ctrl *)(SOCFPGA_SDR_ADDRESS + SDR_CTRLGRP_ADDRESS); | |
42 | ||
43 | static int compute_errata_rows(unsigned long long memsize, int cs, int width, | |
44 | int rows, int banks, int cols) | |
45 | { | |
46 | unsigned long long newrows; | |
47 | int inewrowslog2; | |
48 | int bits; | |
49 | ||
50 | debug("workaround rows - memsize %lld\n", memsize); | |
51 | debug("workaround rows - cs %d\n", cs); | |
52 | debug("workaround rows - width %d\n", width); | |
53 | debug("workaround rows - rows %d\n", rows); | |
54 | debug("workaround rows - banks %d\n", banks); | |
55 | debug("workaround rows - cols %d\n", cols); | |
56 | ||
57 | newrows = lldiv(memsize, (cs * (width / 8))); | |
58 | debug("rows workaround - term1 %lld\n", newrows); | |
59 | ||
60 | newrows = lldiv(newrows, ((1 << banks) * (1 << cols))); | |
61 | debug("rows workaround - term2 %lld\n", newrows); | |
62 | ||
63 | /* Compute the hamming weight - same as number of bits set. | |
64 | * Need to see if result is ordinal power of 2 before | |
65 | * attempting log2 of result. | |
66 | */ | |
67 | bits = hweight32(newrows); | |
68 | ||
69 | debug("rows workaround - bits %d\n", bits); | |
70 | ||
71 | if (bits != 1) { | |
72 | printf("SDRAM workaround failed, bits set %d\n", bits); | |
73 | return rows; | |
74 | } | |
75 | ||
76 | if (newrows > UINT_MAX) { | |
77 | printf("SDRAM workaround rangecheck failed, %lld\n", newrows); | |
78 | return rows; | |
79 | } | |
80 | ||
81 | inewrowslog2 = __ilog2((unsigned int)newrows); | |
82 | ||
83 | debug("rows workaround - ilog2 %d, %d\n", inewrowslog2, | |
84 | (int)newrows); | |
85 | ||
86 | if (inewrowslog2 == -1) { | |
87 | printf("SDRAM workaround failed, newrows %d\n", (int)newrows); | |
88 | return rows; | |
89 | } | |
90 | ||
91 | return inewrowslog2; | |
92 | } | |
93 | ||
94 | /* SDRAM protection rules vary from 0-19, a total of 20 rules. */ | |
95 | static void sdram_set_rule(struct sdram_prot_rule *prule) | |
96 | { | |
97 | uint32_t lo_addr_bits; | |
98 | uint32_t hi_addr_bits; | |
99 | int ruleno = prule->rule; | |
100 | ||
101 | /* Select the rule */ | |
102 | writel(ruleno, &sdr_ctrl->prot_rule_rdwr); | |
103 | ||
104 | /* Obtain the address bits */ | |
105 | lo_addr_bits = (uint32_t)(((prule->sdram_start) >> 20ULL) & 0xFFF); | |
106 | hi_addr_bits = (uint32_t)((((prule->sdram_end-1) >> 20ULL)) & 0xFFF); | |
107 | ||
108 | debug("sdram set rule start %x, %lld\n", lo_addr_bits, | |
109 | prule->sdram_start); | |
110 | debug("sdram set rule end %x, %lld\n", hi_addr_bits, | |
111 | prule->sdram_end); | |
112 | ||
113 | /* Set rule addresses */ | |
114 | writel(lo_addr_bits | (hi_addr_bits << 12), &sdr_ctrl->prot_rule_addr); | |
115 | ||
116 | /* Set rule protection ids */ | |
117 | writel(prule->lo_prot_id | (prule->hi_prot_id << 12), | |
118 | &sdr_ctrl->prot_rule_id); | |
119 | ||
120 | /* Set the rule data */ | |
121 | writel(prule->security | (prule->valid << 2) | | |
122 | (prule->portmask << 3) | (prule->result << 13), | |
123 | &sdr_ctrl->prot_rule_data); | |
124 | ||
125 | /* write the rule */ | |
126 | writel(ruleno | (1L << 5), &sdr_ctrl->prot_rule_rdwr); | |
127 | ||
128 | /* Set rule number to 0 by default */ | |
129 | writel(0, &sdr_ctrl->prot_rule_rdwr); | |
130 | } | |
131 | ||
132 | static void sdram_get_rule(struct sdram_prot_rule *prule) | |
133 | { | |
134 | uint32_t addr; | |
135 | uint32_t id; | |
136 | uint32_t data; | |
137 | int ruleno = prule->rule; | |
138 | ||
139 | /* Read the rule */ | |
140 | writel(ruleno, &sdr_ctrl->prot_rule_rdwr); | |
141 | writel(ruleno | (1L << 6), &sdr_ctrl->prot_rule_rdwr); | |
142 | ||
143 | /* Get the addresses */ | |
144 | addr = readl(&sdr_ctrl->prot_rule_addr); | |
145 | prule->sdram_start = (addr & 0xFFF) << 20; | |
146 | prule->sdram_end = ((addr >> 12) & 0xFFF) << 20; | |
147 | ||
148 | /* Get the configured protection IDs */ | |
149 | id = readl(&sdr_ctrl->prot_rule_id); | |
150 | prule->lo_prot_id = id & 0xFFF; | |
151 | prule->hi_prot_id = (id >> 12) & 0xFFF; | |
152 | ||
153 | /* Get protection data */ | |
154 | data = readl(&sdr_ctrl->prot_rule_data); | |
155 | ||
156 | prule->security = data & 0x3; | |
157 | prule->valid = (data >> 2) & 0x1; | |
158 | prule->portmask = (data >> 3) & 0x3FF; | |
159 | prule->result = (data >> 13) & 0x1; | |
160 | } | |
161 | ||
162 | static void sdram_set_protection_config(uint64_t sdram_start, uint64_t sdram_end) | |
163 | { | |
164 | struct sdram_prot_rule rule; | |
165 | int rules; | |
166 | ||
167 | /* Start with accepting all SDRAM transaction */ | |
168 | writel(0x0, &sdr_ctrl->protport_default); | |
169 | ||
170 | /* Clear all protection rules for warm boot case */ | |
171 | memset(&rule, 0, sizeof(struct sdram_prot_rule)); | |
172 | ||
173 | for (rules = 0; rules < 20; rules++) { | |
174 | rule.rule = rules; | |
175 | sdram_set_rule(&rule); | |
176 | } | |
177 | ||
178 | /* new rule: accept SDRAM */ | |
179 | rule.sdram_start = sdram_start; | |
180 | rule.sdram_end = sdram_end; | |
181 | rule.lo_prot_id = 0x0; | |
182 | rule.hi_prot_id = 0xFFF; | |
183 | rule.portmask = 0x3FF; | |
184 | rule.security = 0x3; | |
185 | rule.result = 0; | |
186 | rule.valid = 1; | |
187 | rule.rule = 0; | |
188 | ||
189 | /* set new rule */ | |
190 | sdram_set_rule(&rule); | |
191 | ||
192 | /* default rule: reject everything */ | |
193 | writel(0x3ff, &sdr_ctrl->protport_default); | |
194 | } | |
195 | ||
196 | static void sdram_dump_protection_config(void) | |
197 | { | |
198 | struct sdram_prot_rule rule; | |
199 | int rules; | |
200 | ||
201 | debug("SDRAM Prot rule, default %x\n", | |
202 | readl(&sdr_ctrl->protport_default)); | |
203 | ||
204 | for (rules = 0; rules < 20; rules++) { | |
205 | sdram_get_rule(&rule); | |
206 | debug("Rule %d, rules ...\n", rules); | |
207 | debug(" sdram start %llx\n", rule.sdram_start); | |
208 | debug(" sdram end %llx\n", rule.sdram_end); | |
209 | debug(" low prot id %d, hi prot id %d\n", | |
210 | rule.lo_prot_id, | |
211 | rule.hi_prot_id); | |
212 | debug(" portmask %x\n", rule.portmask); | |
213 | debug(" security %d\n", rule.security); | |
214 | debug(" result %d\n", rule.result); | |
215 | debug(" valid %d\n", rule.valid); | |
216 | } | |
217 | } | |
218 | ||
219 | /* Function to write to register and verify the write */ | |
220 | static unsigned sdram_write_verify(unsigned int *addr, unsigned reg_value) | |
221 | { | |
222 | #ifndef SDRAM_MMR_SKIP_VERIFY | |
223 | unsigned reg_value1; | |
224 | #endif | |
225 | debug(" Write - Address "); | |
226 | debug("0x%08x Data 0x%08x\n", (u32)addr, reg_value); | |
227 | /* Write to register */ | |
228 | writel(reg_value, addr); | |
229 | #ifndef SDRAM_MMR_SKIP_VERIFY | |
230 | debug(" Read and verify..."); | |
231 | /* Read back the wrote value */ | |
232 | reg_value1 = readl(addr); | |
233 | /* Indicate failure if value not matched */ | |
234 | if (reg_value1 != reg_value) { | |
235 | debug("FAIL - Address 0x%08x Expected 0x%08x Data 0x%08x\n", | |
236 | (u32)addr, reg_value, reg_value1); | |
237 | return 1; | |
238 | } | |
239 | debug("correct!\n"); | |
240 | #endif /* SDRAM_MMR_SKIP_VERIFY */ | |
241 | return 0; | |
242 | } | |
243 | ||
244 | static void set_sdr_ctrlcfg(void) | |
245 | { | |
246 | int addrorder; | |
247 | ||
248 | debug("\nConfiguring CTRLCFG\n"); | |
249 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_MEMTYPE_MASK, | |
250 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE << | |
251 | SDR_CTRLGRP_CTRLCFG_MEMTYPE_LSB); | |
252 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_MEMBL_MASK, | |
253 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL << | |
254 | SDR_CTRLGRP_CTRLCFG_MEMBL_LSB); | |
255 | ||
256 | ||
257 | /* SDRAM Failure When Accessing Non-Existent Memory | |
258 | * Set the addrorder field of the SDRAM control register | |
259 | * based on the CSBITs setting. | |
260 | */ | |
261 | switch (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS) { | |
262 | case 1: | |
263 | addrorder = 0; /* chip, row, bank, column */ | |
264 | if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER != 0) | |
265 | debug("INFO: Changing address order to 0 (chip, row, \ | |
266 | bank, column)\n"); | |
267 | break; | |
268 | case 2: | |
269 | addrorder = 2; /* row, chip, bank, column */ | |
270 | if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER != 2) | |
271 | debug("INFO: Changing address order to 2 (row, chip, \ | |
272 | bank, column)\n"); | |
273 | break; | |
274 | default: | |
275 | addrorder = CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER; | |
276 | break; | |
277 | } | |
278 | ||
279 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_ADDRORDER_MASK, | |
280 | addrorder << SDR_CTRLGRP_CTRLCFG_ADDRORDER_LSB); | |
281 | ||
282 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_ECCEN_MASK, | |
283 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN << | |
284 | SDR_CTRLGRP_CTRLCFG_ECCEN_LSB); | |
285 | ||
286 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_ECCCORREN_MASK, | |
287 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN << | |
288 | SDR_CTRLGRP_CTRLCFG_ECCCORREN_LSB); | |
289 | ||
290 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_REORDEREN_MASK, | |
291 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN << | |
292 | SDR_CTRLGRP_CTRLCFG_REORDEREN_LSB); | |
293 | ||
294 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_STARVELIMIT_MASK, | |
295 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT << | |
296 | SDR_CTRLGRP_CTRLCFG_STARVELIMIT_LSB); | |
297 | ||
298 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_DQSTRKEN_MASK, | |
299 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN << | |
300 | SDR_CTRLGRP_CTRLCFG_DQSTRKEN_LSB); | |
301 | ||
302 | clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_NODMPINS_MASK, | |
303 | CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS << | |
304 | SDR_CTRLGRP_CTRLCFG_NODMPINS_LSB); | |
305 | } | |
306 | ||
307 | static void set_sdr_dram_timing1(void) | |
308 | { | |
309 | debug("Configuring DRAMTIMING1\n"); | |
310 | clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TCWL_MASK, | |
311 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL << | |
312 | SDR_CTRLGRP_DRAMTIMING1_TCWL_LSB); | |
313 | ||
314 | clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TAL_MASK, | |
315 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL << | |
316 | SDR_CTRLGRP_DRAMTIMING1_TAL_LSB); | |
317 | ||
318 | clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TCL_MASK, | |
319 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL << | |
320 | SDR_CTRLGRP_DRAMTIMING1_TCL_LSB); | |
321 | ||
322 | clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TRRD_MASK, | |
323 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD << | |
324 | SDR_CTRLGRP_DRAMTIMING1_TRRD_LSB); | |
325 | ||
326 | clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TFAW_MASK, | |
327 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW << | |
328 | SDR_CTRLGRP_DRAMTIMING1_TFAW_LSB); | |
329 | ||
330 | clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TRFC_MASK, | |
331 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC << | |
332 | SDR_CTRLGRP_DRAMTIMING1_TRFC_LSB); | |
333 | } | |
334 | ||
335 | static void set_sdr_dram_timing2(void) | |
336 | { | |
337 | debug("Configuring DRAMTIMING2\n"); | |
338 | clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TREFI_MASK, | |
339 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI << | |
340 | SDR_CTRLGRP_DRAMTIMING2_TREFI_LSB); | |
341 | ||
342 | clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TRCD_MASK, | |
343 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD << | |
344 | SDR_CTRLGRP_DRAMTIMING2_TRCD_LSB); | |
345 | ||
346 | clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TRP_MASK, | |
347 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP << | |
348 | SDR_CTRLGRP_DRAMTIMING2_TRP_LSB); | |
349 | ||
350 | clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TWR_MASK, | |
351 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR << | |
352 | SDR_CTRLGRP_DRAMTIMING2_TWR_LSB); | |
353 | ||
354 | clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TWTR_MASK, | |
355 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR << | |
356 | SDR_CTRLGRP_DRAMTIMING2_TWTR_LSB); | |
357 | } | |
358 | ||
359 | static void set_sdr_dram_timing3(void) | |
360 | { | |
361 | debug("Configuring DRAMTIMING3\n"); | |
362 | clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TRTP_MASK, | |
363 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP << | |
364 | SDR_CTRLGRP_DRAMTIMING3_TRTP_LSB); | |
365 | ||
366 | clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TRAS_MASK, | |
367 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS << | |
368 | SDR_CTRLGRP_DRAMTIMING3_TRAS_LSB); | |
369 | ||
370 | clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TRC_MASK, | |
371 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC << | |
372 | SDR_CTRLGRP_DRAMTIMING3_TRC_LSB); | |
373 | ||
374 | clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TMRD_MASK, | |
375 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD << | |
376 | SDR_CTRLGRP_DRAMTIMING3_TMRD_LSB); | |
377 | ||
378 | clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TCCD_MASK, | |
379 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD << | |
380 | SDR_CTRLGRP_DRAMTIMING3_TCCD_LSB); | |
381 | } | |
382 | ||
383 | static void set_sdr_dram_timing4(void) | |
384 | { | |
385 | debug("Configuring DRAMTIMING4\n"); | |
386 | clrsetbits_le32(&sdr_ctrl->dram_timing4, | |
387 | SDR_CTRLGRP_DRAMTIMING4_SELFRFSHEXIT_MASK, | |
388 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT << | |
389 | SDR_CTRLGRP_DRAMTIMING4_SELFRFSHEXIT_LSB); | |
390 | ||
391 | clrsetbits_le32(&sdr_ctrl->dram_timing4, | |
392 | SDR_CTRLGRP_DRAMTIMING4_PWRDOWNEXIT_MASK, | |
393 | CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT << | |
394 | SDR_CTRLGRP_DRAMTIMING4_PWRDOWNEXIT_LSB); | |
395 | } | |
396 | ||
397 | static void set_sdr_dram_lowpwr_timing(void) | |
398 | { | |
399 | debug("Configuring LOWPWRTIMING\n"); | |
400 | clrsetbits_le32(&sdr_ctrl->lowpwr_timing, | |
401 | SDR_CTRLGRP_LOWPWRTIMING_AUTOPDCYCLES_MASK, | |
402 | CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES << | |
403 | SDR_CTRLGRP_LOWPWRTIMING_AUTOPDCYCLES_LSB); | |
404 | ||
405 | clrsetbits_le32(&sdr_ctrl->lowpwr_timing, | |
406 | SDR_CTRLGRP_LOWPWRTIMING_CLKDISABLECYCLES_MASK, | |
407 | CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES << | |
408 | SDR_CTRLGRP_LOWPWRTIMING_CLKDISABLECYCLES_LSB); | |
409 | } | |
410 | ||
411 | static void set_sdr_addr_rw(void) | |
412 | { | |
413 | int cs = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS; | |
414 | int width = 8; | |
415 | int rows = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; | |
416 | int banks = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS; | |
417 | int cols = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS; | |
418 | unsigned long long workaround_memsize = MEMSIZE_4G; | |
419 | ||
420 | debug("Configuring DRAMADDRW\n"); | |
421 | clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_COLBITS_MASK, | |
422 | CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS << | |
423 | SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB); | |
424 | /* | |
425 | * SDRAM Failure When Accessing Non-Existent Memory | |
426 | * Update Preloader to artificially increase the number of rows so | |
427 | * that the memory thinks it has 4GB of RAM. | |
428 | */ | |
429 | rows = compute_errata_rows(workaround_memsize, cs, width, rows, banks, | |
430 | cols); | |
431 | ||
432 | clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_ROWBITS_MASK, | |
433 | rows << SDR_CTRLGRP_DRAMADDRW_ROWBITS_LSB); | |
434 | ||
435 | clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_BANKBITS_MASK, | |
436 | CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS << | |
437 | SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB); | |
438 | /* SDRAM Failure When Accessing Non-Existent Memory | |
439 | * Set SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB to | |
440 | * log2(number of chip select bits). Since there's only | |
441 | * 1 or 2 chip selects, log2(1) => 0, and log2(2) => 1, | |
442 | * which is the same as "chip selects" - 1. | |
443 | */ | |
444 | clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_CSBITS_MASK, | |
445 | (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS - 1) << | |
446 | SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB); | |
447 | } | |
448 | ||
449 | static void set_sdr_static_cfg(void) | |
450 | { | |
451 | debug("Configuring STATICCFG\n"); | |
452 | clrsetbits_le32(&sdr_ctrl->static_cfg, SDR_CTRLGRP_STATICCFG_MEMBL_MASK, | |
453 | CONFIG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL << | |
454 | SDR_CTRLGRP_STATICCFG_MEMBL_LSB); | |
455 | ||
456 | clrsetbits_le32(&sdr_ctrl->static_cfg, | |
457 | SDR_CTRLGRP_STATICCFG_USEECCASDATA_MASK, | |
458 | CONFIG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA << | |
459 | SDR_CTRLGRP_STATICCFG_USEECCASDATA_LSB); | |
460 | } | |
461 | ||
462 | static void set_sdr_fifo_cfg(void) | |
463 | { | |
464 | debug("Configuring FIFOCFG\n"); | |
465 | clrsetbits_le32(&sdr_ctrl->fifo_cfg, SDR_CTRLGRP_FIFOCFG_SYNCMODE_MASK, | |
466 | CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE << | |
467 | SDR_CTRLGRP_FIFOCFG_SYNCMODE_LSB); | |
468 | ||
469 | clrsetbits_le32(&sdr_ctrl->fifo_cfg, SDR_CTRLGRP_FIFOCFG_INCSYNC_MASK, | |
470 | CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC << | |
471 | SDR_CTRLGRP_FIFOCFG_INCSYNC_LSB); | |
472 | } | |
473 | ||
474 | static void set_sdr_mp_weight(void) | |
475 | { | |
476 | debug("Configuring MPWEIGHT_MPWEIGHT_0\n"); | |
477 | clrsetbits_le32(&sdr_ctrl->mp_weight0, | |
478 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_0_STATICWEIGHT_31_0_MASK, | |
479 | CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 << | |
480 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_0_STATICWEIGHT_31_0_LSB); | |
481 | ||
482 | clrsetbits_le32(&sdr_ctrl->mp_weight1, | |
483 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_STATICWEIGHT_49_32_MASK, | |
484 | CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 << | |
485 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_STATICWEIGHT_49_32_LSB); | |
486 | ||
487 | clrsetbits_le32(&sdr_ctrl->mp_weight1, | |
488 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_SUMOFWEIGHTS_13_0_MASK, | |
489 | CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 << | |
490 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_SUMOFWEIGHTS_13_0_LSB); | |
491 | ||
492 | clrsetbits_le32(&sdr_ctrl->mp_weight2, | |
493 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_2_SUMOFWEIGHTS_45_14_MASK, | |
494 | CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 << | |
495 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_2_SUMOFWEIGHTS_45_14_LSB); | |
496 | ||
497 | clrsetbits_le32(&sdr_ctrl->mp_weight3, | |
498 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_3_SUMOFWEIGHTS_63_46_MASK, | |
499 | CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 << | |
500 | SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_3_SUMOFWEIGHTS_63_46_LSB); | |
501 | } | |
502 | ||
503 | static void set_sdr_mp_pacing(void) | |
504 | { | |
505 | debug("Configuring MPPACING_MPPACING_0\n"); | |
506 | clrsetbits_le32(&sdr_ctrl->mp_pacing0, | |
507 | SDR_CTRLGRP_MPPACING_MPPACING_0_THRESHOLD1_31_0_MASK, | |
508 | CONFIG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 << | |
509 | SDR_CTRLGRP_MPPACING_MPPACING_0_THRESHOLD1_31_0_LSB); | |
510 | ||
511 | clrsetbits_le32(&sdr_ctrl->mp_pacing1, | |
512 | SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD1_59_32_MASK, | |
513 | CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 << | |
514 | SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD1_59_32_LSB); | |
515 | ||
516 | clrsetbits_le32(&sdr_ctrl->mp_pacing1, | |
517 | SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD2_3_0_MASK, | |
518 | CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 << | |
519 | SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD2_3_0_LSB); | |
520 | ||
521 | clrsetbits_le32(&sdr_ctrl->mp_pacing2, | |
522 | SDR_CTRLGRP_MPPACING_MPPACING_2_THRESHOLD2_35_4_MASK, | |
523 | CONFIG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 << | |
524 | SDR_CTRLGRP_MPPACING_MPPACING_2_THRESHOLD2_35_4_LSB); | |
525 | ||
526 | clrsetbits_le32(&sdr_ctrl->mp_pacing3, | |
527 | SDR_CTRLGRP_MPPACING_MPPACING_3_THRESHOLD2_59_36_MASK, | |
528 | CONFIG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 << | |
529 | SDR_CTRLGRP_MPPACING_MPPACING_3_THRESHOLD2_59_36_LSB); | |
530 | } | |
531 | ||
532 | static void set_sdr_mp_threshold(void) | |
533 | { | |
534 | debug("Configuring MPTHRESHOLDRST_MPTHRESHOLDRST_0\n"); | |
535 | clrsetbits_le32(&sdr_ctrl->mp_threshold0, | |
536 | SDR_CTRLGRP_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0_MASK, | |
537 | CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 << | |
538 | SDR_CTRLGRP_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0_LSB); | |
539 | ||
540 | clrsetbits_le32(&sdr_ctrl->mp_threshold1, | |
541 | SDR_CTRLGRP_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32_MASK, | |
452a81e0 | 542 | CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 << |
9bbd2132 DN |
543 | SDR_CTRLGRP_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32_LSB); |
544 | ||
545 | clrsetbits_le32(&sdr_ctrl->mp_threshold2, | |
546 | SDR_CTRLGRP_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64_MASK, | |
547 | CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 << | |
548 | SDR_CTRLGRP_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64_LSB); | |
549 | } | |
550 | ||
551 | ||
552 | /* Function to initialize SDRAM MMR */ | |
553 | unsigned sdram_mmr_init_full(unsigned int sdr_phy_reg) | |
554 | { | |
555 | unsigned long reg_value; | |
556 | unsigned long status = 0; | |
557 | ||
558 | #if defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS) && \ | |
559 | defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS) && \ | |
560 | defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS) && \ | |
561 | defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS) && \ | |
562 | defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS) | |
563 | ||
564 | writel(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS, | |
565 | &sysmgr_regs->iswgrp_handoff[4]); | |
566 | #endif | |
567 | set_sdr_ctrlcfg(); | |
568 | set_sdr_dram_timing1(); | |
569 | set_sdr_dram_timing2(); | |
570 | set_sdr_dram_timing3(); | |
571 | set_sdr_dram_timing4(); | |
572 | set_sdr_dram_lowpwr_timing(); | |
573 | set_sdr_addr_rw(); | |
574 | ||
575 | debug("Configuring DRAMIFWIDTH\n"); | |
576 | clrsetbits_le32(&sdr_ctrl->dram_if_width, | |
577 | SDR_CTRLGRP_DRAMIFWIDTH_IFWIDTH_MASK, | |
578 | CONFIG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH << | |
579 | SDR_CTRLGRP_DRAMIFWIDTH_IFWIDTH_LSB); | |
580 | ||
581 | debug("Configuring DRAMDEVWIDTH\n"); | |
582 | clrsetbits_le32(&sdr_ctrl->dram_dev_width, | |
583 | SDR_CTRLGRP_DRAMDEVWIDTH_DEVWIDTH_MASK, | |
584 | CONFIG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH << | |
585 | SDR_CTRLGRP_DRAMDEVWIDTH_DEVWIDTH_LSB); | |
586 | ||
587 | debug("Configuring LOWPWREQ\n"); | |
588 | clrsetbits_le32(&sdr_ctrl->lowpwr_eq, | |
589 | SDR_CTRLGRP_LOWPWREQ_SELFRFSHMASK_MASK, | |
590 | CONFIG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK << | |
591 | SDR_CTRLGRP_LOWPWREQ_SELFRFSHMASK_LSB); | |
592 | ||
593 | debug("Configuring DRAMINTR\n"); | |
594 | clrsetbits_le32(&sdr_ctrl->dram_intr, SDR_CTRLGRP_DRAMINTR_INTREN_MASK, | |
595 | CONFIG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN << | |
596 | SDR_CTRLGRP_DRAMINTR_INTREN_LSB); | |
597 | ||
598 | set_sdr_static_cfg(); | |
599 | ||
600 | debug("Configuring CTRLWIDTH\n"); | |
601 | clrsetbits_le32(&sdr_ctrl->ctrl_width, | |
602 | SDR_CTRLGRP_CTRLWIDTH_CTRLWIDTH_MASK, | |
603 | CONFIG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH << | |
604 | SDR_CTRLGRP_CTRLWIDTH_CTRLWIDTH_LSB); | |
605 | ||
606 | debug("Configuring PORTCFG\n"); | |
607 | clrsetbits_le32(&sdr_ctrl->port_cfg, SDR_CTRLGRP_PORTCFG_AUTOPCHEN_MASK, | |
608 | CONFIG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN << | |
609 | SDR_CTRLGRP_PORTCFG_AUTOPCHEN_LSB); | |
610 | ||
611 | set_sdr_fifo_cfg(); | |
612 | ||
613 | debug("Configuring MPPRIORITY\n"); | |
614 | clrsetbits_le32(&sdr_ctrl->mp_priority, | |
615 | SDR_CTRLGRP_MPPRIORITY_USERPRIORITY_MASK, | |
616 | CONFIG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY << | |
617 | SDR_CTRLGRP_MPPRIORITY_USERPRIORITY_LSB); | |
618 | ||
619 | set_sdr_mp_weight(); | |
620 | set_sdr_mp_pacing(); | |
621 | set_sdr_mp_threshold(); | |
622 | ||
623 | debug("Configuring PHYCTRL_PHYCTRL_0\n"); | |
624 | setbits_le32(&sdr_ctrl->phy_ctrl0, | |
625 | CONFIG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0); | |
626 | ||
627 | debug("Configuring CPORTWIDTH\n"); | |
628 | clrsetbits_le32(&sdr_ctrl->cport_width, | |
629 | SDR_CTRLGRP_CPORTWIDTH_CMDPORTWIDTH_MASK, | |
630 | CONFIG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH << | |
631 | SDR_CTRLGRP_CPORTWIDTH_CMDPORTWIDTH_LSB); | |
632 | debug(" Write - Address "); | |
633 | debug("0x%08x Data 0x%08x\n", | |
634 | (unsigned)(&sdr_ctrl->cport_width), | |
635 | (unsigned)reg_value); | |
636 | reg_value = readl(&sdr_ctrl->cport_width); | |
637 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
638 | ||
639 | debug("Configuring CPORTWMAP\n"); | |
640 | clrsetbits_le32(&sdr_ctrl->cport_wmap, | |
641 | SDR_CTRLGRP_CPORTWMAP_CPORTWFIFOMAP_MASK, | |
642 | CONFIG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP << | |
643 | SDR_CTRLGRP_CPORTWMAP_CPORTWFIFOMAP_LSB); | |
644 | debug(" Write - Address "); | |
645 | debug("0x%08x Data 0x%08x\n", | |
646 | (unsigned)(&sdr_ctrl->cport_wmap), | |
647 | (unsigned)reg_value); | |
648 | reg_value = readl(&sdr_ctrl->cport_wmap); | |
649 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
650 | ||
651 | debug("Configuring CPORTRMAP\n"); | |
652 | clrsetbits_le32(&sdr_ctrl->cport_rmap, | |
653 | SDR_CTRLGRP_CPORTRMAP_CPORTRFIFOMAP_MASK, | |
654 | CONFIG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP << | |
655 | SDR_CTRLGRP_CPORTRMAP_CPORTRFIFOMAP_LSB); | |
656 | debug(" Write - Address "); | |
657 | debug("0x%08x Data 0x%08x\n", | |
658 | (unsigned)(&sdr_ctrl->cport_rmap), | |
659 | (unsigned)reg_value); | |
660 | reg_value = readl(&sdr_ctrl->cport_rmap); | |
661 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
662 | ||
663 | debug("Configuring RFIFOCMAP\n"); | |
664 | clrsetbits_le32(&sdr_ctrl->rfifo_cmap, | |
665 | SDR_CTRLGRP_RFIFOCMAP_RFIFOCPORTMAP_MASK, | |
666 | CONFIG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP << | |
667 | SDR_CTRLGRP_RFIFOCMAP_RFIFOCPORTMAP_LSB); | |
668 | debug(" Write - Address "); | |
669 | debug("0x%08x Data 0x%08x\n", | |
670 | (unsigned)(&sdr_ctrl->rfifo_cmap), | |
671 | (unsigned)reg_value); | |
672 | reg_value = readl(&sdr_ctrl->rfifo_cmap); | |
673 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
674 | ||
675 | debug("Configuring WFIFOCMAP\n"); | |
676 | reg_value = readl(&sdr_ctrl->wfifo_cmap); | |
677 | clrsetbits_le32(&sdr_ctrl->wfifo_cmap, | |
678 | SDR_CTRLGRP_WFIFOCMAP_WFIFOCPORTMAP_MASK, | |
679 | CONFIG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP << | |
680 | SDR_CTRLGRP_WFIFOCMAP_WFIFOCPORTMAP_LSB); | |
681 | debug(" Write - Address "); | |
682 | debug("0x%08x Data 0x%08x\n", | |
683 | (unsigned)(&sdr_ctrl->wfifo_cmap), | |
684 | (unsigned)reg_value); | |
685 | reg_value = readl(&sdr_ctrl->wfifo_cmap); | |
686 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
687 | ||
688 | debug("Configuring CPORTRDWR\n"); | |
689 | clrsetbits_le32(&sdr_ctrl->cport_rdwr, | |
690 | SDR_CTRLGRP_CPORTRDWR_CPORTRDWR_MASK, | |
691 | CONFIG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR << | |
692 | SDR_CTRLGRP_CPORTRDWR_CPORTRDWR_LSB); | |
693 | debug(" Write - Address "); | |
694 | debug("0x%08x Data 0x%08x\n", | |
695 | (unsigned)(&sdr_ctrl->cport_rdwr), | |
696 | (unsigned)reg_value); | |
697 | reg_value = readl(&sdr_ctrl->cport_rdwr); | |
698 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
699 | ||
700 | debug("Configuring DRAMODT\n"); | |
701 | clrsetbits_le32(&sdr_ctrl->dram_odt, | |
702 | SDR_CTRLGRP_DRAMODT_READ_MASK, | |
703 | CONFIG_HPS_SDR_CTRLCFG_DRAMODT_READ << | |
704 | SDR_CTRLGRP_DRAMODT_READ_LSB); | |
705 | ||
706 | clrsetbits_le32(&sdr_ctrl->dram_odt, | |
707 | SDR_CTRLGRP_DRAMODT_WRITE_MASK, | |
708 | CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE << | |
709 | SDR_CTRLGRP_DRAMODT_WRITE_LSB); | |
710 | ||
711 | /* saving this value to SYSMGR.ISWGRP.HANDOFF.FPGA2SDR */ | |
712 | writel(CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST, | |
713 | &sysmgr_regs->iswgrp_handoff[3]); | |
714 | ||
715 | /* only enable if the FPGA is programmed */ | |
716 | if (fpgamgr_test_fpga_ready()) { | |
717 | if (sdram_write_verify(&sdr_ctrl->fpgaport_rst, | |
718 | CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST) == 1) { | |
719 | status = 1; | |
720 | return 1; | |
721 | } | |
722 | } | |
723 | ||
724 | /* Restore the SDR PHY Register if valid */ | |
725 | if (sdr_phy_reg != 0xffffffff) | |
726 | writel(sdr_phy_reg, &sdr_ctrl->phy_ctrl0); | |
727 | ||
728 | /***** Final step - apply configuration changes *****/ | |
729 | debug("Configuring STATICCFG_\n"); | |
730 | clrsetbits_le32(&sdr_ctrl->static_cfg, SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK, | |
731 | 1 << SDR_CTRLGRP_STATICCFG_APPLYCFG_LSB); | |
732 | debug(" Write - Address "); | |
733 | debug("0x%08x Data 0x%08x\n", | |
734 | (unsigned)(&sdr_ctrl->static_cfg), | |
735 | (unsigned)reg_value); | |
736 | reg_value = readl(&sdr_ctrl->static_cfg); | |
737 | debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); | |
738 | ||
739 | sdram_set_protection_config(0, sdram_calculate_size()); | |
740 | ||
741 | sdram_dump_protection_config(); | |
742 | ||
743 | return status; | |
744 | } | |
745 | ||
746 | /* | |
747 | * To calculate SDRAM device size based on SDRAM controller parameters. | |
748 | * Size is specified in bytes. | |
749 | * | |
750 | * NOTE: | |
751 | * This function is compiled and linked into the preloader and | |
752 | * Uboot (there may be others). So if this function changes, the Preloader | |
753 | * and UBoot must be updated simultaneously. | |
754 | */ | |
755 | unsigned long sdram_calculate_size(void) | |
756 | { | |
757 | unsigned long temp; | |
758 | unsigned long row, bank, col, cs, width; | |
759 | ||
760 | temp = readl(&sdr_ctrl->dram_addrw); | |
761 | col = (temp & SDR_CTRLGRP_DRAMADDRW_COLBITS_MASK) >> | |
762 | SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB; | |
763 | ||
764 | /* SDRAM Failure When Accessing Non-Existent Memory | |
765 | * Use ROWBITS from Quartus/QSys to calculate SDRAM size | |
766 | * since the FB specifies we modify ROWBITs to work around SDRAM | |
767 | * controller issue. | |
768 | * | |
769 | * If the stored handoff value for rows is 0, it probably means | |
770 | * the preloader is older than UBoot. Use the | |
771 | * #define from the SOCEDS Tools per Crucible review | |
772 | * uboot-socfpga-204. Note that this is not a supported | |
773 | * configuration and is not tested. The customer | |
774 | * should be using preloader and uboot built from the | |
775 | * same tag. | |
776 | */ | |
777 | row = readl(&sysmgr_regs->iswgrp_handoff[4]); | |
778 | if (row == 0) | |
779 | row = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; | |
780 | /* If the stored handoff value for rows is greater than | |
781 | * the field width in the sdr.dramaddrw register then | |
782 | * something is very wrong. Revert to using the the #define | |
783 | * value handed off by the SOCEDS tool chain instead of | |
784 | * using a broken value. | |
785 | */ | |
786 | if (row > 31) | |
787 | row = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; | |
788 | ||
789 | bank = (temp & SDR_CTRLGRP_DRAMADDRW_BANKBITS_MASK) >> | |
790 | SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB; | |
791 | ||
792 | /* SDRAM Failure When Accessing Non-Existent Memory | |
793 | * Use CSBITs from Quartus/QSys to calculate SDRAM size | |
794 | * since the FB specifies we modify CSBITs to work around SDRAM | |
795 | * controller issue. | |
796 | */ | |
797 | cs = (temp & SDR_CTRLGRP_DRAMADDRW_CSBITS_MASK) >> | |
798 | SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB; | |
799 | cs += 1; | |
800 | ||
801 | cs = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS; | |
802 | ||
803 | width = readl(&sdr_ctrl->dram_if_width); | |
804 | /* ECC would not be calculated as its not addressible */ | |
805 | if (width == SDRAM_WIDTH_32BIT_WITH_ECC) | |
806 | width = 32; | |
807 | if (width == SDRAM_WIDTH_16BIT_WITH_ECC) | |
808 | width = 16; | |
809 | ||
810 | /* calculate the SDRAM size base on this info */ | |
811 | temp = 1 << (row + bank + col); | |
812 | temp = temp * cs * (width / 8); | |
813 | ||
814 | debug("sdram_calculate_memory returns %ld\n", temp); | |
815 | ||
816 | return temp; | |
817 | } |