uboot/arch/powerpc/cpu/ppc4xx/44x_spd_ddr.c
<<
>>
Prefs
   1/*
   2 * arch/powerpc/cpu/ppc4xx/44x_spd_ddr.c
   3 * This SPD DDR detection code supports IBM/AMCC PPC44x cpu with a
   4 * DDR controller. Those are 440GP/GX/EP/GR.
   5 *
   6 * (C) Copyright 2001
   7 * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
   8 *
   9 * Based on code by:
  10 *
  11 * Kenneth Johansson ,Ericsson AB.
  12 * kenneth.johansson@etx.ericsson.se
  13 *
  14 * hacked up by bill hunter. fixed so we could run before
  15 * serial_init and console_init. previous version avoided this by
  16 * running out of cache memory during serial/console init, then running
  17 * this code later.
  18 *
  19 * (C) Copyright 2002
  20 * Jun Gu, Artesyn Technology, jung@artesyncp.com
  21 * Support for AMCC 440 based on OpenBIOS draminit.c from IBM.
  22 *
  23 * (C) Copyright 2005-2007
  24 * Stefan Roese, DENX Software Engineering, sr@denx.de.
  25 *
  26 * See file CREDITS for list of people who contributed to this
  27 * project.
  28 *
  29 * This program is free software; you can redistribute it and/or
  30 * modify it under the terms of the GNU General Public License as
  31 * published by the Free Software Foundation; either version 2 of
  32 * the License, or (at your option) any later version.
  33 *
  34 * This program is distributed in the hope that it will be useful,
  35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  37 * GNU General Public License for more details.
  38 *
  39 * You should have received a copy of the GNU General Public License
  40 * along with this program; if not, write to the Free Software
  41 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  42 * MA 02111-1307 USA
  43 */
  44
  45/* define DEBUG for debugging output (obviously ;-)) */
  46#if 0
  47#define DEBUG
  48#endif
  49
  50#include <common.h>
  51#include <asm/processor.h>
  52#include <i2c.h>
  53#include <asm/ppc4xx.h>
  54#include <asm/mmu.h>
  55
  56#include "ecc.h"
  57
  58#if defined(CONFIG_SPD_EEPROM) &&                                       \
  59        (defined(CONFIG_440GP) || defined(CONFIG_440GX) ||              \
  60         defined(CONFIG_440EP) || defined(CONFIG_440GR))
  61
  62/*
  63 * Set default values
  64 */
  65#ifndef CONFIG_SYS_I2C_SPEED
  66#define CONFIG_SYS_I2C_SPEED    50000
  67#endif
  68
  69#define ONE_BILLION     1000000000
  70
  71/*
  72 * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
  73 */
  74void __spd_ddr_init_hang (void)
  75{
  76        hang ();
  77}
  78void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang")));
  79
  80/*-----------------------------------------------------------------------------+
  81  |  General Definition
  82  +-----------------------------------------------------------------------------*/
  83#define DEFAULT_SPD_ADDR1       0x53
  84#define DEFAULT_SPD_ADDR2       0x52
  85#define MAXBANKS                4               /* at most 4 dimm banks */
  86#define MAX_SPD_BYTES           256
  87#define NUMHALFCYCLES           4
  88#define NUMMEMTESTS             8
  89#define NUMMEMWORDS             8
  90#define MAXBXCR                 4
  91#define TRUE                    1
  92#define FALSE                   0
  93
  94/*
  95 * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
  96 * region. Right now the cache should still be disabled in U-Boot because of the
  97 * EMAC driver, that need it's buffer descriptor to be located in non cached
  98 * memory.
  99 *
 100 * If at some time this restriction doesn't apply anymore, just define
 101 * CONFIG_4xx_DCACHE in the board config file and this code should setup
 102 * everything correctly.
 103 */
 104#ifdef CONFIG_4xx_DCACHE
 105#define MY_TLB_WORD2_I_ENABLE   0                       /* enable caching on SDRAM */
 106#else
 107#define MY_TLB_WORD2_I_ENABLE   TLB_WORD2_I_ENABLE      /* disable caching on SDRAM */
 108#endif
 109
 110/* bank_parms is used to sort the bank sizes by descending order */
 111struct bank_param {
 112        unsigned long cr;
 113        unsigned long bank_size_bytes;
 114};
 115
 116typedef struct bank_param BANKPARMS;
 117
 118#ifdef CONFIG_SYS_SIMULATE_SPD_EEPROM
 119extern const unsigned char cfg_simulate_spd_eeprom[128];
 120#endif
 121
 122static unsigned char spd_read(uchar chip, uint addr);
 123static void get_spd_info(unsigned long *dimm_populated,
 124                         unsigned char *iic0_dimm_addr,
 125                         unsigned long num_dimm_banks);
 126static void check_mem_type(unsigned long *dimm_populated,
 127                           unsigned char *iic0_dimm_addr,
 128                           unsigned long num_dimm_banks);
 129static void check_volt_type(unsigned long *dimm_populated,
 130                            unsigned char *iic0_dimm_addr,
 131                            unsigned long num_dimm_banks);
 132static void program_cfg0(unsigned long *dimm_populated,
 133                         unsigned char *iic0_dimm_addr,
 134                         unsigned long  num_dimm_banks);
 135static void program_cfg1(unsigned long *dimm_populated,
 136                         unsigned char *iic0_dimm_addr,
 137                         unsigned long num_dimm_banks);
 138static void program_rtr(unsigned long *dimm_populated,
 139                        unsigned char *iic0_dimm_addr,
 140                        unsigned long num_dimm_banks);
 141static void program_tr0(unsigned long *dimm_populated,
 142                        unsigned char *iic0_dimm_addr,
 143                        unsigned long num_dimm_banks);
 144static void program_tr1(void);
 145
 146static unsigned long program_bxcr(unsigned long *dimm_populated,
 147                                  unsigned char *iic0_dimm_addr,
 148                                  unsigned long num_dimm_banks);
 149
 150/*
 151 * This function is reading data from the DIMM module EEPROM over the SPD bus
 152 * and uses that to program the sdram controller.
 153 *
 154 * This works on boards that has the same schematics that the AMCC walnut has.
 155 *
 156 * BUG: Don't handle ECC memory
 157 * BUG: A few values in the TR register is currently hardcoded
 158 */
 159long int spd_sdram(void) {
 160        unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
 161        unsigned long dimm_populated[sizeof(iic0_dimm_addr)];
 162        unsigned long total_size;
 163        unsigned long cfg0;
 164        unsigned long mcsts;
 165        unsigned long num_dimm_banks;               /* on board dimm banks */
 166
 167        num_dimm_banks = sizeof(iic0_dimm_addr);
 168
 169        /*
 170         * Make sure I2C controller is initialized
 171         * before continuing.
 172         */
 173        i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 174
 175        /*
 176         * Read the SPD information using I2C interface. Check to see if the
 177         * DIMM slots are populated.
 178         */
 179        get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 180
 181        /*
 182         * Check the memory type for the dimms plugged.
 183         */
 184        check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 185
 186        /*
 187         * Check the voltage type for the dimms plugged.
 188         */
 189        check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 190
 191#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
 192        /*
 193         * Soft-reset SDRAM controller.
 194         */
 195        mtsdr(SDR0_SRST, SDR0_SRST_DMC);
 196        mtsdr(SDR0_SRST, 0x00000000);
 197#endif
 198
 199        /*
 200         * program 440GP SDRAM controller options (SDRAM0_CFG0)
 201         */
 202        program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 203
 204        /*
 205         * program 440GP SDRAM controller options (SDRAM0_CFG1)
 206         */
 207        program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 208
 209        /*
 210         * program SDRAM refresh register (SDRAM0_RTR)
 211         */
 212        program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 213
 214        /*
 215         * program SDRAM Timing Register 0 (SDRAM0_TR0)
 216         */
 217        program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
 218
 219        /*
 220         * program the BxCR registers to find out total sdram installed
 221         */
 222        total_size = program_bxcr(dimm_populated, iic0_dimm_addr,
 223                                  num_dimm_banks);
 224
 225#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
 226        /* and program tlb entries for this size (dynamic) */
 227        program_tlb(0, 0, total_size, MY_TLB_WORD2_I_ENABLE);
 228#endif
 229
 230        /*
 231         * program SDRAM Clock Timing Register (SDRAM0_CLKTR)
 232         */
 233        mtsdram(SDRAM0_CLKTR, 0x40000000);
 234
 235        /*
 236         * delay to ensure 200 usec has elapsed
 237         */
 238        udelay(400);
 239
 240        /*
 241         * enable the memory controller
 242         */
 243        mfsdram(SDRAM0_CFG0, cfg0);
 244        mtsdram(SDRAM0_CFG0, cfg0 | SDRAM_CFG0_DCEN);
 245
 246        /*
 247         * wait for SDRAM_CFG0_DC_EN to complete
 248         */
 249        while (1) {
 250                mfsdram(SDRAM0_MCSTS, mcsts);
 251                if ((mcsts & SDRAM_MCSTS_MRSC) != 0)
 252                        break;
 253        }
 254
 255        /*
 256         * program SDRAM Timing Register 1, adding some delays
 257         */
 258        program_tr1();
 259
 260#ifdef CONFIG_DDR_ECC
 261        /*
 262         * If ecc is enabled, initialize the parity bits.
 263         */
 264        ecc_init(CONFIG_SYS_SDRAM_BASE, total_size);
 265#endif
 266
 267        return total_size;
 268}
 269
 270static unsigned char spd_read(uchar chip, uint addr)
 271{
 272        unsigned char data[2];
 273
 274#ifdef CONFIG_SYS_SIMULATE_SPD_EEPROM
 275        if (chip == CONFIG_SYS_SIMULATE_SPD_EEPROM) {
 276                /*
 277                 * Onboard spd eeprom requested -> simulate values
 278                 */
 279                return cfg_simulate_spd_eeprom[addr];
 280        }
 281#endif /* CONFIG_SYS_SIMULATE_SPD_EEPROM */
 282
 283        if (i2c_probe(chip) == 0) {
 284                if (i2c_read(chip, addr, 1, data, 1) == 0) {
 285                        return data[0];
 286                }
 287        }
 288
 289        return 0;
 290}
 291
 292static void get_spd_info(unsigned long *dimm_populated,
 293                         unsigned char *iic0_dimm_addr,
 294                         unsigned long num_dimm_banks)
 295{
 296        unsigned long dimm_num;
 297        unsigned long dimm_found;
 298        unsigned char num_of_bytes;
 299        unsigned char total_size;
 300
 301        dimm_found = FALSE;
 302        for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
 303                num_of_bytes = 0;
 304                total_size = 0;
 305
 306                num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);
 307                total_size = spd_read(iic0_dimm_addr[dimm_num], 1);
 308
 309                if ((num_of_bytes != 0) && (total_size != 0)) {
 310                        dimm_populated[dimm_num] = TRUE;
 311                        dimm_found = TRUE;
 312                        debug("DIMM slot %lu: populated\n", dimm_num);
 313                } else {
 314                        dimm_populated[dimm_num] = FALSE;
 315                        debug("DIMM slot %lu: Not populated\n", dimm_num);
 316                }
 317        }
 318
 319        if (dimm_found == FALSE) {
 320                printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
 321                spd_ddr_init_hang ();
 322        }
 323}
 324
 325static void check_mem_type(unsigned long *dimm_populated,
 326                           unsigned char *iic0_dimm_addr,
 327                           unsigned long num_dimm_banks)
 328{
 329        unsigned long dimm_num;
 330        unsigned char dimm_type;
 331
 332        for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
 333                if (dimm_populated[dimm_num] == TRUE) {
 334                        dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);
 335                        switch (dimm_type) {
 336                        case 7:
 337                                debug("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);
 338                                break;
 339                        default:
 340                                printf("ERROR: Unsupported DIMM detected in slot %lu.\n",
 341                                       dimm_num);
 342                                printf("Only DDR SDRAM DIMMs are supported.\n");
 343                                printf("Replace the DIMM module with a supported DIMM.\n\n");
 344                                spd_ddr_init_hang ();
 345                                break;
 346                        }
 347                }
 348        }
 349}
 350
 351static void check_volt_type(unsigned long *dimm_populated,
 352                            unsigned char *iic0_dimm_addr,
 353                            unsigned long num_dimm_banks)
 354{
 355        unsigned long dimm_num;
 356        unsigned long voltage_type;
 357
 358        for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
 359                if (dimm_populated[dimm_num] == TRUE) {
 360                        voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);
 361                        if (voltage_type != 0x04) {
 362                                printf("ERROR: DIMM %lu with unsupported voltage level.\n",
 363                                       dimm_num);
 364                                spd_ddr_init_hang ();
 365                        } else {
 366                                debug("DIMM %lu voltage level supported.\n", dimm_num);
 367                        }
 368                        break;
 369                }
 370        }
 371}
 372
 373static void program_cfg0(unsigned long *dimm_populated,
 374                         unsigned char *iic0_dimm_addr,
 375                         unsigned long num_dimm_banks)
 376{
 377        unsigned long dimm_num;
 378        unsigned long cfg0;
 379        unsigned long ecc_enabled;
 380        unsigned char ecc;
 381        unsigned char attributes;
 382        unsigned long data_width;
 383
 384        /*
 385         * get Memory Controller Options 0 data
 386         */
 387        mfsdram(SDRAM0_CFG0, cfg0);
 388
 389        /*
 390         * clear bits
 391         */
 392        cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK |
 393                  SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD |
 394                  SDRAM_CFG0_DMWD_MASK |
 395                  SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP);
 396
 397
 398        /*
 399         * FIXME: assume the DDR SDRAMs in both banks are the same
 400         */
 401        ecc_enabled = TRUE;
 402        for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
 403                if (dimm_populated[dimm_num] == TRUE) {
 404                        ecc = spd_read(iic0_dimm_addr[dimm_num], 11);
 405                        if (ecc != 0x02) {
 406                                ecc_enabled = FALSE;
 407                        }
 408
 409                        /*
 410                         * program Registered DIMM Enable
 411                         */
 412                        attributes = spd_read(iic0_dimm_addr[dimm_num], 21);
 413                        if ((attributes & 0x02) != 0x00) {
 414                                cfg0 |= SDRAM_CFG0_RDEN;
 415                        }
 416
 417                        /*
 418                         * program DDR SDRAM Data Width
 419                         */
 420                        data_width =
 421                                (unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) +
 422                                (((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8);
 423                        if (data_width == 64 || data_width == 72) {
 424                                cfg0 |= SDRAM_CFG0_DMWD_64;
 425                        } else if (data_width == 32 || data_width == 40) {
 426                                cfg0 |= SDRAM_CFG0_DMWD_32;
 427                        } else {
 428                                printf("WARNING: DIMM with datawidth of %lu bits.\n",
 429                                       data_width);
 430                                printf("Only DIMMs with 32 or 64 bit datawidths supported.\n");
 431                                spd_ddr_init_hang ();
 432                        }
 433                        break;
 434                }
 435        }
 436
 437        /*
 438         * program Memory Data Error Checking
 439         */
 440        if (ecc_enabled == TRUE) {
 441                cfg0 |= SDRAM_CFG0_MCHK_GEN;
 442        } else {
 443                cfg0 |= SDRAM_CFG0_MCHK_NON;
 444        }
 445
 446        /*
 447         * program Page Management Unit (0 == enabled)
 448         */
 449        cfg0 &= ~SDRAM_CFG0_PMUD;
 450
 451        /*
 452         * program Memory Controller Options 0
 453         * Note: DCEN must be enabled after all DDR SDRAM controller
 454         * configuration registers get initialized.
 455         */
 456        mtsdram(SDRAM0_CFG0, cfg0);
 457}
 458
 459static void program_cfg1(unsigned long *dimm_populated,
 460                         unsigned char *iic0_dimm_addr,
 461                         unsigned long num_dimm_banks)
 462{
 463        unsigned long cfg1;
 464        mfsdram(SDRAM0_CFG1, cfg1);
 465
 466        /*
 467         * Self-refresh exit, disable PM
 468         */
 469        cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN);
 470
 471        /*
 472         * program Memory Controller Options 1
 473         */
 474        mtsdram(SDRAM0_CFG1, cfg1);
 475}
 476
 477static void program_rtr(unsigned long *dimm_populated,
 478                        unsigned char *iic0_dimm_addr,
 479                        unsigned long num_dimm_banks)
 480{
 481        unsigned long dimm_num;
 482        unsigned long bus_period_x_10;
 483        unsigned long refresh_rate = 0;
 484        unsigned char refresh_rate_type;
 485        unsigned long refresh_interval;
 486        unsigned long sdram_rtr;
 487        PPC4xx_SYS_INFO sys_info;
 488
 489        /*
 490         * get the board info
 491         */
 492        get_sys_info(&sys_info);
 493        bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
 494
 495        for (dimm_num = 0;  dimm_num < num_dimm_banks; dimm_num++) {
 496                if (dimm_populated[dimm_num] == TRUE) {
 497                        refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12);
 498                        switch (refresh_rate_type) {
 499                        case 0x00:
 500                                refresh_rate = 15625;
 501                                break;
 502                        case 0x01:
 503                                refresh_rate = 15625/4;
 504                                break;
 505                        case 0x02:
 506                                refresh_rate = 15625/2;
 507                                break;
 508                        case 0x03:
 509                                refresh_rate = 15626*2;
 510                                break;
 511                        case 0x04:
 512                                refresh_rate = 15625*4;
 513                                break;
 514                        case 0x05:
 515                                refresh_rate = 15625*8;
 516                                break;
 517                        default:
 518                                printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n",
 519                                       dimm_num);
 520                                printf("Replace the DIMM module with a supported DIMM.\n");
 521                                break;
 522                        }
 523
 524                        break;
 525                }
 526        }
 527
 528        refresh_interval = refresh_rate * 10 / bus_period_x_10;
 529        sdram_rtr = (refresh_interval & 0x3ff8) <<  16;
 530
 531        /*
 532         * program Refresh Timer Register (SDRAM0_RTR)
 533         */
 534        mtsdram(SDRAM0_RTR, sdram_rtr);
 535}
 536
 537static void program_tr0(unsigned long *dimm_populated,
 538                         unsigned char *iic0_dimm_addr,
 539                         unsigned long num_dimm_banks)
 540{
 541        unsigned long dimm_num;
 542        unsigned long tr0;
 543        unsigned char wcsbc;
 544        unsigned char t_rp_ns;
 545        unsigned char t_rcd_ns;
 546        unsigned char t_ras_ns;
 547        unsigned long t_rp_clk;
 548        unsigned long t_ras_rcd_clk;
 549        unsigned long t_rcd_clk;
 550        unsigned long t_rfc_clk;
 551        unsigned long plb_check;
 552        unsigned char cas_bit;
 553        unsigned long cas_index;
 554        unsigned char cas_2_0_available;
 555        unsigned char cas_2_5_available;
 556        unsigned char cas_3_0_available;
 557        unsigned long cycle_time_ns_x_10[3];
 558        unsigned long tcyc_3_0_ns_x_10;
 559        unsigned long tcyc_2_5_ns_x_10;
 560        unsigned long tcyc_2_0_ns_x_10;
 561        unsigned long tcyc_reg;
 562        unsigned long bus_period_x_10;
 563        PPC4xx_SYS_INFO sys_info;
 564        unsigned long residue;
 565
 566        /*
 567         * get the board info
 568         */
 569        get_sys_info(&sys_info);
 570        bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
 571
 572        /*
 573         * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
 574         */
 575        mfsdram(SDRAM0_TR0, tr0);
 576        tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK |
 577                 SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK |
 578                 SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK |
 579                 SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK);
 580
 581        /*
 582         * initialization
 583         */
 584        wcsbc = 0;
 585        t_rp_ns = 0;
 586        t_rcd_ns = 0;
 587        t_ras_ns = 0;
 588        cas_2_0_available = TRUE;
 589        cas_2_5_available = TRUE;
 590        cas_3_0_available = TRUE;
 591        tcyc_2_0_ns_x_10 = 0;
 592        tcyc_2_5_ns_x_10 = 0;
 593        tcyc_3_0_ns_x_10 = 0;
 594
 595        for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
 596                if (dimm_populated[dimm_num] == TRUE) {
 597                        wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15);
 598                        t_rp_ns  = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2;
 599                        t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2;
 600                        t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30);
 601                        cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);
 602
 603                        for (cas_index = 0; cas_index < 3; cas_index++) {
 604                                switch (cas_index) {
 605                                case 0:
 606                                        tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);
 607                                        break;
 608                                case 1:
 609                                        tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23);
 610                                        break;
 611                                default:
 612                                        tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25);
 613                                        break;
 614                                }
 615
 616                                if ((tcyc_reg & 0x0F) >= 10) {
 617                                        printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n",
 618                                               dimm_num);
 619                                        spd_ddr_init_hang ();
 620                                }
 621
 622                                cycle_time_ns_x_10[cas_index] =
 623                                        (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F);
 624                        }
 625
 626                        cas_index = 0;
 627
 628                        if ((cas_bit & 0x80) != 0) {
 629                                cas_index += 3;
 630                        } else if ((cas_bit & 0x40) != 0) {
 631                                cas_index += 2;
 632                        } else if ((cas_bit & 0x20) != 0) {
 633                                cas_index += 1;
 634                        }
 635
 636                        if (((cas_bit & 0x10) != 0) && (cas_index < 3)) {
 637                                tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
 638                                cas_index++;
 639                        } else {
 640                                if (cas_index != 0) {
 641                                        cas_index++;
 642                                }
 643                                cas_3_0_available = FALSE;
 644                        }
 645
 646                        if (((cas_bit & 0x08) != 0) || (cas_index < 3)) {
 647                                tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index];
 648                                cas_index++;
 649                        } else {
 650                                if (cas_index != 0) {
 651                                        cas_index++;
 652                                }
 653                                cas_2_5_available = FALSE;
 654                        }
 655
 656                        if (((cas_bit & 0x04) != 0) || (cas_index < 3)) {
 657                                tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
 658                                cas_index++;
 659                        } else {
 660                                if (cas_index != 0) {
 661                                        cas_index++;
 662                                }
 663                                cas_2_0_available = FALSE;
 664                        }
 665
 666                        break;
 667                }
 668        }
 669
 670        /*
 671         * Program SD_WR and SD_WCSBC fields
 672         */
 673        tr0 |= SDRAM_TR0_SDWR_2_CLK;                /* Write Recovery: 2 CLK */
 674        switch (wcsbc) {
 675        case 0:
 676                tr0 |= SDRAM_TR0_SDWD_0_CLK;
 677                break;
 678        default:
 679                tr0 |= SDRAM_TR0_SDWD_1_CLK;
 680                break;
 681        }
 682
 683        /*
 684         * Program SD_CASL field
 685         */
 686        if ((cas_2_0_available == TRUE) &&
 687            (bus_period_x_10 >= tcyc_2_0_ns_x_10)) {
 688                tr0 |= SDRAM_TR0_SDCL_2_0_CLK;
 689        } else if ((cas_2_5_available == TRUE) &&
 690                 (bus_period_x_10 >= tcyc_2_5_ns_x_10)) {
 691                tr0 |= SDRAM_TR0_SDCL_2_5_CLK;
 692        } else if ((cas_3_0_available == TRUE) &&
 693                 (bus_period_x_10 >= tcyc_3_0_ns_x_10)) {
 694                tr0 |= SDRAM_TR0_SDCL_3_0_CLK;
 695        } else {
 696                printf("ERROR: No supported CAS latency with the installed DIMMs.\n");
 697                printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
 698                printf("Make sure the PLB speed is within the supported range.\n");
 699                spd_ddr_init_hang ();
 700        }
 701
 702        /*
 703         * Calculate Trp in clock cycles and round up if necessary
 704         * Program SD_PTA field
 705         */
 706        t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION;
 707        plb_check = ONE_BILLION * t_rp_clk / t_rp_ns;
 708        if (sys_info.freqPLB != plb_check) {
 709                t_rp_clk++;
 710        }
 711        switch ((unsigned long)t_rp_clk) {
 712        case 0:
 713        case 1:
 714        case 2:
 715                tr0 |= SDRAM_TR0_SDPA_2_CLK;
 716                break;
 717        case 3:
 718                tr0 |= SDRAM_TR0_SDPA_3_CLK;
 719                break;
 720        default:
 721                tr0 |= SDRAM_TR0_SDPA_4_CLK;
 722                break;
 723        }
 724
 725        /*
 726         * Program SD_CTP field
 727         */
 728        t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION;
 729        plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns);
 730        if (sys_info.freqPLB != plb_check) {
 731                t_ras_rcd_clk++;
 732        }
 733        switch (t_ras_rcd_clk) {
 734        case 0:
 735        case 1:
 736        case 2:
 737                tr0 |= SDRAM_TR0_SDCP_2_CLK;
 738                break;
 739        case 3:
 740                tr0 |= SDRAM_TR0_SDCP_3_CLK;
 741                break;
 742        case 4:
 743                tr0 |= SDRAM_TR0_SDCP_4_CLK;
 744                break;
 745        default:
 746                tr0 |= SDRAM_TR0_SDCP_5_CLK;
 747                break;
 748        }
 749
 750        /*
 751         * Program SD_LDF field
 752         */
 753        tr0 |= SDRAM_TR0_SDLD_2_CLK;
 754
 755        /*
 756         * Program SD_RFTA field
 757         * FIXME tRFC hardcoded as 75 nanoseconds
 758         */
 759        t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75);
 760        residue = sys_info.freqPLB % (ONE_BILLION / 75);
 761        if (residue >= (ONE_BILLION / 150)) {
 762                t_rfc_clk++;
 763        }
 764        switch (t_rfc_clk) {
 765        case 0:
 766        case 1:
 767        case 2:
 768        case 3:
 769        case 4:
 770        case 5:
 771        case 6:
 772                tr0 |= SDRAM_TR0_SDRA_6_CLK;
 773                break;
 774        case 7:
 775                tr0 |= SDRAM_TR0_SDRA_7_CLK;
 776                break;
 777        case 8:
 778                tr0 |= SDRAM_TR0_SDRA_8_CLK;
 779                break;
 780        case 9:
 781                tr0 |= SDRAM_TR0_SDRA_9_CLK;
 782                break;
 783        case 10:
 784                tr0 |= SDRAM_TR0_SDRA_10_CLK;
 785                break;
 786        case 11:
 787                tr0 |= SDRAM_TR0_SDRA_11_CLK;
 788                break;
 789        case 12:
 790                tr0 |= SDRAM_TR0_SDRA_12_CLK;
 791                break;
 792        default:
 793                tr0 |= SDRAM_TR0_SDRA_13_CLK;
 794                break;
 795        }
 796
 797        /*
 798         * Program SD_RCD field
 799         */
 800        t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION;
 801        plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns;
 802        if (sys_info.freqPLB != plb_check) {
 803                t_rcd_clk++;
 804        }
 805        switch (t_rcd_clk) {
 806        case 0:
 807        case 1:
 808        case 2:
 809                tr0 |= SDRAM_TR0_SDRD_2_CLK;
 810                break;
 811        case 3:
 812                tr0 |= SDRAM_TR0_SDRD_3_CLK;
 813                break;
 814        default:
 815                tr0 |= SDRAM_TR0_SDRD_4_CLK;
 816                break;
 817        }
 818
 819        debug("tr0: %lx\n", tr0);
 820        mtsdram(SDRAM0_TR0, tr0);
 821}
 822
 823static int short_mem_test(void)
 824{
 825        unsigned long i, j;
 826        unsigned long bxcr_num;
 827        unsigned long *membase;
 828        const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
 829                {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
 830                 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
 831                {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
 832                 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
 833                {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
 834                 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
 835                {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
 836                 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
 837                {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
 838                 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
 839                {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
 840                 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
 841                {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
 842                 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
 843                {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
 844                 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}};
 845
 846        for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {
 847                mtdcr(SDRAM0_CFGADDR, SDRAM0_B0CR + (bxcr_num << 2));
 848                if ((mfdcr(SDRAM0_CFGDATA) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {
 849                        /* Bank is enabled */
 850                        membase = (unsigned long*)
 851                                (mfdcr(SDRAM0_CFGDATA) & SDRAM_BXCR_SDBA_MASK);
 852
 853                        /*
 854                         * Run the short memory test
 855                         */
 856                        for (i = 0; i < NUMMEMTESTS; i++) {
 857                                for (j = 0; j < NUMMEMWORDS; j++) {
 858                                        /* printf("bank enabled base:%x\n", &membase[j]); */
 859                                        membase[j] = test[i][j];
 860                                        ppcDcbf((unsigned long)&(membase[j]));
 861                                }
 862
 863                                for (j = 0; j < NUMMEMWORDS; j++) {
 864                                        if (membase[j] != test[i][j]) {
 865                                                ppcDcbf((unsigned long)&(membase[j]));
 866                                                return 0;
 867                                        }
 868                                        ppcDcbf((unsigned long)&(membase[j]));
 869                                }
 870
 871                                if (j < NUMMEMWORDS)
 872                                        return 0;
 873                        }
 874
 875                        /*
 876                         * see if the rdclt value passed
 877                         */
 878                        if (i < NUMMEMTESTS)
 879                                return 0;
 880                }
 881        }
 882
 883        return 1;
 884}
 885
 886static void program_tr1(void)
 887{
 888        unsigned long tr0;
 889        unsigned long tr1;
 890        unsigned long cfg0;
 891        unsigned long ecc_temp;
 892        unsigned long dlycal;
 893        unsigned long dly_val;
 894        unsigned long k;
 895        unsigned long max_pass_length;
 896        unsigned long current_pass_length;
 897        unsigned long current_fail_length;
 898        unsigned long current_start;
 899        unsigned long rdclt;
 900        unsigned long rdclt_offset;
 901        long max_start;
 902        long max_end;
 903        long rdclt_average;
 904        unsigned char window_found;
 905        unsigned char fail_found;
 906        unsigned char pass_found;
 907        PPC4xx_SYS_INFO sys_info;
 908
 909        /*
 910         * get the board info
 911         */
 912        get_sys_info(&sys_info);
 913
 914        /*
 915         * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
 916         */
 917        mfsdram(SDRAM0_TR1, tr1);
 918        tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK |
 919                 SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK);
 920
 921        mfsdram(SDRAM0_TR0, tr0);
 922        if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) &&
 923            (sys_info.freqPLB > 100000000)) {
 924                tr1 |= SDRAM_TR1_RDSS_TR2;
 925                tr1 |= SDRAM_TR1_RDSL_STAGE3;
 926                tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
 927        } else {
 928                tr1 |= SDRAM_TR1_RDSS_TR1;
 929                tr1 |= SDRAM_TR1_RDSL_STAGE2;
 930                tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
 931        }
 932
 933        /*
 934         * save CFG0 ECC setting to a temporary variable and turn ECC off
 935         */
 936        mfsdram(SDRAM0_CFG0, cfg0);
 937        ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK;
 938        mtsdram(SDRAM0_CFG0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON);
 939
 940        /*
 941         * get the delay line calibration register value
 942         */
 943        mfsdram(SDRAM0_DLYCAL, dlycal);
 944        dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;
 945
 946        max_pass_length = 0;
 947        max_start = 0;
 948        max_end = 0;
 949        current_pass_length = 0;
 950        current_fail_length = 0;
 951        current_start = 0;
 952        rdclt_offset = 0;
 953        window_found = FALSE;
 954        fail_found = FALSE;
 955        pass_found = FALSE;
 956        debug("Starting memory test ");
 957
 958        for (k = 0; k < NUMHALFCYCLES; k++) {
 959                for (rdclt = 0; rdclt < dly_val; rdclt++) {
 960                        /*
 961                         * Set the timing reg for the test.
 962                         */
 963                        mtsdram(SDRAM0_TR1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));
 964
 965                        if (short_mem_test()) {
 966                                if (fail_found == TRUE) {
 967                                        pass_found = TRUE;
 968                                        if (current_pass_length == 0) {
 969                                                current_start = rdclt_offset + rdclt;
 970                                        }
 971
 972                                        current_fail_length = 0;
 973                                        current_pass_length++;
 974
 975                                        if (current_pass_length > max_pass_length) {
 976                                                max_pass_length = current_pass_length;
 977                                                max_start = current_start;
 978                                                max_end = rdclt_offset + rdclt;
 979                                        }
 980                                }
 981                        } else {
 982                                current_pass_length = 0;
 983                                current_fail_length++;
 984
 985                                if (current_fail_length >= (dly_val>>2)) {
 986                                        if (fail_found == FALSE) {
 987                                                fail_found = TRUE;
 988                                        } else if (pass_found == TRUE) {
 989                                                window_found = TRUE;
 990                                                break;
 991                                        }
 992                                }
 993                        }
 994                }
 995                debug(".");
 996
 997                if (window_found == TRUE) {
 998                        break;
 999                }
1000
1001                tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
1002                rdclt_offset += dly_val;
1003        }
1004        debug("\n");
1005
1006        /*
1007         * make sure we find the window
1008         */
1009        if (window_found == FALSE) {
1010                printf("ERROR: Cannot determine a common read delay.\n");
1011                spd_ddr_init_hang ();
1012        }
1013
1014        /*
1015         * restore the orignal ECC setting
1016         */
1017        mtsdram(SDRAM0_CFG0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp);
1018
1019        /*
1020         * set the SDRAM TR1 RDCD value
1021         */
1022        tr1 &= ~SDRAM_TR1_RDCD_MASK;
1023        if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) {
1024                tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
1025        } else {
1026                tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
1027        }
1028
1029        /*
1030         * set the SDRAM TR1 RDCLT value
1031         */
1032        tr1 &= ~SDRAM_TR1_RDCT_MASK;
1033        while (max_end >= (dly_val << 1)) {
1034                max_end -= (dly_val << 1);
1035                max_start -= (dly_val << 1);
1036        }
1037
1038        rdclt_average = ((max_start + max_end) >> 1);
1039
1040        if (rdclt_average < 0) {
1041                rdclt_average = 0;
1042        }
1043
1044        if (rdclt_average >= dly_val) {
1045                rdclt_average -= dly_val;
1046                tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
1047        }
1048        tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);
1049
1050        debug("tr1: %lx\n", tr1);
1051
1052        /*
1053         * program SDRAM Timing Register 1 TR1
1054         */
1055        mtsdram(SDRAM0_TR1, tr1);
1056}
1057
1058static unsigned long program_bxcr(unsigned long *dimm_populated,
1059                                  unsigned char *iic0_dimm_addr,
1060                                  unsigned long num_dimm_banks)
1061{
1062        unsigned long dimm_num;
1063        unsigned long bank_base_addr;
1064        unsigned long cr;
1065        unsigned long i;
1066        unsigned long j;
1067        unsigned long temp;
1068        unsigned char num_row_addr;
1069        unsigned char num_col_addr;
1070        unsigned char num_banks;
1071        unsigned char bank_size_id;
1072        unsigned long ctrl_bank_num[MAXBANKS];
1073        unsigned long bx_cr_num;
1074        unsigned long largest_size_index;
1075        unsigned long largest_size;
1076        unsigned long current_size_index;
1077        BANKPARMS bank_parms[MAXBXCR];
1078        unsigned long sorted_bank_num[MAXBXCR]; /* DDR Controller bank number table (sorted by size) */
1079        unsigned long sorted_bank_size[MAXBXCR]; /* DDR Controller bank size table (sorted by size)*/
1080
1081        /*
1082         * Set the BxCR regs.  First, wipe out the bank config registers.
1083         */
1084        for (bx_cr_num = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
1085                mtdcr(SDRAM0_CFGADDR, SDRAM0_B0CR + (bx_cr_num << 2));
1086                mtdcr(SDRAM0_CFGDATA, 0x00000000);
1087                bank_parms[bx_cr_num].bank_size_bytes = 0;
1088        }
1089
1090#ifdef CONFIG_BAMBOO
1091        /*
1092         * This next section is hardware dependent and must be programmed
1093         * to match the hardware.  For bamboo, the following holds...
1094         * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 (soldered onboard)
1095         * 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1
1096         * 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1
1097         * 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3
1098         * ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM
1099         */
1100        ctrl_bank_num[0] = 0;
1101        ctrl_bank_num[1] = 1;
1102        ctrl_bank_num[2] = 3;
1103#else
1104        /*
1105         * Ocotea, Ebony and the other IBM/AMCC eval boards have
1106         * 2 DIMM slots with each max 2 banks
1107         */
1108        ctrl_bank_num[0] = 0;
1109        ctrl_bank_num[1] = 2;
1110#endif
1111
1112        /*
1113         * reset the bank_base address
1114         */
1115        bank_base_addr = CONFIG_SYS_SDRAM_BASE;
1116
1117        for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
1118                if (dimm_populated[dimm_num] == TRUE) {
1119                        num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3);
1120                        num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
1121                        num_banks    = spd_read(iic0_dimm_addr[dimm_num], 5);
1122                        bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
1123                        debug("DIMM%ld: row=%d col=%d banks=%d\n", dimm_num,
1124                              num_row_addr, num_col_addr, num_banks);
1125
1126                        /*
1127                         * Set the SDRAM0_BxCR regs
1128                         */
1129                        cr = 0;
1130                        switch (bank_size_id) {
1131                        case 0x02:
1132                                cr |= SDRAM_BXCR_SDSZ_8;
1133                                break;
1134                        case 0x04:
1135                                cr |= SDRAM_BXCR_SDSZ_16;
1136                                break;
1137                        case 0x08:
1138                                cr |= SDRAM_BXCR_SDSZ_32;
1139                                break;
1140                        case 0x10:
1141                                cr |= SDRAM_BXCR_SDSZ_64;
1142                                break;
1143                        case 0x20:
1144                                cr |= SDRAM_BXCR_SDSZ_128;
1145                                break;
1146                        case 0x40:
1147                                cr |= SDRAM_BXCR_SDSZ_256;
1148                                break;
1149                        case 0x80:
1150                                cr |= SDRAM_BXCR_SDSZ_512;
1151                                break;
1152                        default:
1153                                printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",
1154                                       dimm_num);
1155                                printf("ERROR: Unsupported value for the banksize: %d.\n",
1156                                       bank_size_id);
1157                                printf("Replace the DIMM module with a supported DIMM.\n\n");
1158                                spd_ddr_init_hang ();
1159                        }
1160
1161                        switch (num_col_addr) {
1162                        case 0x08:
1163                                cr |= SDRAM_BXCR_SDAM_1;
1164                                break;
1165                        case 0x09:
1166                                cr |= SDRAM_BXCR_SDAM_2;
1167                                break;
1168                        case 0x0A:
1169                                cr |= SDRAM_BXCR_SDAM_3;
1170                                break;
1171                        case 0x0B:
1172                                cr |= SDRAM_BXCR_SDAM_4;
1173                                break;
1174                        default:
1175                                printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",
1176                                       dimm_num);
1177                                printf("ERROR: Unsupported value for number of "
1178                                       "column addresses: %d.\n", num_col_addr);
1179                                printf("Replace the DIMM module with a supported DIMM.\n\n");
1180                                spd_ddr_init_hang ();
1181                        }
1182
1183                        /*
1184                         * enable the bank
1185                         */
1186                        cr |= SDRAM_BXCR_SDBE;
1187
1188                        for (i = 0; i < num_banks; i++) {
1189                                bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
1190                                        (4 << 20) * bank_size_id;
1191                                bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
1192                                debug("DIMM%ld-bank %ld (SDRAM0_B%ldCR): "
1193                                        "bank_size_bytes=%ld\n",
1194                                        dimm_num, i,
1195                                        ctrl_bank_num[dimm_num] + i,
1196                                        bank_parms[ctrl_bank_num[dimm_num] + i].bank_size_bytes);
1197                        }
1198                }
1199        }
1200
1201        /* Initialize sort tables */
1202        for (i = 0; i < MAXBXCR; i++) {
1203                sorted_bank_num[i] = i;
1204                sorted_bank_size[i] = bank_parms[i].bank_size_bytes;
1205        }
1206
1207        for (i = 0; i < MAXBXCR-1; i++) {
1208                largest_size = sorted_bank_size[i];
1209                largest_size_index = 255;
1210
1211                /* Find the largest remaining value */
1212                for (j = i + 1; j < MAXBXCR; j++) {
1213                        if (sorted_bank_size[j] > largest_size) {
1214                                /* Save largest remaining value and its index */
1215                                largest_size = sorted_bank_size[j];
1216                                largest_size_index = j;
1217                        }
1218                }
1219
1220                if (largest_size_index != 255) {
1221                        /* Swap the current and largest values */
1222                        current_size_index = sorted_bank_num[largest_size_index];
1223                        sorted_bank_size[largest_size_index] = sorted_bank_size[i];
1224                        sorted_bank_size[i] = largest_size;
1225                        sorted_bank_num[largest_size_index] = sorted_bank_num[i];
1226                        sorted_bank_num[i] = current_size_index;
1227                }
1228        }
1229
1230        /* Set the SDRAM0_BxCR regs thanks to sort tables */
1231        for (bx_cr_num = 0, bank_base_addr = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
1232                if (bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes) {
1233                        mtdcr(SDRAM0_CFGADDR, SDRAM0_B0CR + (sorted_bank_num[bx_cr_num] << 2));
1234                        temp = mfdcr(SDRAM0_CFGDATA) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK |
1235                                                  SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE);
1236                        temp = temp | (bank_base_addr & SDRAM_BXCR_SDBA_MASK) |
1237                                bank_parms[sorted_bank_num[bx_cr_num]].cr;
1238                        mtdcr(SDRAM0_CFGDATA, temp);
1239                        bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;
1240                        debug("SDRAM0_B%ldCR=0x%08lx\n",
1241                                sorted_bank_num[bx_cr_num], temp);
1242                }
1243        }
1244
1245        return(bank_base_addr);
1246}
1247#endif /* CONFIG_SPD_EEPROM */
1248