uboot/arch/powerpc/cpu/ppc4xx/sdram.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005-2007
   3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   4 *
   5 * (C) Copyright 2006
   6 * DAVE Srl <www.dave-tech.it>
   7 *
   8 * (C) Copyright 2002-2004
   9 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
  10 *
  11 * See file CREDITS for list of people who contributed to this
  12 * project.
  13 *
  14 * This program is free software; you can redistribute it and/or
  15 * modify it under the terms of the GNU General Public License as
  16 * published by the Free Software Foundation; either version 2 of
  17 * the License, or (at your option) any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 * GNU General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, write to the Free Software
  26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  27 * MA 02111-1307 USA
  28 */
  29
  30#include <common.h>
  31#include <asm/ppc4xx.h>
  32#include <asm/processor.h>
  33#include "sdram.h"
  34#include "ecc.h"
  35
  36#ifdef CONFIG_SDRAM_BANK0
  37
  38#ifndef CONFIG_440
  39
  40#ifndef CONFIG_SYS_SDRAM_TABLE
  41sdram_conf_t mb0cf[] = {
  42        {(128 << 20), 13, 0x000A4001},      /* (0-128MB) Address Mode 3, 13x10(4) */
  43        {(64 << 20),  13, 0x00084001},      /* (0-64MB) Address Mode 3, 13x9(4)   */
  44        {(32 << 20),  12, 0x00062001},      /* (0-32MB) Address Mode 2, 12x9(4)   */
  45        {(16 << 20),  12, 0x00046001},      /* (0-16MB) Address Mode 4, 12x8(4)   */
  46        {(4 << 20),   11, 0x00008001},      /* (0-4MB) Address Mode 5, 11x8(2)    */
  47};
  48#else
  49sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
  50#endif
  51
  52#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
  53
  54#ifdef CONFIG_SYS_SDRAM_CASL
  55static ulong ns2clks(ulong ns)
  56{
  57        ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
  58
  59        return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
  60}
  61#endif /* CONFIG_SYS_SDRAM_CASL */
  62
  63static ulong compute_sdtr1(ulong speed)
  64{
  65#ifdef CONFIG_SYS_SDRAM_CASL
  66        ulong tmp;
  67        ulong sdtr1 = 0;
  68
  69        /* CASL */
  70        if (CONFIG_SYS_SDRAM_CASL < 2)
  71                sdtr1 |= (1 << SDRAM0_TR_CASL);
  72        else
  73                if (CONFIG_SYS_SDRAM_CASL > 4)
  74                        sdtr1 |= (3 << SDRAM0_TR_CASL);
  75                else
  76                        sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL);
  77
  78        /* PTA */
  79        tmp = ns2clks(CONFIG_SYS_SDRAM_PTA);
  80        if ((tmp >= 2) && (tmp <= 4))
  81                sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
  82        else
  83                sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
  84
  85        /* CTP */
  86        tmp = ns2clks(CONFIG_SYS_SDRAM_CTP);
  87        if ((tmp >= 2) && (tmp <= 4))
  88                sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
  89        else
  90                sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
  91
  92        /* LDF */
  93        tmp = ns2clks(CONFIG_SYS_SDRAM_LDF);
  94        if ((tmp >= 2) && (tmp <= 4))
  95                sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
  96        else
  97                sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
  98
  99        /* RFTA */
 100        tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA);
 101        if ((tmp >= 4) && (tmp <= 10))
 102                sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
 103        else
 104                sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
 105
 106        /* RCD */
 107        tmp = ns2clks(CONFIG_SYS_SDRAM_RCD);
 108        if ((tmp >= 2) && (tmp <= 4))
 109                sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
 110        else
 111                sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
 112
 113        return sdtr1;
 114#else /* CONFIG_SYS_SDRAM_CASL */
 115        /*
 116         * If no values are configured in the board config file
 117         * use the default values, which seem to be ok for most
 118         * boards.
 119         *
 120         * REMARK:
 121         * For new board ports we strongly recommend to define the
 122         * correct values for the used SDRAM chips in your board
 123         * config file (see PPChameleonEVB.h)
 124         */
 125        if (speed > 100000000) {
 126                /*
 127                 * 133 MHz SDRAM
 128                 */
 129                return 0x01074015;
 130        } else {
 131                /*
 132                 * default: 100 MHz SDRAM
 133                 */
 134                return 0x0086400d;
 135        }
 136#endif /* CONFIG_SYS_SDRAM_CASL */
 137}
 138
 139/* refresh is expressed in ms */
 140static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
 141{
 142#ifdef CONFIG_SYS_SDRAM_CASL
 143        ulong tmp;
 144
 145        tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
 146        tmp /= 1000000;
 147
 148        return ((tmp & 0x00003FF8) << 16);
 149#else /* CONFIG_SYS_SDRAM_CASL */
 150        if (speed > 100000000) {
 151                /*
 152                 * 133 MHz SDRAM
 153                 */
 154                return 0x07f00000;
 155        } else {
 156                /*
 157                 * default: 100 MHz SDRAM
 158                 */
 159                return 0x05f00000;
 160        }
 161#endif /* CONFIG_SYS_SDRAM_CASL */
 162}
 163
 164/*
 165 * Autodetect onboard SDRAM on 405 platforms
 166 */
 167phys_size_t initdram(int board_type)
 168{
 169        ulong speed;
 170        ulong sdtr1;
 171        int i;
 172
 173        /*
 174         * Determine SDRAM speed
 175         */
 176        speed = get_bus_freq(0); /* parameter not used on ppc4xx */
 177
 178        /*
 179         * sdtr1 (register SDRAM0_TR) must take into account timings listed
 180         * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
 181         * account actual SDRAM size. So we can set up sdtr1 according to what
 182         * is specified in board configuration file while rtr dependds on SDRAM
 183         * size we are assuming before detection.
 184         */
 185        sdtr1 = compute_sdtr1(speed);
 186
 187        for (i=0; i<N_MB0CF; i++) {
 188                /*
 189                 * Disable memory controller.
 190                 */
 191                mtsdram(SDRAM0_CFG, 0x00000000);
 192
 193                /*
 194                 * Set MB0CF for bank 0.
 195                 */
 196                mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
 197                mtsdram(SDRAM0_TR, sdtr1);
 198                mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64));
 199
 200                udelay(200);
 201
 202                /*
 203                 * Set memory controller options reg, MCOPT1.
 204                 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
 205                 * read/prefetch.
 206                 */
 207                mtsdram(SDRAM0_CFG, 0x80800000);
 208
 209                udelay(10000);
 210
 211                if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
 212                        phys_size_t size = mb0cf[i].size;
 213
 214                        /*
 215                         * OK, size detected.  Enable second bank if
 216                         * defined (assumes same type as bank 0)
 217                         */
 218#ifdef CONFIG_SDRAM_BANK1
 219                        mtsdram(SDRAM0_CFG, 0x00000000);
 220                        mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
 221                        mtsdram(SDRAM0_CFG, 0x80800000);
 222                        udelay(10000);
 223
 224                        /*
 225                         * Check if 2nd bank is really available.
 226                         * If the size not equal to the size of the first
 227                         * bank, then disable the 2nd bank completely.
 228                         */
 229                        if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
 230                            mb0cf[i].size) {
 231                                mtsdram(SDRAM0_B1CR, 0);
 232                                mtsdram(SDRAM0_CFG, 0);
 233                        } else {
 234                                /*
 235                                 * We have two identical banks, so the size
 236                                 * is twice the bank size
 237                                 */
 238                                size = 2 * size;
 239                        }
 240#endif
 241
 242                        /*
 243                         * OK, size detected -> all done
 244                         */
 245                        return size;
 246                }
 247        }
 248
 249        return 0;
 250}
 251
 252#else /* CONFIG_440 */
 253
 254/*
 255 * Define some default values. Those can be overwritten in the
 256 * board config file.
 257 */
 258
 259#ifndef CONFIG_SYS_SDRAM_TABLE
 260sdram_conf_t mb0cf[] = {
 261        {(256 << 20), 13, 0x000C4001},  /* 256MB mode 3, 13x10(4)       */
 262        {(128 << 20), 13, 0x000A4001},  /* 128MB mode 3, 13x10(4)       */
 263        {(64 << 20),  12, 0x00082001}   /* 64MB mode 2, 12x9(4)         */
 264};
 265#else
 266sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
 267#endif
 268
 269#ifndef CONFIG_SYS_SDRAM0_TR0
 270#define CONFIG_SYS_SDRAM0_TR0           0x41094012
 271#endif
 272
 273#ifndef CONFIG_SYS_SDRAM0_WDDCTR
 274#define CONFIG_SYS_SDRAM0_WDDCTR        0x00000000  /* wrcp=0 dcd=0     */
 275#endif
 276
 277#ifndef CONFIG_SYS_SDRAM0_RTR
 278#define CONFIG_SYS_SDRAM0_RTR           0x04100000 /* 7.8us @ 133MHz PLB */
 279#endif
 280
 281#ifndef CONFIG_SYS_SDRAM0_CFG0
 282#define CONFIG_SYS_SDRAM0_CFG0          0x82000000 /* DCEN=1, PMUD=0, 64-bit */
 283#endif
 284
 285#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
 286
 287#define NUM_TRIES 64
 288#define NUM_READS 10
 289
 290static void sdram_tr1_set(int ram_address, int* tr1_value)
 291{
 292        int i;
 293        int j, k;
 294        volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
 295        int first_good = -1, last_bad = 0x1ff;
 296
 297        unsigned long test[NUM_TRIES] = {
 298                0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
 299                0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
 300                0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
 301                0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
 302                0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
 303                0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
 304                0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
 305                0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
 306                0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
 307                0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
 308                0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
 309                0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
 310                0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
 311                0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
 312                0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
 313                0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
 314
 315        /* go through all possible SDRAM0_TR1[RDCT] values */
 316        for (i=0; i<=0x1ff; i++) {
 317                /* set the current value for TR1 */
 318                mtsdram(SDRAM0_TR1, (0x80800800 | i));
 319
 320                /* write values */
 321                for (j=0; j<NUM_TRIES; j++) {
 322                        ram_pointer[j] = test[j];
 323
 324                        /* clear any cache at ram location */
 325                        __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
 326                }
 327
 328                /* read values back */
 329                for (j=0; j<NUM_TRIES; j++) {
 330                        for (k=0; k<NUM_READS; k++) {
 331                                /* clear any cache at ram location */
 332                                __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
 333
 334                                if (ram_pointer[j] != test[j])
 335                                        break;
 336                        }
 337
 338                        /* read error */
 339                        if (k != NUM_READS)
 340                                break;
 341                }
 342
 343                /* we have a SDRAM0_TR1[RDCT] that is part of the window */
 344                if (j == NUM_TRIES) {
 345                        if (first_good == -1)
 346                                first_good = i;         /* found beginning of window */
 347                } else { /* bad read */
 348                        /* if we have not had a good read then don't care */
 349                        if (first_good != -1) {
 350                                /* first failure after a good read */
 351                                last_bad = i-1;
 352                                break;
 353                        }
 354                }
 355        }
 356
 357        /* return the current value for TR1 */
 358        *tr1_value = (first_good + last_bad) / 2;
 359}
 360
 361/*
 362 * Autodetect onboard DDR SDRAM on 440 platforms
 363 *
 364 * NOTE: Some of the hardcoded values are hardware dependant,
 365 *       so this should be extended for other future boards
 366 *       using this routine!
 367 */
 368phys_size_t initdram(int board_type)
 369{
 370        int i;
 371        int tr1_bank1;
 372
 373#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
 374    defined(CONFIG_440GR) || defined(CONFIG_440SP)
 375        /*
 376         * Soft-reset SDRAM controller.
 377         */
 378        mtsdr(SDR0_SRST, SDR0_SRST_DMC);
 379        mtsdr(SDR0_SRST, 0x00000000);
 380#endif
 381
 382        for (i=0; i<N_MB0CF; i++) {
 383                /*
 384                 * Disable memory controller.
 385                 */
 386                mtsdram(SDRAM0_CFG0, 0x00000000);
 387
 388                /*
 389                 * Setup some default
 390                 */
 391                mtsdram(SDRAM0_UABBA, 0x00000000); /* ubba=0 (default)          */
 392                mtsdram(SDRAM0_SLIO, 0x00000000);       /* rdre=0 wrre=0 rarw=0         */
 393                mtsdram(SDRAM0_DEVOPT, 0x00000000); /* dll=0 ds=0 (normal)              */
 394                mtsdram(SDRAM0_WDDCTR, CONFIG_SYS_SDRAM0_WDDCTR);
 395                mtsdram(SDRAM0_CLKTR, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
 396
 397                /*
 398                 * Following for CAS Latency = 2.5 @ 133 MHz PLB
 399                 */
 400                mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
 401                mtsdram(SDRAM0_TR0, CONFIG_SYS_SDRAM0_TR0);
 402                mtsdram(SDRAM0_TR1, 0x80800800);        /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
 403                mtsdram(SDRAM0_RTR, CONFIG_SYS_SDRAM0_RTR);
 404                mtsdram(SDRAM0_CFG1, 0x00000000);       /* Self-refresh exit, disable PM*/
 405                udelay(400);                    /* Delay 200 usecs (min)        */
 406
 407                /*
 408                 * Enable the controller, then wait for DCEN to complete
 409                 */
 410                mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
 411                udelay(10000);
 412
 413                if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
 414                        phys_size_t size = mb0cf[i].size;
 415                        /*
 416                         * Optimize TR1 to current hardware environment
 417                         */
 418                        sdram_tr1_set(0x00000000, &tr1_bank1);
 419                        mtsdram(SDRAM0_TR1, (tr1_bank1 | 0x80800800));
 420
 421
 422                        /*
 423                         * OK, size detected.  Enable second bank if
 424                         * defined (assumes same type as bank 0)
 425                         */
 426#ifdef CONFIG_SDRAM_BANK1
 427                        mtsdram(SDRAM0_CFG0, 0);
 428                        mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
 429                        mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
 430                        udelay(10000);
 431
 432                        /*
 433                         * Check if 2nd bank is really available.
 434                         * If the size not equal to the size of the first
 435                         * bank, then disable the 2nd bank completely.
 436                         */
 437                        if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size)
 438                            != mb0cf[i].size) {
 439                                mtsdram(SDRAM0_CFG0, 0);
 440                                mtsdram(SDRAM0_B1CR, 0);
 441                                mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
 442                                udelay(10000);
 443                        } else {
 444                                /*
 445                                 * We have two identical banks, so the size
 446                                 * is twice the bank size
 447                                 */
 448                                size = 2 * size;
 449                        }
 450#endif
 451
 452#ifdef CONFIG_SDRAM_ECC
 453                        ecc_init(0, size);
 454#endif
 455
 456                        /*
 457                         * OK, size detected -> all done
 458                         */
 459                        return size;
 460                }
 461        }
 462
 463        return 0;                               /* nothing found !              */
 464}
 465
 466#endif /* CONFIG_440 */
 467
 468#endif /* CONFIG_SDRAM_BANK0 */
 469