uboot/arch/powerpc/cpu/mpc85xx/cpu.c
<<
>>
Prefs
   1/*
   2 * Copyright 2004,2007-2011 Freescale Semiconductor, Inc.
   3 * (C) Copyright 2002, 2003 Motorola Inc.
   4 * Xianghua Xiao (X.Xiao@motorola.com)
   5 *
   6 * (C) Copyright 2000
   7 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   8 *
   9 * SPDX-License-Identifier:     GPL-2.0+
  10 */
  11
  12#include <config.h>
  13#include <common.h>
  14#include <watchdog.h>
  15#include <command.h>
  16#include <fsl_esdhc.h>
  17#include <asm/cache.h>
  18#include <asm/io.h>
  19#include <asm/mmu.h>
  20#include <fsl_ifc.h>
  21#include <asm/fsl_law.h>
  22#include <asm/fsl_lbc.h>
  23#include <post.h>
  24#include <asm/processor.h>
  25#include <fsl_ddr_sdram.h>
  26#include <asm/ppc.h>
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30/*
  31 * Default board reset function
  32 */
  33static void
  34__board_reset(void)
  35{
  36        /* Do nothing */
  37}
  38void board_reset(void) __attribute__((weak, alias("__board_reset")));
  39
  40int checkcpu (void)
  41{
  42        sys_info_t sysinfo;
  43        uint pvr, svr;
  44        uint ver;
  45        uint major, minor;
  46        struct cpu_type *cpu;
  47        char buf1[32], buf2[32];
  48#if defined(CONFIG_DDR_CLK_FREQ) || defined(CONFIG_FSL_CORENET)
  49        ccsr_gur_t __iomem *gur =
  50                (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  51#endif
  52
  53        /*
  54         * Cornet platforms use ddr sync bit in RCW to indicate sync vs async
  55         * mode. Previous platform use ddr ratio to do the same. This
  56         * information is only for display here.
  57         */
  58#ifdef CONFIG_FSL_CORENET
  59#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
  60        u32 ddr_sync = 0;       /* only async mode is supported */
  61#else
  62        u32 ddr_sync = ((gur->rcwsr[5]) & FSL_CORENET_RCWSR5_DDR_SYNC)
  63                >> FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT;
  64#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
  65#else   /* CONFIG_FSL_CORENET */
  66#ifdef CONFIG_DDR_CLK_FREQ
  67        u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO)
  68                >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
  69#else
  70        u32 ddr_ratio = 0;
  71#endif /* CONFIG_DDR_CLK_FREQ */
  72#endif /* CONFIG_FSL_CORENET */
  73
  74        unsigned int i, core, nr_cores = cpu_numcores();
  75        u32 mask = cpu_mask();
  76
  77#ifdef CONFIG_HETROGENOUS_CLUSTERS
  78        unsigned int j, dsp_core, dsp_numcores = cpu_num_dspcores();
  79        u32 dsp_mask = cpu_dsp_mask();
  80#endif
  81
  82        svr = get_svr();
  83        major = SVR_MAJ(svr);
  84        minor = SVR_MIN(svr);
  85
  86#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
  87        if (SVR_SOC_VER(svr) == SVR_T4080) {
  88                ccsr_rcpm_t *rcpm =
  89                        (void __iomem *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR);
  90
  91                setbits_be32(&gur->devdisr2, FSL_CORENET_DEVDISR2_DTSEC1_6 ||
  92                             FSL_CORENET_DEVDISR2_DTSEC1_9);
  93                setbits_be32(&gur->devdisr3, FSL_CORENET_DEVDISR3_PCIE3);
  94                setbits_be32(&gur->devdisr5, FSL_CORENET_DEVDISR5_DDR3);
  95
  96                /* It needs SW to disable core4~7 as HW design sake on T4080 */
  97                for (i = 4; i < 8; i++)
  98                        cpu_disable(i);
  99
 100                /* request core4~7 into PH20 state, prior to entering PCL10
 101                 * state, all cores in cluster should be placed in PH20 state.
 102                 */
 103                setbits_be32(&rcpm->pcph20setr, 0xf0);
 104
 105                /* put the 2nd cluster into PCL10 state */
 106                setbits_be32(&rcpm->clpcl10setr, 1 << 1);
 107        }
 108#endif
 109
 110        if (cpu_numcores() > 1) {
 111#ifndef CONFIG_MP
 112                puts("Unicore software on multiprocessor system!!\n"
 113                     "To enable mutlticore build define CONFIG_MP\n");
 114#endif
 115                volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);
 116                printf("CPU%d:  ", pic->whoami);
 117        } else {
 118                puts("CPU:   ");
 119        }
 120
 121        cpu = gd->arch.cpu;
 122
 123        puts(cpu->name);
 124        if (IS_E_PROCESSOR(svr))
 125                puts("E");
 126
 127        printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
 128
 129        pvr = get_pvr();
 130        ver = PVR_VER(pvr);
 131        major = PVR_MAJ(pvr);
 132        minor = PVR_MIN(pvr);
 133
 134        printf("Core:  ");
 135        switch(ver) {
 136        case PVR_VER_E500_V1:
 137        case PVR_VER_E500_V2:
 138                puts("e500");
 139                break;
 140        case PVR_VER_E500MC:
 141                puts("e500mc");
 142                break;
 143        case PVR_VER_E5500:
 144                puts("e5500");
 145                break;
 146        case PVR_VER_E6500:
 147                puts("e6500");
 148                break;
 149        default:
 150                puts("Unknown");
 151                break;
 152        }
 153
 154        printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
 155
 156        if (nr_cores > CONFIG_MAX_CPUS) {
 157                panic("\nUnexpected number of cores: %d, max is %d\n",
 158                        nr_cores, CONFIG_MAX_CPUS);
 159        }
 160
 161        get_sys_info(&sysinfo);
 162
 163#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
 164        if (sysinfo.diff_sysclk == 1)
 165                puts("Single Source Clock Configuration\n");
 166#endif
 167
 168        puts("Clock Configuration:");
 169        for_each_cpu(i, core, nr_cores, mask) {
 170                if (!(i & 3))
 171                        printf ("\n       ");
 172                printf("CPU%d:%-4s MHz, ", core,
 173                        strmhz(buf1, sysinfo.freq_processor[core]));
 174        }
 175
 176#ifdef CONFIG_HETROGENOUS_CLUSTERS
 177        for_each_cpu(j, dsp_core, dsp_numcores, dsp_mask) {
 178                if (!(j & 3))
 179                        printf("\n       ");
 180                printf("DSP CPU%d:%-4s MHz, ", j,
 181                       strmhz(buf1, sysinfo.freq_processor_dsp[dsp_core]));
 182        }
 183#endif
 184
 185        printf("\n       CCB:%-4s MHz,", strmhz(buf1, sysinfo.freq_systembus));
 186        printf("\n");
 187
 188#ifdef CONFIG_FSL_CORENET
 189        if (ddr_sync == 1) {
 190                printf("       DDR:%-4s MHz (%s MT/s data rate) "
 191                        "(Synchronous), ",
 192                        strmhz(buf1, sysinfo.freq_ddrbus/2),
 193                        strmhz(buf2, sysinfo.freq_ddrbus));
 194        } else {
 195                printf("       DDR:%-4s MHz (%s MT/s data rate) "
 196                        "(Asynchronous), ",
 197                        strmhz(buf1, sysinfo.freq_ddrbus/2),
 198                        strmhz(buf2, sysinfo.freq_ddrbus));
 199        }
 200#else
 201        switch (ddr_ratio) {
 202        case 0x0:
 203                printf("       DDR:%-4s MHz (%s MT/s data rate), ",
 204                        strmhz(buf1, sysinfo.freq_ddrbus/2),
 205                        strmhz(buf2, sysinfo.freq_ddrbus));
 206                break;
 207        case 0x7:
 208                printf("       DDR:%-4s MHz (%s MT/s data rate) "
 209                        "(Synchronous), ",
 210                        strmhz(buf1, sysinfo.freq_ddrbus/2),
 211                        strmhz(buf2, sysinfo.freq_ddrbus));
 212                break;
 213        default:
 214                printf("       DDR:%-4s MHz (%s MT/s data rate) "
 215                        "(Asynchronous), ",
 216                        strmhz(buf1, sysinfo.freq_ddrbus/2),
 217                        strmhz(buf2, sysinfo.freq_ddrbus));
 218                break;
 219        }
 220#endif
 221
 222#if defined(CONFIG_FSL_LBC)
 223        if (sysinfo.freq_localbus > LCRR_CLKDIV) {
 224                printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freq_localbus));
 225        } else {
 226                printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n",
 227                       sysinfo.freq_localbus);
 228        }
 229#endif
 230
 231#if defined(CONFIG_FSL_IFC)
 232        printf("IFC:%-4s MHz\n", strmhz(buf1, sysinfo.freq_localbus));
 233#endif
 234
 235#ifdef CONFIG_CPM2
 236        printf("CPM:   %s MHz\n", strmhz(buf1, sysinfo.freq_systembus));
 237#endif
 238
 239#ifdef CONFIG_QE
 240        printf("       QE:%-4s MHz\n", strmhz(buf1, sysinfo.freq_qe));
 241#endif
 242
 243#if defined(CONFIG_SYS_CPRI)
 244        printf("       ");
 245        printf("CPRI:%-4s MHz", strmhz(buf1, sysinfo.freq_cpri));
 246#endif
 247
 248#if defined(CONFIG_SYS_MAPLE)
 249        printf("\n       ");
 250        printf("MAPLE:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple));
 251        printf("MAPLE-ULB:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple_ulb));
 252        printf("MAPLE-eTVPE:%-4s MHz\n",
 253               strmhz(buf1, sysinfo.freq_maple_etvpe));
 254#endif
 255
 256#ifdef CONFIG_SYS_DPAA_FMAN
 257        for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) {
 258                printf("       FMAN%d: %s MHz\n", i + 1,
 259                        strmhz(buf1, sysinfo.freq_fman[i]));
 260        }
 261#endif
 262
 263#ifdef CONFIG_SYS_DPAA_QBMAN
 264        printf("       QMAN:  %s MHz\n", strmhz(buf1, sysinfo.freq_qman));
 265#endif
 266
 267#ifdef CONFIG_SYS_DPAA_PME
 268        printf("       PME:   %s MHz\n", strmhz(buf1, sysinfo.freq_pme));
 269#endif
 270
 271        puts("L1:    D-cache 32 KiB enabled\n       I-cache 32 KiB enabled\n");
 272
 273#ifdef CONFIG_FSL_CORENET
 274        /* Display the RCW, so that no one gets confused as to what RCW
 275         * we're actually using for this boot.
 276         */
 277        puts("Reset Configuration Word (RCW):");
 278        for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
 279                u32 rcw = in_be32(&gur->rcwsr[i]);
 280
 281                if ((i % 4) == 0)
 282                        printf("\n       %08x:", i * 4);
 283                printf(" %08x", rcw);
 284        }
 285        puts("\n");
 286#endif
 287
 288        return 0;
 289}
 290
 291
 292/* ------------------------------------------------------------------------- */
 293
 294int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 295{
 296/* Everything after the first generation of PQ3 parts has RSTCR */
 297#if defined(CONFIG_ARCH_MPC8540) || defined(CONFIG_ARCH_MPC8541) || \
 298        defined(CONFIG_ARCH_MPC8555) || defined(CONFIG_ARCH_MPC8560)
 299        unsigned long val, msr;
 300
 301        /*
 302         * Initiate hard reset in debug control register DBCR0
 303         * Make sure MSR[DE] = 1.  This only resets the core.
 304         */
 305        msr = mfmsr ();
 306        msr |= MSR_DE;
 307        mtmsr (msr);
 308
 309        val = mfspr(DBCR0);
 310        val |= 0x70000000;
 311        mtspr(DBCR0,val);
 312#else
 313        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 314
 315        /* Attempt board-specific reset */
 316        board_reset();
 317
 318        /* Next try asserting HRESET_REQ */
 319        out_be32(&gur->rstcr, 0x2);
 320        udelay(100);
 321#endif
 322
 323        return 1;
 324}
 325
 326
 327/*
 328 * Get timebase clock frequency
 329 */
 330#ifndef CONFIG_SYS_FSL_TBCLK_DIV
 331#define CONFIG_SYS_FSL_TBCLK_DIV 8
 332#endif
 333__weak unsigned long get_tbclk (void)
 334{
 335        unsigned long tbclk_div = CONFIG_SYS_FSL_TBCLK_DIV;
 336
 337        return (gd->bus_clk + (tbclk_div >> 1)) / tbclk_div;
 338}
 339
 340
 341#if defined(CONFIG_WATCHDOG)
 342#define WATCHDOG_MASK (TCR_WP(63) | TCR_WRC(3) | TCR_WIE)
 343void
 344init_85xx_watchdog(void)
 345{
 346        mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WATCHDOG_MASK) |
 347              TCR_WP(CONFIG_WATCHDOG_PRESC) | TCR_WRC(CONFIG_WATCHDOG_RC));
 348}
 349
 350void
 351reset_85xx_watchdog(void)
 352{
 353        /*
 354         * Clear TSR(WIS) bit by writing 1
 355         */
 356        mtspr(SPRN_TSR, TSR_WIS);
 357}
 358
 359void
 360watchdog_reset(void)
 361{
 362        int re_enable = disable_interrupts();
 363
 364        reset_85xx_watchdog();
 365        if (re_enable)
 366                enable_interrupts();
 367}
 368#endif  /* CONFIG_WATCHDOG */
 369
 370/*
 371 * Initializes on-chip MMC controllers.
 372 * to override, implement board_mmc_init()
 373 */
 374int cpu_mmc_init(bd_t *bis)
 375{
 376#ifdef CONFIG_FSL_ESDHC
 377        return fsl_esdhc_mmc_init(bis);
 378#else
 379        return 0;
 380#endif
 381}
 382
 383/*
 384 * Print out the state of various machine registers.
 385 * Currently prints out LAWs, BR0/OR0 for LBC, CSPR/CSOR/Timing
 386 * parameters for IFC and TLBs
 387 */
 388void print_reginfo(void)
 389{
 390        print_tlbcam();
 391        print_laws();
 392#if defined(CONFIG_FSL_LBC)
 393        print_lbc_regs();
 394#endif
 395#ifdef CONFIG_FSL_IFC
 396        print_ifc_regs();
 397#endif
 398
 399}
 400
 401/* Common ddr init for non-corenet fsl 85xx platforms */
 402#ifndef CONFIG_FSL_CORENET
 403#if (defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)) && \
 404        !defined(CONFIG_SYS_INIT_L2_ADDR)
 405int dram_init(void)
 406{
 407#if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD) || \
 408        defined(CONFIG_ARCH_QEMU_E500)
 409        gd->ram_size = fsl_ddr_sdram_size();
 410#else
 411        gd->ram_size = (phys_size_t)CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
 412#endif
 413
 414        return 0;
 415}
 416#else /* CONFIG_SYS_RAMBOOT */
 417int dram_init(void)
 418{
 419        phys_size_t dram_size = 0;
 420
 421#if defined(CONFIG_SYS_FSL_ERRATUM_DDR_MSYNC_IN)
 422        {
 423                ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 424                unsigned int x = 10;
 425                unsigned int i;
 426
 427                /*
 428                 * Work around to stabilize DDR DLL
 429                 */
 430                out_be32(&gur->ddrdllcr, 0x81000000);
 431                asm("sync;isync;msync");
 432                udelay(200);
 433                while (in_be32(&gur->ddrdllcr) != 0x81000100) {
 434                        setbits_be32(&gur->devdisr, 0x00010000);
 435                        for (i = 0; i < x; i++)
 436                                ;
 437                        clrbits_be32(&gur->devdisr, 0x00010000);
 438                        x++;
 439                }
 440        }
 441#endif
 442
 443#if     defined(CONFIG_SPD_EEPROM)      || \
 444        defined(CONFIG_DDR_SPD)         || \
 445        defined(CONFIG_SYS_DDR_RAW_TIMING)
 446        dram_size = fsl_ddr_sdram();
 447#else
 448        dram_size = fixed_sdram();
 449#endif
 450        dram_size = setup_ddr_tlbs(dram_size / 0x100000);
 451        dram_size *= 0x100000;
 452
 453#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 454        /*
 455         * Initialize and enable DDR ECC.
 456         */
 457        ddr_enable_ecc(dram_size);
 458#endif
 459
 460#if defined(CONFIG_FSL_LBC)
 461        /* Some boards also have sdram on the lbc */
 462        lbc_sdram_init();
 463#endif
 464
 465        debug("DDR: ");
 466        gd->ram_size = dram_size;
 467
 468        return 0;
 469}
 470#endif /* CONFIG_SYS_RAMBOOT */
 471#endif
 472
 473#if CONFIG_POST & CONFIG_SYS_POST_MEMORY
 474
 475/* Board-specific functions defined in each board's ddr.c */
 476void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
 477        unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl);
 478void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
 479                       phys_addr_t *rpn);
 480unsigned int
 481        setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg);
 482
 483void clear_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg);
 484
 485static void dump_spd_ddr_reg(void)
 486{
 487        int i, j, k, m;
 488        u8 *p_8;
 489        u32 *p_32;
 490        struct ccsr_ddr __iomem *ddr[CONFIG_SYS_NUM_DDR_CTLRS];
 491        generic_spd_eeprom_t
 492                spd[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR];
 493
 494        for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++)
 495                fsl_ddr_get_spd(spd[i], i, CONFIG_DIMM_SLOTS_PER_CTLR);
 496
 497        puts("SPD data of all dimms (zero value is omitted)...\n");
 498        puts("Byte (hex)  ");
 499        k = 1;
 500        for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
 501                for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++)
 502                        printf("Dimm%d ", k++);
 503        }
 504        puts("\n");
 505        for (k = 0; k < sizeof(generic_spd_eeprom_t); k++) {
 506                m = 0;
 507                printf("%3d (0x%02x)  ", k, k);
 508                for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
 509                        for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
 510                                p_8 = (u8 *) &spd[i][j];
 511                                if (p_8[k]) {
 512                                        printf("0x%02x  ", p_8[k]);
 513                                        m++;
 514                                } else
 515                                        puts("      ");
 516                        }
 517                }
 518                if (m)
 519                        puts("\n");
 520                else
 521                        puts("\r");
 522        }
 523
 524        for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
 525                switch (i) {
 526                case 0:
 527                        ddr[i] = (void *)CONFIG_SYS_FSL_DDR_ADDR;
 528                        break;
 529#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
 530                case 1:
 531                        ddr[i] = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
 532                        break;
 533#endif
 534#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
 535                case 2:
 536                        ddr[i] = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
 537                        break;
 538#endif
 539#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
 540                case 3:
 541                        ddr[i] = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
 542                        break;
 543#endif
 544                default:
 545                        printf("%s unexpected controller number = %u\n",
 546                                __func__, i);
 547                        return;
 548                }
 549        }
 550        printf("DDR registers dump for all controllers "
 551                "(zero value is omitted)...\n");
 552        puts("Offset (hex)   ");
 553        for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++)
 554                printf("     Base + 0x%04x", (u32)ddr[i] & 0xFFFF);
 555        puts("\n");
 556        for (k = 0; k < sizeof(struct ccsr_ddr)/4; k++) {
 557                m = 0;
 558                printf("%6d (0x%04x)", k * 4, k * 4);
 559                for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) {
 560                        p_32 = (u32 *) ddr[i];
 561                        if (p_32[k]) {
 562                                printf("        0x%08x", p_32[k]);
 563                                m++;
 564                        } else
 565                                puts("                  ");
 566                }
 567                if (m)
 568                        puts("\n");
 569                else
 570                        puts("\r");
 571        }
 572        puts("\n");
 573}
 574
 575/* invalid the TLBs for DDR and setup new ones to cover p_addr */
 576static int reset_tlb(phys_addr_t p_addr, u32 size, phys_addr_t *phys_offset)
 577{
 578        u32 vstart = CONFIG_SYS_DDR_SDRAM_BASE;
 579        unsigned long epn;
 580        u32 tsize, valid, ptr;
 581        int ddr_esel;
 582
 583        clear_ddr_tlbs_phys(p_addr, size>>20);
 584
 585        /* Setup new tlb to cover the physical address */
 586        setup_ddr_tlbs_phys(p_addr, size>>20);
 587
 588        ptr = vstart;
 589        ddr_esel = find_tlb_idx((void *)ptr, 1);
 590        if (ddr_esel != -1) {
 591                read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, phys_offset);
 592        } else {
 593                printf("TLB error in function %s\n", __func__);
 594                return -1;
 595        }
 596
 597        return 0;
 598}
 599
 600/*
 601 * slide the testing window up to test another area
 602 * for 32_bit system, the maximum testable memory is limited to
 603 * CONFIG_MAX_MEM_MAPPED
 604 */
 605int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
 606{
 607        phys_addr_t test_cap, p_addr;
 608        phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);
 609
 610#if !defined(CONFIG_PHYS_64BIT) || \
 611    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
 612        (CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
 613                test_cap = p_size;
 614#else
 615                test_cap = gd->ram_size;
 616#endif
 617        p_addr = (*vstart) + (*size) + (*phys_offset);
 618        if (p_addr < test_cap - 1) {
 619                p_size = min(test_cap - p_addr, CONFIG_MAX_MEM_MAPPED);
 620                if (reset_tlb(p_addr, p_size, phys_offset) == -1)
 621                        return -1;
 622                *vstart = CONFIG_SYS_DDR_SDRAM_BASE;
 623                *size = (u32) p_size;
 624                printf("Testing 0x%08llx - 0x%08llx\n",
 625                        (u64)(*vstart) + (*phys_offset),
 626                        (u64)(*vstart) + (*phys_offset) + (*size) - 1);
 627        } else
 628                return 1;
 629
 630        return 0;
 631}
 632
 633/* initialization for testing area */
 634int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
 635{
 636        phys_size_t p_size = min(gd->ram_size, CONFIG_MAX_MEM_MAPPED);
 637
 638        *vstart = CONFIG_SYS_DDR_SDRAM_BASE;
 639        *size = (u32) p_size;   /* CONFIG_MAX_MEM_MAPPED < 4G */
 640        *phys_offset = 0;
 641
 642#if !defined(CONFIG_PHYS_64BIT) || \
 643    !defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS) || \
 644        (CONFIG_SYS_INIT_RAM_ADDR_PHYS < 0x100000000ull)
 645                if (gd->ram_size > CONFIG_MAX_MEM_MAPPED) {
 646                        puts("Cannot test more than ");
 647                        print_size(CONFIG_MAX_MEM_MAPPED,
 648                                " without proper 36BIT support.\n");
 649                }
 650#endif
 651        printf("Testing 0x%08llx - 0x%08llx\n",
 652                (u64)(*vstart) + (*phys_offset),
 653                (u64)(*vstart) + (*phys_offset) + (*size) - 1);
 654
 655        return 0;
 656}
 657
 658/* invalid TLBs for DDR and remap as normal after testing */
 659int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
 660{
 661        unsigned long epn;
 662        u32 tsize, valid, ptr;
 663        phys_addr_t rpn = 0;
 664        int ddr_esel;
 665
 666        /* disable the TLBs for this testing */
 667        ptr = *vstart;
 668
 669        while (ptr < (*vstart) + (*size)) {
 670                ddr_esel = find_tlb_idx((void *)ptr, 1);
 671                if (ddr_esel != -1) {
 672                        read_tlbcam_entry(ddr_esel, &valid, &tsize, &epn, &rpn);
 673                        disable_tlb(ddr_esel);
 674                }
 675                ptr += TSIZE_TO_BYTES(tsize);
 676        }
 677
 678        puts("Remap DDR ");
 679        setup_ddr_tlbs(gd->ram_size>>20);
 680        puts("\n");
 681
 682        return 0;
 683}
 684
 685void arch_memory_failure_handle(void)
 686{
 687        dump_spd_ddr_reg();
 688}
 689#endif
 690