Commit 4516ff816084605990115d127df97950c23e389c
1 parent
6b95be2280
Exists in
v2017.01-smarct4x
and in
34 other branches
driver/ddr/fsl: Add built-in memory test for DDR4 driver
Add built-in memory test to catch errors after DDR is initialized, before any other transactions. To enable this test, define CONFIG_FSL_DDR_BIST. An environmental variable "ddr_bist" is checked before starting test. It takes a while (several seconds) depending on system memory size. Signed-off-by: York Sun <yorksun@freescale.com>
Showing 2 changed files with 76 additions and 0 deletions Side-by-side Diff
README
... | ... | @@ -4884,6 +4884,9 @@ |
4884 | 4884 | - CONFIG_FSL_DDR_SYNC_REFRESH |
4885 | 4885 | Enable sync of refresh for multiple controllers. |
4886 | 4886 | |
4887 | +- CONFIG_FSL_DDR_BIST | |
4888 | + Enable built-in memory test for Freescale DDR controllers. | |
4889 | + | |
4887 | 4890 | - CONFIG_SYS_83XX_DDR_USES_CS0 |
4888 | 4891 | Only for 83xx systems. If specified, then DDR should |
4889 | 4892 | be configured using CS0 and CS1 instead of CS2 and CS3. |
drivers/ddr/fsl/fsl_ddr_gen4.c
... | ... | @@ -36,6 +36,13 @@ |
36 | 36 | defined(CONFIG_SYS_FSL_ERRATUM_A008514) |
37 | 37 | u32 *eddrtqcr1; |
38 | 38 | #endif |
39 | +#ifdef CONFIG_FSL_DDR_BIST | |
40 | + u32 mtcr, err_detect, err_sbe; | |
41 | + u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config; | |
42 | +#endif | |
43 | +#ifdef CONFIG_FSL_DDR_BIST | |
44 | + char buffer[CONFIG_SYS_CBSIZE]; | |
45 | +#endif | |
39 | 46 | |
40 | 47 | switch (ctrl_num) { |
41 | 48 | case 0: |
... | ... | @@ -307,6 +314,72 @@ |
307 | 314 | temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); |
308 | 315 | temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR; |
309 | 316 | ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); |
317 | + } | |
318 | +#endif | |
319 | + | |
320 | +#ifdef CONFIG_FSL_DDR_BIST | |
321 | +#define BIST_PATTERN1 0xFFFFFFFF | |
322 | +#define BIST_PATTERN2 0x0 | |
323 | +#define BIST_CR 0x80010000 | |
324 | +#define BIST_CR_EN 0x80000000 | |
325 | +#define BIST_CR_STAT 0x00000001 | |
326 | +#define CTLR_INTLV_MASK 0x20000000 | |
327 | + /* Perform build-in test on memory. Three-way interleaving is not yet | |
328 | + * supported by this code. */ | |
329 | + if (getenv_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) { | |
330 | + puts("Running BIST test. This will take a while..."); | |
331 | + cs0_config = ddr_in32(&ddr->cs0_config); | |
332 | + if (cs0_config & CTLR_INTLV_MASK) { | |
333 | + cs0_bnds = ddr_in32(&cs0_bnds); | |
334 | + cs1_bnds = ddr_in32(&cs1_bnds); | |
335 | + cs2_bnds = ddr_in32(&cs2_bnds); | |
336 | + cs3_bnds = ddr_in32(&cs3_bnds); | |
337 | + /* set bnds to non-interleaving */ | |
338 | + ddr_out32(&cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1); | |
339 | + ddr_out32(&cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1); | |
340 | + ddr_out32(&cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1); | |
341 | + ddr_out32(&cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1); | |
342 | + } | |
343 | + ddr_out32(&ddr->mtp1, BIST_PATTERN1); | |
344 | + ddr_out32(&ddr->mtp2, BIST_PATTERN1); | |
345 | + ddr_out32(&ddr->mtp3, BIST_PATTERN2); | |
346 | + ddr_out32(&ddr->mtp4, BIST_PATTERN2); | |
347 | + ddr_out32(&ddr->mtp5, BIST_PATTERN1); | |
348 | + ddr_out32(&ddr->mtp6, BIST_PATTERN1); | |
349 | + ddr_out32(&ddr->mtp7, BIST_PATTERN2); | |
350 | + ddr_out32(&ddr->mtp8, BIST_PATTERN2); | |
351 | + ddr_out32(&ddr->mtp9, BIST_PATTERN1); | |
352 | + ddr_out32(&ddr->mtp10, BIST_PATTERN2); | |
353 | + mtcr = BIST_CR; | |
354 | + ddr_out32(&ddr->mtcr, mtcr); | |
355 | + timeout = 100; | |
356 | + while (timeout > 0 && (mtcr & BIST_CR_EN)) { | |
357 | + mdelay(1000); | |
358 | + timeout--; | |
359 | + mtcr = ddr_in32(&ddr->mtcr); | |
360 | + } | |
361 | + if (timeout <= 0) | |
362 | + puts("Timeout\n"); | |
363 | + else | |
364 | + puts("Done\n"); | |
365 | + err_detect = ddr_in32(&ddr->err_detect); | |
366 | + err_sbe = ddr_in32(&ddr->err_sbe); | |
367 | + if (mtcr & BIST_CR_STAT) { | |
368 | + printf("BIST test failed on controller %d.\n", | |
369 | + ctrl_num); | |
370 | + } | |
371 | + if (err_detect || (err_sbe & 0xffff)) { | |
372 | + printf("ECC error detected on controller %d.\n", | |
373 | + ctrl_num); | |
374 | + } | |
375 | + | |
376 | + if (cs0_config & CTLR_INTLV_MASK) { | |
377 | + /* restore bnds registers */ | |
378 | + ddr_out32(&cs0_bnds, cs0_bnds); | |
379 | + ddr_out32(&cs1_bnds, cs1_bnds); | |
380 | + ddr_out32(&cs2_bnds, cs2_bnds); | |
381 | + ddr_out32(&cs3_bnds, cs3_bnds); | |
382 | + } | |
310 | 383 | } |
311 | 384 | #endif |
312 | 385 | } |